From 6beb446925c967aca92f5513adf36c5db77c00d6 Mon Sep 17 00:00:00 2001 From: TATTAVARADA Date: Thu, 27 Apr 2017 07:53:18 -0400 Subject: [PATCH] [PORTAL-7] Rebase This rebasing includes common libraries and common overlays projects abstraction of components Change-Id: Ia1efa4deacdc5701e6205104ac021a6c80ed60ba Signed-off-by: st782s --- ecomp-sdk/LICENSE.txt | 19 - ecomp-sdk/README.md | 12 +- ecomp-sdk/epsdk-analytics/.gitignore | 5 + ecomp-sdk/epsdk-analytics/README.md | 16 + .../epsdk-analytics/license/licenses.properties | 1 + .../epsdk-analytics/license/my_license/header.txt | 11 + .../epsdk-analytics/license/my_license/license.txt | 4 + ecomp-sdk/epsdk-analytics/pom.xml | 209 + .../openecomp/portalsdk/analytics/AntBuild.java | 91 + .../portalsdk/analytics/RaptorObject.java | 0 .../portalsdk/analytics/config/ConfigLoader.java | 193 + .../portalsdk/analytics/controller/Action.java | 91 + .../analytics/controller/ActionHandler.java | 2417 ++ .../analytics/controller/ActionMapping.java | 34 + .../portalsdk/analytics/controller/Controller.java | 125 + .../analytics/controller/ErrorHandler.java | 151 + .../analytics/controller/WizardProcessor.java | 2356 ++ .../analytics/controller/WizardSequence.java | 191 + .../controller/WizardSequenceCrossTab.java | 45 + .../controller/WizardSequenceDashboard.java | 40 + .../analytics/controller/WizardSequenceLinear.java | 47 + .../controller/WizardSequenceSQLBasedCrossTab.java | 44 + .../controller/WizardSequenceSQLBasedHive.java | 46 + .../controller/WizardSequenceSQLBasedLinear.java | 47 + .../WizardSequenceSQLBasedLinearDatamining.java | 46 + .../portalsdk/analytics/error/RaptorException.java | 0 .../analytics/error/RaptorRuntimeException.java | 0 .../analytics/error/RaptorSchedularException.java | 0 .../analytics/error/ReportSQLException.java | 0 .../analytics/error/UserAccessException.java | 0 .../analytics/error/UserDefinedException.java | 36 + .../analytics/error/ValidationException.java | 0 .../portalsdk/analytics/gmap/line/Line.java | 0 .../analytics/gmap/line/LineCollection.java | 0 .../portalsdk/analytics/gmap/line/LineInfo.java | 0 .../analytics/gmap/map/ColorProperties.java | 0 .../analytics/gmap/map/GMapProperties.java | 49 + .../analytics/gmap/map/GeoCoordinate.java | 0 .../portalsdk/analytics/gmap/map/MapConstant.java | 0 .../portalsdk/analytics/gmap/map/NovaMap.java | 0 .../analytics/gmap/map/layer/SwingLayer.java | 235 + .../portalsdk/analytics/gmap/node/Node.java | 0 .../analytics/gmap/node/NodeCollection.java | 0 .../portalsdk/analytics/gmap/node/NodeInfo.java | 0 .../portalsdk/analytics/gmap/utils/MapUtils.java | 70 + .../analytics/gmap/utils/SwingWorker.java | 0 .../portalsdk/analytics/model/DataCache.java | 516 + .../portalsdk/analytics/model/ReportHandler.java | 6638 +++ .../portalsdk/analytics/model/ReportLoader.java | 1079 + .../portalsdk/analytics/model/SearchHandler.java | 479 + .../analytics/model/base/ChartSeqComparator.java | 0 .../analytics/model/base/IdNameColLookup.java | 37 + .../portalsdk/analytics/model/base/IdNameList.java | 183 + .../analytics/model/base/IdNameLookup.java | 204 + .../portalsdk/analytics/model/base/IdNameSql.java | 400 + .../analytics/model/base/IdNameValue.java | 100 + .../analytics/model/base/NameComparator.java | 34 + .../analytics/model/base/OrderBySeqComparator.java | 0 .../analytics/model/base/OrderSeqComparator.java | 0 .../analytics/model/base/ReportSecurity.java | 404 + .../analytics/model/base/ReportWrapper.java | 5719 +++ .../analytics/model/definition/DBColumnInfo.java | 0 .../model/definition/DrillDownParamDef.java | 0 .../analytics/model/definition/Marker.java | 0 .../model/definition/ReportDefinition.java | 1471 + .../analytics/model/definition/ReportLogEntry.java | 0 .../analytics/model/definition/ReportMap.java | 86 + .../analytics/model/definition/ReportSchedule.java | 0 .../analytics/model/definition/SecurityEntry.java | 44 + .../analytics/model/definition/TableJoin.java | 0 .../analytics/model/definition/TableSource.java | 0 .../model/definition/wizard/ColumnEditJSON.java | 110 + .../model/definition/wizard/ColumnJSON.java | 41 + .../model/definition/wizard/DefinitionJSON.java | 215 + .../model/definition/wizard/ElementJSON.java | 33 + .../model/definition/wizard/FormEditJSON.java | 113 + .../model/definition/wizard/IdNameBooleanJSON.java | 32 + .../model/definition/wizard/ImportJSON.java | 54 + .../model/definition/wizard/ListJSON.java | 40 + .../model/definition/wizard/MessageJSON.java | 55 + .../model/definition/wizard/NameBooleanJSON.java | 25 + .../model/definition/wizard/QueryJSON.java | 60 + .../model/definition/wizard/QueryResultJSON.java | 70 + .../model/definition/wizard/SearchFieldJSON.java | 41 + .../model/definition/wizard/WizardJSON.java | 9 + .../portalsdk/analytics/model/pdf/PageEvent.java | 256 + .../portalsdk/analytics/model/pdf/PdfBean.java | 0 .../analytics/model/pdf/PdfReportHandler.java | 1898 + .../analytics/model/runtime/BarChartOptions.java | 0 .../analytics/model/runtime/CategoryAxisJSON.java | 0 .../analytics/model/runtime/ChartD3Helper.java | 4073 ++ .../analytics/model/runtime/ChartJSON.java | 451 + .../analytics/model/runtime/ChartJSONHelper.java | 0 .../analytics/model/runtime/ChartWebRuntime.java | 423 + .../model/runtime/CommonChartOptions.java | 81 + .../analytics/model/runtime/ErrorJSONRuntime.java | 58 + .../model/runtime/FlexTimeSeriesChartOptions.java | 0 .../analytics/model/runtime/FormField.java | 2103 + .../analytics/model/runtime/FormatProcessor.java | 369 + .../portalsdk/analytics/model/runtime/Item.java | 0 .../analytics/model/runtime/LookupDBInfo.java | 0 .../analytics/model/runtime/RangeAxisJSON.java | 93 + .../analytics/model/runtime/ReportFormFields.java | 356 + .../analytics/model/runtime/ReportJSONRuntime.java | 709 + .../model/runtime/ReportParamDateValueParser.java | 196 + .../analytics/model/runtime/ReportParamValues.java | 369 + .../runtime/ReportParamValuesForPDFExcel.java | 0 .../analytics/model/runtime/ReportRuntime.java | 3401 ++ .../model/runtime/TimeSeriesChartOptions.java | 0 .../analytics/model/runtime/VisualManager.java | 69 + .../analytics/model/search/ReportSearchResult.java | 85 + .../model/search/ReportSearchResultJSON.java | 249 + .../analytics/model/search/SearchResult.java | 212 + .../analytics/model/search/SearchResultColumn.java | 256 + .../analytics/model/search/SearchResultField.java | 214 + .../analytics/model/search/SearchResultJSON.java | 86 + .../analytics/model/search/SearchResultRow.java | 92 + .../analytics/scheduler/SchedulerUtil.java | 369 + .../portalsdk/analytics/scheduler/SendEmail.java | 416 + .../analytics/scheduler/SendNotifications.java | 462 + .../portalsdk/analytics/system/AppUtils.java | 344 + .../analytics/system/ConnectionUtils.java | 0 .../portalsdk/analytics/system/DbUtils.java | 271 + .../portalsdk/analytics/system/ExecuteQuery.java | 61 + .../portalsdk/analytics/system/Globals.java | 2307 + .../portalsdk/analytics/system/IAppUtils.java | 177 + .../portalsdk/analytics/system/IDbUtils.java | 36 + .../portalsdk/analytics/system/RDbUtils.java | 35 + .../portalsdk/analytics/system/RemDbUtils.java | 0 .../analytics/system/fusion/AntBuild.java | 67 + .../analytics/system/fusion/AppUtils.java | 367 + .../portalsdk/analytics/system/fusion/DbUtils.java | 78 + .../analytics/system/fusion/RemoteDbUtils.java | 57 + .../adapter/AdapterSessionFactoryContainer.java | 39 + .../analytics/system/fusion/adapter/DateUtils.java | 0 .../system/fusion/adapter/FusionAdapter.java | 121 + .../analytics/system/fusion/adapter/IdName.java | 67 + .../analytics/system/fusion/adapter/Item.java | 0 .../analytics/system/fusion/adapter/Lookup.java | 85 + .../system/fusion/adapter/RaptorAdapter.java | 367 + .../system/fusion/adapter/SpringContext.java | 0 .../fusion/controller/FileServletController.java | 0 .../analytics/system/fusion/domain/CR_Report.java | 307 + .../analytics/system/fusion/domain/QuickLink.java | 0 .../system/fusion/domain/RaptorSearch.java | 0 .../analytics/system/fusion/domain/ReportInfo.java | 0 .../system/fusion/service/RaptorService.java | 35 + .../system/fusion/service/RaptorServiceImpl.java | 183 + .../system/fusion/web/RaptorController.java | 190 + .../system/fusion/web/RaptorControllerAsync.java | 1752 + .../fusion/web/ReportsSearchListController.java | 77 + .../portalsdk/analytics/util/AppConstants.java | 667 + .../portalsdk/analytics/util/DataSet.java | 177 + .../portalsdk/analytics/util/ExcelColorDef.java | 65 + .../portalsdk/analytics/util/HtmlStripper.java | 157 + .../openecomp/portalsdk/analytics/util/Log.java | 0 .../portalsdk/analytics/util/RemDbInfo.java | 0 .../portalsdk/analytics/util/SQLCorrector.java | 0 .../portalsdk/analytics/util/Scheduler.java | 91 + .../openecomp/portalsdk/analytics/util/Utils.java | 372 + .../portalsdk/analytics/util/XSSFilter.java | 91 + .../portalsdk/analytics/util/jar/ExtractJar.java | 237 + .../analytics/util/upgrade/SystemUpgrade.java | 127 + .../portalsdk/analytics/view/ColumnHeader.java | 241 + .../portalsdk/analytics/view/ColumnHeaderRow.java | 102 + .../portalsdk/analytics/view/ColumnVisual.java | 0 .../analytics/view/CrossTabColumnValues.java | 75 + .../analytics/view/CrossTabOrderManager.java | 98 + .../analytics/view/CrossTabTotalValue.java | 56 + .../portalsdk/analytics/view/DataRow.java | 168 + .../portalsdk/analytics/view/DataValue.java | 361 + .../portalsdk/analytics/view/HtmlFormatter.java | 0 .../analytics/view/ReportColumnHeaderRows.java | 71 + .../portalsdk/analytics/view/ReportData.java | 813 + .../portalsdk/analytics/view/ReportDataRows.java | 72 + .../analytics/view/ReportRowHeaderCols.java | 71 + .../portalsdk/analytics/view/RowHeader.java | 121 + .../portalsdk/analytics/view/RowHeaderCol.java | 158 + .../analytics/xmlobj/ChartAdditionalOptions.java | 0 .../analytics/xmlobj/ChartDrillFormfield.java | 0 .../analytics/xmlobj/ChartDrillOptions.java | 206 + .../portalsdk/analytics/xmlobj/ColFilterList.java | 93 + .../portalsdk/analytics/xmlobj/ColFilterType.java | 0 .../analytics/xmlobj/CustomReportType.java | 0 .../analytics/xmlobj/DashboardEditorList.java | 93 + .../analytics/xmlobj/DashboardEditorReport.java | 0 .../analytics/xmlobj/DashboardReports.java | 93 + .../analytics/xmlobj/DashboardReportsNew.java | 147 + .../portalsdk/analytics/xmlobj/DataColumnList.java | 95 + .../portalsdk/analytics/xmlobj/DataColumnType.java | 0 .../portalsdk/analytics/xmlobj/DataSourceList.java | 93 + .../portalsdk/analytics/xmlobj/DataSourceType.java | 0 .../analytics/xmlobj/DataminingOptions.java | 0 .../portalsdk/analytics/xmlobj/FormFieldList.java | 120 + .../portalsdk/analytics/xmlobj/FormFieldType.java | 0 .../portalsdk/analytics/xmlobj/FormatList.java | 95 + .../portalsdk/analytics/xmlobj/FormatType.java | 0 .../analytics/xmlobj/JavascriptItemType.java | 0 .../portalsdk/analytics/xmlobj/JavascriptList.java | 93 + .../portalsdk/analytics/xmlobj/Marker.java | 0 .../portalsdk/analytics/xmlobj/ObjectFactory.java | 0 .../analytics/xmlobj/PDFAdditionalOptions.java | 0 .../analytics/xmlobj/PredefinedValueList.java | 93 + .../portalsdk/analytics/xmlobj/ReportMap.java | 444 + .../portalsdk/analytics/xmlobj/Reports.java | 0 .../portalsdk/analytics/xmlobj/SemaphoreList.java | 93 + .../portalsdk/analytics/xmlobj/SemaphoreType.java | 0 ecomp-sdk/epsdk-app-common/.gitignore | 5 + ecomp-sdk/epsdk-app-common/README.md | 31 + .../db-scripts/EcompSdkDDLMySql_1707_Common.sql | 1399 + .../db-scripts/EcompSdkDMLMySql_1707_Common.sql | 2837 ++ ecomp-sdk/epsdk-app-common/db-scripts/readme.txt | 54 + ecomp-sdk/epsdk-app-common/pom.xml | 294 + .../portalapp/controller/core/AdminController.java | 52 + .../controller/core/AngularAdminController.java | 51 + .../controller/core/CacheAdminController.java | 248 + .../controller/core/FavoritesController.java | 118 + .../controller/core/FnMenuController.java | 223 + .../controller/core/FuncMenuController.java | 175 + .../controller/core/LogoutController.java | 113 + .../controller/core/ManifestController.java | 111 + .../controller/core/MenuListController.java | 255 + .../controller/core/PostSearchController.java | 211 + .../controller/core/ProfileController.java | 352 + .../controller/core/ProfileSearchController.java | 163 + .../portalapp/controller/core/RoleController.java | 342 + .../core/RoleFunctionListController.java | 172 + .../controller/core/RoleListController.java | 170 + .../controller/core/SDKLoginController.java | 99 + .../controller/core/SingleSignOnController.java | 223 + .../controller/core/UsageListController.java | 165 + .../controller/core/UserProfileController.java | 68 + .../controller/core/WelcomeController.java | 43 + .../portalapp/controller/core/package-info.java | 6 + .../sample/AngularSinglePageController.java | 49 + .../controller/sample/BroadcastController.java | 131 + .../controller/sample/BroadcastListController.java | 143 + .../controller/sample/CallflowController.java | 45 + .../sample/CamundaCockpitController.java | 60 + .../sample/CollaborateListController.java | 85 + .../controller/sample/CollaborationController.java | 55 + .../controller/sample/DS2SampleController.java | 54 + .../controller/sample/ElasticSearchController.java | 128 + .../controller/sample/ElementModelController.java | 87 + .../controller/sample/LeafletMapContoller.java | 43 + .../controller/sample/NetMapController.java | 57 + .../controller/sample/PostDroolsController.java | 122 + .../sample/ReportDashboardController.java | 46 + .../controller/sample/SamplePageController.java | 50 + .../portalapp/controller/sample/package-info.java | 5 + .../java/org/openecomp/portalapp/model/Result.java | 37 + .../org/openecomp/portalapp/scheduler/LogJob.java | 45 + .../openecomp/portalapp/scheduler/LogRegistry.java | 57 + .../portalapp/service/IAdminAuthExtension.java | 65 + .../service/OnBoardingApiServiceImpl.java | 361 + .../portalapp/util/CustomLoggingFilter.java | 54 + .../main/webapp/app/fusion/external/d3/js/intro.js | 1 + .../java/org/openecomp/portalapp/SanityTest.java | 20 + .../controller/CollaborationControllerTest.java | 29 + .../openecomp/portalapp/controller/NetMapTest.java | 19 + .../core/MockApplicationContextTestSuite.java | 127 + .../portalapp/service/ProfileServiceTest.java | 39 + .../services/WorkflowScheduleServiceTest.java | 44 + ecomp-sdk/epsdk-app-os/.gitignore | 5 + ecomp-sdk/epsdk-app-os/README.md | 66 + .../db-scripts/EcompSdkDDLMySql_1707_OS.sql | 12 + .../db-scripts/EcompSdkDMLMySql_1707_OS.sql | 40 + .../EcompSdkMySql_Rollback_1707_to_1610.2_OS.sql | 57 + .../EcompSdkMySql_Upgrade_1610.2_to_1707_OS.sql | 59 + ecomp-sdk/epsdk-app-os/db-scripts/readme.txt | 36 + ecomp-sdk/epsdk-app-os/distribution.xml | 33 + ecomp-sdk/epsdk-app-os/pom.xml | 305 + .../portalapp/conf/ExternalAppConfig.java | 161 + .../portalapp/conf/ExternalAppInitializer.java | 47 + .../portalapp/conf/HibernateMappingLocations.java | 57 + .../portalapp/lm/FusionLicenseManagerImpl.java | 69 + .../portalapp/lm/LicenseableClassImpl.java | 62 + .../portalapp/login/LoginStrategyImpl.java | 70 + .../openecomp/portalapp/scheduler/Register.java | 71 + .../portalapp/scheduler/RegistryAdapter.java | 92 + .../portalapp/service/AdminAuthExtension.java | 64 + .../epsdk-app-os/src/main/resources/logback.xml | 370 + .../src/main/resources/portal.properties | 52 + .../src/main/webapp/WEB-INF/conf/system.properties | 69 + .../src/main/webapp/WEB-INF/defs/definitions.xml | 17 + .../webapp/WEB-INF/fusion/conf/fusion.properties | 29 + .../main/webapp/WEB-INF/fusion/jsp/ds2/footer.jsp | 17 + .../main/webapp/WEB-INF/fusion/jsp/ds2/header.jsp | 1 + .../webapp/WEB-INF/fusion/jsp/ds2/left-menu.jsp | 778 + .../fusion/orm/RNoteBookIntegration.hbm.xml | 0 .../src/main/webapp/WEB-INF}/index.jsp | 0 .../src/main/webapp/WEB-INF/jsp/login.jsp | 113 + .../src/main/webapp/WEB-INF/jsp/login_external.jsp | 117 + .../epsdk-app-os/src/main/webapp/WEB-INF/web.xml | 17 + .../external/b2b/css/b2b-angular/font_icons.css | 1 + .../ds2/css/digital-ng-library/ionicons.css | 1493 + .../fusion/external/ds2/css}/fonts/ionicons.eot | Bin .../fusion/external/ds2/css}/fonts/ionicons.svg | 0 .../fusion/external/ds2/css}/fonts/ionicons.ttf | Bin .../fusion/external/ds2/css}/fonts/ionicons.woff | Bin .../DS2-controllers/ds-profile/post-controller.js | 3 + .../scripts/DS2-controllers/samplePage-route.js | 19 + .../app/fusion/scripts/DS2-services/postSearch.js | 5 + .../scripts/DS2-view-models/ds2-profile/post.html | 3 + .../ds2-profile/profile_searchDS2.html | 59 + .../DS2-view-models/ds2-profile/self_profile.html | 189 + .../ds2-samplePages/samplePage.html | 62 + .../app/fusion/scripts/DS2-view-models/footer.html | 13 + .../app/fusion/scripts/utils/page-resource-ds2.js | 97 + .../app/fusion/scripts/view-models/footer.html | 17 + .../css}/att_angular_gridster/sandbox-gridster.css | 0 .../css/att_angular_gridster/ui-gridster.css | 116 + .../main/webapp/static/fusion/css/fusion-sunny.css | 362 + .../fusion/images/att_angular_gridster/grips.png | Bin .../static/fusion/images/ecomp-login-550x360.jpg | Bin 0 -> 62502 bytes .../webapp/static/fusion/images/ecomp-login.jpg | Bin 0 -> 21266 bytes .../src/main/webapp/static/fusion/images/ecomp.png | Bin .../webapp/static/fusion/images/ecomp_trans.png | Bin .../js}/att_angular_gridster/angular-gridster.js | 0 .../js}/att_angular_gridster/ui-gridster-tpls.js | 0 .../webapp/static/fusion/sample/css/flexslider.css | 275 + .../fusion/sample/css/fonts/flexslider-icon.eot | Bin 0 -> 2082 bytes .../fusion/sample/css/fonts/flexslider-icon.svg | 19 + .../fusion/sample/css/fonts/flexslider-icon.ttf | Bin 0 -> 1892 bytes .../fusion/sample/css/fonts/flexslider-icon.woff | Bin 0 -> 1268 bytes .../static/fusion/sample/css}/images/blank.gif | Bin .../webapp/static/fusion/sample/css/scribble.css | 0 .../webapp/static/fusion/sample/css/slider.css | 0 .../static/fusion/sample/css/spacegallery.css | 0 .../webapp/static/fusion/sample/css/welcome.css | 173 + .../static/fusion/sample/html/area_chart.html | 0 .../static/fusion/sample/html/bar_chart.html | 0 .../static/fusion/sample/html/d3_gauges_demo.html | 0 .../fusion/sample/html/data/speedometer2.csv | 0 .../fusion/sample/html/data/speedometer3.csv | 0 .../static/fusion/sample/html/data/worddata.csv | 1 + .../webapp/static/fusion/sample/html/donut_d3.html | 0 .../static/fusion/sample/html/js/area_chart.min.js | 0 .../static/fusion/sample/html/js/donut.min.js | 0 .../static/fusion/sample/html/js/gauges.min.js | 0 .../static/fusion/sample/html/js/line_chart.min.js | 0 .../static/fusion/sample/html/js/pie_chart.min.js | 0 .../static/fusion/sample/html/js/worddata.min.js | 0 .../static/fusion/sample/html/line_chart.html | 0 .../static/fusion/sample/html/pie_chart.html | 0 .../static/fusion/sample/html/wordcloud.html | 36 + .../static/fusion/sample/images/Calendar-16x16.png | Bin .../static/fusion/sample}/images/arrow-next.png | Bin .../static/fusion/sample}/images/arrow-prev.png | Bin .../images/carousel/slide_b_drive_test_map.png | Bin .../sample/images/carousel/slide_b_eppt_county.png | Bin .../images/carousel/slide_b_eppt_regression.png | Bin .../images/carousel/slide_b_ios_throughput.png | Bin .../sample/images/carousel/slide_b_lata_map.png | Bin .../images/carousel/slide_b_lata_map_legend.png | Bin .../images/carousel/slide_b_nova_sdn_map.png | Bin .../static/fusion/sample}/images/copyicon.png | Bin .../static/fusion/sample}/images/deleteicon.gif | Bin .../static/fusion/sample}/images/example-frame.png | Bin .../static/fusion/sample}/images/loading.gif | Bin .../static/fusion/sample/images/tunnels/1_mon.png | Bin .../static/fusion/sample/images/tunnels/2_tue.png | Bin .../static/fusion/sample/images/tunnels/3_wed.png | Bin .../static/fusion/sample/images/tunnels/4_thu.png | Bin .../static/fusion/sample/images/tunnels/5_fri.png | Bin .../static/fusion/sample/images/tunnels/6_sat.png | Bin .../static/fusion/sample/images/tunnels/7_sun.png | Bin .../fusion/sample/images/tunnels/BH_DLSTX_IN.png | Bin .../fusion/sample/images/tunnels/BH_DLSTX_OUT.png | Bin .../static/fusion/sample/images/tunnels/BH_Nat.png | Bin .../fusion/sample/images/tunnels/BH_Nat_Def.png | Bin .../sample/images/tunnels/BH_Nat_Priority.png | Bin .../webapp/static/fusion/sample/js/FusionCharts.js | 0 .../main/webapp/static/fusion/sample/js/charts.js | 0 .../src/main/webapp/static/fusion/sample/js/eye.js | 0 .../fusion/sample/js/jquery.flexslider-min.js | 0 .../webapp/static/fusion/sample/js/scribble.js | 0 .../static/fusion/sample/js/slides.min.jquery.js | 0 .../webapp/static/fusion/sample/js/spacegallery.js | 0 .../main/webapp/static/fusion/sample/js/utils.js | 0 .../fusion/sample/org_chart/css/bootstrap.min.css | 0 .../static/fusion/sample/org_chart/css/custom.css | 0 .../sample/org_chart/css/jquery.jOrgChart.css | 0 .../fusion/sample/org_chart/css/prettify.css | 0 .../static/fusion/sample/org_chart/example.html | 0 .../fusion/sample/org_chart/example_vsp.html | 0 .../static/fusion/sample/org_chart/images/bkgd.png | Bin .../fusion/sample/org_chart/images/raspberry.jpg | Bin .../fusion/sample/org_chart/jquery.jOrgChart.js | 0 .../static/fusion/sample/org_chart/prettify.js | 0 ecomp-sdk/epsdk-app-overlay/.gitignore | 5 + ecomp-sdk/epsdk-app-overlay/README.md | 24 + ecomp-sdk/epsdk-app-overlay/pom.xml | 52 + .../src/main/resources/att-rules.drl | 0 .../src/main/resources/cache.ccf | 0 .../src/main/resources/mchange-log.properties | 0 .../src/main/resources/state-rules.drl | 0 .../src/main/webapp/WEB-INF/conf/quartz.properties | 29 + .../src/main/webapp/WEB-INF/conf/raptor.properties | 172 + .../WEB-INF/conf/raptor_app_fusion.properties | 20 + .../WEB-INF/conf/raptor_db_fusion.properties} | 0 .../main/webapp/WEB-INF/conf/raptor_pdf.properties | 30 + .../src/main/webapp/WEB-INF/conf/sql.properties | 305 + .../main/webapp/WEB-INF/conf/sql.properties.oracle | 282 + .../webapp/WEB-INF/fusion/conf/fusion.properties | 43 + .../webapp/WEB-INF/fusion/defs/definitions.xml | 194 + .../src/main/webapp/WEB-INF/fusion/jsp/.gitignore} | 0 .../main/webapp/WEB-INF/fusion/jsp/broadcast.jsp | 137 + .../webapp/WEB-INF/fusion/jsp/broadcast_list.jsp | 201 + .../main/webapp/WEB-INF/fusion/jsp/data_out.jsp | 0 .../webapp/WEB-INF/fusion/jsp/ds2/template.jsp | 101 + .../webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp | 41 + .../webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp | 747 + .../WEB-INF/fusion/jsp/ebz/loginSnippet.html | 115 + .../webapp/WEB-INF/fusion/jsp/ebz_template.jsp | 45 + .../fusion/jsp/ebz_template_noheader_nofooter.jsp | 35 + .../fusion/jsp/ebz_template_report_embedded.jsp | 48 + .../webapp/WEB-INF/fusion/jsp/es_search_demo.jsp | 97 + .../webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp | 97 + .../webapp/WEB-INF/fusion/jsp/frame_insert.jsp | 44 + .../src/main/webapp/WEB-INF/fusion/jsp/include.jsp | 0 .../src/main/webapp/WEB-INF/fusion/jsp/meta.jsp | 36 + .../webapp/WEB-INF/fusion/jsp/popup_modal.html | 0 .../WEB-INF/fusion/jsp/popup_modal_role.html | 0 .../fusion/jsp/popup_modal_rolefunction.html | 0 .../webapp/WEB-INF/fusion/jsp/sequence/details.jsp | 1 + .../WEB-INF/fusion/jsp/webrtc/collaboration.jsp | 494 + .../main/webapp/WEB-INF/fusion/orm/Fusion.hbm.xml | 0 .../webapp/WEB-INF/fusion/orm/Workflow.hbm.xml | 0 .../fusion/raptor/custom_header_include.jsp | 0 .../WEB-INF/fusion/raptor/custom_js_include.jsp | 0 .../fusion/raptor/date_end_field_run_sql.jsp | 0 .../fusion/raptor/date_start_field_run_sql.jsp | 0 .../fusion/raptor/default_field_run_sql.jsp | 0 .../webapp/WEB-INF/fusion/raptor/disclaimer.jsp | 0 .../webapp/WEB-INF/fusion/raptor/error_include.jsp | 0 .../webapp/WEB-INF/fusion/raptor/error_page.jsp | 0 .../main/webapp/WEB-INF/fusion/raptor/footer.jsp | 0 .../fusion/raptor/popup_drill_down_report.jsp | 623 + .../fusion/raptor/popup_import_semaphore.jsp | 0 .../WEB-INF/fusion/raptor/popup_semaphore.jsp | 0 .../webapp/WEB-INF/fusion/raptor/popup_sql.jsp | 0 .../WEB-INF/fusion/raptor/popup_table_cols.jsp | 0 .../WEB-INF/fusion/raptor/popup_testrun_sql.jsp | 0 .../WEB-INF/fusion/raptor/report_download_csv.jsp | 0 .../WEB-INF/fusion/raptor/report_download_pdf.jsp | 0 .../WEB-INF/fusion/raptor/report_download_xls.jsp | 0 .../webapp/WEB-INF/fusion/raptor/report_ebz.jsp | 0 .../webapp/WEB-INF/fusion/raptor/report_import.jsp | 84 + .../webapp/WEB-INF/fusion/raptor/report_sample.jsp | 0 .../webapp/WEB-INF/fusion/raptor/report_search.jsp | 0 .../webapp/WEB-INF/fusion/raptor/report_wizard.jsp | 322 + .../WEB-INF/fusion/raptor/test_field_run_sql.jsp | 0 .../webapp/WEB-INF/fusion/raptor/test_run_sql.jsp | 0 .../WEB-INF/fusion/raptor/tree/folderNav.jsp | 464 + .../webapp/WEB-INF/fusion/raptor/tree/testTree.jsp | 229 + .../fusion/raptor/wizard_adhoc_schedule.jsp | 0 .../webapp/WEB-INF/fusion/raptor/wizard_chart.jsp | 0 .../fusion/raptor/wizard_columns_add_multi.jsp | 0 .../WEB-INF/fusion/raptor/wizard_columns_edit.jsp | 0 .../WEB-INF/fusion/raptor/wizard_columns_list.jsp | 0 .../fusion/raptor/wizard_columns_order_all.jsp | 0 .../fusion/raptor/wizard_data_forecasting.jsp | 0 .../WEB-INF/fusion/raptor/wizard_definition.jsp | 0 .../WEB-INF/fusion/raptor/wizard_filters_edit.jsp | 0 .../WEB-INF/fusion/raptor/wizard_filters_list.jsp | 0 .../fusion/raptor/wizard_form_fields_edit.jsp | 0 .../fusion/raptor/wizard_form_fields_list.jsp | 0 .../WEB-INF/fusion/raptor/wizard_javascript.jsp | 0 .../webapp/WEB-INF/fusion/raptor/wizard_log.jsp | 0 .../webapp/WEB-INF/fusion/raptor/wizard_map.jsp | 0 .../webapp/WEB-INF/fusion/raptor/wizard_run.jsp | 0 .../WEB-INF/fusion/raptor/wizard_schedule.jsp | 0 .../raptor/wizard_schedule_formfield_include.jsp | 0 .../fusion/raptor/wizard_schedule_multiple.jsp | 0 .../WEB-INF/fusion/raptor/wizard_schedule_only.jsp | 0 .../raptor/wizard_schedule_only_from_search.jsp | 0 .../WEB-INF/fusion/raptor/wizard_sorting_edit.jsp | 0 .../WEB-INF/fusion/raptor/wizard_sorting_list.jsp | 0 .../fusion/raptor/wizard_sorting_order_all.jsp | 0 .../WEB-INF/fusion/raptor/wizard_sql_def.jsp | 0 .../WEB-INF/fusion/raptor/wizard_tables_edit.jsp | 0 .../WEB-INF/fusion/raptor/wizard_tables_list.jsp | 0 .../WEB-INF/fusion/raptor/wizard_user_access.jsp | 0 .../src/main/webapp/WEB-INF/jsp/error.jsp | 0 .../src/main/webapp/WEB-INF/jsp/leafletMap.jsp | 216 + .../main/webapp/WEB-INF/jsp/login_external_ng.jsp | 79 + .../src/main/webapp/WEB-INF/jsp/net_map.jsp | 0 .../src/main/webapp/WEB-INF/web.xml | 10 + .../external/angular-1.4.8/angular-animate.js | 3930 ++ .../external/angular-1.4.8/angular-animate.min.js | 56 + .../angular-1.4.8/angular-animate.min.js.map | 8 + .../fusion/external/angular-1.4.8/angular-aria.js | 398 + .../external/angular-1.4.8/angular-aria.min.js | 14 + .../external/angular-1.4.8/angular-aria.min.js.map | 8 + .../external/angular-1.4.8/angular-cookies.js | 321 + .../external/angular-1.4.8/angular-cookies.min.js | 9 + .../angular-1.4.8/angular-cookies.min.js.map | 8 + .../fusion/external/angular-1.4.8/angular-csp.css | 21 + .../external/angular-1.4.8/angular-loader.js | 443 + .../external/angular-1.4.8/angular-loader.min.js | 10 + .../angular-1.4.8/angular-loader.min.js.map | 8 + .../angular-1.4.8/angular-message-format.js | 980 + .../angular-1.4.8/angular-message-format.min.js | 26 + .../angular-message-format.min.js.map | 0 .../external/angular-1.4.8/angular-messages.js | 685 + .../external/angular-1.4.8/angular-messages.min.js | 12 + .../angular-1.4.8/angular-messages.min.js.map | 8 + .../fusion/external/angular-1.4.8/angular-mocks.js | 2471 ++ .../external/angular-1.4.8/angular-resource.js | 684 + .../external/angular-1.4.8/angular-resource.min.js | 14 + .../angular-1.4.8/angular-resource.min.js.map | 8 + .../fusion/external/angular-1.4.8/angular-route.js | 991 + .../external/angular-1.4.8/angular-route.min.js | 15 + .../angular-1.4.8/angular-route.min.js.map | 8 + .../external/angular-1.4.8/angular-sanitize.js | 683 + .../external/angular-1.4.8/angular-sanitize.min.js | 16 + .../angular-1.4.8/angular-sanitize.min.js.map | 8 + .../external/angular-1.4.8/angular-scenario.js | 40439 ++++++++++++++++++ .../fusion/external/angular-1.4.8/angular-touch.js | 628 + .../external/angular-1.4.8/angular-touch.min.js | 13 + .../angular-1.4.8/angular-touch.min.js.map | 8 + .../app/fusion/external/angular-1.4.8/angular.js | 29018 +++++++++++++ .../fusion/external/angular-1.4.8/angular.min.js | 295 + .../external/angular-1.4.8/angular.min.js.map | 8 + .../app/fusion/external/angular-1.4.8/errors.json | 1 + .../angular-1.4.8/i18n/angular-locale_aa-dj.js | 128 + .../angular-1.4.8/i18n/angular-locale_aa-er.js | 128 + .../angular-1.4.8/i18n/angular-locale_aa-et.js | 128 + .../angular-1.4.8/i18n/angular-locale_aa.js | 128 + .../angular-1.4.8/i18n/angular-locale_af-na.js | 110 + .../angular-1.4.8/i18n/angular-locale_af-za.js | 110 + .../angular-1.4.8/i18n/angular-locale_af.js | 110 + .../angular-1.4.8/i18n/angular-locale_agq-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_agq.js | 128 + .../angular-1.4.8/i18n/angular-locale_ak-gh.js | 128 + .../angular-1.4.8/i18n/angular-locale_ak.js | 128 + .../angular-1.4.8/i18n/angular-locale_am-et.js | 110 + .../angular-1.4.8/i18n/angular-locale_am.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-001.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-ae.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-bh.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-dj.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-dz.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-eg.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-eh.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-er.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-il.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-iq.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-jo.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-km.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-kw.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-lb.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-ly.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-ma.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-mr.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-om.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-ps.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-qa.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-sa.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-sd.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-so.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-ss.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-sy.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-td.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-tn.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar-ye.js | 110 + .../angular-1.4.8/i18n/angular-locale_ar.js | 110 + .../angular-1.4.8/i18n/angular-locale_as-in.js | 128 + .../angular-1.4.8/i18n/angular-locale_as.js | 128 + .../angular-1.4.8/i18n/angular-locale_asa-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_asa.js | 128 + .../angular-1.4.8/i18n/angular-locale_ast-es.js | 128 + .../angular-1.4.8/i18n/angular-locale_ast.js | 128 + .../i18n/angular-locale_az-cyrl-az.js | 110 + .../angular-1.4.8/i18n/angular-locale_az-cyrl.js | 110 + .../i18n/angular-locale_az-latn-az.js | 110 + .../angular-1.4.8/i18n/angular-locale_az-latn.js | 110 + .../angular-1.4.8/i18n/angular-locale_az.js | 110 + .../angular-1.4.8/i18n/angular-locale_bas-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_bas.js | 128 + .../angular-1.4.8/i18n/angular-locale_be-by.js | 110 + .../angular-1.4.8/i18n/angular-locale_be.js | 110 + .../angular-1.4.8/i18n/angular-locale_bem-zm.js | 128 + .../angular-1.4.8/i18n/angular-locale_bem.js | 128 + .../angular-1.4.8/i18n/angular-locale_bez-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_bez.js | 128 + .../angular-1.4.8/i18n/angular-locale_bg-bg.js | 110 + .../angular-1.4.8/i18n/angular-locale_bg.js | 110 + .../i18n/angular-locale_bm-latn-ml.js | 128 + .../angular-1.4.8/i18n/angular-locale_bm-latn.js | 128 + .../angular-1.4.8/i18n/angular-locale_bm-ml.js | 115 + .../angular-1.4.8/i18n/angular-locale_bm.js | 128 + .../angular-1.4.8/i18n/angular-locale_bn-bd.js | 110 + .../angular-1.4.8/i18n/angular-locale_bn-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_bn.js | 110 + .../angular-1.4.8/i18n/angular-locale_bo-cn.js | 128 + .../angular-1.4.8/i18n/angular-locale_bo-in.js | 128 + .../angular-1.4.8/i18n/angular-locale_bo.js | 128 + .../angular-1.4.8/i18n/angular-locale_br-fr.js | 110 + .../angular-1.4.8/i18n/angular-locale_br.js | 110 + .../angular-1.4.8/i18n/angular-locale_brx-in.js | 128 + .../angular-1.4.8/i18n/angular-locale_brx.js | 128 + .../i18n/angular-locale_bs-cyrl-ba.js | 128 + .../angular-1.4.8/i18n/angular-locale_bs-cyrl.js | 128 + .../i18n/angular-locale_bs-latn-ba.js | 128 + .../angular-1.4.8/i18n/angular-locale_bs-latn.js | 128 + .../angular-1.4.8/i18n/angular-locale_bs.js | 128 + .../angular-1.4.8/i18n/angular-locale_byn-er.js | 115 + .../angular-1.4.8/i18n/angular-locale_byn.js | 115 + .../angular-1.4.8/i18n/angular-locale_ca-ad.js | 128 + .../i18n/angular-locale_ca-es-valencia.js | 128 + .../angular-1.4.8/i18n/angular-locale_ca-es.js | 128 + .../angular-1.4.8/i18n/angular-locale_ca-fr.js | 128 + .../angular-1.4.8/i18n/angular-locale_ca-it.js | 128 + .../angular-1.4.8/i18n/angular-locale_ca.js | 128 + .../angular-1.4.8/i18n/angular-locale_cgg-ug.js | 128 + .../angular-1.4.8/i18n/angular-locale_cgg.js | 128 + .../angular-1.4.8/i18n/angular-locale_chr-us.js | 110 + .../angular-1.4.8/i18n/angular-locale_chr.js | 110 + .../i18n/angular-locale_ckb-arab-iq.js | 128 + .../i18n/angular-locale_ckb-arab-ir.js | 128 + .../angular-1.4.8/i18n/angular-locale_ckb-arab.js | 128 + .../angular-1.4.8/i18n/angular-locale_ckb-iq.js | 128 + .../angular-1.4.8/i18n/angular-locale_ckb-ir.js | 128 + .../i18n/angular-locale_ckb-latn-iq.js | 128 + .../angular-1.4.8/i18n/angular-locale_ckb-latn.js | 128 + .../angular-1.4.8/i18n/angular-locale_ckb.js | 128 + .../angular-1.4.8/i18n/angular-locale_cs-cz.js | 128 + .../angular-1.4.8/i18n/angular-locale_cs.js | 128 + .../angular-1.4.8/i18n/angular-locale_cy-gb.js | 110 + .../angular-1.4.8/i18n/angular-locale_cy.js | 110 + .../angular-1.4.8/i18n/angular-locale_da-dk.js | 141 + .../angular-1.4.8/i18n/angular-locale_da-gl.js | 141 + .../angular-1.4.8/i18n/angular-locale_da.js | 141 + .../angular-1.4.8/i18n/angular-locale_dav-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_dav.js | 128 + .../angular-1.4.8/i18n/angular-locale_de-at.js | 128 + .../angular-1.4.8/i18n/angular-locale_de-be.js | 128 + .../angular-1.4.8/i18n/angular-locale_de-ch.js | 128 + .../angular-1.4.8/i18n/angular-locale_de-de.js | 128 + .../angular-1.4.8/i18n/angular-locale_de-li.js | 128 + .../angular-1.4.8/i18n/angular-locale_de-lu.js | 128 + .../angular-1.4.8/i18n/angular-locale_de.js | 128 + .../angular-1.4.8/i18n/angular-locale_dje-ne.js | 128 + .../angular-1.4.8/i18n/angular-locale_dje.js | 128 + .../angular-1.4.8/i18n/angular-locale_dsb-de.js | 128 + .../angular-1.4.8/i18n/angular-locale_dsb.js | 128 + .../angular-1.4.8/i18n/angular-locale_dua-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_dua.js | 128 + .../angular-1.4.8/i18n/angular-locale_dyo-sn.js | 128 + .../angular-1.4.8/i18n/angular-locale_dyo.js | 128 + .../angular-1.4.8/i18n/angular-locale_dz-bt.js | 128 + .../angular-1.4.8/i18n/angular-locale_dz.js | 128 + .../angular-1.4.8/i18n/angular-locale_ebu-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_ebu.js | 128 + .../angular-1.4.8/i18n/angular-locale_ee-gh.js | 128 + .../angular-1.4.8/i18n/angular-locale_ee-tg.js | 128 + .../angular-1.4.8/i18n/angular-locale_ee.js | 128 + .../angular-1.4.8/i18n/angular-locale_el-cy.js | 110 + .../angular-1.4.8/i18n/angular-locale_el-gr.js | 110 + .../angular-1.4.8/i18n/angular-locale_el.js | 110 + .../angular-1.4.8/i18n/angular-locale_en-001.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-150.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ag.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ai.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-as.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-au.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-bb.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-be.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-bm.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-bs.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-bw.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-bz.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ca.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-cc.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ck.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-cx.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-dg.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-dm.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-er.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-fj.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-fk.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-fm.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-gb.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-gd.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-gg.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-gh.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-gi.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-gm.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-gu.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-gy.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-hk.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ie.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-im.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-in.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-io.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-iso.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-je.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-jm.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ki.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-kn.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ky.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-lc.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-lr.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ls.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-mg.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-mh.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-mo.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-mp.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ms.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-mt.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-mu.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-mw.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-my.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-na.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-nf.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ng.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-nr.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-nu.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-nz.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-pg.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ph.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-pk.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-pn.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-pr.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-pw.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-rw.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-sb.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-sc.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-sd.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-sg.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-sh.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-sl.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ss.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-sx.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-sz.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-tc.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-tk.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-to.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-tt.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-tv.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ug.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-um.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-us.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-vc.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-vg.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-vi.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-vu.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-ws.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-za.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-zm.js | 128 + .../angular-1.4.8/i18n/angular-locale_en-zw.js | 128 + .../angular-1.4.8/i18n/angular-locale_en.js | 128 + .../angular-1.4.8/i18n/angular-locale_eo-001.js | 128 + .../angular-1.4.8/i18n/angular-locale_eo.js | 128 + .../angular-1.4.8/i18n/angular-locale_es-419.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-ar.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-bo.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-cl.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-co.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-cr.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-cu.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-do.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-ea.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-ec.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-es.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-gq.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-gt.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-hn.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-ic.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-mx.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-ni.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-pa.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-pe.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-ph.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-pr.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-py.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-sv.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-us.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-uy.js | 110 + .../angular-1.4.8/i18n/angular-locale_es-ve.js | 110 + .../angular-1.4.8/i18n/angular-locale_es.js | 110 + .../angular-1.4.8/i18n/angular-locale_et-ee.js | 128 + .../angular-1.4.8/i18n/angular-locale_et.js | 128 + .../angular-1.4.8/i18n/angular-locale_eu-es.js | 110 + .../angular-1.4.8/i18n/angular-locale_eu.js | 110 + .../angular-1.4.8/i18n/angular-locale_ewo-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_ewo.js | 128 + .../angular-1.4.8/i18n/angular-locale_fa-af.js | 110 + .../angular-1.4.8/i18n/angular-locale_fa-ir.js | 110 + .../angular-1.4.8/i18n/angular-locale_fa.js | 110 + .../angular-1.4.8/i18n/angular-locale_ff-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_ff-gn.js | 128 + .../angular-1.4.8/i18n/angular-locale_ff-mr.js | 128 + .../angular-1.4.8/i18n/angular-locale_ff-sn.js | 128 + .../angular-1.4.8/i18n/angular-locale_ff.js | 128 + .../angular-1.4.8/i18n/angular-locale_fi-fi.js | 128 + .../angular-1.4.8/i18n/angular-locale_fi.js | 128 + .../angular-1.4.8/i18n/angular-locale_fil-ph.js | 128 + .../angular-1.4.8/i18n/angular-locale_fil.js | 128 + .../angular-1.4.8/i18n/angular-locale_fo-fo.js | 128 + .../angular-1.4.8/i18n/angular-locale_fo.js | 128 + .../angular-1.4.8/i18n/angular-locale_fr-be.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-bf.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-bi.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-bj.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-bl.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-ca.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-cd.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-cf.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-cg.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-ch.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-ci.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-cm.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-dj.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-dz.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-fr.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-ga.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-gf.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-gn.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-gp.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-gq.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-ht.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-km.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-lu.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-ma.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-mc.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-mf.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-mg.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-ml.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-mq.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-mr.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-mu.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-nc.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-ne.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-pf.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-pm.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-re.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-rw.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-sc.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-sn.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-sy.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-td.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-tg.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-tn.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-vu.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-wf.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr-yt.js | 110 + .../angular-1.4.8/i18n/angular-locale_fr.js | 110 + .../angular-1.4.8/i18n/angular-locale_fur-it.js | 128 + .../angular-1.4.8/i18n/angular-locale_fur.js | 128 + .../angular-1.4.8/i18n/angular-locale_fy-nl.js | 128 + .../angular-1.4.8/i18n/angular-locale_fy.js | 128 + .../angular-1.4.8/i18n/angular-locale_ga-ie.js | 110 + .../angular-1.4.8/i18n/angular-locale_ga.js | 110 + .../angular-1.4.8/i18n/angular-locale_gd-gb.js | 128 + .../angular-1.4.8/i18n/angular-locale_gd.js | 128 + .../angular-1.4.8/i18n/angular-locale_gl-es.js | 128 + .../angular-1.4.8/i18n/angular-locale_gl.js | 128 + .../angular-1.4.8/i18n/angular-locale_gsw-ch.js | 110 + .../angular-1.4.8/i18n/angular-locale_gsw-fr.js | 110 + .../angular-1.4.8/i18n/angular-locale_gsw-li.js | 110 + .../angular-1.4.8/i18n/angular-locale_gsw.js | 110 + .../angular-1.4.8/i18n/angular-locale_gu-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_gu.js | 110 + .../angular-1.4.8/i18n/angular-locale_guz-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_guz.js | 128 + .../angular-1.4.8/i18n/angular-locale_gv-im.js | 128 + .../angular-1.4.8/i18n/angular-locale_gv.js | 128 + .../i18n/angular-locale_ha-latn-gh.js | 128 + .../i18n/angular-locale_ha-latn-ne.js | 128 + .../i18n/angular-locale_ha-latn-ng.js | 128 + .../angular-1.4.8/i18n/angular-locale_ha-latn.js | 128 + .../angular-1.4.8/i18n/angular-locale_ha.js | 128 + .../angular-1.4.8/i18n/angular-locale_haw-us.js | 110 + .../angular-1.4.8/i18n/angular-locale_haw.js | 110 + .../angular-1.4.8/i18n/angular-locale_he-il.js | 128 + .../angular-1.4.8/i18n/angular-locale_he.js | 128 + .../angular-1.4.8/i18n/angular-locale_hi-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_hi.js | 110 + .../angular-1.4.8/i18n/angular-locale_hr-ba.js | 128 + .../angular-1.4.8/i18n/angular-locale_hr-hr.js | 128 + .../angular-1.4.8/i18n/angular-locale_hr.js | 128 + .../angular-1.4.8/i18n/angular-locale_hsb-de.js | 128 + .../angular-1.4.8/i18n/angular-locale_hsb.js | 128 + .../angular-1.4.8/i18n/angular-locale_hu-hu.js | 110 + .../angular-1.4.8/i18n/angular-locale_hu.js | 110 + .../angular-1.4.8/i18n/angular-locale_hy-am.js | 110 + .../angular-1.4.8/i18n/angular-locale_hy.js | 110 + .../angular-1.4.8/i18n/angular-locale_ia-fr.js | 128 + .../angular-1.4.8/i18n/angular-locale_ia.js | 128 + .../angular-1.4.8/i18n/angular-locale_id-id.js | 110 + .../angular-1.4.8/i18n/angular-locale_id.js | 110 + .../angular-1.4.8/i18n/angular-locale_ig-ng.js | 128 + .../angular-1.4.8/i18n/angular-locale_ig.js | 128 + .../angular-1.4.8/i18n/angular-locale_ii-cn.js | 128 + .../angular-1.4.8/i18n/angular-locale_ii.js | 128 + .../angular-1.4.8/i18n/angular-locale_in.js | 110 + .../angular-1.4.8/i18n/angular-locale_is-is.js | 141 + .../angular-1.4.8/i18n/angular-locale_is.js | 141 + .../angular-1.4.8/i18n/angular-locale_it-ch.js | 128 + .../angular-1.4.8/i18n/angular-locale_it-it.js | 128 + .../angular-1.4.8/i18n/angular-locale_it-sm.js | 128 + .../angular-1.4.8/i18n/angular-locale_it.js | 128 + .../angular-1.4.8/i18n/angular-locale_iw.js | 128 + .../angular-1.4.8/i18n/angular-locale_ja-jp.js | 110 + .../angular-1.4.8/i18n/angular-locale_ja.js | 110 + .../angular-1.4.8/i18n/angular-locale_jgo-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_jgo.js | 128 + .../angular-1.4.8/i18n/angular-locale_jmc-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_jmc.js | 128 + .../angular-1.4.8/i18n/angular-locale_ka-ge.js | 110 + .../angular-1.4.8/i18n/angular-locale_ka.js | 110 + .../angular-1.4.8/i18n/angular-locale_kab-dz.js | 128 + .../angular-1.4.8/i18n/angular-locale_kab.js | 128 + .../angular-1.4.8/i18n/angular-locale_kam-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_kam.js | 128 + .../angular-1.4.8/i18n/angular-locale_kde-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_kde.js | 128 + .../angular-1.4.8/i18n/angular-locale_kea-cv.js | 128 + .../angular-1.4.8/i18n/angular-locale_kea.js | 128 + .../angular-1.4.8/i18n/angular-locale_khq-ml.js | 128 + .../angular-1.4.8/i18n/angular-locale_khq.js | 128 + .../angular-1.4.8/i18n/angular-locale_ki-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_ki.js | 128 + .../i18n/angular-locale_kk-cyrl-kz.js | 110 + .../angular-1.4.8/i18n/angular-locale_kk-cyrl.js | 110 + .../angular-1.4.8/i18n/angular-locale_kk.js | 110 + .../angular-1.4.8/i18n/angular-locale_kkj-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_kkj.js | 128 + .../angular-1.4.8/i18n/angular-locale_kl-gl.js | 128 + .../angular-1.4.8/i18n/angular-locale_kl.js | 128 + .../angular-1.4.8/i18n/angular-locale_kln-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_kln.js | 128 + .../angular-1.4.8/i18n/angular-locale_km-kh.js | 110 + .../angular-1.4.8/i18n/angular-locale_km.js | 110 + .../angular-1.4.8/i18n/angular-locale_kn-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_kn.js | 110 + .../angular-1.4.8/i18n/angular-locale_ko-kp.js | 110 + .../angular-1.4.8/i18n/angular-locale_ko-kr.js | 110 + .../angular-1.4.8/i18n/angular-locale_ko.js | 110 + .../angular-1.4.8/i18n/angular-locale_kok-in.js | 128 + .../angular-1.4.8/i18n/angular-locale_kok.js | 128 + .../i18n/angular-locale_ks-arab-in.js | 128 + .../angular-1.4.8/i18n/angular-locale_ks-arab.js | 128 + .../angular-1.4.8/i18n/angular-locale_ks.js | 128 + .../angular-1.4.8/i18n/angular-locale_ksb-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_ksb.js | 128 + .../angular-1.4.8/i18n/angular-locale_ksf-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_ksf.js | 128 + .../angular-1.4.8/i18n/angular-locale_ksh-de.js | 128 + .../angular-1.4.8/i18n/angular-locale_ksh.js | 128 + .../angular-1.4.8/i18n/angular-locale_kw-gb.js | 128 + .../angular-1.4.8/i18n/angular-locale_kw.js | 128 + .../i18n/angular-locale_ky-cyrl-kg.js | 110 + .../angular-1.4.8/i18n/angular-locale_ky-cyrl.js | 110 + .../angular-1.4.8/i18n/angular-locale_ky.js | 110 + .../angular-1.4.8/i18n/angular-locale_lag-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_lag.js | 128 + .../angular-1.4.8/i18n/angular-locale_lb-lu.js | 128 + .../angular-1.4.8/i18n/angular-locale_lb.js | 128 + .../angular-1.4.8/i18n/angular-locale_lg-ug.js | 128 + .../angular-1.4.8/i18n/angular-locale_lg.js | 128 + .../angular-1.4.8/i18n/angular-locale_lkt-us.js | 128 + .../angular-1.4.8/i18n/angular-locale_lkt.js | 128 + .../angular-1.4.8/i18n/angular-locale_ln-ao.js | 110 + .../angular-1.4.8/i18n/angular-locale_ln-cd.js | 110 + .../angular-1.4.8/i18n/angular-locale_ln-cf.js | 110 + .../angular-1.4.8/i18n/angular-locale_ln-cg.js | 110 + .../angular-1.4.8/i18n/angular-locale_ln.js | 110 + .../angular-1.4.8/i18n/angular-locale_lo-la.js | 110 + .../angular-1.4.8/i18n/angular-locale_lo.js | 110 + .../angular-1.4.8/i18n/angular-locale_lt-lt.js | 128 + .../angular-1.4.8/i18n/angular-locale_lt.js | 128 + .../angular-1.4.8/i18n/angular-locale_lu-cd.js | 128 + .../angular-1.4.8/i18n/angular-locale_lu.js | 128 + .../angular-1.4.8/i18n/angular-locale_luo-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_luo.js | 128 + .../angular-1.4.8/i18n/angular-locale_luy-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_luy.js | 128 + .../angular-1.4.8/i18n/angular-locale_lv-lv.js | 128 + .../angular-1.4.8/i18n/angular-locale_lv.js | 128 + .../angular-1.4.8/i18n/angular-locale_mas-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_mas-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_mas.js | 128 + .../angular-1.4.8/i18n/angular-locale_mer-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_mer.js | 128 + .../angular-1.4.8/i18n/angular-locale_mfe-mu.js | 128 + .../angular-1.4.8/i18n/angular-locale_mfe.js | 128 + .../angular-1.4.8/i18n/angular-locale_mg-mg.js | 128 + .../angular-1.4.8/i18n/angular-locale_mg.js | 128 + .../angular-1.4.8/i18n/angular-locale_mgh-mz.js | 128 + .../angular-1.4.8/i18n/angular-locale_mgh.js | 128 + .../angular-1.4.8/i18n/angular-locale_mgo-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_mgo.js | 128 + .../angular-1.4.8/i18n/angular-locale_mk-mk.js | 128 + .../angular-1.4.8/i18n/angular-locale_mk.js | 128 + .../angular-1.4.8/i18n/angular-locale_ml-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_ml.js | 110 + .../i18n/angular-locale_mn-cyrl-mn.js | 110 + .../angular-1.4.8/i18n/angular-locale_mn-cyrl.js | 110 + .../angular-1.4.8/i18n/angular-locale_mn.js | 110 + .../angular-1.4.8/i18n/angular-locale_mr-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_mr.js | 110 + .../i18n/angular-locale_ms-latn-bn.js | 110 + .../i18n/angular-locale_ms-latn-my.js | 110 + .../i18n/angular-locale_ms-latn-sg.js | 110 + .../angular-1.4.8/i18n/angular-locale_ms-latn.js | 110 + .../angular-1.4.8/i18n/angular-locale_ms.js | 110 + .../angular-1.4.8/i18n/angular-locale_mt-mt.js | 110 + .../angular-1.4.8/i18n/angular-locale_mt.js | 110 + .../angular-1.4.8/i18n/angular-locale_mua-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_mua.js | 128 + .../angular-1.4.8/i18n/angular-locale_my-mm.js | 110 + .../angular-1.4.8/i18n/angular-locale_my.js | 110 + .../angular-1.4.8/i18n/angular-locale_naq-na.js | 128 + .../angular-1.4.8/i18n/angular-locale_naq.js | 128 + .../angular-1.4.8/i18n/angular-locale_nb-no.js | 110 + .../angular-1.4.8/i18n/angular-locale_nb-sj.js | 110 + .../angular-1.4.8/i18n/angular-locale_nb.js | 110 + .../angular-1.4.8/i18n/angular-locale_nd-zw.js | 128 + .../angular-1.4.8/i18n/angular-locale_nd.js | 128 + .../angular-1.4.8/i18n/angular-locale_ne-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_ne-np.js | 110 + .../angular-1.4.8/i18n/angular-locale_ne.js | 110 + .../angular-1.4.8/i18n/angular-locale_nl-aw.js | 128 + .../angular-1.4.8/i18n/angular-locale_nl-be.js | 128 + .../angular-1.4.8/i18n/angular-locale_nl-bq.js | 128 + .../angular-1.4.8/i18n/angular-locale_nl-cw.js | 128 + .../angular-1.4.8/i18n/angular-locale_nl-nl.js | 128 + .../angular-1.4.8/i18n/angular-locale_nl-sr.js | 128 + .../angular-1.4.8/i18n/angular-locale_nl-sx.js | 128 + .../angular-1.4.8/i18n/angular-locale_nl.js | 128 + .../angular-1.4.8/i18n/angular-locale_nmg-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_nmg.js | 128 + .../angular-1.4.8/i18n/angular-locale_nn-no.js | 128 + .../angular-1.4.8/i18n/angular-locale_nn.js | 128 + .../angular-1.4.8/i18n/angular-locale_nnh-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_nnh.js | 128 + .../angular-1.4.8/i18n/angular-locale_no-no.js | 110 + .../angular-1.4.8/i18n/angular-locale_no.js | 110 + .../angular-1.4.8/i18n/angular-locale_nr-za.js | 128 + .../angular-1.4.8/i18n/angular-locale_nr.js | 128 + .../angular-1.4.8/i18n/angular-locale_nso-za.js | 128 + .../angular-1.4.8/i18n/angular-locale_nso.js | 128 + .../angular-1.4.8/i18n/angular-locale_nus-sd.js | 128 + .../angular-1.4.8/i18n/angular-locale_nus.js | 128 + .../angular-1.4.8/i18n/angular-locale_nyn-ug.js | 128 + .../angular-1.4.8/i18n/angular-locale_nyn.js | 128 + .../angular-1.4.8/i18n/angular-locale_om-et.js | 128 + .../angular-1.4.8/i18n/angular-locale_om-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_om.js | 128 + .../angular-1.4.8/i18n/angular-locale_or-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_or.js | 110 + .../angular-1.4.8/i18n/angular-locale_os-ge.js | 128 + .../angular-1.4.8/i18n/angular-locale_os-ru.js | 128 + .../angular-1.4.8/i18n/angular-locale_os.js | 128 + .../i18n/angular-locale_pa-arab-pk.js | 110 + .../angular-1.4.8/i18n/angular-locale_pa-arab.js | 110 + .../i18n/angular-locale_pa-guru-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_pa-guru.js | 110 + .../angular-1.4.8/i18n/angular-locale_pa.js | 110 + .../angular-1.4.8/i18n/angular-locale_pl-pl.js | 128 + .../angular-1.4.8/i18n/angular-locale_pl.js | 128 + .../angular-1.4.8/i18n/angular-locale_ps-af.js | 128 + .../angular-1.4.8/i18n/angular-locale_ps.js | 128 + .../angular-1.4.8/i18n/angular-locale_pt-ao.js | 110 + .../angular-1.4.8/i18n/angular-locale_pt-br.js | 110 + .../angular-1.4.8/i18n/angular-locale_pt-cv.js | 110 + .../angular-1.4.8/i18n/angular-locale_pt-gw.js | 110 + .../angular-1.4.8/i18n/angular-locale_pt-mo.js | 110 + .../angular-1.4.8/i18n/angular-locale_pt-mz.js | 110 + .../angular-1.4.8/i18n/angular-locale_pt-pt.js | 110 + .../angular-1.4.8/i18n/angular-locale_pt-st.js | 110 + .../angular-1.4.8/i18n/angular-locale_pt-tl.js | 110 + .../angular-1.4.8/i18n/angular-locale_pt.js | 110 + .../angular-1.4.8/i18n/angular-locale_qu-bo.js | 128 + .../angular-1.4.8/i18n/angular-locale_qu-ec.js | 128 + .../angular-1.4.8/i18n/angular-locale_qu-pe.js | 128 + .../angular-1.4.8/i18n/angular-locale_qu.js | 128 + .../angular-1.4.8/i18n/angular-locale_rm-ch.js | 128 + .../angular-1.4.8/i18n/angular-locale_rm.js | 128 + .../angular-1.4.8/i18n/angular-locale_rn-bi.js | 128 + .../angular-1.4.8/i18n/angular-locale_rn.js | 128 + .../angular-1.4.8/i18n/angular-locale_ro-md.js | 128 + .../angular-1.4.8/i18n/angular-locale_ro-ro.js | 128 + .../angular-1.4.8/i18n/angular-locale_ro.js | 128 + .../angular-1.4.8/i18n/angular-locale_rof-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_rof.js | 128 + .../angular-1.4.8/i18n/angular-locale_ru-by.js | 128 + .../angular-1.4.8/i18n/angular-locale_ru-kg.js | 128 + .../angular-1.4.8/i18n/angular-locale_ru-kz.js | 128 + .../angular-1.4.8/i18n/angular-locale_ru-md.js | 128 + .../angular-1.4.8/i18n/angular-locale_ru-ru.js | 128 + .../angular-1.4.8/i18n/angular-locale_ru-ua.js | 128 + .../angular-1.4.8/i18n/angular-locale_ru.js | 128 + .../angular-1.4.8/i18n/angular-locale_rw-rw.js | 128 + .../angular-1.4.8/i18n/angular-locale_rw.js | 128 + .../angular-1.4.8/i18n/angular-locale_rwk-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_rwk.js | 128 + .../angular-1.4.8/i18n/angular-locale_sah-ru.js | 128 + .../angular-1.4.8/i18n/angular-locale_sah.js | 128 + .../angular-1.4.8/i18n/angular-locale_saq-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_saq.js | 128 + .../angular-1.4.8/i18n/angular-locale_sbp-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_sbp.js | 128 + .../angular-1.4.8/i18n/angular-locale_se-fi.js | 128 + .../angular-1.4.8/i18n/angular-locale_se-no.js | 128 + .../angular-1.4.8/i18n/angular-locale_se-se.js | 128 + .../angular-1.4.8/i18n/angular-locale_se.js | 128 + .../angular-1.4.8/i18n/angular-locale_seh-mz.js | 128 + .../angular-1.4.8/i18n/angular-locale_seh.js | 128 + .../angular-1.4.8/i18n/angular-locale_ses-ml.js | 128 + .../angular-1.4.8/i18n/angular-locale_ses.js | 128 + .../angular-1.4.8/i18n/angular-locale_sg-cf.js | 128 + .../angular-1.4.8/i18n/angular-locale_sg.js | 128 + .../i18n/angular-locale_shi-latn-ma.js | 128 + .../angular-1.4.8/i18n/angular-locale_shi-latn.js | 128 + .../i18n/angular-locale_shi-tfng-ma.js | 128 + .../angular-1.4.8/i18n/angular-locale_shi-tfng.js | 128 + .../angular-1.4.8/i18n/angular-locale_shi.js | 128 + .../angular-1.4.8/i18n/angular-locale_si-lk.js | 128 + .../angular-1.4.8/i18n/angular-locale_si.js | 128 + .../angular-1.4.8/i18n/angular-locale_sk-sk.js | 128 + .../angular-1.4.8/i18n/angular-locale_sk.js | 128 + .../angular-1.4.8/i18n/angular-locale_sl-si.js | 128 + .../angular-1.4.8/i18n/angular-locale_sl.js | 128 + .../angular-1.4.8/i18n/angular-locale_smn-fi.js | 128 + .../angular-1.4.8/i18n/angular-locale_smn.js | 128 + .../angular-1.4.8/i18n/angular-locale_sn-zw.js | 128 + .../angular-1.4.8/i18n/angular-locale_sn.js | 128 + .../angular-1.4.8/i18n/angular-locale_so-dj.js | 128 + .../angular-1.4.8/i18n/angular-locale_so-et.js | 128 + .../angular-1.4.8/i18n/angular-locale_so-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_so-so.js | 128 + .../angular-1.4.8/i18n/angular-locale_so.js | 128 + .../angular-1.4.8/i18n/angular-locale_sq-al.js | 110 + .../angular-1.4.8/i18n/angular-locale_sq-mk.js | 110 + .../angular-1.4.8/i18n/angular-locale_sq-xk.js | 110 + .../angular-1.4.8/i18n/angular-locale_sq.js | 110 + .../i18n/angular-locale_sr-cyrl-ba.js | 128 + .../i18n/angular-locale_sr-cyrl-me.js | 128 + .../i18n/angular-locale_sr-cyrl-rs.js | 128 + .../i18n/angular-locale_sr-cyrl-xk.js | 128 + .../angular-1.4.8/i18n/angular-locale_sr-cyrl.js | 128 + .../i18n/angular-locale_sr-latn-ba.js | 128 + .../i18n/angular-locale_sr-latn-me.js | 128 + .../i18n/angular-locale_sr-latn-rs.js | 128 + .../i18n/angular-locale_sr-latn-xk.js | 128 + .../angular-1.4.8/i18n/angular-locale_sr-latn.js | 128 + .../angular-1.4.8/i18n/angular-locale_sr.js | 128 + .../angular-1.4.8/i18n/angular-locale_ss-sz.js | 128 + .../angular-1.4.8/i18n/angular-locale_ss-za.js | 128 + .../angular-1.4.8/i18n/angular-locale_ss.js | 128 + .../angular-1.4.8/i18n/angular-locale_ssy-er.js | 128 + .../angular-1.4.8/i18n/angular-locale_ssy.js | 128 + .../angular-1.4.8/i18n/angular-locale_st-ls.js | 115 + .../angular-1.4.8/i18n/angular-locale_st-za.js | 115 + .../angular-1.4.8/i18n/angular-locale_st.js | 115 + .../angular-1.4.8/i18n/angular-locale_sv-ax.js | 128 + .../angular-1.4.8/i18n/angular-locale_sv-fi.js | 128 + .../angular-1.4.8/i18n/angular-locale_sv-se.js | 128 + .../angular-1.4.8/i18n/angular-locale_sv.js | 128 + .../angular-1.4.8/i18n/angular-locale_sw-cd.js | 128 + .../angular-1.4.8/i18n/angular-locale_sw-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_sw-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_sw-ug.js | 128 + .../angular-1.4.8/i18n/angular-locale_sw.js | 128 + .../angular-1.4.8/i18n/angular-locale_swc-cd.js | 128 + .../angular-1.4.8/i18n/angular-locale_swc.js | 128 + .../angular-1.4.8/i18n/angular-locale_ta-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_ta-lk.js | 110 + .../angular-1.4.8/i18n/angular-locale_ta-my.js | 110 + .../angular-1.4.8/i18n/angular-locale_ta-sg.js | 110 + .../angular-1.4.8/i18n/angular-locale_ta.js | 110 + .../angular-1.4.8/i18n/angular-locale_te-in.js | 110 + .../angular-1.4.8/i18n/angular-locale_te.js | 110 + .../angular-1.4.8/i18n/angular-locale_teo-ke.js | 128 + .../angular-1.4.8/i18n/angular-locale_teo-ug.js | 128 + .../angular-1.4.8/i18n/angular-locale_teo.js | 128 + .../i18n/angular-locale_tg-cyrl-tj.js | 115 + .../angular-1.4.8/i18n/angular-locale_tg-cyrl.js | 115 + .../angular-1.4.8/i18n/angular-locale_tg.js | 115 + .../angular-1.4.8/i18n/angular-locale_th-th.js | 110 + .../angular-1.4.8/i18n/angular-locale_th.js | 110 + .../angular-1.4.8/i18n/angular-locale_ti-er.js | 128 + .../angular-1.4.8/i18n/angular-locale_ti-et.js | 128 + .../angular-1.4.8/i18n/angular-locale_ti.js | 128 + .../angular-1.4.8/i18n/angular-locale_tig-er.js | 115 + .../angular-1.4.8/i18n/angular-locale_tig.js | 115 + .../angular-1.4.8/i18n/angular-locale_tl.js | 128 + .../angular-1.4.8/i18n/angular-locale_tn-bw.js | 128 + .../angular-1.4.8/i18n/angular-locale_tn-za.js | 128 + .../angular-1.4.8/i18n/angular-locale_tn.js | 128 + .../angular-1.4.8/i18n/angular-locale_to-to.js | 128 + .../angular-1.4.8/i18n/angular-locale_to.js | 128 + .../angular-1.4.8/i18n/angular-locale_tr-cy.js | 110 + .../angular-1.4.8/i18n/angular-locale_tr-tr.js | 110 + .../angular-1.4.8/i18n/angular-locale_tr.js | 110 + .../angular-1.4.8/i18n/angular-locale_ts-za.js | 128 + .../angular-1.4.8/i18n/angular-locale_ts.js | 128 + .../angular-1.4.8/i18n/angular-locale_twq-ne.js | 128 + .../angular-1.4.8/i18n/angular-locale_twq.js | 128 + .../i18n/angular-locale_tzm-latn-ma.js | 128 + .../angular-1.4.8/i18n/angular-locale_tzm-latn.js | 128 + .../angular-1.4.8/i18n/angular-locale_tzm.js | 128 + .../i18n/angular-locale_ug-arab-cn.js | 128 + .../angular-1.4.8/i18n/angular-locale_ug-arab.js | 128 + .../angular-1.4.8/i18n/angular-locale_ug.js | 128 + .../angular-1.4.8/i18n/angular-locale_uk-ua.js | 128 + .../angular-1.4.8/i18n/angular-locale_uk.js | 128 + .../angular-1.4.8/i18n/angular-locale_ur-in.js | 128 + .../angular-1.4.8/i18n/angular-locale_ur-pk.js | 128 + .../angular-1.4.8/i18n/angular-locale_ur.js | 128 + .../i18n/angular-locale_uz-arab-af.js | 110 + .../angular-1.4.8/i18n/angular-locale_uz-arab.js | 110 + .../i18n/angular-locale_uz-cyrl-uz.js | 110 + .../angular-1.4.8/i18n/angular-locale_uz-cyrl.js | 110 + .../i18n/angular-locale_uz-latn-uz.js | 110 + .../angular-1.4.8/i18n/angular-locale_uz-latn.js | 110 + .../angular-1.4.8/i18n/angular-locale_uz.js | 110 + .../i18n/angular-locale_vai-latn-lr.js | 128 + .../angular-1.4.8/i18n/angular-locale_vai-latn.js | 128 + .../i18n/angular-locale_vai-vaii-lr.js | 128 + .../angular-1.4.8/i18n/angular-locale_vai-vaii.js | 128 + .../angular-1.4.8/i18n/angular-locale_vai.js | 128 + .../angular-1.4.8/i18n/angular-locale_ve-za.js | 128 + .../angular-1.4.8/i18n/angular-locale_ve.js | 128 + .../angular-1.4.8/i18n/angular-locale_vi-vn.js | 110 + .../angular-1.4.8/i18n/angular-locale_vi.js | 110 + .../angular-1.4.8/i18n/angular-locale_vo-001.js | 128 + .../angular-1.4.8/i18n/angular-locale_vo.js | 128 + .../angular-1.4.8/i18n/angular-locale_vun-tz.js | 128 + .../angular-1.4.8/i18n/angular-locale_vun.js | 128 + .../angular-1.4.8/i18n/angular-locale_wae-ch.js | 128 + .../angular-1.4.8/i18n/angular-locale_wae.js | 128 + .../angular-1.4.8/i18n/angular-locale_wal-et.js | 115 + .../angular-1.4.8/i18n/angular-locale_wal.js | 115 + .../angular-1.4.8/i18n/angular-locale_xh-za.js | 115 + .../angular-1.4.8/i18n/angular-locale_xh.js | 115 + .../angular-1.4.8/i18n/angular-locale_xog-ug.js | 128 + .../angular-1.4.8/i18n/angular-locale_xog.js | 128 + .../angular-1.4.8/i18n/angular-locale_yav-cm.js | 128 + .../angular-1.4.8/i18n/angular-locale_yav.js | 128 + .../angular-1.4.8/i18n/angular-locale_yi-001.js | 128 + .../angular-1.4.8/i18n/angular-locale_yi.js | 128 + .../angular-1.4.8/i18n/angular-locale_yo-bj.js | 128 + .../angular-1.4.8/i18n/angular-locale_yo-ng.js | 128 + .../angular-1.4.8/i18n/angular-locale_yo.js | 128 + .../angular-1.4.8/i18n/angular-locale_zgh-ma.js | 128 + .../angular-1.4.8/i18n/angular-locale_zgh.js | 128 + .../angular-1.4.8/i18n/angular-locale_zh-cn.js | 110 + .../i18n/angular-locale_zh-hans-cn.js | 110 + .../i18n/angular-locale_zh-hans-hk.js | 110 + .../i18n/angular-locale_zh-hans-mo.js | 110 + .../i18n/angular-locale_zh-hans-sg.js | 110 + .../angular-1.4.8/i18n/angular-locale_zh-hans.js | 110 + .../i18n/angular-locale_zh-hant-hk.js | 110 + .../i18n/angular-locale_zh-hant-mo.js | 110 + .../i18n/angular-locale_zh-hant-tw.js | 110 + .../angular-1.4.8/i18n/angular-locale_zh-hant.js | 110 + .../angular-1.4.8/i18n/angular-locale_zh-hk.js | 110 + .../angular-1.4.8/i18n/angular-locale_zh-tw.js | 110 + .../angular-1.4.8/i18n/angular-locale_zh.js | 110 + .../angular-1.4.8/i18n/angular-locale_zu-za.js | 110 + .../angular-1.4.8/i18n/angular-locale_zu.js | 110 + .../app/fusion/external/angular-1.4.8/version.json | 1 + .../app/fusion/external/angular-1.4.8/version.txt | 1 + .../app/fusion/external/angular-bootstrap/index.js | 2 + .../angular-bootstrap/ui-bootstrap-csp.css | 115 + .../angular-bootstrap/ui-bootstrap-tpls.js | 7776 ++++ .../angular-bootstrap/ui-bootstrap-tpls.min.js | 10 + .../external/angular-bootstrap/ui-bootstrap.js | 7412 ++++ .../external/angular-bootstrap/ui-bootstrap.min.js | 10 + .../angular-gridster/dist/angular-gridster.css | 145 + .../angular-gridster/dist/angular-gridster.min.css | 1 + .../angular-gridster/dist/angular-gridster.min.js | 8 + .../angular-gridster/src/angular-gridster.js | 2239 + .../angular-gridster/src/angular-gridster.less | 167 + .../app/fusion/external/angular-ui-grid/index.js | 2 + .../fusion/external/angular-ui-grid/ui-grid.css | 2005 + .../fusion/external/angular-ui-grid/ui-grid.eot | Bin 0 -> 10320 bytes .../app/fusion/external/angular-ui-grid/ui-grid.js | 28935 +++++++++++++ .../external/angular-ui-grid/ui-grid.min.css | 4 + .../fusion/external/angular-ui-grid/ui-grid.min.js | 15 + .../fusion/external/angular-ui-grid/ui-grid.svg | 56 + .../fusion/external/angular-ui-grid/ui-grid.ttf | Bin 0 -> 10156 bytes .../fusion/external/angular-ui-grid/ui-grid.woff | Bin 0 -> 5728 bytes .../angular-ui/ui-bootstrap-tpls-1.1.2.min.js | 0 .../angular-ui/ui-bootstrap-tpls-1.2.4.min.js | 0 .../angular-ui/ui-sortable/v0.13.4/sortable.min.js | 8 + .../main/webapp/app/fusion/external/b2b/README.md | 26 + .../external/b2b/css/b2b-angular/b2b-angular.css | 11827 ++++++ .../css/b2b-angular/style/images/horse_shoe.jpg | Bin 0 -> 16573 bytes .../css/b2b-angular/style/images/icon-flyout.png | Bin 0 -> 947 bytes .../b2b/css/b2b-angular/style/images/treebg.png | Bin 0 -> 82 bytes .../b2b-angular/style/images/widget-thumbnail.png | Bin 0 -> 1929 bytes .../external/b2b/js/b2b-angular/b2b-library.min.js | 22054 ++++++++++ .../b2b/js/b2b-angular/style/images/horse_shoe.jpg | Bin 0 -> 16573 bytes .../js/b2b-angular/style/images/icon-flyout.png | Bin 0 -> 947 bytes .../b2b/js/b2b-angular/style/images/treebg.png | Bin 0 -> 82 bytes .../b2b-angular/style/images/widget-thumbnail.png | Bin 0 -> 1929 bytes .../js/b2b-angular/styles/images/icon-flyout.png | Bin 0 -> 947 bytes .../webapp/app/fusion/external/bootstrap/bs.css | 0 .../webapp/app/fusion/external/d3/css/nv.d3.css | 0 .../main/webapp/app/fusion/external/d3/js/cie.js | 0 .../app/fusion/external/d3/js/colorbrewer.js | 0 .../main/webapp/app/fusion/external/d3/js/core.js | 0 .../app/fusion/external/d3/js/crossfilter.js | 0 .../app/fusion/external/d3/js/crossfilter.min.js | 0 .../webapp/app/fusion/external/d3/js/d3.geom.js | 0 .../main/webapp/app/fusion/external/d3/js/d3.js | 0 .../app/fusion/external/d3/js/d3.layout.cloud.js | 0 .../webapp/app/fusion/external/d3/js/d3.layout.js | 0 .../main/webapp/app/fusion/external/d3/js/d3.v2.js | 0 .../webapp/app/fusion/external/d3/js/d3.v2.min.js | 0 .../webapp/app/fusion/external/d3/js/d3.v3.min.js | 0 .../webapp/app/fusion/external/d3/js/fisheye.js | 0 .../main/webapp/app/fusion/external/d3/js/hive.js | 0 .../webapp/app/fusion/external/d3/js/horizon.js | 0 .../app/fusion/external/d3/js/interactiveLayer.js | 0 .../main/webapp/app/fusion/external/d3/js/intro.js | 2 + .../app/fusion/external/d3/js/models/axis-min.js | 0 .../app/fusion/external/d3/js/models/axis.js | 0 .../app/fusion/external/d3/js/models/axis.min.js | 0 .../fusion/external/d3/js/models/backup/bullet.js | 0 .../external/d3/js/models/backup/bulletChart.js | 0 .../fusion/external/d3/js/models/boilerplate.js | 0 .../app/fusion/external/d3/js/models/bullet.js | 0 .../fusion/external/d3/js/models/bulletChart.js | 0 .../external/d3/js/models/cumulativeLineChart.js | 0 .../fusion/external/d3/js/models/discreteBar.js | 0 .../external/d3/js/models/discreteBarChart.js | 0 .../fusion/external/d3/js/models/distribution.js | 0 .../fusion/external/d3/js/models/historicalBar.js | 0 .../external/d3/js/models/historicalBarChart.js | 0 .../fusion/external/d3/js/models/indentedTree.js | 0 .../app/fusion/external/d3/js/models/legend.js | 0 .../app/fusion/external/d3/js/models/line.js | 0 .../app/fusion/external/d3/js/models/lineChart.js | 0 .../external/d3/js/models/linePlusBarChart.js | 0 .../d3/js/models/linePlusBarWithFocusChart.js | 0 .../external/d3/js/models/lineWithFisheye.js | 0 .../external/d3/js/models/lineWithFisheyeChart.js | 0 .../external/d3/js/models/lineWithFocusChart.js | 0 .../app/fusion/external/d3/js/models/multiBar.js | 0 .../fusion/external/d3/js/models/multiBarChart.js | 0 .../external/d3/js/models/multiBarHorizontal.js | 0 .../d3/js/models/multiBarHorizontalChart.js | 0 .../external/d3/js/models/multiBarTimeSeries.js | 0 .../d3/js/models/multiBarTimeSeriesChart.js | 0 .../app/fusion/external/d3/js/models/multiChart.js | 0 .../app/fusion/external/d3/js/models/ohlcBar.js | 0 .../external/d3/js/models/parallelCoordinates.js | 0 .../webapp/app/fusion/external/d3/js/models/pie.js | 0 .../app/fusion/external/d3/js/models/pieChart.js | 0 .../app/fusion/external/d3/js/models/scatter.js | 0 .../fusion/external/d3/js/models/scatterChart.js | 0 .../external/d3/js/models/scatterPlusLineChart.js | 0 .../app/fusion/external/d3/js/models/sparkline.js | 0 .../fusion/external/d3/js/models/sparklinePlus.js | 0 .../fusion/external/d3/js/models/stackedArea.js | 0 .../external/d3/js/models/stackedAreaChart.js | 0 .../main/webapp/app/fusion/external/d3/js/nv.d3.js | 0 .../webapp/app/fusion/external/d3/js/nv.d3.min.js | 0 .../main/webapp/app/fusion/external/d3/js/outro.js | 0 .../webapp/app/fusion/external/d3/js/sankey.js | 0 .../webapp/app/fusion/external/d3/js/tooltip.js | 0 .../main/webapp/app/fusion/external/d3/js/utils.js | 0 .../webapp/app/fusion/external/ds2/js/appDS2.js | 1 + .../external/ebz/copyrighted-material-removed.txt} | 0 .../webapp/app/fusion/external/gis/js/local.js | 178 + .../detect-element-resize.js | 147 + .../jquery.resize.js | 164 + .../webapp/app/fusion/external/jquery/.bower.json | 25 + .../app/fusion/external/jquery/dist/jquery.js | 9814 +++++ .../app/fusion/external/jquery/dist/jquery.min.js | 4 + .../app/fusion/external/jquery/dist/jquery.min.map | 1 + .../app/fusion/external/leaflet-0.7.3/leaflet.css | 478 + .../app/fusion/external/leaflet-0.7.3/leaflet.js | 9 + .../app/fusion/external/lodash/4.5.1/lodash.js | 14932 +++++++ .../fusion/external/samples}/css/images/blank.gif | Bin .../app/fusion/external/samples/css/scribble.css | 40 + .../app/fusion/external/samples/css/slider.css | 142 + .../fusion/external/samples/css/spacegallery.css | 18 + .../fusion/external/samples/html/area_chart.html | 49 + .../fusion/external/samples/html/bar_chart.html | 95 + .../external/samples/html/busy_hour_traffic.html | 188 + .../external/samples/html/d3_gauges_demo.html | 39 + .../external/samples/html/data/speedometer2.csv | 16 + .../external/samples/html/data/speedometer3.csv | 2 + .../external/samples}/html/data/worddata.csv | 0 .../app/fusion/external/samples/html/donut_d3.html | 43 + .../external/samples/html/js/area_chart.min.js | 1 + .../fusion/external/samples/html/js/donut.min.js | 1 + .../fusion/external/samples/html/js/gauges.min.js | 1 + .../external/samples/html/js/line_chart.min.js | 1 + .../external/samples/html/js/pie_chart.min.js | 1 + .../external/samples/html/js/worddata.min.js | 1 + .../fusion/external/samples/html/line_chart.html | 49 + .../fusion/external/samples/html/pie_chart.html | 38 + .../samples/html/traffic_distribution.html | 205 + .../fusion/external/samples}/html/wordcloud.html | 0 .../external/samples/images/Calendar-16x16.png | Bin 0 -> 552 bytes .../fusion/external/samples}/images/arrow-next.png | Bin .../fusion/external/samples}/images/arrow-prev.png | Bin .../images/carousel/slide_b_drive_test_map.png | Bin 0 -> 202465 bytes .../images/carousel/slide_b_eppt_county.png | Bin 0 -> 21222 bytes .../images/carousel/slide_b_eppt_regression.png | Bin 0 -> 11536 bytes .../images/carousel/slide_b_ios_throughput.png | Bin 0 -> 26131 bytes .../samples/images/carousel/slide_b_lata_map.png | Bin 0 -> 192031 bytes .../images/carousel/slide_b_lata_map_legend.png | Bin 0 -> 3021 bytes .../images/carousel/slide_b_nova_sdn_map.png | Bin 0 -> 179361 bytes .../fusion/external/samples}/images/copyicon.png | Bin .../fusion/external/samples}/images/deleteicon.gif | Bin .../external/samples}/images/example-frame.png | Bin .../fusion/external/samples}/images/loading.gif | Bin .../external/samples/images/tunnels/1_mon.png | Bin 0 -> 22762 bytes .../external/samples/images/tunnels/2_tue.png | Bin 0 -> 22772 bytes .../external/samples/images/tunnels/3_wed.png | Bin 0 -> 24012 bytes .../external/samples/images/tunnels/4_thu.png | Bin 0 -> 23902 bytes .../external/samples/images/tunnels/5_fri.png | Bin 0 -> 22349 bytes .../external/samples/images/tunnels/6_sat.png | Bin 0 -> 23674 bytes .../external/samples/images/tunnels/7_sun.png | Bin 0 -> 22845 bytes .../samples/images/tunnels/BH_DLSTX_IN.png | Bin 0 -> 10575 bytes .../samples/images/tunnels/BH_DLSTX_OUT.png | Bin 0 -> 10460 bytes .../external/samples/images/tunnels/BH_Nat.png | Bin 0 -> 10420 bytes .../external/samples/images/tunnels/BH_Nat_Def.png | Bin 0 -> 8941 bytes .../samples/images/tunnels/BH_Nat_Priority.png | Bin 0 -> 10590 bytes .../app/fusion/external/samples/js/FusionCharts.js | 361 + .../app/fusion/external/samples/js/charts.js | 132 + .../webapp/app/fusion/external/samples/js/eye.js | 34 + .../app/fusion/external/samples/js/scribble.js | 19 + .../external/samples/js/slides.min.jquery.js | 20 + .../app/fusion/external/samples/js/spacegallery.js | 235 + .../webapp/app/fusion/external/samples/js/utils.js | 252 + .../samples/org_chart/css/bootstrap.min.css | 351 + .../external/samples/org_chart/css/custom.css | 97 + .../samples/org_chart/css/jquery.jOrgChart.css | 51 + .../external/samples/org_chart/css/prettify.css | 1 + .../fusion/external/samples/org_chart/example.html | 85 + .../external/samples/org_chart/example_vsp.html | 88 + .../external/samples/org_chart/images/bkgd.png | Bin 0 -> 133 bytes .../samples/org_chart/images/raspberry.jpg | Bin 0 -> 5755 bytes .../external/samples/org_chart/jquery.jOrgChart.js | 267 + .../fusion/external/samples/org_chart/prettify.js | 28 + .../app/fusion/external/showdown/0.3.4/showdown.js | 1454 + .../app/fusion/external/utils/js/browserCheck.js | 5 + .../src/main/webapp/app/fusion/fonts}/dummy.txt | 0 .../scripts/controllers/nbook-framecontroller.js | 15 + .../scripts/controllers/nbookController.js | 97 + .../scripts/controllers/notebookFrameController.js | 81 + .../scripts/dependency/angular.js | 0 .../scripts/view-models/notebook-frame.html | 65 + .../scripts/view-models/notebook-viz.html | 7 + .../scripts/view-models/notebook.htm | 33 + .../scripts/view-models/notebookInputs.html | 70 + .../scripts/DS2-controllers/admin-closed-cloop.js | 28 + .../scripts/DS2-controllers/admin-controller.js | 940 + .../scripts/DS2-controllers/admin-menu-edit.js | 184 + .../fusion/scripts/DS2-controllers/admin-route.js | 43 + .../scripts/DS2-controllers/admin-whitelist.js | 3 + .../DS2-controllers/collaborate-list-controller.js | 71 + .../DS2-controllers/collaborate/collaborate.js | 7 + .../collaborate/workflowController.js | 490 + .../DS2-controllers/collaborateList-route.js | 19 + .../DS2-controllers/collaboration-controller.js | 266 + .../ds2-profile/self-profile-controller.js | 358 + .../ds2-reports/report-import-controller.js | 20 + .../DS2-controllers/ds2-reports/report-router.js | 37 + .../ds2-reports/report-run-controller.js | 326 + .../ds2-reports/report-search-controller.js | 184 + .../ds2-reports/report-step-controller.js | 900 + .../ds2-sample/drools-controller.js | 53 + .../ds2-sample/nbook-framecontroller.js | 15 + .../ds2-sample/notebook-controller.js | 170 + .../ds2-sample/notebookFrameController.js | 85 + .../DS2-controllers/ds2-workflows/workflowApp.js | 5 + .../ds2-workflows/workflowController.js | 513 + .../ds2-workflows/workflowRouting.js | 8 + .../fn-menu-add-popup-controller.js | 339 + .../scripts/DS2-controllers/profile-route.js | 19 + .../profile-search-controller-DS2.js | 64 + .../DS2-controllers/sampleProfileController.js | 22 + .../DS2-controllers/usage-list-controller.js | 39 + .../scripts/DS2-controllers/welcome-controller.js | 408 + .../scripts/DS2-controllers/welcome-route.js | 7 + .../scripts/DS2-directives/b2b-leftnav-ext.js | 64 + .../app/fusion/scripts/DS2-directives/ds2Header.js | 152 + .../fusion/scripts/DS2-directives/ds2LeftMenu.js | 89 + .../app/fusion/scripts/DS2-directives/footer.js | 27 + .../app/fusion/scripts/DS2-modal/error_modal.html | 19 + .../fusion/scripts/DS2-modal/success_modal.html | 20 + .../scripts/DS2-modal/success_modalpopup.html | 20 + .../scripts/DS2-services/adminMenuService.js | 129 + .../fusion/scripts/DS2-services/adminService.js | 453 + .../scripts/DS2-services/ds2-modal/modalService.js | 38 + .../DS2-services/ds2-profile/selfProfileService.js | 114 + .../ds2-raptor-report/raptorReportFactory.js | 331 + .../ds2-raptor-report/stepFormFactory.js | 198 + .../DS2-services/ds2-sample-page/droolsService.js | 53 + .../scripts/DS2-services/headerServiceDS2.js | 483 + .../scripts/DS2-services/leftMenuServiceDS2.js | 110 + .../fusion/scripts/DS2-services/manifestService.js | 24 + .../fusion/scripts/DS2-services/modalService.js | 57 + .../fusion/scripts/DS2-services/modalServiceDS2.js | 31 + .../scripts/DS2-services/profileServiceDS2.js | 78 + .../fusion/scripts/DS2-services/sampleService.js | 19 + .../scripts/DS2-services/userInfoServiceDS2.js | 32 + .../DS2-workflows-page/workflow-landing.html | 66 + .../DS2-workflows-page/workflow-listing.html | 65 + .../DS2-workflows-page/workflow-new.html | 110 + .../DS2-workflows-page/workflow-preview.html | 24 + .../DS2-workflows-page/workflow-remove.html | 26 + .../DS2-workflows-page/workflow-schedule.html | 130 + .../scripts/DS2-view-models/b2b-leftnav-ext.html | 43 + .../DS2-view-models/ds2-admin/admin-menu-edit.html | 102 + .../scripts/DS2-view-models/ds2-admin/admin.html | 66 + .../ds2-admin/admin_closed_loop.html | 17 + .../ds2-admin/collaborate-list.html | 76 + .../DS2-view-models/ds2-admin/collaboration.html | 182 + .../DS2-view-models/ds2-admin/jcs_admin.html | 73 + .../ds2-admin/modals/admin-menu-del-confirm.html | 22 + .../ds2-admin/modals/cache-menu-clear-confirm.html | 22 + .../modals/cache-menu-clear-region-confirm.html | 22 + .../ds2-admin/modals/clearItem-region-confirm.html | 22 + ...laborate-list-toggle-profile-active-status.html | 22 + .../ds2-admin/modals/popup-modal-fn-menu-edit.html | 129 + .../ds2-admin/modals/popup-modal-fnmenu-add.html | 136 + .../ds2-admin/modals/role-child-add-confirm.html | 25 + .../ds2-admin/modals/role-confirm-activation.html | 23 + .../ds2-admin/modals/role-delete-confirm.html | 22 + .../ds2-admin/modals/role-fun-add-confirm.html | 25 + .../modals/role-fun-role-del-confirm.html | 22 + .../ds2-admin/modals/role-function-add.html | 32 + .../modals/role-function-del-confirm.html | 22 + .../ds2-admin/modals/role-function-edit.html | 22 + .../modals/role-functions-child-roles-modal.html | 34 + .../ds2-admin/modals/role-functions-modal.html | 36 + .../DS2-view-models/ds2-admin/role-function.html | 63 + .../scripts/DS2-view-models/ds2-admin/role.html | 96 + .../DS2-view-models/ds2-admin/role_list.html | 42 + .../scripts/DS2-view-models/ds2-admin/usage.html | 43 + .../ds2-profile/modals/role-add-confirm.html | 25 + .../ds2-profile/modals/role-add.html | 36 + .../ds2-profile/modals/role-del-confirm.html | 23 + .../DS2-view-models/ds2-profile/profile.html | 67 + .../DS2-view-models/ds2-reports/all-reports.html | 74 + .../ds2-reports/directive/dynamicform.js | 113 + .../ds2-reports/directive/step-form-directive.js | 14 + .../ds2-reports/modal/report-del-confirm.html | 26 + .../modal/report-formfield-del-confirm.html | 26 + .../ds2-reports/modal/report-wizard-col-edit.html | 125 + .../modal/report-wizard-formfield-edit.html | 149 + .../modal/report-wizard-test-run-sql.html | 62 + .../DS2-view-models/ds2-reports/report-import.html | 14 + .../DS2-view-models/ds2-reports/report-run.html | 91 + .../DS2-view-models/ds2-reports/report-search.html | 54 + .../ds2-reports/wz_steps/json/step1.json | 218 + .../ds2-reports/wz_steps/json/step2.json | 34 + .../ds2-reports/wz_steps/json/step3.json | 19 + .../ds2-reports/wz_steps/json/step4.json | 25 + .../ds2-reports/wz_steps/json/step5.json | 28 + .../ds2-reports/wz_steps/report-step.html | 101 + .../ds2-samplePages/drools-list.html | 32 + .../DS2-view-models/ds2-samplePages/drools.html | 55 + .../ds2-samplePages/frame_insert.html | 27 + .../ds2-samplePages/notebook-frame.html | 74 + .../ds2-samplePages/notebook-page.html | 80 + .../ds2-samplePages/notebook-viz.html | 7 + .../fusion/scripts/DS2-view-models/ds2Header.html | 69 + .../scripts/DS2-view-models/ds2Left_menu.html | 3 + .../scripts/DS2-view-models/loginSnippet.html | 63 + .../scripts/DS2-view-models/welcome-content.html | 191 + .../scripts/DS2-view-models/welcome-sample.html | 112 + .../fusion/scripts/DS2-view-models/welcome.html | 151 + .../att_angular_gridster/angular-gridster.js | 0 .../att_angular_gridster/ui-gridster-tpls.js | 0 .../scripts/controllers/admin-closed-cloop.js | 28 + .../fusion/scripts/controllers/admin-whitelist.js | 3 + .../fusion/scripts/controllers/ase-controller.js | 3 + .../scripts/controllers/broadcast-controller.js | 60 + .../controllers/broadcast-list-controller.js | 101 + .../controllers/collaborate-list-controller.js | 44 + .../app/fusion/scripts/controllers}/dummy.txt | 0 .../scripts/controllers/modelpopupController.js | 21 + .../app/fusion/scripts/directives}/dummy.txt | 0 .../webapp/app/fusion/scripts/directives/footer.js | 11 + .../webapp/app/fusion/scripts/directives/header.js | 479 + .../app/fusion/scripts/directives/leftMenu.js | 184 + .../webapp/app/fusion/scripts/jquery.resize.js | 0 .../main/webapp/app/fusion/scripts/layout/debug.js | 0 .../app/fusion/scripts/layout/jquery-latest.js | 0 .../app/fusion/scripts/layout/jquery-ui-latest.js | 0 .../fusion/scripts/layout/jquery.layout-latest.js | 0 .../main/webapp/app/fusion/scripts/modalService.js | 0 .../main/webapp/app/fusion/scripts/moment.min.js | 0 .../webapp/app/fusion/scripts/network/net_map.js | 947 + .../app/fusion/scripts/services/adminService.js | 141 + .../app/fusion/scripts/services/headerService.js | 70 + .../app/fusion/scripts/services/leftMenuService.js | 35 + .../app/fusion/scripts/services/profileService.js | 79 + .../app/fusion/scripts/services/userInfoService.js | 32 + .../app/fusion/scripts/socket/peerBroadcast.js | 103 + .../webapp/app/fusion/scripts/utils}/dummy.txt | 0 .../fusion/scripts/utils/sandbox-resources.html | 0 .../app/fusion/scripts/view-models}/dummy.txt | 0 .../app/fusion/scripts/view-models/header.html | 162 + .../app/fusion/scripts/view-models/left_menu.html | 27 + .../profile-page/admin_closed_loop.html | 20 + .../view-models/profile-page/broadcast.html | 42 + .../view-models/profile-page/broadcast_list.html | 52 + .../view-models/profile-page/popup_modal.html | 263 + .../profile-page/popup_modal_fn_menu_add.html | 136 + .../profile-page/popup_modal_fn_menu_edit.html | 129 + .../view-models/profile-page/popup_modal_role.html | 75 + .../profile-page/popup_modal_rolefunction.html | 27 + .../src/app/customWidgetSettings.js | 133 + .../reportdashboard-page/src/app/dataModel.js | 58 + .../reportdashboard-page/src/app/demo.js | 167 + .../reportdashboard-page/src/app/demo.less | 24 + .../reportdashboard-page/src/app/directives.js | 230 + .../reportdashboard-page/src/app/explicitSave.js | 33 + .../reportdashboard-page/src/app/index.css | 146 + .../reportdashboard-page/src/app/index.js | 3 + .../reportdashboard-page/src/app/index.less | 16 + .../src/app/index_original.css | 113 + .../reportdashboard-page/src/app/layouts.js | 72 + .../src/app/report_whitelist.js | 3 + .../reportdashboard-page/src/app/resize.js | 45 + .../template/configurableWidgetModalOptions.html | 6 + .../src/app/template/customSettingsTemplate.html | 19 + .../src/app/template/fluid.html | 8 + .../src/app/template/layouts.html | 1 + .../src/app/template/r-cloud.html | 8 + .../src/app/template/raptor-report.html | 29 + .../src/app/template/resizable.html | 6 + .../src/app/template/view.html | 5 + .../src/app/template/widgetSpecificSettings.html | 19 + .../reportdashboard-page/src/app/vendor.css | 6658 +++ .../reportdashboard-page/src/app/vendor.less | 3 + .../angular-markdown-directive/markdown.js | 36 + .../directives/dashboard/WidgetSettingsCtrl.js | 34 + .../dashboard/WidgetSettingsRaptorReportCtrl.js | 215 + .../dashboard/add-raptor-report-template.html | 26 + .../dashboard/add-rcloud-notebook-template.html | 22 + .../directives/dashboard/altDashboard.html | 49 + .../components/directives/dashboard/dashboard.html | 74 + .../components/directives/dashboard/dashboard.js | 427 + .../components/directives/dashboard/dashboard.less | 88 + .../directives/dashboard/dashboard.spec.js | 878 + .../widget-settings-raptor-report-template.html | 58 + .../dashboard/widget-settings-template.html | 22 + .../dashboardLayouts/SaveChangesModal.html | 13 + .../dashboardLayouts/SaveChangesModalCtrl.js | 32 + .../dashboardLayouts/dashboardLayouts.html | 19 + .../dashboardLayouts/dashboardLayouts.js | 151 + .../dashboardLayouts/dashboardLayouts.spec.js | 392 + .../directives/widget/DashboardWidgetCtrl.js | 246 + .../directives/widget/DashboardWidgetCtrl.spec.js | 164 + .../src/components/directives/widget/widget.js | 64 + .../components/directives/widget/widget.spec.js | 104 + .../src/components/models/DashboardState.js | 180 + .../src/components/models/LayoutStorage.js | 253 + .../src/components/models/LayoutStorage.spec.js | 692 + .../src/components/models/WidgetDataModel.js | 45 + .../src/components/models/WidgetDefCollection.js | 56 + .../src/components/models/WidgetModel.js | 112 + .../src/components/models/WidgetModel.spec.js | 156 + .../reportdashboard-page/src/report-dashboard.html | 220 + .../fusion/scripts/webrtc/RTCMultiConnection.js | 6788 +++ .../app/fusion/scripts/webrtc/getSourceId.html | 0 .../att_angular_gridster/sandbox-gridster.css | 0 .../styles/att_angular_gridster/ui-gridster.css | 0 .../src/main/webapp/app/fusion/styles/ecomp.css | 135 + .../main/webapp/app/fusion/styles/fusion-sunny.css | 362 + .../src/main/webapp/app/fusion/styles/global.css | 178 + .../main/webapp/app/fusion/styles/jquery-ui.css | 0 .../fusion/styles/layout/layout-default-latest.css | 0 .../app/fusion/styles/workflows/bs-workflow.css | 134 + .../app/fusion/styles/workflows/workflows.css | 31 + .../drools/controller/drools-list-controller.js | 43 + .../drools/controller/drools-view-controller.js | 45 + .../drools/controller/droolsController.js | 11 + .../app/fusionapp/drools/controller}/dummy.txt | 0 .../app/fusionapp/drools/directives}/dummy.txt | 0 .../app/fusionapp/drools/services/droolsService.js | 57 + .../webapp/app/fusionapp/drools/utils}/dummy.txt | 0 .../fusionapp/drools/view-models/droolsList.html | 28 + .../drools/view-models/droolsSinglePage.html | 72 + .../fusionapp/drools/view-models/droolsView.html | 42 + .../app/fusionapp/drools/view-models}/dummy.txt | 0 .../main/webapp/app/fusionapp/external}/dummy.txt | 0 .../src/main/webapp/app/fusionapp/fonts}/dummy.txt | 0 .../main/webapp/app/fusionapp/icons/7450-icon.png | Bin 0 -> 465 bytes .../main/webapp/app/fusionapp/icons/7450-text.png | Bin 0 -> 295 bytes .../main/webapp/app/fusionapp/icons/7750-icon.png | Bin 0 -> 565 bytes .../main/webapp/app/fusionapp/icons/7750-text.png | Bin 0 -> 632 bytes .../webapp/app/fusionapp/icons/apn-dns-icon.png | Bin 0 -> 1065 bytes .../webapp/app/fusionapp/icons/apn-dns-text.png | Bin 0 -> 901 bytes .../main/webapp/app/fusionapp/icons/atcf-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/atcf-text.png | Bin 0 -> 650 bytes .../main/webapp/app/fusionapp/icons/atgw-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/atgw-text.png | Bin 0 -> 780 bytes .../main/webapp/app/fusionapp/icons/bgcf-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/bgcf-text.png | Bin 0 -> 645 bytes .../main/webapp/app/fusionapp/icons/com-icon.png | Bin 0 -> 437 bytes .../main/webapp/app/fusionapp/icons/cpm-icon.png | Bin 0 -> 201 bytes .../main/webapp/app/fusionapp/icons/cpm-text.png | Bin 0 -> 572 bytes .../webapp/app/fusionapp/icons/default-icon.png | Bin 0 -> 329 bytes .../webapp/app/fusionapp/icons/dra-epc-icon.png | Bin 0 -> 700 bytes .../webapp/app/fusionapp/icons/dra-epc-text.png | Bin 0 -> 820 bytes .../webapp/app/fusionapp/icons/dra-ims-icon.png | Bin 0 -> 700 bytes .../webapp/app/fusionapp/icons/dra-ims-text.png | Bin 0 -> 851 bytes .../main/webapp/app/fusionapp/icons/dslam-icon.png | Bin 0 -> 774 bytes .../main/webapp/app/fusionapp/icons/dslam-text.png | Bin 0 -> 739 bytes .../main/webapp/app/fusionapp/icons/eatf-icon.png | Bin 0 -> 437 bytes .../main/webapp/app/fusionapp/icons/eatf-text.png | Bin 0 -> 439 bytes .../main/webapp/app/fusionapp/icons/ecscf-icon.png | Bin 0 -> 855 bytes .../main/webapp/app/fusionapp/icons/ecscf-text.png | Bin 0 -> 604 bytes .../main/webapp/app/fusionapp/icons/emsc-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/enb-icon.png | Bin 0 -> 1127 bytes .../main/webapp/app/fusionapp/icons/enb-text.png | Bin 0 -> 627 bytes .../main/webapp/app/fusionapp/icons/enum-icon.png | Bin 0 -> 646 bytes .../main/webapp/app/fusionapp/icons/enum-text.png | Bin 0 -> 551 bytes .../main/webapp/app/fusionapp/icons/esmlc-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/esmlc-text.png | Bin 0 -> 701 bytes .../main/webapp/app/fusionapp/icons/ettcs-icon.png | Bin 0 -> 95 bytes .../main/webapp/app/fusionapp/icons/ettcs-text.png | Bin 0 -> 95 bytes .../main/webapp/app/fusionapp/icons/gmlc-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/gmlc-text.png | Bin 0 -> 755 bytes .../main/webapp/app/fusionapp/icons/hlr-icon.png | Bin 0 -> 646 bytes .../main/webapp/app/fusionapp/icons/hlr-text.png | Bin 0 -> 376 bytes .../webapp/app/fusionapp/icons/hss-epc-icon.png | Bin 0 -> 646 bytes .../webapp/app/fusionapp/icons/hss-epc-text.png | Bin 0 -> 726 bytes .../webapp/app/fusionapp/icons/hss-ims-icon.png | Bin 0 -> 646 bytes .../webapp/app/fusionapp/icons/hss-ims-text.png | Bin 0 -> 757 bytes .../main/webapp/app/fusionapp/icons/icscf-icon.png | Bin 0 -> 855 bytes .../main/webapp/app/fusionapp/icons/icscf-text.png | Bin 0 -> 657 bytes .../main/webapp/app/fusionapp/icons/ipag-icon.png | Bin 0 -> 95 bytes .../main/webapp/app/fusionapp/icons/ipag-text.png | Bin 0 -> 95 bytes .../main/webapp/app/fusionapp/icons/isbc-icon.png | Bin 0 -> 855 bytes .../main/webapp/app/fusionapp/icons/isbc-text.png | Bin 0 -> 649 bytes .../main/webapp/app/fusionapp/icons/iwf-icon.png | Bin 0 -> 696 bytes .../main/webapp/app/fusionapp/icons/iwf-text.png | Bin 0 -> 595 bytes .../webapp/app/fusionapp/icons/lrf-rdf-icon.png | Bin 0 -> 953 bytes .../webapp/app/fusionapp/icons/lrf-rdf-text.png | Bin 0 -> 638 bytes .../webapp/app/fusionapp/icons/lrg-rdf-text.png | Bin 0 -> 769 bytes .../main/webapp/app/fusionapp/icons/mgc8-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/mgc8-text.png | Bin 0 -> 771 bytes .../webapp/app/fusionapp/icons/mgcf-emsc-icon.png | Bin 0 -> 388 bytes .../webapp/app/fusionapp/icons/mgcf-emsc-text.png | Bin 0 -> 1140 bytes .../main/webapp/app/fusionapp/icons/mgw-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/mgw-text.png | Bin 0 -> 823 bytes .../main/webapp/app/fusionapp/icons/mind-icon.png | Bin 0 -> 646 bytes .../main/webapp/app/fusionapp/icons/mind-text.png | Bin 0 -> 550 bytes .../main/webapp/app/fusionapp/icons/mme-icon.png | Bin 0 -> 232 bytes .../main/webapp/app/fusionapp/icons/mme-text.png | Bin 0 -> 252 bytes .../main/webapp/app/fusionapp/icons/mrf-icon.png | Bin 0 -> 437 bytes .../main/webapp/app/fusionapp/icons/mrf-text.png | Bin 0 -> 504 bytes .../main/webapp/app/fusionapp/icons/msc-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/msn-icon.png | Bin 0 -> 465 bytes .../main/webapp/app/fusionapp/icons/msn-text.png | Bin 0 -> 318 bytes .../main/webapp/app/fusionapp/icons/multi-icon.png | Bin 0 -> 329 bytes .../main/webapp/app/fusionapp/icons/n7450-icon.png | Bin 0 -> 464 bytes .../main/webapp/app/fusionapp/icons/n7450-text.png | Bin 0 -> 295 bytes .../webapp/app/fusionapp/icons/n7750a-icon.png | Bin 0 -> 393 bytes .../webapp/app/fusionapp/icons/n7750a-text.png | Bin 0 -> 258 bytes .../webapp/app/fusionapp/icons/n7750b-icon.png | Bin 0 -> 393 bytes .../webapp/app/fusionapp/icons/n7750b-text.png | Bin 0 -> 258 bytes .../webapp/app/fusionapp/icons/n7750c-icon.png | Bin 0 -> 391 bytes .../webapp/app/fusionapp/icons/n7750c-text.png | Bin 0 -> 258 bytes .../webapp/app/fusionapp/icons/n7750d-icon.png | Bin 0 -> 391 bytes .../webapp/app/fusionapp/icons/n7750d-text.png | Bin 0 -> 258 bytes .../main/webapp/app/fusionapp/icons/nb-icon.png | Bin 0 -> 1127 bytes .../main/webapp/app/fusionapp/icons/nb-text.png | Bin 0 -> 499 bytes .../main/webapp/app/fusionapp/icons/pas-icon.png | Bin 0 -> 700 bytes .../main/webapp/app/fusionapp/icons/pas-text.png | Bin 0 -> 596 bytes .../main/webapp/app/fusionapp/icons/pcef-icon.png | Bin 0 -> 785 bytes .../main/webapp/app/fusionapp/icons/pcef-text.png | Bin 0 -> 539 bytes .../main/webapp/app/fusionapp/icons/pcrf-icon.png | Bin 0 -> 785 bytes .../main/webapp/app/fusionapp/icons/pcrf-text.png | Bin 0 -> 594 bytes .../main/webapp/app/fusionapp/icons/pcscf-icon.png | Bin 0 -> 855 bytes .../main/webapp/app/fusionapp/icons/pcscf-text.png | Bin 0 -> 744 bytes .../main/webapp/app/fusionapp/icons/pgw-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/pgw-text.png | Bin 0 -> 807 bytes .../main/webapp/app/fusionapp/icons/plrf-icon.png | Bin 0 -> 953 bytes .../main/webapp/app/fusionapp/icons/plrf-text.png | Bin 0 -> 735 bytes .../main/webapp/app/fusionapp/icons/psap-icon.png | Bin 0 -> 322 bytes .../webapp/app/fusionapp/icons/pstn-tdm-icon.png | Bin 0 -> 95 bytes .../webapp/app/fusionapp/icons/pstn-tdm-text.png | Bin 0 -> 95 bytes .../main/webapp/app/fusionapp/icons/rg-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/rg-text.png | Bin 0 -> 540 bytes .../main/webapp/app/fusionapp/icons/rnc-icon.png | Bin 0 -> 591 bytes .../main/webapp/app/fusionapp/icons/rnc-text.png | Bin 0 -> 646 bytes .../main/webapp/app/fusionapp/icons/sbc-icon.png | Bin 0 -> 855 bytes .../main/webapp/app/fusionapp/icons/sbc-text.png | Bin 0 -> 632 bytes .../main/webapp/app/fusionapp/icons/sccas-icon.png | Bin 0 -> 437 bytes .../main/webapp/app/fusionapp/icons/sccas-text.png | Bin 0 -> 861 bytes .../main/webapp/app/fusionapp/icons/scscf-icon.png | Bin 0 -> 855 bytes .../main/webapp/app/fusionapp/icons/scscf-text.png | Bin 0 -> 704 bytes .../main/webapp/app/fusionapp/icons/sdg-icon.png | Bin 0 -> 491 bytes .../main/webapp/app/fusionapp/icons/sdg-text.png | Bin 0 -> 696 bytes .../webapp/app/fusionapp/icons/sgsns4-icon.png | Bin 0 -> 230 bytes .../webapp/app/fusionapp/icons/sgsns4-text.png | Bin 0 -> 469 bytes .../main/webapp/app/fusionapp/icons/sgw-icon.png | Bin 0 -> 388 bytes .../main/webapp/app/fusionapp/icons/sgw-text.png | Bin 0 -> 884 bytes .../main/webapp/app/fusionapp/icons/siad-icon.png | Bin 0 -> 774 bytes .../main/webapp/app/fusionapp/icons/siad-text.png | Bin 0 -> 753 bytes .../webapp/app/fusionapp/icons/ss7-gport-icon.png | Bin 0 -> 286 bytes .../webapp/app/fusionapp/icons/ss7-gport-text.png | Bin 0 -> 418 bytes .../webapp/app/fusionapp/icons/ss7gport-icon.png | Bin 0 -> 646 bytes .../webapp/app/fusionapp/icons/ss7gport-text.png | Bin 0 -> 1011 bytes .../webapp/app/fusionapp/icons/switch-icon.png | Bin 0 -> 877 bytes .../main/webapp/app/fusionapp/icons/tas-icon.png | Bin 0 -> 437 bytes .../main/webapp/app/fusionapp/icons/tas-text.png | Bin 0 -> 858 bytes .../webapp/app/fusionapp/icons/transcoder-icon.png | Bin 0 -> 774 bytes .../webapp/app/fusionapp/icons/transcoder-text.png | Bin 0 -> 1242 bytes .../main/webapp/app/fusionapp/icons/ue-icon.png | Bin 0 -> 577 bytes .../webapp/app/fusionapp/icons/uephone-icon.png | Bin 0 -> 1190 bytes .../webapp/app/fusionapp/icons/usp-dns-icon.png | Bin 0 -> 1065 bytes .../webapp/app/fusionapp/icons/usp-dns-text.png | Bin 0 -> 826 bytes .../main/webapp/app/fusionapp/images}/dummy.txt | 0 .../app/fusionapp/scripts/controller}/dummy.txt | 0 .../scripts/controller/sample-page-controller.js | 61 + .../controller/sample-page-iframe-controller.js | 4 + .../scripts/controller/sampleController.js | 11 + .../app/fusionapp/scripts/directives}/dummy.txt | 0 .../webapp/app/fusionapp/scripts/utils/dummy.txt | 0 .../app/fusionapp/scripts/view-models/dummy.txt | 0 .../scripts/view-models/sampleWithIframe.html | 3 + .../src/main/webapp/app/fusionapp/styles/dummy.txt | 0 .../epsdk-app-overlay/src/main/webapp/index.jsp | 24 + .../src/main/webapp/manifest.jsp | 0 .../css/att_angular_gridster/sandbox-gridster.css | 173 + .../css/att_angular_gridster/ui-gridster.css | 0 .../main/webapp/static/fusion/css/fusion-sunny.css | 362 + .../src/main/webapp/static/fusion/d3/css/nv.d3.css | 0 .../src/main/webapp/static/fusion/d3/js/cie.js | 0 .../main/webapp/static/fusion/d3/js/colorbrewer.js | 0 .../src/main/webapp/static/fusion/d3/js/core.js | 0 .../main/webapp/static/fusion/d3/js/crossfilter.js | 0 .../webapp/static/fusion/d3/js/crossfilter.min.js | 0 .../src/main/webapp/static/fusion/d3/js/d3.geom.js | 0 .../src/main/webapp/static/fusion/d3/js/d3.js | 0 .../webapp/static/fusion/d3/js/d3.layout.cloud.js | 0 .../main/webapp/static/fusion/d3/js/d3.layout.js | 0 .../src/main/webapp/static/fusion/d3/js/d3.v2.js | 0 .../main/webapp/static/fusion/d3/js/d3.v2.min.js | 0 .../main/webapp/static/fusion/d3/js/d3.v3.min.js | 0 .../src/main/webapp/static/fusion/d3/js/fisheye.js | 0 .../src/main/webapp/static/fusion/d3/js/hive.js | 0 .../src/main/webapp/static/fusion/d3/js/horizon.js | 0 .../webapp/static/fusion/d3/js/interactiveLayer.js | 0 .../src/main/webapp/static/fusion}/d3/js/intro.js | 0 .../webapp/static/fusion/d3/js/models/axis-min.js | 0 .../main/webapp/static/fusion/d3/js/models/axis.js | 0 .../webapp/static/fusion/d3/js/models/axis.min.js | 0 .../static/fusion/d3/js/models/backup/bullet.js | 0 .../fusion/d3/js/models/backup/bulletChart.js | 0 .../static/fusion/d3/js/models/boilerplate.js | 0 .../webapp/static/fusion/d3/js/models/bullet.js | 0 .../static/fusion/d3/js/models/bulletChart.js | 0 .../fusion/d3/js/models/cumulativeLineChart.js | 0 .../static/fusion/d3/js/models/discreteBar.js | 0 .../static/fusion/d3/js/models/discreteBarChart.js | 0 .../static/fusion/d3/js/models/distribution.js | 0 .../static/fusion/d3/js/models/historicalBar.js | 0 .../fusion/d3/js/models/historicalBarChart.js | 0 .../static/fusion/d3/js/models/indentedTree.js | 0 .../webapp/static/fusion/d3/js/models/legend.js | 0 .../main/webapp/static/fusion/d3/js/models/line.js | 0 .../webapp/static/fusion/d3/js/models/lineChart.js | 0 .../static/fusion/d3/js/models/linePlusBarChart.js | 0 .../d3/js/models/linePlusBarWithFocusChart.js | 0 .../static/fusion/d3/js/models/lineWithFisheye.js | 0 .../fusion/d3/js/models/lineWithFisheyeChart.js | 0 .../fusion/d3/js/models/lineWithFocusChart.js | 0 .../webapp/static/fusion/d3/js/models/multiBar.js | 0 .../static/fusion/d3/js/models/multiBarChart.js | 0 .../fusion/d3/js/models/multiBarHorizontal.js | 0 .../fusion/d3/js/models/multiBarHorizontalChart.js | 0 .../fusion/d3/js/models/multiBarTimeSeries.js | 0 .../fusion/d3/js/models/multiBarTimeSeriesChart.js | 0 .../static/fusion/d3/js/models/multiChart.js | 0 .../webapp/static/fusion/d3/js/models/ohlcBar.js | 0 .../fusion/d3/js/models/parallelCoordinates.js | 0 .../main/webapp/static/fusion/d3/js/models/pie.js | 0 .../webapp/static/fusion/d3/js/models/pieChart.js | 0 .../webapp/static/fusion/d3/js/models/scatter.js | 0 .../static/fusion/d3/js/models/scatterChart.js | 0 .../fusion/d3/js/models/scatterPlusLineChart.js | 0 .../webapp/static/fusion/d3/js/models/sparkline.js | 0 .../static/fusion/d3/js/models/sparklinePlus.js | 0 .../static/fusion/d3/js/models/stackedArea.js | 0 .../static/fusion/d3/js/models/stackedAreaChart.js | 0 .../src/main/webapp/static/fusion/d3/js/nv.d3.js | 0 .../main/webapp/static/fusion/d3/js/nv.d3.min.js | 0 .../src/main/webapp/static/fusion/d3/js/outro.js | 0 .../src/main/webapp/static/fusion/d3/js/sankey.js | 0 .../src/main/webapp/static/fusion/d3/js/tooltip.js | 0 .../src/main/webapp/static/fusion/d3/js/utils.js | 0 .../src/main/webapp/static/fusion/gis/js/local.js | 178 + .../js/att_angular_gridster/angular-gridster.js | 2244 + .../js/att_angular_gridster/ui-gridster-tpls.js | 168 + .../main/webapp/static/fusion/js/jquery.resize.js | 0 .../main/webapp/static/fusion/js/layout/debug.js | 0 .../static/fusion/js/layout/jquery-latest.js | 0 .../static/fusion/js/layout/jquery-ui-latest.js | 0 .../fusion/js/layout/jquery.layout-latest.js | 0 .../src/main/webapp/static/fusion/js/moment.min.js | 0 .../webapp/static/fusion/raptor/css/CVS/Entries | 9 + .../webapp/static/fusion/raptor/css/CVS/Repository | 1 + .../main/webapp/static/fusion/raptor/css/CVS/Root | 0 .../main/webapp/static/fusion/raptor/css/CVS/Tag | 1 + .../main/webapp/static/fusion/raptor/css/Style.css | 0 .../static/fusion/raptor/css/bd_quantum_raptor.css | 0 .../webapp/static/fusion/raptor/css/calendar.css | 0 .../webapp/static/fusion/raptor/css/dashboard.css | 0 .../webapp/static/fusion/raptor/css/drupal.css | 0 .../fusion/raptor/css/form-field-tooltip.css | 0 .../static/fusion/raptor/css/mobile_raptor.css | 0 .../webapp/static/fusion/raptor/css/novamap.css | 0 .../webapp/static/fusion/raptor/css/picker.css | 0 .../main/webapp/static/fusion/raptor/css/ral.css | 1437 + .../webapp/static/fusion/raptor/css/raptor.css | 0 .../static/fusion/raptor/css/tree/context-menu.css | 57 + .../raptor/css/tree/drag-drop-folder-tree.css | 64 + .../webapp/static/fusion/raptor/d3/css/nv.d3.css | 0 .../main/webapp/static/fusion/raptor/d3/js/cie.js | 0 .../static/fusion/raptor/d3/js/colorbrewer.js | 0 .../main/webapp/static/fusion/raptor/d3/js/core.js | 0 .../static/fusion/raptor/d3/js/crossfilter.js | 0 .../static/fusion/raptor/d3/js/crossfilter.min.js | 0 .../webapp/static/fusion/raptor/d3/js/d3.geom.js | 0 .../main/webapp/static/fusion/raptor/d3/js/d3.js | 0 .../webapp/static/fusion/raptor/d3/js/d3.layout.js | 0 .../webapp/static/fusion/raptor/d3/js/d3.v2.js | 0 .../webapp/static/fusion/raptor/d3/js/d3.v2.min.js | 0 .../webapp/static/fusion/raptor/d3/js/d3.v3.js | 0 .../webapp/static/fusion/raptor/d3/js/d3.v3.min.js | 0 .../webapp/static/fusion/raptor/d3/js/fisheye.js | 0 .../main/webapp/static/fusion/raptor/d3/js/hive.js | 0 .../webapp/static/fusion/raptor/d3/js/horizon.js | 0 .../static/fusion/raptor/d3/js/interactiveLayer.js | 0 .../webapp/static/fusion/raptor}/d3/js/intro.js | 0 .../static/fusion/raptor/d3/js/models/axis-min.js | 0 .../static/fusion/raptor/d3/js/models/axis.js | 0 .../static/fusion/raptor/d3/js/models/axis.min.js | 0 .../fusion/raptor/d3/js/models/boilerplate.js | 0 .../static/fusion/raptor/d3/js/models/bullet.js | 0 .../fusion/raptor/d3/js/models/bulletChart.js | 0 .../raptor/d3/js/models/cumulativeLineChart.js | 0 .../fusion/raptor/d3/js/models/discreteBar.js | 0 .../fusion/raptor/d3/js/models/discreteBarChart.js | 0 .../fusion/raptor/d3/js/models/distribution.js | 0 .../fusion/raptor/d3/js/models/historicalBar.js | 0 .../raptor/d3/js/models/historicalBarChart.js | 0 .../fusion/raptor/d3/js/models/indentedTree.js | 0 .../static/fusion/raptor/d3/js/models/legend.js | 0 .../static/fusion/raptor/d3/js/models/line.js | 0 .../static/fusion/raptor/d3/js/models/lineChart.js | 0 .../fusion/raptor/d3/js/models/linePlusBarChart.js | 0 .../d3/js/models/linePlusBarWithFocusChart.js | 0 .../fusion/raptor/d3/js/models/lineWithFisheye.js | 0 .../raptor/d3/js/models/lineWithFisheyeChart.js | 0 .../raptor/d3/js/models/lineWithFocusChart.js | 0 .../static/fusion/raptor/d3/js/models/multiBar.js | 0 .../fusion/raptor/d3/js/models/multiBarChart.js | 0 .../raptor/d3/js/models/multiBarHorizontal.js | 0 .../raptor/d3/js/models/multiBarHorizontalChart.js | 0 .../raptor/d3/js/models/multiBarTimeSeries.js | 0 .../raptor/d3/js/models/multiBarTimeSeriesChart.js | 0 .../fusion/raptor/d3/js/models/multiChart.js | 0 .../static/fusion/raptor/d3/js/models/ohlcBar.js | 0 .../raptor/d3/js/models/parallelCoordinates.js | 0 .../static/fusion/raptor/d3/js/models/pie.js | 0 .../static/fusion/raptor/d3/js/models/pie.js.bak | 0 .../static/fusion/raptor/d3/js/models/pieChart.js | 0 .../static/fusion/raptor/d3/js/models/scatter.js | 0 .../fusion/raptor/d3/js/models/scatterChart.js | 0 .../raptor/d3/js/models/scatterPlusLineChart.js | 0 .../static/fusion/raptor/d3/js/models/sparkline.js | 0 .../fusion/raptor/d3/js/models/sparklinePlus.js | 0 .../fusion/raptor/d3/js/models/stackedArea.js | 0 .../fusion/raptor/d3/js/models/stackedAreaChart.js | 0 .../webapp/static/fusion/raptor/d3/js/nv.d3.min.js | 0 .../webapp/static/fusion/raptor/d3/js/outro.js | 0 .../webapp/static/fusion/raptor/d3/js/sankey.js | 0 .../webapp/static/fusion/raptor/d3/js/tooltip.js | 0 .../webapp/static/fusion/raptor/d3/js/utils.js | 0 .../static/fusion/raptor/dy3/js/dashed-canvas.js | 0 .../webapp/static/fusion/raptor/dy3/js/data.js | 0 .../static/fusion/raptor/dy3/js/dygraph-canvas.js | 0 .../fusion/raptor/dy3/js/dygraph-combined.js | 0 .../raptor/dy3/js/dygraph-combined_bak_color.js | 0 .../static/fusion/raptor/dy3/js/dygraph-dev.js | 0 .../static/fusion/raptor/dy3/js/dygraph-externs.js | 0 .../static/fusion/raptor/dy3/js/dygraph-gviz.js | 0 .../raptor/dy3/js/dygraph-interaction-model.js | 0 .../static/fusion/raptor/dy3/js/dygraph-layout.js | 0 .../raptor/dy3/js/dygraph-options-reference.js | 0 .../static/fusion/raptor/dy3/js/dygraph-options.js | 0 .../fusion/raptor/dy3/js/dygraph-plugin-base.js | 0 .../fusion/raptor/dy3/js/dygraph-plugin-install.js | 0 .../static/fusion/raptor/dy3/js/dygraph-tickers.js | 0 .../static/fusion/raptor/dy3/js/dygraph-utils.js | 0 .../webapp/static/fusion/raptor/dy3/js/dygraph.js | 0 .../webapp/static/fusion/raptor/dy3/js/excanvas.js | 0 .../static/fusion/raptor/dy3/js/interaction.js | 0 .../static/fusion/raptor/dy3/js/interaction.min.js | 0 .../static/fusion/raptor/dy3/js/interaction_sun.js | 0 .../static/fusion/raptor/dy3/js/moment.min.js | 0 .../static/fusion/raptor/dy3/js/phantom-driver.js | 0 .../static/fusion/raptor/dy3/js/phantom-perf.js | 0 .../static/fusion/raptor/dy3/js/plugins/README | 0 .../fusion/raptor/dy3/js/plugins/annotations.js | 0 .../static/fusion/raptor/dy3/js/plugins/axes.js | 0 .../fusion/raptor/dy3/js/plugins/chart-labels.js | 0 .../static/fusion/raptor/dy3/js/plugins/grid.js | 0 .../static/fusion/raptor/dy3/js/plugins/legend.js | 0 .../fusion/raptor/dy3/js/plugins/range-selector.js | 0 .../fusion/raptor/dy3/js/rgbcolor/rgbcolor.js | 0 .../static/fusion/raptor/dy3/js/stacktrace.js | 0 .../static/fusion/raptor/dy3/js/strftime/Doxyfile | 0 .../fusion/raptor/dy3/js/strftime/strftime-min.js | 0 .../fusion/raptor/dy3/js/strftime/strftime.js | 0 .../static/fusion/raptor/ebz/date_time_picker.css | 0 .../static/fusion/raptor/ebz/date_time_picker.js | 0 .../webapp/static/fusion/raptor/ebz/dynamicform.js | 0 .../main/webapp/static/fusion/raptor/ebz/moment.js | 0 .../webapp/static/fusion/raptor/ebz/multiselect.js | 0 .../webapp/static/fusion/raptor/ebz/quick_links.js | 0 .../fusion/raptor/ebz/report_chart_wizard.html | 0 .../fusion/raptor/ebz/report_chart_wizard.js | 0 .../static/fusion/raptor/ebz/report_run.html | 72 + .../webapp/static/fusion/raptor/ebz/report_run.js | 322 + .../static/fusion/raptor/ebz/report_search.html | 35 + .../static/fusion/raptor/ebz/report_search.js | 136 + .../fusion/raptor/images/ATT_Business_logo.gif | Bin 0 -> 8203 bytes .../static/fusion/raptor/images/RAPTOR_BANNER.jpg | Bin 0 -> 6249 bytes .../static/fusion/raptor/images/accessicon.gif | Bin 0 -> 329 bytes .../webapp/static/fusion/raptor/images/active.gif | Bin 0 -> 338 bytes .../webapp/static/fusion/raptor/images/addbtn.png | Bin 0 -> 662 bytes .../static/fusion/raptor/images/ajax-loader.gif | Bin 0 -> 673 bytes .../static/fusion/raptor/images/arrow_add.gif | Bin 0 -> 469 bytes .../static/fusion/raptor/images/arrow_add_edge.gif | Bin 0 -> 564 bytes .../fusion/raptor/images/arrow_add_multiple.gif | Bin 0 -> 748 bytes .../static/fusion/raptor/images/arrow_add_one.gif | Bin 0 -> 631 bytes .../static/fusion/raptor/images/arrow_back.gif | Bin 0 -> 621 bytes .../static/fusion/raptor/images/arrow_cancel.gif | Bin 0 -> 652 bytes .../static/fusion/raptor/images/arrow_left.gif | Bin 0 -> 382 bytes .../static/fusion/raptor/images/arrow_left2.gif | Bin 0 -> 399 bytes .../static/fusion/raptor/images/arrow_next.gif | Bin 0 -> 609 bytes .../static/fusion/raptor/images/arrow_plus.gif | Bin 0 -> 67 bytes .../fusion/raptor/images/arrow_reorder_all.gif | Bin 0 -> 686 bytes .../fusion/raptor/images/arrow_reorder_all.png | Bin 0 -> 29837 bytes .../static/fusion/raptor/images/arrow_right.gif | Bin 0 -> 381 bytes .../static/fusion/raptor/images/arrow_right2.gif | Bin 0 -> 399 bytes .../static/fusion/raptor/images/arrow_save.gif | Bin 0 -> 606 bytes .../static/fusion/raptor/images/att-globe1.jpg | Bin 0 -> 5855 bytes .../static/fusion/raptor/images/button_import.png | Bin 0 -> 546 bytes .../static/fusion/raptor/images/calendar_icon.gif | Bin 0 -> 552 bytes .../fusion/raptor/images/calendar_icon_nav.gif | Bin 0 -> 538 bytes .../fusion/raptor/images/calendar_icon_nav1.gif | Bin 0 -> 1065 bytes .../static/fusion/raptor/images/calender_icon.gif | Bin 0 -> 552 bytes .../fusion/raptor/images/columnblankdown.gif | Bin 0 -> 192 bytes .../static/fusion/raptor/images/columnblankup.gif | Bin 0 -> 193 bytes .../static/fusion/raptor/images/columndown.gif | Bin 0 -> 124 bytes .../static/fusion/raptor/images/columnup.gif | Bin 0 -> 126 bytes .../static/fusion/raptor/images/crosshairs.png | Bin 0 -> 218 bytes .../static/fusion/raptor/images/csv_icon.gif | Bin 0 -> 447 bytes .../static/fusion/raptor/images/deleteicon.gif | Bin 0 -> 80 bytes .../static/fusion/raptor/images/downloadicon.gif | Bin 0 -> 74 bytes .../static/fusion/raptor/images/excel2007.jpg | Bin 0 -> 761 bytes .../static/fusion/raptor/images/excel2007.png | Bin 0 -> 3186 bytes .../static/fusion/raptor/images/excelicon.gif | Bin 0 -> 1055 bytes .../fusion/raptor/images/excelicon_multi.gif | Bin 0 -> 1026 bytes .../fusion/raptor/images/green-arrow-right.gif | Bin 0 -> 201 bytes .../static/fusion/raptor/images/green-arrow.gif | Bin 0 -> 195 bytes .../static/fusion/raptor/images/grnarrowdn.gif | Bin 0 -> 74 bytes .../static/fusion/raptor/images/grnarrowup.gif | Bin 0 -> 106 bytes .../main/webapp/static/fusion/raptor/images/h.png | Bin 0 -> 380 bytes .../static/fusion/raptor/images/inactive.gif | Bin 0 -> 352 bytes .../webapp/static/fusion/raptor/images/loader.gif | Bin 0 -> 958 bytes .../webapp/static/fusion/raptor/images/loading.gif | Bin 0 -> 4176 bytes .../static/fusion/raptor/images/lookup_arrow.gif | Bin 0 -> 645 bytes .../static/fusion/raptor/images/maps/blue.png | Bin 0 -> 1309 bytes .../static/fusion/raptor/images/maps/green.png | Bin 0 -> 1190 bytes .../static/fusion/raptor/images/maps/lightblue.png | Bin 0 -> 1269 bytes .../fusion/raptor/images/maps/map_iphone.jpg | Bin 0 -> 712 bytes .../static/fusion/raptor/images/maps/orange.png | Bin 0 -> 3413 bytes .../static/fusion/raptor/images/maps/pink.png | Bin 0 -> 1321 bytes .../static/fusion/raptor/images/maps/purple.png | Bin 0 -> 1324 bytes .../static/fusion/raptor/images/maps/red.png | Bin 0 -> 1305 bytes .../static/fusion/raptor/images/maps/yellow.png | Bin 0 -> 1309 bytes .../webapp/static/fusion/raptor}/images/minus.gif | Bin .../static/fusion/raptor}/images/modify_icon.gif | Bin .../webapp/static/fusion/raptor/images/page.gif | Bin 0 -> 554 bytes .../static/fusion/raptor/images/pdficon_large.gif | Bin 0 -> 434 bytes .../static/fusion/raptor/images/pdficon_small.gif | Bin 0 -> 361 bytes .../static/fusion/raptor/images/pen_paper.gif | Bin 0 -> 618 bytes .../webapp/static/fusion/raptor}/images/plus.gif | Bin .../static/fusion/raptor/images/popupicon.gif | Bin 0 -> 79 bytes .../static/fusion/raptor/images/position.png | Bin 0 -> 267 bytes .../webapp/static/fusion/raptor/images/printer.gif | Bin 0 -> 1019 bytes .../static/fusion/raptor/images/progress.gif | Bin 0 -> 734 bytes .../static/fusion/raptor/images/question_mark.jpg | Bin 0 -> 426 bytes .../static/fusion/raptor/images/quickhelp_dk.gif | Bin 0 -> 155 bytes .../static/fusion/raptor/images/quickhelp_lt.gif | Bin 0 -> 897 bytes .../webapp/static/fusion/raptor/images/r_back.gif | Bin 0 -> 918 bytes .../webapp/static/fusion/raptor/images/raptor.jpg | Bin 0 -> 889 bytes .../static/fusion/raptor/images/raptor_logo.gif | Bin 0 -> 3150 bytes .../static/fusion/raptor/images/raptor_logo.jpg | Bin 0 -> 1827 bytes .../static/fusion/raptor/images/required.gif | Bin 0 -> 854 bytes .../static/fusion/raptor/images/shareicon.gif | Bin 0 -> 542 bytes .../main/webapp/static/fusion/raptor/images/sv.png | Bin 0 -> 11373 bytes .../static/fusion/raptor/images/tab_left.gif | Bin 0 -> 137 bytes .../static/fusion/raptor/images/tab_left_sel.gif | Bin 0 -> 106 bytes .../static/fusion/raptor/images/tab_right.gif | Bin 0 -> 138 bytes .../static/fusion/raptor/images/tab_right_sel.gif | Bin 0 -> 104 bytes .../static/fusion/raptor/images/test_run.gif | Bin 0 -> 330 bytes .../webapp/static/fusion/raptor/images/text.gif | Bin 0 -> 141 bytes .../raptor/images/tree/context-menu-gradient.gif | Bin 0 -> 807 bytes .../raptor/images/tree/dhtmlgoodies_folder.gif | Bin 0 -> 1120 bytes .../raptor/images/tree/dhtmlgoodies_minus.gif | Bin 0 -> 197 bytes .../raptor/images/tree/dhtmlgoodies_plus.gif | Bin 0 -> 200 bytes .../raptor/images/tree/dhtmlgoodies_sheet.gif | Bin 0 -> 906 bytes .../images/tree/dhtmlgoodies_sheet_crosstab.gif | Bin 0 -> 1144 bytes .../images/tree/dhtmlgoodies_sheet_dashboard.gif | Bin 0 -> 1164 bytes .../images/tree/dhtmlgoodies_sheet_graph.gif | Bin 0 -> 983 bytes .../fusion/raptor/images/tree/dragDrop_ind1.gif | Bin 0 -> 53 bytes .../fusion/raptor/images/tree/dragDrop_ind2.gif | Bin 0 -> 56 bytes .../fusion/raptor/images/tree/folder_close.gif | Bin 0 -> 283 bytes .../fusion/raptor/images/tree/folder_dots.gif | Bin 0 -> 68 bytes .../fusion/raptor/images/tree/folder_folder.gif | Bin 0 -> 980 bytes .../fusion/raptor/images/tree/folder_lastsub.gif | Bin 0 -> 78 bytes .../fusion/raptor/images/tree/folder_open.gif | Bin 0 -> 286 bytes .../fusion/raptor/images/tree/folder_sub.gif | Bin 0 -> 265 bytes .../fusion/raptor/images/tree/grnarrowleft.gif | Bin 0 -> 854 bytes .../fusion/raptor/images/tree/grnarrowright.gif | Bin 0 -> 845 bytes .../static/fusion/raptor/images/txt_icon.gif | Bin 0 -> 154 bytes .../webapp/static/fusion/raptor/images/uF033.png | Bin 0 -> 520 bytes .../webapp/static/fusion/raptor/images/uF034.png | Bin 0 -> 536 bytes .../webapp/static/fusion/raptor/images/uF035.png | Bin 0 -> 487 bytes .../webapp/static/fusion/raptor/images/uF036.png | Bin 0 -> 482 bytes .../fusion/raptor/img/BorderLayout-24x24.png | Bin 0 -> 1369 bytes .../static/fusion/raptor/img/Calendar-16x16.png | Bin 0 -> 552 bytes .../static/fusion/raptor/img/DeleteCross-16x16.png | Bin 0 -> 750 bytes .../webapp/static/fusion/raptor/img/addbtn.png | Bin 0 -> 662 bytes .../static/fusion/raptor/img/button_import.png | Bin 0 -> 546 bytes .../fusion/raptor/img}/copyicon-highlighted.png | Bin .../webapp/static/fusion/raptor/img/copyicon.png | Bin 0 -> 235 bytes .../static/fusion/raptor/img/cross-small.png | Bin 0 -> 291 bytes .../webapp/static/fusion/raptor/img/csv_icon.gif | Bin 0 -> 447 bytes .../webapp/static/fusion/raptor/img}/csv_icon.jpg | Bin .../webapp/static/fusion/raptor/img}/csv_icon.png | Bin .../fusion/raptor/img}/deleteicon-highlighted.gif | Bin .../fusion/raptor/img}/deleteicon-highlighted.png | Bin .../webapp/static/fusion/raptor/img/deleteicon.gif | Bin 0 -> 579 bytes .../static/fusion/raptor/img/downloadicon.gif | Bin 0 -> 74 bytes .../webapp/static/fusion/raptor/img}/editicon.gif | Bin .../webapp/static/fusion/raptor/img/excel2007.jpg | Bin 0 -> 761 bytes .../webapp/static/fusion/raptor/img/excelicon.gif | Bin 0 -> 1055 bytes .../static/fusion/raptor/img/excelicon_multi.gif | Bin 0 -> 1026 bytes .../static/fusion/raptor/img}/executeicon.png | Bin .../static/fusion/raptor/img}/file_import.png | Bin .../static/fusion/raptor/img/pdficon_small.gif | Bin 0 -> 361 bytes .../webapp/static/fusion/raptor/img/pen_paper.gif | Bin 0 -> 618 bytes .../static/fusion/raptor/img/pencil-small.png | Bin 0 -> 309 bytes .../static/fusion/raptor/img}/report-add.png | Bin .../static/fusion/raptor/img}/report-favorite.png | Bin .../webapp/static/fusion/raptor/img}/report-my.png | Bin .../static/fusion/raptor/img}/report-public.png | Bin .../webapp/static/fusion/raptor/img}/report.png | Bin .../webapp/static/fusion/raptor/img}/reports.png | Bin .../webapp/static/fusion/raptor/img/search.gif | Bin 0 -> 223 bytes .../webapp/static/fusion/raptor/img}/search.png | Bin .../webapp/static/fusion/raptor/img/tick-small.png | Bin 0 -> 283 bytes .../static/fusion/raptor/js/CalendarPopup.js | 0 .../main/webapp/static/fusion/raptor/js/ajax.js | 0 .../fusion/raptor/js/ajax_dynamic_content.js | 0 .../static/fusion/raptor/js/cingular_button.js | 0 .../main/webapp/static/fusion/raptor/js/drupal.js | 0 .../static/fusion/raptor/js/editabledropdown.js | 0 .../static/fusion/raptor/js/form-field-tooltip.js | 0 .../main/webapp/static/fusion/raptor/js/gmap.js | 0 .../main/webapp/static/fusion/raptor/js/jquery.js | 0 .../webapp/static/fusion/raptor/js/jquery.min.js | 0 .../static/fusion/raptor/js/label_quantum.js | 0 .../webapp/static/fusion/raptor/js/nova_button.js | 0 .../static/fusion/raptor/js/other_scripts.js | 331 + .../fusion/raptor/js/persist_table_header.js | 0 .../static/fusion/raptor/js/projected_overlay.js | 129 + .../static/fusion/raptor/js/prototype-1.6.0.3.js | 0 .../main/webapp/static/fusion/raptor/js/raptor.js | 0 .../static/fusion/raptor/js/rounded-corners.js | 0 .../main/webapp/static/fusion/raptor/js/script.js | 0 .../webapp/static/fusion/raptor/js/tree/ajax.js | 194 + .../static/fusion/raptor/js/tree/context-menu.js | 444 + .../fusion/raptor/js/tree/drag-drop-folder-tree.js | 1059 + .../webapp/static/fusion/raptor/uigrid/ui-grid.css | 0 .../webapp/static/fusion/raptor/uigrid/ui-grid.eot | Bin .../webapp/static/fusion/raptor/uigrid/ui-grid.js | 26735 ++++++++++++ .../webapp/static/fusion/raptor/uigrid/ui-grid.svg | 0 .../webapp/static/fusion/raptor/uigrid/ui-grid.ttf | Bin .../static/fusion/raptor/uigrid/ui-grid.woff | Bin .../static/fusion/raptor/uigrid/vfs_fonts.js | 0 .../webapp/static/fusion/sample/css/flexslider.css | 275 + .../fusion/sample/css/fonts/flexslider-icon.eot | Bin 0 -> 2082 bytes .../fusion/sample/css/fonts/flexslider-icon.svg | 19 + .../fusion/sample/css/fonts/flexslider-icon.ttf | Bin 0 -> 1892 bytes .../fusion/sample/css/fonts/flexslider-icon.woff | Bin 0 -> 1268 bytes .../static/fusion/sample/css/images/blank.gif | Bin 0 -> 49 bytes .../webapp/static/fusion/sample/css/scribble.css | 40 + .../webapp/static/fusion/sample/css/slider.css | 142 + .../static/fusion/sample/css/spacegallery.css | 18 + .../webapp/static/fusion/sample/css/welcome.css | 173 + .../static/fusion/sample/html/area_chart.html | 49 + .../static/fusion/sample/html/bar_chart.html | 95 + .../static/fusion/sample/html/d3_gauges_demo.html | 39 + .../fusion/sample/html/data/speedometer2.csv | 16 + .../fusion/sample/html/data/speedometer3.csv | 2 + .../static/fusion/sample/html/data/worddata.csv | 1 + .../webapp/static/fusion/sample/html/donut_d3.html | 43 + .../static/fusion/sample/html/js/area_chart.min.js | 1 + .../static/fusion/sample/html/js/donut.min.js | 1 + .../static/fusion/sample/html/js/gauges.min.js | 1 + .../static/fusion/sample/html/js/line_chart.min.js | 1 + .../static/fusion/sample/html/js/pie_chart.min.js | 1 + .../static/fusion/sample/html/js/worddata.min.js | 1 + .../static/fusion/sample/html/line_chart.html | 49 + .../static/fusion/sample/html/pie_chart.html | 38 + .../static/fusion/sample/html/wordcloud.html | 36 + .../static/fusion/sample/images/Calendar-16x16.png | Bin 0 -> 552 bytes .../static/fusion/sample/images/arrow-next.png | Bin 0 -> 1561 bytes .../static/fusion/sample/images/arrow-prev.png | Bin 0 -> 1557 bytes .../images/carousel/slide_b_drive_test_map.png | Bin 0 -> 202465 bytes .../sample/images/carousel/slide_b_eppt_county.png | Bin 0 -> 21222 bytes .../images/carousel/slide_b_eppt_regression.png | Bin 0 -> 11536 bytes .../images/carousel/slide_b_ios_throughput.png | Bin 0 -> 26131 bytes .../sample/images/carousel/slide_b_lata_map.png | Bin 0 -> 192031 bytes .../images/carousel/slide_b_lata_map_legend.png | Bin 0 -> 3021 bytes .../images/carousel/slide_b_nova_sdn_map.png | Bin 0 -> 179361 bytes .../static/fusion/sample/images/copyicon.png | Bin 0 -> 235 bytes .../static/fusion/sample/images/deleteicon.gif | Bin 0 -> 579 bytes .../static/fusion/sample/images/example-frame.png | Bin 0 -> 33699 bytes .../webapp/static/fusion/sample/images/loading.gif | Bin 0 -> 6820 bytes .../static/fusion/sample/images/tunnels/1_mon.png | Bin 0 -> 22762 bytes .../static/fusion/sample/images/tunnels/2_tue.png | Bin 0 -> 22772 bytes .../static/fusion/sample/images/tunnels/3_wed.png | Bin 0 -> 24012 bytes .../static/fusion/sample/images/tunnels/4_thu.png | Bin 0 -> 23902 bytes .../static/fusion/sample/images/tunnels/5_fri.png | Bin 0 -> 22349 bytes .../static/fusion/sample/images/tunnels/6_sat.png | Bin 0 -> 23674 bytes .../static/fusion/sample/images/tunnels/7_sun.png | Bin 0 -> 22845 bytes .../fusion/sample/images/tunnels/BH_DLSTX_IN.png | Bin 0 -> 10575 bytes .../fusion/sample/images/tunnels/BH_DLSTX_OUT.png | Bin 0 -> 10460 bytes .../static/fusion/sample/images/tunnels/BH_Nat.png | Bin 0 -> 10420 bytes .../fusion/sample/images/tunnels/BH_Nat_Def.png | Bin 0 -> 8941 bytes .../sample/images/tunnels/BH_Nat_Priority.png | Bin 0 -> 10590 bytes .../webapp/static/fusion/sample/js/FusionCharts.js | 361 + .../main/webapp/static/fusion/sample/js/charts.js | 132 + .../src/main/webapp/static/fusion/sample/js/eye.js | 34 + .../fusion/sample/js/jquery.flexslider-min.js | 5 + .../webapp/static/fusion/sample/js/scribble.js | 19 + .../static/fusion/sample/js/slides.min.jquery.js | 20 + .../webapp/static/fusion/sample/js/spacegallery.js | 235 + .../main/webapp/static/fusion/sample/js/utils.js | 252 + .../fusion/sample/org_chart/css/bootstrap.min.css | 351 + .../static/fusion/sample/org_chart/css/custom.css | 97 + .../sample/org_chart/css/jquery.jOrgChart.css | 51 + .../fusion/sample/org_chart/css/prettify.css | 1 + .../static/fusion/sample/org_chart/example.html | 85 + .../fusion/sample/org_chart/example_vsp.html | 88 + .../static/fusion/sample/org_chart/images/bkgd.png | Bin 0 -> 133 bytes .../fusion/sample/org_chart/images/raspberry.jpg | Bin 0 -> 5755 bytes .../fusion/sample/org_chart/jquery.jOrgChart.js | 267 + .../static/fusion/sample/org_chart/prettify.js | 28 + .../src/main/webapp/static/js/jquery-1.10.2.js | 0 .../src/main/webapp/static/js/jquery-ui.js | 0 .../src/main/webapp/static/js/jquery.mask.min.js | 0 .../src/main/webapp/static/js/modalService.js | 0 .../src/main/webapp/static/js/search.js | 830 + ecomp-sdk/epsdk-core/.gitignore | 5 + ecomp-sdk/epsdk-core/README.md | 168 + ecomp-sdk/epsdk-core/license/licenses.properties | 1 + ecomp-sdk/epsdk-core/license/my_license/header.txt | 11 + .../epsdk-core/license/my_license/license.txt | 4 + ecomp-sdk/epsdk-core/pom.xml | 406 + .../org/openecomp/portalsdk/core/FusionObject.java | 111 + .../portalsdk/core/auth/LoginStrategy.java | 131 + .../portalsdk/core/command/LoginBean.java | 193 + .../portalsdk/core/command/PostDroolsBean.java | 0 .../portalsdk/core/command/PostSearchBean.java | 375 + .../portalsdk/core/command/UserRowBean.java | 85 + .../portalsdk/core/command/support/SearchBase.java | 270 + .../core/command/support/SearchResult.java | 67 + .../openecomp/portalsdk/core/conf/AppConfig.java | 313 + .../portalsdk/core/conf/AppInitializer.java | 69 + .../portalsdk/core/conf/Configurable.java | 0 .../core/conf/HibernateConfiguration.java | 139 + .../core/conf/HibernateMappingLocatable.java | 43 + .../core/controller/FusionBaseController.java | 0 .../core/controller/RestrictedBaseController.java | 0 .../RestrictedRESTfulBaseController.java | 0 .../controller/UnRestrictedBaseController.java | 0 .../openecomp/portalsdk/core/dao/AbstractDao.java | 0 .../openecomp/portalsdk/core/dao/ProfileDao.java | 0 .../portalsdk/core/dao/ProfileDaoImpl.java | 51 + .../core/dao/hibernate/ModelOperationsCommon.java | 0 .../portalsdk/core/dao/support/FusionDao.java | 36 + .../org/openecomp/portalsdk/core/domain/App.java | 0 .../openecomp/portalsdk/core/domain/AuditLog.java | 106 + .../portalsdk/core/domain/BroadcastMessage.java | 124 + .../openecomp/portalsdk/core/domain/DomainVo.java | 0 .../openecomp/portalsdk/core/domain/FnMenu.java | 141 + .../openecomp/portalsdk/core/domain/FusionVo.java | 0 .../openecomp/portalsdk/core/domain/LoginBean.java | 187 + .../openecomp/portalsdk/core/domain/Lookup.java | 85 + .../openecomp/portalsdk/core/domain/LuCountry.java | 87 + .../openecomp/portalsdk/core/domain/LuState.java | 70 + .../portalsdk/core/domain/LuTimeZone.java | 79 + .../org/openecomp/portalsdk/core/domain/Menu.java | 160 + .../openecomp/portalsdk/core/domain/MenuData.java | 72 + .../openecomp/portalsdk/core/domain/Profile.java | 0 .../org/openecomp/portalsdk/core/domain/Role.java | 174 + .../portalsdk/core/domain/RoleFunction.java | 71 + .../portalsdk/core/domain/UrlsAccessible.java | 83 + .../portalsdk/core/domain/UrlsAccessibleKey.java | 90 + .../org/openecomp/portalsdk/core/domain/User.java | 584 + .../openecomp/portalsdk/core/domain/UserApp.java | 111 + .../openecomp/portalsdk/core/domain/UserAppId.java | 0 .../core/domain/sessionmgt/TimeoutVO.java | 63 + .../portalsdk/core/domain/support/Attribute.java | 0 .../core/domain/support/CollaborateList.java | 0 .../portalsdk/core/domain/support/Container.java | 331 + .../portalsdk/core/domain/support/Domain.java | 259 + .../portalsdk/core/domain/support/DomainVo.java | 166 + .../portalsdk/core/domain/support/Element.java | 165 + .../core/domain/support/ElementDetails.java | 71 + .../core/domain/support/FusionCommand.java | 0 .../portalsdk/core/domain/support/Layout.java | 1209 + .../portalsdk/core/domain/support/NameValueId.java | 94 + .../portalsdk/core/domain/support/Position.java | 0 .../portalsdk/core/domain/support/Size.java | 0 .../portalsdk/core/drools/DroolsRuleService.java | 0 .../core/drools/DroolsRuleServiceImpl.java | 58 + .../core/exception/FusionExceptionResolver.java | 50 + .../core/exception/SessionExpiredException.java | 35 + .../exception/UrlAccessRestrictedException.java | 35 + .../core/exception/support/FusionException.java | 0 .../exception/support/FusionRuntimeException.java | 35 + .../core/interceptor/ResourceInterceptor.java | 167 + .../interceptor/SessionTimeoutInterceptor.java | 0 .../core/interfaces/SecurityInterface.java | 0 .../core/listener/ApplicationContextListener.java | 49 + .../listener/CollaborateListBindingListener.java | 0 .../core/listener/UserSessionListener.java | 0 .../portalsdk/core/lm/FusionLicenseManager.java | 60 + .../core/lm/FusionLicenseManagerUtils.java | 74 + .../portalsdk/core/lm/LicenseableClass.java | 38 + .../portalsdk/core/logging/aspect/AuditLog.java | 32 + .../core/logging/aspect/EELFLoggerAdvice.java | 234 + .../core/logging/aspect/EELFLoggerAspect.java | 0 .../portalsdk/core/logging/aspect/MetricsLog.java | 0 .../core/logging/format/AlarmSeverityEnum.java | 0 .../core/logging/format/AppMessagesEnum.java | 0 .../logging/format/ApplicationCodes.properties | 0 .../core/logging/format/AuditLogFormatter.java | 0 .../core/logging/format/ErrorCodesEnum.java | 89 + .../core/logging/format/ErrorSeverityEnum.java | 0 .../core/logging/format/ErrorTypeEnum.java | 0 .../core/logging/logic/EELFLoggerDelegate.java | 484 + .../openecomp/portalsdk/core/menu/MenuBuilder.java | 163 + .../portalsdk/core/menu/MenuProperties.java | 114 + .../core/objectcache/AbstractCacheManager.java | 60 + .../core/objectcache/jcs/JCSCacheEventHandler.java | 0 .../core/objectcache/jcs/JCSCacheManager.java | 0 .../objectcache/support/FusionCacheManager.java | 36 + .../core/onboarding/client/AppContextManager.java | 45 + .../core/onboarding/session/TestClass.java | 0 .../portalsdk/core/onboarding/sso/TestClass.java | 0 .../portalsdk/core/onboarding/ueb/Consumer.java | 155 + .../core/onboarding/ueb/FunctionalMenu.java | 61 + .../portalsdk/core/onboarding/ueb/Helper.java | 64 + .../portalsdk/core/onboarding/ueb/Publisher.java | 125 + .../core/onboarding/ueb/PublisherList.java | 77 + .../core/onboarding/ueb/TopicManager.java | 135 + .../core/onboarding/ueb/UebException.java | 65 + .../portalsdk/core/onboarding/ueb/UebManager.java | 358 + .../portalsdk/core/onboarding/ueb/UebMsg.java | 119 + .../portalsdk/core/onboarding/ueb/UebMsgTypes.java | 28 + .../onboarding/ueb/WaitingRequestersQueueList.java | 73 + .../core/restful/client/HttpStatusAndResponse.java | 0 .../core/restful/client/PortalRestClientBase.java | 171 + .../restful/client/SharedContextRestClient.java | 351 + .../portalsdk/core/scheduler/CoreRegister.java | 0 .../portalsdk/core/scheduler/CronRegistry.java | 125 + .../portalsdk/core/scheduler/Registerable.java | 0 .../portalsdk/core/service/AppService.java | 0 .../portalsdk/core/service/AppServiceImpl.java | 106 + .../portalsdk/core/service/AuditService.java | 37 + .../portalsdk/core/service/AuditServiceImpl.java | 50 + .../portalsdk/core/service/BroadcastService.java | 36 + .../core/service/BroadcastServiceImpl.java | 250 + .../portalsdk/core/service/DataAccessService.java | 0 .../core/service/DataAccessServiceImpl.java | 594 + .../portalsdk/core/service/ElementLinkService.java | 290 + .../portalsdk/core/service/ElementMapService.java | 1029 + .../portalsdk/core/service/FnMenuService.java | 0 .../portalsdk/core/service/FnMenuServiceImpl.java | 161 + .../portalsdk/core/service/LdapService.java | 0 .../portalsdk/core/service/LdapServiceImpl.java | 267 + .../portalsdk/core/service/LoginService.java | 36 + .../portalsdk/core/service/LoginServiceImpl.java | 205 + .../portalsdk/core/service/PostDroolsService.java | 0 .../core/service/PostDroolsServiceImpl.java | 186 + .../portalsdk/core/service/PostSearchService.java | 37 + .../core/service/PostSearchServiceImpl.java | 207 + .../portalsdk/core/service/ProfileService.java | 0 .../portalsdk/core/service/ProfileServiceImpl.java | 74 + .../portalsdk/core/service/RoleService.java | 0 .../portalsdk/core/service/RoleServiceImpl.java | 171 + .../core/service/RoleServiceNonSpringImpl.java | 122 + .../portalsdk/core/service/UserProfileService.java | 34 + .../core/service/UserProfileServiceImpl.java | 116 + .../core/service/WebServiceCallService.java | 0 .../core/service/WebServiceCallServiceImpl.java | 189 + .../core/service/support/FusionService.java | 0 .../core/service/support/ServiceLocator.java | 0 .../core/service/support/ServiceLocatorImpl.java | 105 + .../portalsdk/core/util/CacheManager.java | 0 .../portalsdk/core/util/EncDecUtilTest.java | 112 + .../openecomp/portalsdk/core/util/JSONUtil.java | 0 .../portalsdk/core/util/SystemProperties.java | 327 + .../openecomp/portalsdk/core/util/UsageUtils.java | 0 .../openecomp/portalsdk/core/util/YamlUtils.java | 72 + .../core/web/socket/PeerBroadcastSocket.java | 0 .../portalsdk/core/web/socket/WebRTCSocket.java | 0 .../portalsdk/core/web/support/AppUtils.java | 213 + .../core/web/support/ControllerProperties.java | 0 .../core/web/support/FeedbackMessage.java | 0 .../portalsdk/core/web/support/JsonMessage.java | 0 .../portalsdk/core/web/support/MessagesList.java | 92 + .../portalsdk/core/web/support/UserUtils.java | 423 + .../core/MockApplicationContextTestSuite.java | 114 + .../fusion/core/MockHibernateMappingLocations.java | 23 + .../portalsdk/MockApplicationContextTestSuite.java | 143 + .../portalsdk/MockHibernateMappingLocations.java | 42 + .../sessionmgt/PortalCommunicationTest.java | 75 + ecomp-sdk/epsdk-fw/.gitignore | 5 + ecomp-sdk/epsdk-fw/README.md | 111 + ecomp-sdk/epsdk-fw/pom.xml | 87 + .../onboarding/crossapi/IPortalRestAPIService.java | 175 + .../onboarding/crossapi/IPortalUebAPIService.java | 47 + .../onboarding/crossapi/PortalAPIResponse.java | 58 + .../onboarding/crossapi/PortalRestAPIProxy.java | 618 + .../crossapi/SessionCommunicationService.java | 161 + .../onboarding/exception/PortalAPIException.java | 46 + .../listener/PortalTimeoutBindingListener.java | 53 + .../onboarding/listener/PortalTimeoutHandler.java | 420 + .../onboarding/listener/UserContextListener.java | 54 + .../onboarding/listener/UserSessionListener.java | 85 + .../core/onboarding/rest/FavoritesClient.java | 51 + .../core/onboarding/rest/FunctionalMenuClient.java | 54 + .../core/onboarding/rest/RestWebServiceClient.java | 342 + .../portalsdk/core/onboarding/util/CipherUtil.java | 125 + .../core/onboarding/util/PortalApiConstants.java | 64 + .../core/onboarding/util/PortalApiProperties.java | 102 + .../portalsdk/core/onboarding/util/SSOFilter.java | 75 + .../portalsdk/core/onboarding/util/SSOUtil.java | 45 + .../portalsdk/core/restful/domain/EcompRole.java | 87 + .../portalsdk/core/restful/domain/EcompUser.java | 197 + .../core/restful/domain/PortalTimeoutVO.java | 63 + .../core/restful/domain/SharedContext.java | 300 + ecomp-sdk/epsdk-workflow/.gitignore | 5 + ecomp-sdk/epsdk-workflow/README.md | 18 + ecomp-sdk/epsdk-workflow/pom.xml | 114 + .../controller/NotebookController.java | 53 + .../controller/NotebookTestController.java | 55 + .../controller/RNoteBookController.java | 100 + .../controller/RNoteBookFEController.java | 0 .../domain/RNoteBookCredentials.java | 94 + .../exception/RNotebookIntegrationException.java | 0 .../service/RNoteBookIntegrationService.java | 0 .../service/RNoteBookIntegrationServiceImpl.java | 146 + .../workflow/controllers/WorkflowController.java | 0 .../portalsdk/workflow/dao/WorkflowDAO.java | 0 .../portalsdk/workflow/dao/WorkflowDAOImpl.java | 0 .../workflow/domain/WorkflowSchedule.java | 0 .../portalsdk/workflow/models/Workflow.java | 203 + .../portalsdk/workflow/models/WorkflowLite.java | 0 .../workflow/scheduler/WorkFlowScheduleJob.java | 0 .../scheduler/WorkFlowScheduleRegistry.java | 0 .../services/WorkflowScheduleExecutor.java | 108 + .../workflow/services/WorkflowScheduleService.java | 0 .../services/WorkflowScheduleServiceImpl.java | 0 .../workflow/services/WorkflowService.java | 16 + .../workflow/services/WorkflowServiceImpl.java | 0 .../main/resources/RNoteBookIntegration.hbm.xml | 0 ecomp-sdk/pom.xml | 141 +- ecomp-sdk/quantum/.gitignore | 1 - ecomp-sdk/quantum/README.md | 11 - ecomp-sdk/quantum/pom.xml | 330 - .../org/openecomp/portalsdk/core/FusionObject.java | 113 - .../portalsdk/core/command/LoginBean.java | 196 - .../portalsdk/core/command/PostSearchBean.java | 374 - .../portalsdk/core/command/UserRowBean.java | 85 - .../portalsdk/core/command/support/SearchBase.java | 268 - .../core/command/support/SearchResult.java | 58 - .../openecomp/portalsdk/core/conf/AppConfig.java | 301 - .../portalsdk/core/conf/AppInitializer.java | 69 - .../core/conf/HibernateConfiguration.java | 155 - .../core/conf/HibernateMappingLocatable.java | 28 - .../controller/AdminAuthGenericController.java | 134 - .../core/controller/AngularAdminController.java | 50 - .../core/controller/BroadcastController.java | 130 - .../core/controller/BroadcastListController.java | 142 - .../core/controller/CacheAdminController.java | 252 - .../core/controller/CollaborateListController.java | 84 - .../core/controller/CollaborationController.java | 47 - .../core/controller/ElementModelController.java | 91 - .../core/controller/ExternalLoginController.java | 121 - .../core/controller/FavoritesController.java | 117 - .../core/controller/FnMenuController.java | 224 - .../core/controller/FuncMenuController.java | 174 - .../core/controller/LogoutController.java | 110 - .../core/controller/MenuListController.java | 245 - .../core/controller/PostSearchController.java | 219 - .../core/controller/ProfileController.java | 349 - .../core/controller/ProfileSearchController.java | 149 - .../portalsdk/core/controller/RoleController.java | 332 - .../controller/RoleFunctionListController.java | 184 - .../core/controller/RoleListController.java | 179 - .../core/controller/SingleSignOnController.java | 232 - .../core/controller/UsageListController.java | 163 - .../portalsdk/core/dao/ProfileDaoImpl.java | 50 - .../portalsdk/core/dao/support/FusionDao.java | 35 - .../openecomp/portalsdk/core/domain/AuditLog.java | 79 - .../portalsdk/core/domain/BroadcastMessage.java | 123 - .../openecomp/portalsdk/core/domain/FnMenu.java | 142 - .../openecomp/portalsdk/core/domain/LoginBean.java | 187 - .../openecomp/portalsdk/core/domain/Lookup.java | 85 - .../openecomp/portalsdk/core/domain/LuCountry.java | 86 - .../openecomp/portalsdk/core/domain/LuState.java | 68 - .../portalsdk/core/domain/LuTimeZone.java | 77 - .../org/openecomp/portalsdk/core/domain/Menu.java | 160 - .../openecomp/portalsdk/core/domain/MenuData.java | 61 - .../org/openecomp/portalsdk/core/domain/Role.java | 174 - .../portalsdk/core/domain/RoleFunction.java | 69 - .../portalsdk/core/domain/UrlsAccessible.java | 83 - .../portalsdk/core/domain/UrlsAccessibleKey.java | 90 - .../org/openecomp/portalsdk/core/domain/User.java | 585 - .../openecomp/portalsdk/core/domain/UserApp.java | 108 - .../core/domain/sessionmgt/TimeoutVO.java | 63 - .../portalsdk/core/domain/support/Container.java | 331 - .../portalsdk/core/domain/support/Domain.java | 259 - .../portalsdk/core/domain/support/DomainVo.java | 179 - .../portalsdk/core/domain/support/Element.java | 161 - .../core/domain/support/ElementDetails.java | 68 - .../portalsdk/core/domain/support/Layout.java | 991 - .../portalsdk/core/domain/support/NameValueId.java | 94 - .../core/drools/DroolsRuleServiceImpl.java | 58 - .../core/exception/FusionExceptionResolver.java | 50 - .../core/exception/SessionExpiredException.java | 34 - .../exception/UrlAccessRestrictedException.java | 34 - .../exception/support/FusionRuntimeException.java | 36 - .../core/interceptor/ResourceInterceptor.java | 164 - .../core/listener/ApplicationContextListener.java | 43 - .../portalsdk/core/logging/aspect/AuditLog.java | 32 - .../core/logging/aspect/EELFLoggerAdvice.java | 193 - .../core/logging/format/ErrorCodesEnum.java | 87 - .../core/logging/logic/EELFLoggerDelegate.java | 323 - .../openecomp/portalsdk/core/menu/MenuBuilder.java | 164 - .../portalsdk/core/menu/MenuProperties.java | 114 - .../core/objectcache/AbstractCacheManager.java | 60 - .../objectcache/support/FusionCacheManager.java | 36 - .../core/onboarding/client/AppContextManager.java | 45 - .../client/OnBoardingApiServiceImpl.java | 316 - .../core/restful/client/PortalRestClientBase.java | 171 - .../restful/client/SharedContextRestClient.java | 330 - .../portalsdk/core/scheduler/CronRegistry.java | 124 - .../portalsdk/core/service/AppServiceImpl.java | 106 - .../portalsdk/core/service/AuditService.java | 36 - .../portalsdk/core/service/AuditServiceImpl.java | 50 - .../portalsdk/core/service/BroadcastService.java | 37 - .../core/service/BroadcastServiceImpl.java | 248 - .../core/service/DataAccessServiceImpl.java | 592 - .../portalsdk/core/service/ElementLinkService.java | 269 - .../portalsdk/core/service/ElementMapService.java | 915 - .../portalsdk/core/service/FnMenuServiceImpl.java | 145 - .../portalsdk/core/service/LdapServiceImpl.java | 269 - .../portalsdk/core/service/LoginService.java | 36 - .../portalsdk/core/service/LoginServiceImpl.java | 190 - .../core/service/PostDroolsServiceImpl.java | 179 - .../portalsdk/core/service/PostSearchService.java | 30 - .../core/service/PostSearchServiceImpl.java | 203 - .../portalsdk/core/service/ProfileServiceImpl.java | 72 - .../portalsdk/core/service/RoleServiceImpl.java | 171 - .../core/service/RoleServiceNonSpringImpl.java | 122 - .../portalsdk/core/service/UserProfileService.java | 36 - .../core/service/UserProfileServiceImpl.java | 210 - .../core/service/WebServiceCallServiceImpl.java | 189 - .../core/service/support/ServiceLocatorImpl.java | 74 - .../openecomp/portalsdk/core/util/CipherUtil.java | 125 - .../portalsdk/core/util/EncDecUtilTest.java | 112 - .../org/openecomp/portalsdk/core/util/EncTest.java | 39 - .../portalsdk/core/util/SystemProperties.java | 279 - .../openecomp/portalsdk/core/util/YamlUtils.java | 69 - .../portalsdk/core/web/support/AppUtils.java | 195 - .../portalsdk/core/web/support/MessagesList.java | 93 - .../portalsdk/core/web/support/UserUtils.java | 373 - .../core/MockApplicationContextTestSuite.java | 127 - .../core/MockHibernateMappingLocations.java | 20 - .../sessionmgt/PortalCommunicationTest.java | 56 - ecomp-sdk/sdk-analytics/.gitignore | 2 - ecomp-sdk/sdk-analytics/README.md | 8 - ecomp-sdk/sdk-analytics/pom.xml | 160 - .../openecomp/portalsdk/analytics/AntBuild.java | 89 - .../portalsdk/analytics/config/ConfigLoader.java | 196 - .../portalsdk/analytics/controller/Action.java | 89 - .../analytics/controller/ActionHandler.java | 2417 -- .../analytics/controller/ActionMapping.java | 34 - .../portalsdk/analytics/controller/Controller.java | 124 - .../analytics/controller/ErrorHandler.java | 112 - .../analytics/controller/WizardProcessor.java | 2354 -- .../analytics/controller/WizardSequence.java | 189 - .../controller/WizardSequenceCrossTab.java | 43 - .../controller/WizardSequenceDashboard.java | 38 - .../analytics/controller/WizardSequenceLinear.java | 45 - .../controller/WizardSequenceSQLBasedCrossTab.java | 42 - .../controller/WizardSequenceSQLBasedHive.java | 44 - .../controller/WizardSequenceSQLBasedLinear.java | 45 - .../WizardSequenceSQLBasedLinearDatamining.java | 44 - .../analytics/error/UserDefinedException.java | 35 - .../analytics/gmap/map/GMapProperties.java | 46 - .../analytics/gmap/map/layer/SwingLayer.java | 234 - .../portalsdk/analytics/gmap/utils/MapUtils.java | 62 - .../portalsdk/analytics/model/DataCache.java | 524 - .../portalsdk/analytics/model/ReportHandler.java | 6605 --- .../portalsdk/analytics/model/ReportLoader.java | 1061 - .../portalsdk/analytics/model/SearchHandler.java | 490 - .../analytics/model/base/IdNameColLookup.java | 35 - .../portalsdk/analytics/model/base/IdNameList.java | 183 - .../analytics/model/base/IdNameLookup.java | 198 - .../portalsdk/analytics/model/base/IdNameSql.java | 400 - .../analytics/model/base/IdNameValue.java | 100 - .../analytics/model/base/NameComparator.java | 32 - .../analytics/model/base/ReportSecurity.java | 407 - .../analytics/model/base/ReportWrapper.java | 5719 --- .../model/definition/ReportDefinition.java | 1465 - .../analytics/model/definition/ReportMap.java | 82 - .../analytics/model/definition/SecurityEntry.java | 44 - .../portalsdk/analytics/model/pdf/PageEvent.java | 256 - .../analytics/model/pdf/PdfReportHandler.java | 1890 - .../analytics/model/runtime/ChartD3Helper.java | 4064 -- .../analytics/model/runtime/ChartGen.java | 73 - .../analytics/model/runtime/ChartJSON.java | 448 - .../analytics/model/runtime/ChartWebRuntime.java | 420 - .../model/runtime/CommonChartOptions.java | 81 - .../analytics/model/runtime/ErrorJSONRuntime.java | 43 - .../analytics/model/runtime/FormField.java | 2111 - .../analytics/model/runtime/FormatProcessor.java | 375 - .../analytics/model/runtime/RangeAxisJSON.java | 93 - .../analytics/model/runtime/ReportFormFields.java | 366 - .../analytics/model/runtime/ReportJSONRuntime.java | 694 - .../model/runtime/ReportParamDateValueParser.java | 194 - .../analytics/model/runtime/ReportParamValues.java | 370 - .../analytics/model/runtime/ReportRuntime.java | 3618 -- .../analytics/model/runtime/VisualManager.java | 68 - .../analytics/model/search/ReportSearchResult.java | 84 - .../model/search/ReportSearchResultJSON.java | 251 - .../analytics/model/search/SearchResult.java | 213 - .../analytics/model/search/SearchResultColumn.java | 254 - .../analytics/model/search/SearchResultField.java | 212 - .../analytics/model/search/SearchResultJSON.java | 80 - .../analytics/model/search/SearchResultRow.java | 92 - .../analytics/scheduler/SchedulerUtil.java | 369 - .../portalsdk/analytics/scheduler/SendEmail.java | 415 - .../analytics/scheduler/SendNotifications.java | 460 - .../portalsdk/analytics/system/AppUtils.java | 333 - .../portalsdk/analytics/system/DbUtils.java | 1298 - .../portalsdk/analytics/system/ExecuteQuery.java | 60 - .../portalsdk/analytics/system/Globals.java | 2282 - .../portalsdk/analytics/system/IAppUtils.java | 175 - .../portalsdk/analytics/system/IDbUtils.java | 35 - .../portalsdk/analytics/system/RDbUtils.java | 36 - .../analytics/system/fusion/AntBuild.java | 66 - .../analytics/system/fusion/AppUtils.java | 363 - .../portalsdk/analytics/system/fusion/DbUtils.java | 75 - .../analytics/system/fusion/RemoteDbUtils.java | 50 - .../adapter/AdapterSessionFactoryContainer.java | 39 - .../system/fusion/adapter/FusionAdapter.java | 135 - .../analytics/system/fusion/adapter/IdName.java | 59 - .../analytics/system/fusion/adapter/Lookup.java | 85 - .../system/fusion/adapter/RaptorAdapter.java | 368 - .../analytics/system/fusion/domain/CR_Report.java | 306 - .../system/fusion/service/RaptorService.java | 36 - .../system/fusion/service/RaptorServiceImpl.java | 163 - .../system/fusion/web/RaptorController.java | 191 - .../system/fusion/web/RaptorControllerAsync.java | 410 - .../fusion/web/ReportsSearchListController.java | 74 - .../portalsdk/analytics/util/AppConstants.java | 658 - .../portalsdk/analytics/util/DataSet.java | 177 - .../portalsdk/analytics/util/ExcelColorDef.java | 68 - .../portalsdk/analytics/util/HtmlStripper.java | 155 - .../portalsdk/analytics/util/Scheduler.java | 91 - .../openecomp/portalsdk/analytics/util/Utils.java | 378 - .../portalsdk/analytics/util/XSSFilter.java | 90 - .../analytics/util/upgrade/SystemUpgrade.java | 125 - .../portalsdk/analytics/view/ColumnHeader.java | 239 - .../portalsdk/analytics/view/ColumnHeaderRow.java | 100 - .../analytics/view/CrossTabColumnValues.java | 75 - .../analytics/view/CrossTabOrderManager.java | 98 - .../analytics/view/CrossTabTotalValue.java | 56 - .../portalsdk/analytics/view/DataRow.java | 169 - .../portalsdk/analytics/view/DataValue.java | 359 - .../analytics/view/ReportColumnHeaderRows.java | 71 - .../portalsdk/analytics/view/ReportData.java | 812 - .../portalsdk/analytics/view/ReportDataRows.java | 72 - .../analytics/view/ReportRowHeaderCols.java | 71 - .../portalsdk/analytics/view/RowHeader.java | 119 - .../portalsdk/analytics/view/RowHeaderCol.java | 156 - .../analytics/xmlobj/ChartDrillOptions.java | 207 - .../portalsdk/analytics/xmlobj/ColFilterList.java | 94 - .../analytics/xmlobj/DashboardEditorList.java | 94 - .../analytics/xmlobj/DashboardReports.java | 94 - .../analytics/xmlobj/DashboardReportsNew.java | 148 - .../portalsdk/analytics/xmlobj/DataColumnList.java | 96 - .../portalsdk/analytics/xmlobj/DataSourceList.java | 94 - .../portalsdk/analytics/xmlobj/FormFieldList.java | 121 - .../portalsdk/analytics/xmlobj/FormatList.java | 96 - .../portalsdk/analytics/xmlobj/JavascriptList.java | 94 - .../analytics/xmlobj/PredefinedValueList.java | 94 - .../portalsdk/analytics/xmlobj/ReportMap.java | 445 - .../portalsdk/analytics/xmlobj/SemaphoreList.java | 94 - ecomp-sdk/sdk-app/.gitignore | 1 - ecomp-sdk/sdk-app/README.md | 14 - .../EcompSdkDDLMySql_1610_Complete_OS.sql | 1402 - .../EcompSdkDMLMySql_1610_Complete_OS.sql | 2891 -- ecomp-sdk/sdk-app/distribution.xml | 21 - ecomp-sdk/sdk-app/pom.xml | 361 - .../portalapp/conf/ExternalAppConfig.java | 188 - .../portalapp/conf/ExternalAppInitializer.java | 60 - .../portalapp/conf/HibernateMappingLocations.java | 37 - .../controller/AngularSinglePageController.java | 48 - .../portalapp/controller/CallflowController.java | 44 - .../controller/ElasticSearchController.java | 128 - .../portalapp/controller/LeafletMapContoller.java | 43 - .../portalapp/controller/PostDroolsController.java | 138 - .../controller/UserProfileController.java | 72 - .../portalapp/controller/WelcomeController.java | 43 - .../java/org/openecomp/portalapp/model/Result.java | 37 - .../org/openecomp/portalapp/scheduler/LogJob.java | 47 - .../openecomp/portalapp/scheduler/LogRegistry.java | 57 - .../openecomp/portalapp/scheduler/Register.java | 82 - .../portalapp/scheduler/RegistryAdapter.java | 108 - .../portalapp/service/AdminAuthExtension.java | 34 - .../portalapp/uebhandler/InitUebHandler.java | 73 - .../portalapp/uebhandler/MainUebHandler.java | 104 - .../uebhandler/WidgetNotificationHandler.java | 46 - .../portalapp/util/CustomLoggingFilter.java | 54 - ecomp-sdk/sdk-app/src/main/resources/logback.xml | 370 - .../sdk-app/src/main/resources/portal.properties | 69 - .../src/main/webapp/WEB-INF/conf/quartz.properties | 30 - .../src/main/webapp/WEB-INF/conf/raptor.properties | 187 - .../WEB-INF/conf/raptor_app_fusion.properties | 39 - .../WEB-INF/conf/raptor_db_fusion.properties | 19 - .../main/webapp/WEB-INF/conf/raptor_pdf.properties | 49 - .../src/main/webapp/WEB-INF/conf/sql.properties | 322 - .../src/main/webapp/WEB-INF/conf/system.properties | 86 - .../src/main/webapp/WEB-INF/defs/definitions.xml | 22 - .../webapp/WEB-INF/fusion/conf/fusion.properties | 61 - .../webapp/WEB-INF/fusion/defs/definitions.xml | 240 - .../main/webapp/WEB-INF/fusion/jsp/broadcast.jsp | 137 - .../webapp/WEB-INF/fusion/jsp/broadcast_list.jsp | 201 - .../webapp/WEB-INF/fusion/jsp/collaborateList.jsp | 146 - .../webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp | 46 - .../webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp | 799 - .../WEB-INF/fusion/jsp/ebz/loginSnippet.html | 120 - .../webapp/WEB-INF/fusion/jsp/ebz_template.jsp | 45 - .../fusion/jsp/ebz_template_noheader_nofooter.jsp | 35 - .../fusion/jsp/ebz_template_report_embedded.jsp | 48 - .../webapp/WEB-INF/fusion/jsp/es_search_demo.jsp | 97 - .../webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp | 97 - .../webapp/WEB-INF/fusion/jsp/frame_insert.jsp | 44 - .../main/webapp/WEB-INF/fusion/jsp/jcs_admin.jsp | 144 - .../src/main/webapp/WEB-INF/fusion/jsp/meta.jsp | 36 - .../main/webapp/WEB-INF/fusion/jsp/post_search.jsp | 356 - .../src/main/webapp/WEB-INF/fusion/jsp/profile.jsp | 442 - .../webapp/WEB-INF/fusion/jsp/profile_search.jsp | 104 - .../src/main/webapp/WEB-INF/fusion/jsp/role.jsp | 286 - .../WEB-INF/fusion/jsp/role_function_list.jsp | 213 - .../main/webapp/WEB-INF/fusion/jsp/role_list.jsp | 139 - .../main/webapp/WEB-INF/fusion/jsp/usage_list.jsp | 87 - .../WEB-INF/fusion/jsp/webrtc/collaboration.jsp | 492 - .../fusion/raptor/popup_drill_down_report.jsp | 601 - .../webapp/WEB-INF/fusion/raptor/report_import.jsp | 69 - .../webapp/WEB-INF/fusion/raptor/report_wizard.jsp | 309 - .../src/main/webapp/WEB-INF/jsp/leafletMap.jsp | 288 - .../src/main/webapp/WEB-INF/jsp/login_external.jsp | 154 - .../src/main/webapp/WEB-INF/jsp/user_profile.jsp | 84 - .../src/main/webapp/WEB-INF/jsp/welcome.jsp | 630 - ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/web.xml | 17 - .../fusion/external/angular-1.5/angular-animate.js | 4121 -- .../external/angular-1.5/angular-animate.min.js | 56 - .../angular-1.5/angular-animate.min.js.map | 8 - .../fusion/external/angular-1.5/angular-aria.js | 398 - .../external/angular-1.5/angular-aria.min.js | 14 - .../external/angular-1.5/angular-aria.min.js.map | 8 - .../fusion/external/angular-1.5/angular-cookies.js | 322 - .../external/angular-1.5/angular-cookies.min.js | 9 - .../angular-1.5/angular-cookies.min.js.map | 8 - .../fusion/external/angular-1.5/angular-csp.css | 20 - .../fusion/external/angular-1.5/angular-loader.js | 484 - .../external/angular-1.5/angular-loader.min.js | 10 - .../external/angular-1.5/angular-loader.min.js.map | 8 - .../external/angular-1.5/angular-message-format.js | 980 - .../angular-1.5/angular-message-format.min.js | 26 - .../external/angular-1.5/angular-messages.js | 687 - .../external/angular-1.5/angular-messages.min.js | 12 - .../angular-1.5/angular-messages.min.js.map | 8 - .../fusion/external/angular-1.5/angular-mocks.js | 2842 -- .../external/angular-1.5/angular-resource.js | 768 - .../external/angular-1.5/angular-resource.min.js | 15 - .../angular-1.5/angular-resource.min.js.map | 8 - .../fusion/external/angular-1.5/angular-route.js | 1016 - .../external/angular-1.5/angular-route.min.js | 15 - .../external/angular-1.5/angular-route.min.js.map | 8 - .../external/angular-1.5/angular-sanitize.js | 717 - .../external/angular-1.5/angular-sanitize.min.js | 15 - .../angular-1.5/angular-sanitize.min.js.map | 8 - .../external/angular-1.5/angular-scenario.js | 41849 ------------------- .../fusion/external/angular-1.5/angular-touch.js | 729 - .../external/angular-1.5/angular-touch.min.js | 14 - .../external/angular-1.5/angular-touch.min.js.map | 8 - .../app/fusion/external/angular-1.5/angular.js | 30428 -------------- .../app/fusion/external/angular-1.5/angular.min.js | 307 - .../fusion/external/angular-1.5/angular.min.js.map | 8 - .../app/fusion/external/angular-1.5/errors.json | 1 - .../app/fusion/external/angular-1.5/version.json | 1 - .../app/fusion/external/angular-1.5/version.txt | 1 - .../external/ebz/angular_js/angular-animate.js | 3721 -- .../external/ebz/angular_js/angular-cookies.js | 206 - .../external/ebz/angular_js/angular-route.js | 911 - .../external/ebz/angular_js/angular-route.min.js | 14 - .../external/ebz/angular_js/angular-sanitize.js | 647 - .../external/ebz/angular_js/angular-touch.js | 628 - .../app/fusion/external/ebz/angular_js/angular.js | 22024 ---------- .../app/fusion/external/ebz/angular_js/app.js | 6 - .../external/ebz/angular_js/checklist-model.js | 99 - .../external/ebz/angular_js/checklist-model.min.js | 1 - .../app/fusion/external/ebz/angular_js/gestures.js | 1495 - .../app/fusion/external/ebz/angular_js/ng_base.js | 4 - .../external/ebz/angular_js/ui-charts-tpls.js | 3909 -- .../app/fusion/external/ebz/ebz_header/footer.css | 311 - .../app/fusion/external/ebz/ebz_header/header.css | 1866 - .../external/ebz/ebz_header/portal_ebz_header.css | 63 - .../main/webapp/app/fusion/external/ebz/fn-ebz.css | 1614 - .../external/ebz/images/no_favorites_star.png | Bin 2794 -> 0 bytes .../app/fusion/external/ebz/js/attHeaderSnippet.js | 210 - .../webapp/app/fusion/external/ebz/js/footer.js | 110 - .../fusion/external/ebz/sandbox/att-abs-tpls.js | 20451 --------- .../external/ebz/sandbox/att-abs-tpls.min.js | 22 - .../fusion/external/ebz/sandbox/styles/base.css | 1 - .../app/fusion/external/ebz/sandbox/styles/btn.css | 1 - .../fusion/external/ebz/sandbox/styles/demo.css | 2 - .../fusion/external/ebz/sandbox/styles/dtpk.css | 9 - .../fusion/external/ebz/sandbox/styles/frms.css | 1 - .../ebz/sandbox/styles/ie/backgroundsize.min.htc | 12 - .../ebz/sandbox/styles/images/upanddown.png | Bin 1033 -> 0 bytes .../ebz/sandbox/styles/pages/iconography.css | 2 - .../fusion/external/ebz/sandbox/styles/sldr.css | 1 - .../fusion/external/ebz/sandbox/styles/style.css | 1 - .../app/fusion/external/ebz/sandbox/styles/tbs.css | 1 - .../app/fusion/external/ionicons-2.0.1/.gitignore | 4 - .../app/fusion/external/ionicons-2.0.1/LICENSE | 21 - .../app/fusion/external/ionicons-2.0.1/bower.json | 31 - .../fusion/external/ionicons-2.0.1/component.json | 19 - .../fusion/external/ionicons-2.0.1/composer.json | 36 - .../external/ionicons-2.0.1/css/ionicons.css | 1480 - .../external/ionicons-2.0.1/css/ionicons.min.css | 11 - .../ionicons-2.0.1/less/_ionicons-font.less | 27 - .../ionicons-2.0.1/less/_ionicons-icons.less | 1473 - .../ionicons-2.0.1/less/_ionicons-variables.less | 747 - .../external/ionicons-2.0.1/less/ionicons.less | 3 - .../ionicons-2.0.1/png/512/alert-circled.png | Bin 2551 -> 0 bytes .../external/ionicons-2.0.1/png/512/alert.png | Bin 766 -> 0 bytes .../ionicons-2.0.1/png/512/android-add-contact.png | Bin 3279 -> 0 bytes .../ionicons-2.0.1/png/512/android-add.png | Bin 240 -> 0 bytes .../ionicons-2.0.1/png/512/android-alarm.png | Bin 6428 -> 0 bytes .../ionicons-2.0.1/png/512/android-archive.png | Bin 1628 -> 0 bytes .../ionicons-2.0.1/png/512/android-arrow-back.png | Bin 1218 -> 0 bytes .../png/512/android-arrow-down-left.png | Bin 1451 -> 0 bytes .../png/512/android-arrow-down-right.png | Bin 1462 -> 0 bytes .../png/512/android-arrow-forward.png | Bin 1191 -> 0 bytes .../png/512/android-arrow-up-left.png | Bin 1499 -> 0 bytes .../png/512/android-arrow-up-right.png | Bin 1482 -> 0 bytes .../ionicons-2.0.1/png/512/android-battery.png | Bin 238 -> 0 bytes .../ionicons-2.0.1/png/512/android-book.png | Bin 3746 -> 0 bytes .../ionicons-2.0.1/png/512/android-calendar.png | Bin 849 -> 0 bytes .../ionicons-2.0.1/png/512/android-call.png | Bin 4766 -> 0 bytes .../ionicons-2.0.1/png/512/android-camera.png | Bin 3871 -> 0 bytes .../ionicons-2.0.1/png/512/android-chat.png | Bin 3577 -> 0 bytes .../ionicons-2.0.1/png/512/android-checkmark.png | Bin 1846 -> 0 bytes .../ionicons-2.0.1/png/512/android-clock.png | Bin 5268 -> 0 bytes .../ionicons-2.0.1/png/512/android-close.png | Bin 2156 -> 0 bytes .../ionicons-2.0.1/png/512/android-contact.png | Bin 3658 -> 0 bytes .../ionicons-2.0.1/png/512/android-contacts.png | Bin 4299 -> 0 bytes .../ionicons-2.0.1/png/512/android-data.png | Bin 4808 -> 0 bytes .../ionicons-2.0.1/png/512/android-developer.png | Bin 4115 -> 0 bytes .../ionicons-2.0.1/png/512/android-display.png | Bin 4909 -> 0 bytes .../ionicons-2.0.1/png/512/android-download.png | Bin 4890 -> 0 bytes .../ionicons-2.0.1/png/512/android-drawer.png | Bin 190 -> 0 bytes .../ionicons-2.0.1/png/512/android-dropdown.png | Bin 777 -> 0 bytes .../ionicons-2.0.1/png/512/android-earth.png | Bin 6517 -> 0 bytes .../ionicons-2.0.1/png/512/android-folder.png | Bin 1688 -> 0 bytes .../ionicons-2.0.1/png/512/android-forums.png | Bin 1739 -> 0 bytes .../ionicons-2.0.1/png/512/android-friends.png | Bin 4868 -> 0 bytes .../ionicons-2.0.1/png/512/android-hand.png | Bin 4650 -> 0 bytes .../ionicons-2.0.1/png/512/android-image.png | Bin 1433 -> 0 bytes .../ionicons-2.0.1/png/512/android-inbox.png | Bin 3018 -> 0 bytes .../ionicons-2.0.1/png/512/android-information.png | Bin 3370 -> 0 bytes .../ionicons-2.0.1/png/512/android-keypad.png | Bin 1055 -> 0 bytes .../ionicons-2.0.1/png/512/android-lightbulb.png | Bin 3515 -> 0 bytes .../ionicons-2.0.1/png/512/android-locate.png | Bin 5003 -> 0 bytes .../ionicons-2.0.1/png/512/android-location.png | Bin 3067 -> 0 bytes .../ionicons-2.0.1/png/512/android-mail.png | Bin 3455 -> 0 bytes .../ionicons-2.0.1/png/512/android-microphone.png | Bin 3267 -> 0 bytes .../ionicons-2.0.1/png/512/android-mixer.png | Bin 2727 -> 0 bytes .../ionicons-2.0.1/png/512/android-more.png | Bin 224 -> 0 bytes .../ionicons-2.0.1/png/512/android-note.png | Bin 249 -> 0 bytes .../ionicons-2.0.1/png/512/android-playstore.png | Bin 3165 -> 0 bytes .../ionicons-2.0.1/png/512/android-printer.png | Bin 1721 -> 0 bytes .../ionicons-2.0.1/png/512/android-promotion.png | Bin 2374 -> 0 bytes .../ionicons-2.0.1/png/512/android-reminder.png | Bin 2890 -> 0 bytes .../ionicons-2.0.1/png/512/android-remove.png | Bin 160 -> 0 bytes .../ionicons-2.0.1/png/512/android-search.png | Bin 4232 -> 0 bytes .../ionicons-2.0.1/png/512/android-send.png | Bin 2079 -> 0 bytes .../ionicons-2.0.1/png/512/android-settings.png | Bin 3883 -> 0 bytes .../ionicons-2.0.1/png/512/android-share.png | Bin 3212 -> 0 bytes .../ionicons-2.0.1/png/512/android-social-user.png | Bin 3644 -> 0 bytes .../ionicons-2.0.1/png/512/android-social.png | Bin 3849 -> 0 bytes .../ionicons-2.0.1/png/512/android-sort.png | Bin 197 -> 0 bytes .../png/512/android-stair-drawer.png | Bin 209 -> 0 bytes .../ionicons-2.0.1/png/512/android-star.png | Bin 2926 -> 0 bytes .../ionicons-2.0.1/png/512/android-stopwatch.png | Bin 5225 -> 0 bytes .../ionicons-2.0.1/png/512/android-storage.png | Bin 233 -> 0 bytes .../ionicons-2.0.1/png/512/android-system-back.png | Bin 1796 -> 0 bytes .../ionicons-2.0.1/png/512/android-system-home.png | Bin 1107 -> 0 bytes .../png/512/android-system-windows.png | Bin 202 -> 0 bytes .../ionicons-2.0.1/png/512/android-timer.png | Bin 3904 -> 0 bytes .../ionicons-2.0.1/png/512/android-trash.png | Bin 2865 -> 0 bytes .../ionicons-2.0.1/png/512/android-user-menu.png | Bin 3568 -> 0 bytes .../ionicons-2.0.1/png/512/android-volume.png | Bin 6022 -> 0 bytes .../ionicons-2.0.1/png/512/android-wifi.png | Bin 4868 -> 0 bytes .../external/ionicons-2.0.1/png/512/aperture.png | Bin 9500 -> 0 bytes .../external/ionicons-2.0.1/png/512/archive.png | Bin 2445 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-down-a.png | Bin 1173 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-down-b.png | Bin 1307 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-down-c.png | Bin 1966 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-expand.png | Bin 2498 -> 0 bytes .../png/512/arrow-graph-down-left.png | Bin 2478 -> 0 bytes .../png/512/arrow-graph-down-right.png | Bin 2545 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-graph-up-left.png | Bin 2440 -> 0 bytes .../png/512/arrow-graph-up-right.png | Bin 2440 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-left-a.png | Bin 1260 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-left-b.png | Bin 1608 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-left-c.png | Bin 1662 -> 0 bytes .../external/ionicons-2.0.1/png/512/arrow-move.png | Bin 1948 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-resize.png | Bin 1266 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-return-left.png | Bin 1082 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-return-right.png | Bin 1124 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-right-a.png | Bin 1317 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-right-b.png | Bin 1671 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-right-c.png | Bin 1657 -> 0 bytes .../ionicons-2.0.1/png/512/arrow-shrink.png | Bin 2594 -> 0 bytes .../external/ionicons-2.0.1/png/512/arrow-swap.png | Bin 1521 -> 0 bytes .../external/ionicons-2.0.1/png/512/arrow-up-a.png | Bin 1115 -> 0 bytes .../external/ionicons-2.0.1/png/512/arrow-up-b.png | Bin 1343 -> 0 bytes .../external/ionicons-2.0.1/png/512/arrow-up-c.png | Bin 2002 -> 0 bytes .../external/ionicons-2.0.1/png/512/asterisk.png | Bin 4023 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/at.png | Bin 5852 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/bag.png | Bin 3665 -> 0 bytes .../ionicons-2.0.1/png/512/battery-charging.png | Bin 1897 -> 0 bytes .../ionicons-2.0.1/png/512/battery-empty.png | Bin 1019 -> 0 bytes .../ionicons-2.0.1/png/512/battery-full.png | Bin 982 -> 0 bytes .../ionicons-2.0.1/png/512/battery-half.png | Bin 1320 -> 0 bytes .../ionicons-2.0.1/png/512/battery-low.png | Bin 1342 -> 0 bytes .../external/ionicons-2.0.1/png/512/beaker.png | Bin 3931 -> 0 bytes .../external/ionicons-2.0.1/png/512/beer.png | Bin 4559 -> 0 bytes .../external/ionicons-2.0.1/png/512/bluetooth.png | Bin 2909 -> 0 bytes .../external/ionicons-2.0.1/png/512/bonfire.png | Bin 4852 -> 0 bytes .../external/ionicons-2.0.1/png/512/bookmark.png | Bin 1102 -> 0 bytes .../external/ionicons-2.0.1/png/512/briefcase.png | Bin 1475 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/bug.png | Bin 4736 -> 0 bytes .../external/ionicons-2.0.1/png/512/calculator.png | Bin 1315 -> 0 bytes .../external/ionicons-2.0.1/png/512/calendar.png | Bin 2577 -> 0 bytes .../external/ionicons-2.0.1/png/512/camera.png | Bin 4190 -> 0 bytes .../external/ionicons-2.0.1/png/512/card.png | Bin 1494 -> 0 bytes .../external/ionicons-2.0.1/png/512/cash.png | Bin 3435 -> 0 bytes .../ionicons-2.0.1/png/512/chatbox-working.png | Bin 2301 -> 0 bytes .../external/ionicons-2.0.1/png/512/chatbox.png | Bin 1870 -> 0 bytes .../external/ionicons-2.0.1/png/512/chatboxes.png | Bin 2562 -> 0 bytes .../ionicons-2.0.1/png/512/chatbubble-working.png | Bin 3028 -> 0 bytes .../external/ionicons-2.0.1/png/512/chatbubble.png | Bin 2579 -> 0 bytes .../ionicons-2.0.1/png/512/chatbubbles.png | Bin 3751 -> 0 bytes .../ionicons-2.0.1/png/512/checkmark-circled.png | Bin 3687 -> 0 bytes .../ionicons-2.0.1/png/512/checkmark-round.png | Bin 2367 -> 0 bytes .../external/ionicons-2.0.1/png/512/checkmark.png | Bin 2134 -> 0 bytes .../ionicons-2.0.1/png/512/chevron-down.png | Bin 1689 -> 0 bytes .../ionicons-2.0.1/png/512/chevron-left.png | Bin 1769 -> 0 bytes .../ionicons-2.0.1/png/512/chevron-right.png | Bin 1831 -> 0 bytes .../external/ionicons-2.0.1/png/512/chevron-up.png | Bin 1677 -> 0 bytes .../external/ionicons-2.0.1/png/512/clipboard.png | Bin 2593 -> 0 bytes .../external/ionicons-2.0.1/png/512/clock.png | Bin 5866 -> 0 bytes .../ionicons-2.0.1/png/512/close-circled.png | Bin 3809 -> 0 bytes .../ionicons-2.0.1/png/512/close-round.png | Bin 2177 -> 0 bytes .../external/ionicons-2.0.1/png/512/close.png | Bin 2244 -> 0 bytes .../ionicons-2.0.1/png/512/closed-captioning.png | Bin 3665 -> 0 bytes .../external/ionicons-2.0.1/png/512/cloud.png | Bin 2067 -> 0 bytes .../ionicons-2.0.1/png/512/code-download.png | Bin 2423 -> 0 bytes .../ionicons-2.0.1/png/512/code-working.png | Bin 2433 -> 0 bytes .../external/ionicons-2.0.1/png/512/code.png | Bin 1720 -> 0 bytes .../external/ionicons-2.0.1/png/512/coffee.png | Bin 3205 -> 0 bytes .../external/ionicons-2.0.1/png/512/compass.png | Bin 7318 -> 0 bytes .../external/ionicons-2.0.1/png/512/compose.png | Bin 4296 -> 0 bytes .../ionicons-2.0.1/png/512/connection-bars.png | Bin 214 -> 0 bytes .../external/ionicons-2.0.1/png/512/contrast.png | Bin 4087 -> 0 bytes .../external/ionicons-2.0.1/png/512/cube.png | Bin 3265 -> 0 bytes .../external/ionicons-2.0.1/png/512/disc.png | Bin 4935 -> 0 bytes .../ionicons-2.0.1/png/512/document-text.png | Bin 1918 -> 0 bytes .../external/ionicons-2.0.1/png/512/document.png | Bin 1914 -> 0 bytes .../external/ionicons-2.0.1/png/512/drag.png | Bin 178 -> 0 bytes .../external/ionicons-2.0.1/png/512/earth.png | Bin 6476 -> 0 bytes .../external/ionicons-2.0.1/png/512/edit.png | Bin 2741 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/egg.png | Bin 4234 -> 0 bytes .../external/ionicons-2.0.1/png/512/eject.png | Bin 3209 -> 0 bytes .../external/ionicons-2.0.1/png/512/email.png | Bin 3125 -> 0 bytes .../ionicons-2.0.1/png/512/eye-disabled.png | Bin 3558 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/eye.png | Bin 3297 -> 0 bytes .../external/ionicons-2.0.1/png/512/female.png | Bin 2779 -> 0 bytes .../external/ionicons-2.0.1/png/512/filing.png | Bin 2349 -> 0 bytes .../ionicons-2.0.1/png/512/film-marker.png | Bin 2645 -> 0 bytes .../external/ionicons-2.0.1/png/512/fireball.png | Bin 3325 -> 0 bytes .../external/ionicons-2.0.1/png/512/flag.png | Bin 2337 -> 0 bytes .../external/ionicons-2.0.1/png/512/flame.png | Bin 3012 -> 0 bytes .../external/ionicons-2.0.1/png/512/flash-off.png | Bin 5437 -> 0 bytes .../external/ionicons-2.0.1/png/512/flash.png | Bin 1965 -> 0 bytes .../external/ionicons-2.0.1/png/512/flask.png | Bin 2939 -> 0 bytes .../external/ionicons-2.0.1/png/512/folder.png | Bin 1689 -> 0 bytes .../external/ionicons-2.0.1/png/512/fork-repo.png | Bin 3236 -> 0 bytes .../external/ionicons-2.0.1/png/512/fork.png | Bin 3007 -> 0 bytes .../external/ionicons-2.0.1/png/512/forward.png | Bin 2142 -> 0 bytes .../external/ionicons-2.0.1/png/512/funnel.png | Bin 3354 -> 0 bytes .../ionicons-2.0.1/png/512/game-controller-a.png | Bin 2548 -> 0 bytes .../ionicons-2.0.1/png/512/game-controller-b.png | Bin 3623 -> 0 bytes .../external/ionicons-2.0.1/png/512/gear-a.png | Bin 3806 -> 0 bytes .../external/ionicons-2.0.1/png/512/gear-b.png | Bin 2756 -> 0 bytes .../external/ionicons-2.0.1/png/512/grid.png | Bin 1066 -> 0 bytes .../external/ionicons-2.0.1/png/512/hammer.png | Bin 2493 -> 0 bytes .../external/ionicons-2.0.1/png/512/happy.png | Bin 5732 -> 0 bytes .../external/ionicons-2.0.1/png/512/headphone.png | Bin 4082 -> 0 bytes .../ionicons-2.0.1/png/512/heart-broken.png | Bin 4007 -> 0 bytes .../external/ionicons-2.0.1/png/512/heart.png | Bin 2322 -> 0 bytes .../external/ionicons-2.0.1/png/512/help-buoy.png | Bin 5824 -> 0 bytes .../ionicons-2.0.1/png/512/help-circled.png | Bin 3940 -> 0 bytes .../external/ionicons-2.0.1/png/512/help.png | Bin 2678 -> 0 bytes .../external/ionicons-2.0.1/png/512/home.png | Bin 1275 -> 0 bytes .../external/ionicons-2.0.1/png/512/icecream.png | Bin 2317 -> 0 bytes .../png/512/icon-social-google-plus-outline.png | Bin 4071 -> 0 bytes .../png/512/icon-social-google-plus.png | Bin 3888 -> 0 bytes .../external/ionicons-2.0.1/png/512/image.png | Bin 2952 -> 0 bytes .../external/ionicons-2.0.1/png/512/images.png | Bin 5073 -> 0 bytes .../ionicons-2.0.1/png/512/information-circled.png | Bin 3300 -> 0 bytes .../ionicons-2.0.1/png/512/information.png | Bin 2236 -> 0 bytes .../external/ionicons-2.0.1/png/512/ionic.png | Bin 5541 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-alarm-outline.png | Bin 5769 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-alarm.png | Bin 3922 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-albums-outline.png | Bin 231 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-albums.png | Bin 226 -> 0 bytes .../png/512/ios7-americanfootball-outline.png | Bin 5767 -> 0 bytes .../png/512/ios7-americanfootball.png | Bin 5675 -> 0 bytes .../png/512/ios7-analytics-outline.png | Bin 5847 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-analytics.png | Bin 4406 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-arrow-back.png | Bin 881 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-arrow-down.png | Bin 1451 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-arrow-forward.png | Bin 898 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-arrow-left.png | Bin 1550 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-arrow-right.png | Bin 1537 -> 0 bytes .../png/512/ios7-arrow-thin-down.png | Bin 1632 -> 0 bytes .../png/512/ios7-arrow-thin-left.png | Bin 1258 -> 0 bytes .../png/512/ios7-arrow-thin-right.png | Bin 1235 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-arrow-thin-up.png | Bin 1647 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-arrow-up.png | Bin 1482 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-at-outline.png | Bin 4303 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-at.png | Bin 4153 -> 0 bytes .../png/512/ios7-barcode-outline.png | Bin 233 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-barcode.png | Bin 219 -> 0 bytes .../png/512/ios7-baseball-outline.png | Bin 6676 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-baseball.png | Bin 5565 -> 0 bytes .../png/512/ios7-basketball-outline.png | Bin 6200 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-basketball.png | Bin 6525 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-bell-outline.png | Bin 3615 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-bell.png | Bin 2769 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-bolt-outline.png | Bin 2384 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-bolt.png | Bin 1892 -> 0 bytes .../png/512/ios7-bookmarks-outline.png | Bin 2454 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-bookmarks.png | Bin 2172 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-box-outline.png | Bin 1602 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-box.png | Bin 1032 -> 0 bytes .../png/512/ios7-briefcase-outline.png | Bin 1359 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-briefcase.png | Bin 1316 -> 0 bytes .../png/512/ios7-browsers-outline.png | Bin 372 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-browsers.png | Bin 357 -> 0 bytes .../png/512/ios7-calculator-outline.png | Bin 1785 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-calculator.png | Bin 1500 -> 0 bytes .../png/512/ios7-calendar-outline.png | Bin 236 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-calendar.png | Bin 230 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-camera-outline.png | Bin 3582 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-camera.png | Bin 3099 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-cart-outline.png | Bin 2861 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-cart.png | Bin 2200 -> 0 bytes .../png/512/ios7-chatboxes-outline.png | Bin 901 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-chatboxes.png | Bin 512 -> 0 bytes .../png/512/ios7-chatbubble-outline.png | Bin 3640 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-chatbubble.png | Bin 2259 -> 0 bytes .../png/512/ios7-checkmark-empty.png | Bin 920 -> 0 bytes .../png/512/ios7-checkmark-outline.png | Bin 4706 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-checkmark.png | Bin 3080 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-circle-filled.png | Bin 6478 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-circle-outline.png | Bin 4120 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-clock-outline.png | Bin 4320 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-clock.png | Bin 2762 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-close-empty.png | Bin 1204 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-close-outline.png | Bin 4999 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-close.png | Bin 3426 -> 0 bytes .../png/512/ios7-cloud-download-outline.png | Bin 3953 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-cloud-download.png | Bin 2782 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-cloud-outline.png | Bin 3339 -> 0 bytes .../png/512/ios7-cloud-upload-outline.png | Bin 3927 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-cloud-upload.png | Bin 2815 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-cloud.png | Bin 2082 -> 0 bytes .../png/512/ios7-cloudy-night-outline.png | Bin 3814 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-cloudy-night.png | Bin 2870 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-cloudy-outline.png | Bin 2280 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-cloudy.png | Bin 1572 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-cog-outline.png | Bin 8008 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-cog.png | Bin 6029 -> 0 bytes .../png/512/ios7-compose-outline.png | Bin 1584 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-compose.png | Bin 2061 -> 0 bytes .../png/512/ios7-contact-outline.png | Bin 4846 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-contact.png | Bin 4218 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-copy-outline.png | Bin 927 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-copy.png | Bin 782 -> 0 bytes .../png/512/ios7-download-outline.png | Bin 1163 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-download.png | Bin 1135 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-drag.png | Bin 165 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-email-outline.png | Bin 2592 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-email.png | Bin 4167 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-expand.png | Bin 485 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-eye-outline.png | Bin 4381 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-eye.png | Bin 2973 -> 0 bytes .../png/512/ios7-fastforward-outline.png | Bin 2726 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-fastforward.png | Bin 2158 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-filing-outline.png | Bin 2041 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-filing.png | Bin 1933 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-film-outline.png | Bin 772 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-film.png | Bin 722 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-flag-outline.png | Bin 1928 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-flag.png | Bin 1483 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-folder-outline.png | Bin 1606 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-folder.png | Bin 1640 -> 0 bytes .../png/512/ios7-football-outline.png | Bin 6266 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-football.png | Bin 5391 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-gear-outline.png | Bin 5721 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-gear.png | Bin 3445 -> 0 bytes .../png/512/ios7-glasses-outline.png | Bin 3597 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-glasses.png | Bin 2350 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-heart-outline.png | Bin 3097 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-heart.png | Bin 2078 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-help-empty.png | Bin 1669 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-help-outline.png | Bin 5608 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-help.png | Bin 3587 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-home-outline.png | Bin 1710 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-home.png | Bin 1518 -> 0 bytes .../png/512/ios7-infinite-outline.png | Bin 3028 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-infinite.png | Bin 2989 -> 0 bytes .../png/512/ios7-information-empty.png | Bin 837 -> 0 bytes .../png/512/ios7-information-outline.png | Bin 4563 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-information.png | Bin 2959 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-ionic-outline.png | Bin 5780 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-keypad-outline.png | Bin 7485 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-keypad.png | Bin 7505 -> 0 bytes .../png/512/ios7-lightbulb-outline.png | Bin 3791 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-lightbulb.png | Bin 2696 -> 0 bytes .../png/512/ios7-location-outline.png | Bin 4116 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-location.png | Bin 2767 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-locked-outline.png | Bin 2640 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-locked.png | Bin 2674 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-loop-strong.png | Bin 4101 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-loop.png | Bin 4270 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-medkit-outline.png | Bin 1386 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-medkit.png | Bin 1373 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-mic-off.png | Bin 7597 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-mic-outline.png | Bin 3550 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-mic.png | Bin 3878 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-minus-empty.png | Bin 153 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-minus-outline.png | Bin 4137 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-minus.png | Bin 2520 -> 0 bytes .../png/512/ios7-monitor-outline.png | Bin 225 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-monitor.png | Bin 230 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-moon-outline.png | Bin 2566 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-moon.png | Bin 1784 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-more-outline.png | Bin 1598 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-more.png | Bin 1700 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-musical-note.png | Bin 1521 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-musical-notes.png | Bin 2124 -> 0 bytes .../png/512/ios7-navigate-outline.png | Bin 4901 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-navigate.png | Bin 3333 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-paper-outline.png | Bin 1361 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-paper.png | Bin 1197 -> 0 bytes .../png/512/ios7-paperplane-outline.png | Bin 2952 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-paperplane.png | Bin 4805 -> 0 bytes .../png/512/ios7-partlysunny-outline.png | Bin 4823 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-partlysunny.png | Bin 4052 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-pause-outline.png | Bin 227 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-pause.png | Bin 213 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-paw-outline.png | Bin 6318 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-paw.png | Bin 4119 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-people-outline.png | Bin 5295 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-people.png | Bin 3439 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-person-outline.png | Bin 3189 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-person.png | Bin 2046 -> 0 bytes .../png/512/ios7-personadd-outline.png | Bin 3246 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-personadd.png | Bin 2110 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-photos-outline.png | Bin 234 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-photos.png | Bin 226 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-pie-outline.png | Bin 4549 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-pie.png | Bin 3646 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-play-outline.png | Bin 1474 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-play.png | Bin 1216 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-plus-empty.png | Bin 204 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-plus-outline.png | Bin 4415 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-plus.png | Bin 2970 -> 0 bytes .../png/512/ios7-pricetag-outline.png | Bin 3007 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-pricetag.png | Bin 2593 -> 0 bytes .../png/512/ios7-pricetags-outline.png | Bin 3563 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-pricetags.png | Bin 3219 -> 0 bytes .../png/512/ios7-printer-outline.png | Bin 1764 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-printer.png | Bin 1456 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-pulse-strong.png | Bin 3326 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-pulse.png | Bin 2955 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-rainy-outline.png | Bin 3346 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-rainy.png | Bin 2567 -> 0 bytes .../png/512/ios7-recording-outline.png | Bin 4926 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-recording.png | Bin 3762 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-redo-outline.png | Bin 3094 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-redo.png | Bin 2054 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-refresh-empty.png | Bin 2685 -> 0 bytes .../png/512/ios7-refresh-outline.png | Bin 6021 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-refresh.png | Bin 4579 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-reload.png | Bin 4195 -> 0 bytes .../png/512/ios7-reverse-camera-outline.png | Bin 3404 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-reverse-camera.png | Bin 3019 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-rewind-outline.png | Bin 2898 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-rewind.png | Bin 2362 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-search-strong.png | Bin 3329 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-search.png | Bin 3361 -> 0 bytes .../png/512/ios7-settings-strong.png | Bin 1714 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-settings.png | Bin 2160 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-shrink.png | Bin 490 -> 0 bytes .../png/512/ios7-skipbackward-outline.png | Bin 1890 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-skipbackward.png | Bin 1533 -> 0 bytes .../png/512/ios7-skipforward-outline.png | Bin 1827 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-skipforward.png | Bin 1556 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-snowy.png | Bin 3775 -> 0 bytes .../png/512/ios7-speedometer-outline.png | Bin 4678 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-speedometer.png | Bin 5748 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-star-half.png | Bin 3431 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-star-outline.png | Bin 3572 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-star.png | Bin 2463 -> 0 bytes .../png/512/ios7-stopwatch-outline.png | Bin 4823 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-stopwatch.png | Bin 3451 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-sunny-outline.png | Bin 2669 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-sunny.png | Bin 2506 -> 0 bytes .../png/512/ios7-telephone-outline.png | Bin 3779 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-telephone.png | Bin 2352 -> 0 bytes .../png/512/ios7-tennisball-outline.png | Bin 5535 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-tennisball.png | Bin 6356 -> 0 bytes .../png/512/ios7-thunderstorm-outline.png | Bin 3053 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-thunderstorm.png | Bin 2492 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-time-outline.png | Bin 5875 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-time.png | Bin 4136 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-timer-outline.png | Bin 4578 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-timer.png | Bin 6013 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-toggle-outline.png | Bin 5660 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-toggle.png | Bin 4825 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-trash-outline.png | Bin 4497 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-trash.png | Bin 2760 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-undo-outline.png | Bin 3114 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-undo.png | Bin 1954 -> 0 bytes .../png/512/ios7-unlocked-outline.png | Bin 2580 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-unlocked.png | Bin 2605 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-upload-outline.png | Bin 1128 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-upload.png | Bin 1085 -> 0 bytes .../png/512/ios7-videocam-outline.png | Bin 2038 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-videocam.png | Bin 2715 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-volume-high.png | Bin 2977 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-volume-low.png | Bin 956 -> 0 bytes .../png/512/ios7-wineglass-outline.png | Bin 2527 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-wineglass.png | Bin 2013 -> 0 bytes .../ionicons-2.0.1/png/512/ios7-world-outline.png | Bin 7420 -> 0 bytes .../external/ionicons-2.0.1/png/512/ios7-world.png | Bin 10031 -> 0 bytes .../external/ionicons-2.0.1/png/512/ipad.png | Bin 1356 -> 0 bytes .../external/ionicons-2.0.1/png/512/iphone.png | Bin 1651 -> 0 bytes .../external/ionicons-2.0.1/png/512/ipod.png | Bin 3207 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/jet.png | Bin 2856 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/key.png | Bin 2722 -> 0 bytes .../external/ionicons-2.0.1/png/512/knife.png | Bin 1822 -> 0 bytes .../external/ionicons-2.0.1/png/512/laptop.png | Bin 2474 -> 0 bytes .../external/ionicons-2.0.1/png/512/leaf.png | Bin 3440 -> 0 bytes .../external/ionicons-2.0.1/png/512/levels.png | Bin 2431 -> 0 bytes .../external/ionicons-2.0.1/png/512/lightbulb.png | Bin 2474 -> 0 bytes .../external/ionicons-2.0.1/png/512/link.png | Bin 2306 -> 0 bytes .../external/ionicons-2.0.1/png/512/load-a.png | Bin 3941 -> 0 bytes .../external/ionicons-2.0.1/png/512/load-b.png | Bin 5473 -> 0 bytes .../external/ionicons-2.0.1/png/512/load-c.png | Bin 4337 -> 0 bytes .../external/ionicons-2.0.1/png/512/load-d.png | Bin 6618 -> 0 bytes .../external/ionicons-2.0.1/png/512/location.png | Bin 2739 -> 0 bytes .../external/ionicons-2.0.1/png/512/locked.png | Bin 2494 -> 0 bytes .../external/ionicons-2.0.1/png/512/log-in.png | Bin 1460 -> 0 bytes .../external/ionicons-2.0.1/png/512/log-out.png | Bin 1637 -> 0 bytes .../external/ionicons-2.0.1/png/512/loop.png | Bin 3794 -> 0 bytes .../external/ionicons-2.0.1/png/512/magnet.png | Bin 4495 -> 0 bytes .../external/ionicons-2.0.1/png/512/male.png | Bin 3788 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/man.png | Bin 2126 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/map.png | Bin 4906 -> 0 bytes .../external/ionicons-2.0.1/png/512/medkit.png | Bin 1605 -> 0 bytes .../external/ionicons-2.0.1/png/512/merge.png | Bin 3879 -> 0 bytes .../external/ionicons-2.0.1/png/512/mic-a.png | Bin 4098 -> 0 bytes .../external/ionicons-2.0.1/png/512/mic-b.png | Bin 2576 -> 0 bytes .../external/ionicons-2.0.1/png/512/mic-c.png | Bin 1726 -> 0 bytes .../ionicons-2.0.1/png/512/minus-circled.png | Bin 2655 -> 0 bytes .../ionicons-2.0.1/png/512/minus-round.png | Bin 937 -> 0 bytes .../external/ionicons-2.0.1/png/512/minus.png | Bin 160 -> 0 bytes .../external/ionicons-2.0.1/png/512/model-s.png | Bin 4262 -> 0 bytes .../external/ionicons-2.0.1/png/512/monitor.png | Bin 1469 -> 0 bytes .../external/ionicons-2.0.1/png/512/more.png | Bin 3357 -> 0 bytes .../external/ionicons-2.0.1/png/512/mouse.png | Bin 2891 -> 0 bytes .../external/ionicons-2.0.1/png/512/music-note.png | Bin 2519 -> 0 bytes .../ionicons-2.0.1/png/512/navicon-round.png | Bin 1628 -> 0 bytes .../external/ionicons-2.0.1/png/512/navicon.png | Bin 175 -> 0 bytes .../external/ionicons-2.0.1/png/512/navigate.png | Bin 1693 -> 0 bytes .../external/ionicons-2.0.1/png/512/network.png | Bin 3041 -> 0 bytes .../external/ionicons-2.0.1/png/512/no-smoking.png | Bin 5816 -> 0 bytes .../external/ionicons-2.0.1/png/512/nuclear.png | Bin 3618 -> 0 bytes .../external/ionicons-2.0.1/png/512/outlet.png | Bin 2882 -> 0 bytes .../ionicons-2.0.1/png/512/paper-airplane.png | Bin 3678 -> 0 bytes .../external/ionicons-2.0.1/png/512/paperclip.png | Bin 2710 -> 0 bytes .../external/ionicons-2.0.1/png/512/pause.png | Bin 1340 -> 0 bytes .../external/ionicons-2.0.1/png/512/person-add.png | Bin 2410 -> 0 bytes .../ionicons-2.0.1/png/512/person-stalker.png | Bin 3272 -> 0 bytes .../external/ionicons-2.0.1/png/512/person.png | Bin 2258 -> 0 bytes .../external/ionicons-2.0.1/png/512/pie-graph.png | Bin 3608 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/pin.png | Bin 2270 -> 0 bytes .../external/ionicons-2.0.1/png/512/pinpoint.png | Bin 4799 -> 0 bytes .../external/ionicons-2.0.1/png/512/pizza.png | Bin 4548 -> 0 bytes .../external/ionicons-2.0.1/png/512/plane.png | Bin 3218 -> 0 bytes .../external/ionicons-2.0.1/png/512/planet.png | Bin 4319 -> 0 bytes .../external/ionicons-2.0.1/png/512/play.png | Bin 1787 -> 0 bytes .../ionicons-2.0.1/png/512/playstation.png | Bin 3275 -> 0 bytes .../ionicons-2.0.1/png/512/plus-circled.png | Bin 3114 -> 0 bytes .../external/ionicons-2.0.1/png/512/plus-round.png | Bin 1567 -> 0 bytes .../external/ionicons-2.0.1/png/512/plus.png | Bin 223 -> 0 bytes .../external/ionicons-2.0.1/png/512/podium.png | Bin 209 -> 0 bytes .../external/ionicons-2.0.1/png/512/pound.png | Bin 2383 -> 0 bytes .../external/ionicons-2.0.1/png/512/power.png | Bin 4727 -> 0 bytes .../external/ionicons-2.0.1/png/512/pricetag.png | Bin 2457 -> 0 bytes .../external/ionicons-2.0.1/png/512/pricetags.png | Bin 2906 -> 0 bytes .../external/ionicons-2.0.1/png/512/printer.png | Bin 1869 -> 0 bytes .../ionicons-2.0.1/png/512/pull-request.png | Bin 3613 -> 0 bytes .../external/ionicons-2.0.1/png/512/qr-scanner.png | Bin 1842 -> 0 bytes .../external/ionicons-2.0.1/png/512/quote.png | Bin 1743 -> 0 bytes .../ionicons-2.0.1/png/512/radio-waves.png | Bin 4978 -> 0 bytes .../external/ionicons-2.0.1/png/512/record.png | Bin 3779 -> 0 bytes .../external/ionicons-2.0.1/png/512/refresh.png | Bin 3582 -> 0 bytes .../external/ionicons-2.0.1/png/512/reply-all.png | Bin 3033 -> 0 bytes .../external/ionicons-2.0.1/png/512/reply.png | Bin 2131 -> 0 bytes .../external/ionicons-2.0.1/png/512/ribbon-a.png | Bin 6449 -> 0 bytes .../external/ionicons-2.0.1/png/512/ribbon-b.png | Bin 5913 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/sad.png | Bin 5517 -> 0 bytes .../external/ionicons-2.0.1/png/512/scissors.png | Bin 5061 -> 0 bytes .../external/ionicons-2.0.1/png/512/search.png | Bin 3229 -> 0 bytes .../external/ionicons-2.0.1/png/512/settings.png | Bin 4141 -> 0 bytes .../external/ionicons-2.0.1/png/512/share.png | Bin 2616 -> 0 bytes .../external/ionicons-2.0.1/png/512/shuffle.png | Bin 3420 -> 0 bytes .../ionicons-2.0.1/png/512/skip-backward.png | Bin 2421 -> 0 bytes .../ionicons-2.0.1/png/512/skip-forward.png | Bin 2402 -> 0 bytes .../png/512/social-android-outline.png | Bin 3772 -> 0 bytes .../ionicons-2.0.1/png/512/social-android.png | Bin 2784 -> 0 bytes .../png/512/social-apple-outline.png | Bin 4104 -> 0 bytes .../ionicons-2.0.1/png/512/social-apple.png | Bin 2647 -> 0 bytes .../png/512/social-bitcoin-outline.png | Bin 3790 -> 0 bytes .../ionicons-2.0.1/png/512/social-bitcoin.png | Bin 2424 -> 0 bytes .../png/512/social-buffer-outline.png | Bin 3913 -> 0 bytes .../ionicons-2.0.1/png/512/social-buffer.png | Bin 4687 -> 0 bytes .../png/512/social-designernews-outline.png | Bin 4754 -> 0 bytes .../ionicons-2.0.1/png/512/social-designernews.png | Bin 4242 -> 0 bytes .../png/512/social-dribbble-outline.png | Bin 5588 -> 0 bytes .../ionicons-2.0.1/png/512/social-dribbble.png | Bin 6983 -> 0 bytes .../png/512/social-dropbox-outline.png | Bin 5113 -> 0 bytes .../ionicons-2.0.1/png/512/social-dropbox.png | Bin 6161 -> 0 bytes .../png/512/social-facebook-outline.png | Bin 1788 -> 0 bytes .../ionicons-2.0.1/png/512/social-facebook.png | Bin 1402 -> 0 bytes .../png/512/social-foursquare-outline.png | Bin 3364 -> 0 bytes .../ionicons-2.0.1/png/512/social-foursquare.png | Bin 3021 -> 0 bytes .../png/512/social-freebsd-devil.png | Bin 5300 -> 0 bytes .../png/512/social-github-outline.png | Bin 7475 -> 0 bytes .../ionicons-2.0.1/png/512/social-github.png | Bin 4561 -> 0 bytes .../png/512/social-google-outline.png | Bin 3890 -> 0 bytes .../ionicons-2.0.1/png/512/social-google.png | Bin 3682 -> 0 bytes .../png/512/social-googleplus-outline.png | Bin 4071 -> 0 bytes .../ionicons-2.0.1/png/512/social-googleplus.png | Bin 3888 -> 0 bytes .../png/512/social-hackernews-outline.png | Bin 1994 -> 0 bytes .../ionicons-2.0.1/png/512/social-hackernews.png | Bin 1905 -> 0 bytes .../png/512/social-instagram-outline.png | Bin 3317 -> 0 bytes .../ionicons-2.0.1/png/512/social-instagram.png | Bin 4403 -> 0 bytes .../png/512/social-linkedin-outline.png | Bin 2370 -> 0 bytes .../ionicons-2.0.1/png/512/social-linkedin.png | Bin 2275 -> 0 bytes .../png/512/social-pinterest-outline.png | Bin 6933 -> 0 bytes .../ionicons-2.0.1/png/512/social-pinterest.png | Bin 5532 -> 0 bytes .../png/512/social-reddit-outline.png | Bin 6414 -> 0 bytes .../ionicons-2.0.1/png/512/social-reddit.png | Bin 4498 -> 0 bytes .../ionicons-2.0.1/png/512/social-rss-outline.png | Bin 5945 -> 0 bytes .../external/ionicons-2.0.1/png/512/social-rss.png | Bin 4789 -> 0 bytes .../png/512/social-skype-outline.png | Bin 5608 -> 0 bytes .../ionicons-2.0.1/png/512/social-skype.png | Bin 4269 -> 0 bytes .../png/512/social-tumblr-outline.png | Bin 2725 -> 0 bytes .../ionicons-2.0.1/png/512/social-tumblr.png | Bin 1946 -> 0 bytes .../external/ionicons-2.0.1/png/512/social-tux.png | Bin 7103 -> 0 bytes .../png/512/social-twitter-outline.png | Bin 5569 -> 0 bytes .../ionicons-2.0.1/png/512/social-twitter.png | Bin 3405 -> 0 bytes .../ionicons-2.0.1/png/512/social-usd-outline.png | Bin 5744 -> 0 bytes .../external/ionicons-2.0.1/png/512/social-usd.png | Bin 3446 -> 0 bytes .../png/512/social-vimeo-outline.png | Bin 5525 -> 0 bytes .../ionicons-2.0.1/png/512/social-vimeo.png | Bin 3456 -> 0 bytes .../png/512/social-windows-outline.png | Bin 1775 -> 0 bytes .../ionicons-2.0.1/png/512/social-windows.png | Bin 2550 -> 0 bytes .../png/512/social-wordpress-outline.png | Bin 6418 -> 0 bytes .../ionicons-2.0.1/png/512/social-wordpress.png | Bin 5465 -> 0 bytes .../png/512/social-yahoo-outline.png | Bin 2119 -> 0 bytes .../ionicons-2.0.1/png/512/social-yahoo.png | Bin 1729 -> 0 bytes .../png/512/social-youtube-outline.png | Bin 4655 -> 0 bytes .../ionicons-2.0.1/png/512/social-youtube.png | Bin 2511 -> 0 bytes .../ionicons-2.0.1/png/512/speakerphone.png | Bin 4310 -> 0 bytes .../ionicons-2.0.1/png/512/speedometer.png | Bin 4238 -> 0 bytes .../external/ionicons-2.0.1/png/512/spoon.png | Bin 2306 -> 0 bytes .../external/ionicons-2.0.1/png/512/star.png | Bin 2195 -> 0 bytes .../external/ionicons-2.0.1/png/512/stats-bars.png | Bin 218 -> 0 bytes .../external/ionicons-2.0.1/png/512/steam.png | Bin 3875 -> 0 bytes .../external/ionicons-2.0.1/png/512/stop.png | Bin 1090 -> 0 bytes .../ionicons-2.0.1/png/512/thermometer.png | Bin 1980 -> 0 bytes .../external/ionicons-2.0.1/png/512/thumbsdown.png | Bin 2288 -> 0 bytes .../external/ionicons-2.0.1/png/512/thumbsup.png | Bin 2356 -> 0 bytes .../ionicons-2.0.1/png/512/toggle-filled.png | Bin 3194 -> 0 bytes .../external/ionicons-2.0.1/png/512/toggle.png | Bin 3599 -> 0 bytes .../external/ionicons-2.0.1/png/512/trash-a.png | Bin 2752 -> 0 bytes .../external/ionicons-2.0.1/png/512/trash-b.png | Bin 1882 -> 0 bytes .../external/ionicons-2.0.1/png/512/trophy.png | Bin 3579 -> 0 bytes .../external/ionicons-2.0.1/png/512/umbrella.png | Bin 3416 -> 0 bytes .../external/ionicons-2.0.1/png/512/university.png | Bin 3167 -> 0 bytes .../external/ionicons-2.0.1/png/512/unlocked.png | Bin 2412 -> 0 bytes .../external/ionicons-2.0.1/png/512/upload.png | Bin 2480 -> 0 bytes .../fusion/external/ionicons-2.0.1/png/512/usb.png | Bin 3950 -> 0 bytes .../ionicons-2.0.1/png/512/videocamera.png | Bin 2381 -> 0 bytes .../ionicons-2.0.1/png/512/volume-high.png | Bin 4334 -> 0 bytes .../external/ionicons-2.0.1/png/512/volume-low.png | Bin 2136 -> 0 bytes .../ionicons-2.0.1/png/512/volume-medium.png | Bin 3174 -> 0 bytes .../ionicons-2.0.1/png/512/volume-mute.png | Bin 4803 -> 0 bytes .../external/ionicons-2.0.1/png/512/wand.png | Bin 1933 -> 0 bytes .../external/ionicons-2.0.1/png/512/waterdrop.png | Bin 3169 -> 0 bytes .../external/ionicons-2.0.1/png/512/wifi.png | Bin 3037 -> 0 bytes .../external/ionicons-2.0.1/png/512/wineglass.png | Bin 3734 -> 0 bytes .../external/ionicons-2.0.1/png/512/woman.png | Bin 3592 -> 0 bytes .../external/ionicons-2.0.1/png/512/wrench.png | Bin 2866 -> 0 bytes .../external/ionicons-2.0.1/png/512/xbox.png | Bin 4958 -> 0 bytes .../app/fusion/external/ionicons-2.0.1/readme.md | 60 - .../ionicons-2.0.1/scss/_ionicons-font.scss | 27 - .../ionicons-2.0.1/scss/_ionicons-icons.scss | 1473 - .../ionicons-2.0.1/scss/_ionicons-variables.scss | 741 - .../external/ionicons-2.0.1/scss/ionicons.scss | 15 - .../external/ionicons-2.0.1/src/alert-circled.svg | 11 - .../fusion/external/ionicons-2.0.1/src/alert.svg | 9 - .../ionicons-2.0.1/src/android-add-circle.svg | 12 - .../external/ionicons-2.0.1/src/android-add.svg | 11 - .../ionicons-2.0.1/src/android-alarm-clock.svg | 15 - .../external/ionicons-2.0.1/src/android-alert.svg | 12 - .../external/ionicons-2.0.1/src/android-apps.svg | 12 - .../ionicons-2.0.1/src/android-archive.svg | 12 - .../ionicons-2.0.1/src/android-arrow-back.svg | 11 - .../ionicons-2.0.1/src/android-arrow-down.svg | 11 - .../src/android-arrow-dropdown-circle.svg | 10 - .../ionicons-2.0.1/src/android-arrow-dropdown.svg | 9 - .../src/android-arrow-dropleft-circle.svg | 10 - .../ionicons-2.0.1/src/android-arrow-dropleft.svg | 9 - .../src/android-arrow-dropright-circle.svg | 10 - .../ionicons-2.0.1/src/android-arrow-dropright.svg | 9 - .../src/android-arrow-dropup-circle.svg | 10 - .../ionicons-2.0.1/src/android-arrow-dropup.svg | 9 - .../ionicons-2.0.1/src/android-arrow-forward.svg | 11 - .../ionicons-2.0.1/src/android-arrow-up.svg | 11 - .../external/ionicons-2.0.1/src/android-attach.svg | 15 - .../external/ionicons-2.0.1/src/android-bar.svg | 12 - .../ionicons-2.0.1/src/android-bicycle.svg | 19 - .../external/ionicons-2.0.1/src/android-boat.svg | 16 - .../ionicons-2.0.1/src/android-bookmark.svg | 7 - .../external/ionicons-2.0.1/src/android-bulb.svg | 18 - .../external/ionicons-2.0.1/src/android-bus.svg | 18 - .../ionicons-2.0.1/src/android-calendar.svg | 11 - .../external/ionicons-2.0.1/src/android-call.svg | 10 - .../external/ionicons-2.0.1/src/android-camera.svg | 12 - .../external/ionicons-2.0.1/src/android-cancel.svg | 11 - .../external/ionicons-2.0.1/src/android-car.svg | 15 - .../external/ionicons-2.0.1/src/android-cart.svg | 14 - .../external/ionicons-2.0.1/src/android-chat.svg | 12 - .../ionicons-2.0.1/src/android-checkbox-blank.svg | 12 - .../src/android-checkbox-outline-blank.svg | 13 - .../src/android-checkbox-outline.svg | 13 - .../ionicons-2.0.1/src/android-checkbox.svg | 13 - .../src/android-checkmark-circle.svg | 9 - .../ionicons-2.0.1/src/android-clipboard.svg | 10 - .../external/ionicons-2.0.1/src/android-close.svg | 12 - .../ionicons-2.0.1/src/android-cloud-circle.svg | 16 - .../ionicons-2.0.1/src/android-cloud-done.svg | 12 - .../ionicons-2.0.1/src/android-cloud-outline.svg | 16 - .../external/ionicons-2.0.1/src/android-cloud.svg | 9 - .../ionicons-2.0.1/src/android-color-palette.svg | 17 - .../ionicons-2.0.1/src/android-compass.svg | 9 - .../ionicons-2.0.1/src/android-contact.svg | 15 - .../ionicons-2.0.1/src/android-contacts.svg | 26 - .../ionicons-2.0.1/src/android-contract.svg | 12 - .../external/ionicons-2.0.1/src/android-create.svg | 13 - .../external/ionicons-2.0.1/src/android-delete.svg | 10 - .../ionicons-2.0.1/src/android-desktop.svg | 13 - .../ionicons-2.0.1/src/android-document.svg | 10 - .../ionicons-2.0.1/src/android-done-all.svg | 13 - .../external/ionicons-2.0.1/src/android-done.svg | 13 - .../ionicons-2.0.1/src/android-download.svg | 9 - .../external/ionicons-2.0.1/src/android-drafts.svg | 15 - .../external/ionicons-2.0.1/src/android-exit.svg | 9 - .../external/ionicons-2.0.1/src/android-expand.svg | 12 - .../src/android-favorite-outline.svg | 13 - .../ionicons-2.0.1/src/android-favorite.svg | 11 - .../external/ionicons-2.0.1/src/android-film.svg | 9 - .../ionicons-2.0.1/src/android-folder-open.svg | 10 - .../external/ionicons-2.0.1/src/android-folder.svg | 14 - .../external/ionicons-2.0.1/src/android-funnel.svg | 7 - .../external/ionicons-2.0.1/src/android-globe.svg | 24 - .../external/ionicons-2.0.1/src/android-hand.svg | 15 - .../ionicons-2.0.1/src/android-hangout.svg | 9 - .../external/ionicons-2.0.1/src/android-happy.svg | 12 - .../external/ionicons-2.0.1/src/android-home.svg | 9 - .../external/ionicons-2.0.1/src/android-image.svg | 13 - .../external/ionicons-2.0.1/src/android-laptop.svg | 14 - .../external/ionicons-2.0.1/src/android-list.svg | 10 - .../external/ionicons-2.0.1/src/android-locate.svg | 16 - .../external/ionicons-2.0.1/src/android-lock.svg | 14 - .../external/ionicons-2.0.1/src/android-mail.svg | 13 - .../external/ionicons-2.0.1/src/android-map.svg | 16 - .../external/ionicons-2.0.1/src/android-menu.svg | 11 - .../ionicons-2.0.1/src/android-microphone-off.svg | 17 - .../ionicons-2.0.1/src/android-microphone.svg | 12 - .../ionicons-2.0.1/src/android-more-horizontal.svg | 9 - .../ionicons-2.0.1/src/android-more-vertical.svg | 9 - .../ionicons-2.0.1/src/android-navigate.svg | 11 - .../src/android-notifications-none.svg | 11 - .../src/android-notifications-off.svg | 13 - .../ionicons-2.0.1/src/android-notifications.svg | 9 - .../external/ionicons-2.0.1/src/android-open.svg | 9 - .../ionicons-2.0.1/src/android-options.svg | 26 - .../external/ionicons-2.0.1/src/android-people.svg | 11 - .../ionicons-2.0.1/src/android-person-add.svg | 17 - .../external/ionicons-2.0.1/src/android-person.svg | 10 - .../ionicons-2.0.1/src/android-phone-landscape.svg | 12 - .../ionicons-2.0.1/src/android-phone-portrait.svg | 12 - .../external/ionicons-2.0.1/src/android-pin.svg | 11 - .../external/ionicons-2.0.1/src/android-plane.svg | 12 - .../ionicons-2.0.1/src/android-playstore.svg | 11 - .../external/ionicons-2.0.1/src/android-print.svg | 10 - .../src/android-radio-button-off.svg | 12 - .../ionicons-2.0.1/src/android-radio-button-on.svg | 13 - .../ionicons-2.0.1/src/android-refresh.svg | 11 - .../ionicons-2.0.1/src/android-remove-circle.svg | 10 - .../external/ionicons-2.0.1/src/android-remove.svg | 7 - .../ionicons-2.0.1/src/android-restaurant.svg | 17 - .../external/ionicons-2.0.1/src/android-sad.svg | 16 - .../external/ionicons-2.0.1/src/android-search.svg | 19 - .../external/ionicons-2.0.1/src/android-send.svg | 7 - .../ionicons-2.0.1/src/android-settings.svg | 19 - .../ionicons-2.0.1/src/android-share-alt.svg | 16 - .../external/ionicons-2.0.1/src/android-share.svg | 12 - .../ionicons-2.0.1/src/android-star-half.svg | 9 - .../ionicons-2.0.1/src/android-star-outline.svg | 10 - .../external/ionicons-2.0.1/src/android-star.svg | 10 - .../ionicons-2.0.1/src/android-stopwatch.svg | 21 - .../external/ionicons-2.0.1/src/android-subway.svg | 13 - .../external/ionicons-2.0.1/src/android-sunny.svg | 18 - .../external/ionicons-2.0.1/src/android-sync.svg | 10 - .../ionicons-2.0.1/src/android-textsms.svg | 10 - .../external/ionicons-2.0.1/src/android-time.svg | 15 - .../external/ionicons-2.0.1/src/android-train.svg | 15 - .../external/ionicons-2.0.1/src/android-unlock.svg | 10 - .../external/ionicons-2.0.1/src/android-upload.svg | 9 - .../ionicons-2.0.1/src/android-volume-down.svg | 8 - .../ionicons-2.0.1/src/android-volume-mute.svg | 7 - .../ionicons-2.0.1/src/android-volume-off.svg | 15 - .../ionicons-2.0.1/src/android-volume-up.svg | 9 - .../external/ionicons-2.0.1/src/android-walk.svg | 12 - .../ionicons-2.0.1/src/android-warning.svg | 11 - .../external/ionicons-2.0.1/src/android-watch.svg | 15 - .../external/ionicons-2.0.1/src/android-wifi.svg | 14 - .../external/ionicons-2.0.1/src/aperture.svg | 20 - .../fusion/external/ionicons-2.0.1/src/archive.svg | 12 - .../external/ionicons-2.0.1/src/arrow-down-a.svg | 7 - .../external/ionicons-2.0.1/src/arrow-down-b.svg | 8 - .../external/ionicons-2.0.1/src/arrow-down-c.svg | 9 - .../external/ionicons-2.0.1/src/arrow-expand.svg | 12 - .../ionicons-2.0.1/src/arrow-graph-down-left.svg | 7 - .../ionicons-2.0.1/src/arrow-graph-down-right.svg | 7 - .../ionicons-2.0.1/src/arrow-graph-up-left.svg | 7 - .../ionicons-2.0.1/src/arrow-graph-up-right.svg | 7 - .../external/ionicons-2.0.1/src/arrow-left-a.svg | 7 - .../external/ionicons-2.0.1/src/arrow-left-b.svg | 8 - .../external/ionicons-2.0.1/src/arrow-left-c.svg | 9 - .../external/ionicons-2.0.1/src/arrow-move.svg | 8 - .../external/ionicons-2.0.1/src/arrow-resize.svg | 8 - .../ionicons-2.0.1/src/arrow-return-left.svg | 8 - .../ionicons-2.0.1/src/arrow-return-right.svg | 8 - .../external/ionicons-2.0.1/src/arrow-right-a.svg | 7 - .../external/ionicons-2.0.1/src/arrow-right-b.svg | 8 - .../external/ionicons-2.0.1/src/arrow-right-c.svg | 9 - .../external/ionicons-2.0.1/src/arrow-shrink.svg | 12 - .../external/ionicons-2.0.1/src/arrow-swap.svg | 10 - .../external/ionicons-2.0.1/src/arrow-up-a.svg | 7 - .../external/ionicons-2.0.1/src/arrow-up-b.svg | 8 - .../external/ionicons-2.0.1/src/arrow-up-c.svg | 9 - .../external/ionicons-2.0.1/src/asterisk.svg | 8 - .../app/fusion/external/ionicons-2.0.1/src/at.svg | 25 - .../ionicons-2.0.1/src/backspace-outline.svg | 21 - .../external/ionicons-2.0.1/src/backspace.svg | 17 - .../app/fusion/external/ionicons-2.0.1/src/bag.svg | 10 - .../ionicons-2.0.1/src/battery-charging.svg | 9 - .../external/ionicons-2.0.1/src/battery-empty.svg | 8 - .../external/ionicons-2.0.1/src/battery-full.svg | 8 - .../external/ionicons-2.0.1/src/battery-half.svg | 9 - .../external/ionicons-2.0.1/src/battery-low.svg | 9 - .../fusion/external/ionicons-2.0.1/src/beaker.svg | 20 - .../fusion/external/ionicons-2.0.1/src/beer.svg | 28 - .../external/ionicons-2.0.1/src/bluetooth.svg | 18 - .../fusion/external/ionicons-2.0.1/src/bonfire.svg | 32 - .../external/ionicons-2.0.1/src/bookmark.svg | 10 - .../fusion/external/ionicons-2.0.1/src/bowtie.svg | 22 - .../external/ionicons-2.0.1/src/briefcase.svg | 12 - .../app/fusion/external/ionicons-2.0.1/src/bug.svg | 30 - .../external/ionicons-2.0.1/src/calculator.svg | 10 - .../external/ionicons-2.0.1/src/calendar.svg | 12 - .../fusion/external/ionicons-2.0.1/src/camera.svg | 15 - .../fusion/external/ionicons-2.0.1/src/card.svg | 14 - .../fusion/external/ionicons-2.0.1/src/cash.svg | 31 - .../ionicons-2.0.1/src/chatbox-working.svg | 11 - .../fusion/external/ionicons-2.0.1/src/chatbox.svg | 8 - .../external/ionicons-2.0.1/src/chatboxes.svg | 12 - .../ionicons-2.0.1/src/chatbubble-working.svg | 12 - .../external/ionicons-2.0.1/src/chatbubble.svg | 9 - .../external/ionicons-2.0.1/src/chatbubbles.svg | 16 - .../ionicons-2.0.1/src/checkmark-circled.svg | 13 - .../ionicons-2.0.1/src/checkmark-round.svg | 9 - .../external/ionicons-2.0.1/src/checkmark.svg | 10 - .../external/ionicons-2.0.1/src/chevron-down.svg | 9 - .../external/ionicons-2.0.1/src/chevron-left.svg | 9 - .../external/ionicons-2.0.1/src/chevron-right.svg | 9 - .../external/ionicons-2.0.1/src/chevron-up.svg | 9 - .../external/ionicons-2.0.1/src/clipboard.svg | 22 - .../fusion/external/ionicons-2.0.1/src/clock.svg | 21 - .../external/ionicons-2.0.1/src/close-circled.svg | 13 - .../external/ionicons-2.0.1/src/close-round.svg | 9 - .../fusion/external/ionicons-2.0.1/src/close.svg | 10 - .../ionicons-2.0.1/src/closed-captioning.svg | 31 - .../fusion/external/ionicons-2.0.1/src/cloud.svg | 9 - .../external/ionicons-2.0.1/src/code-download.svg | 31 - .../external/ionicons-2.0.1/src/code-working.svg | 21 - .../fusion/external/ionicons-2.0.1/src/code.svg | 14 - .../fusion/external/ionicons-2.0.1/src/coffee.svg | 13 - .../fusion/external/ionicons-2.0.1/src/compass.svg | 16 - .../fusion/external/ionicons-2.0.1/src/compose.svg | 14 - .../ionicons-2.0.1/src/connection-bars.svg | 12 - .../external/ionicons-2.0.1/src/contrast.svg | 9 - .../fusion/external/ionicons-2.0.1/src/crop.svg | 11 - .../fusion/external/ionicons-2.0.1/src/cube.svg | 19 - .../fusion/external/ionicons-2.0.1/src/disc.svg | 13 - .../external/ionicons-2.0.1/src/document-text.svg | 15 - .../external/ionicons-2.0.1/src/document.svg | 10 - .../fusion/external/ionicons-2.0.1/src/drag.svg | 11 - .../fusion/external/ionicons-2.0.1/src/earth.svg | 44 - .../fusion/external/ionicons-2.0.1/src/easel.svg | 15 - .../fusion/external/ionicons-2.0.1/src/edit.svg | 13 - .../app/fusion/external/ionicons-2.0.1/src/egg.svg | 7 - .../fusion/external/ionicons-2.0.1/src/eject.svg | 12 - .../external/ionicons-2.0.1/src/email-unread.svg | 19 - .../fusion/external/ionicons-2.0.1/src/email.svg | 15 - .../src/erlenmeyer-flask-bubbles.svg | 15 - .../ionicons-2.0.1/src/erlenmeyer-flask.svg | 21 - .../external/ionicons-2.0.1/src/eye-disabled.svg | 18 - .../app/fusion/external/ionicons-2.0.1/src/eye.svg | 15 - .../fusion/external/ionicons-2.0.1/src/female.svg | 8 - .../fusion/external/ionicons-2.0.1/src/filing.svg | 12 - .../external/ionicons-2.0.1/src/film-marker.svg | 10 - .../external/ionicons-2.0.1/src/fireball.svg | 16 - .../fusion/external/ionicons-2.0.1/src/flag.svg | 12 - .../fusion/external/ionicons-2.0.1/src/flame.svg | 11 - .../external/ionicons-2.0.1/src/flash-off.svg | 16 - .../fusion/external/ionicons-2.0.1/src/flash.svg | 7 - .../fusion/external/ionicons-2.0.1/src/folder.svg | 14 - .../external/ionicons-2.0.1/src/fork-repo.svg | 20 - .../fusion/external/ionicons-2.0.1/src/fork.svg | 14 - .../fusion/external/ionicons-2.0.1/src/forward.svg | 9 - .../fusion/external/ionicons-2.0.1/src/funnel.svg | 13 - .../fusion/external/ionicons-2.0.1/src/gear-a.svg | 15 - .../fusion/external/ionicons-2.0.1/src/gear-b.svg | 11 - .../fusion/external/ionicons-2.0.1/src/grid.svg | 32 - .../fusion/external/ionicons-2.0.1/src/hammer.svg | 11 - .../external/ionicons-2.0.1/src/happy-outline.svg | 23 - .../fusion/external/ionicons-2.0.1/src/happy.svg | 20 - .../external/ionicons-2.0.1/src/headphone.svg | 15 - .../external/ionicons-2.0.1/src/heart-broken.svg | 17 - .../fusion/external/ionicons-2.0.1/src/heart.svg | 10 - .../external/ionicons-2.0.1/src/help-buoy.svg | 13 - .../external/ionicons-2.0.1/src/help-circled.svg | 15 - .../fusion/external/ionicons-2.0.1/src/help.svg | 14 - .../fusion/external/ionicons-2.0.1/src/home.svg | 9 - .../external/ionicons-2.0.1/src/icecream.svg | 15 - .../fusion/external/ionicons-2.0.1/src/image.svg | 13 - .../fusion/external/ionicons-2.0.1/src/images.svg | 20 - .../ionicons-2.0.1/src/information-circled.svg | 11 - .../external/ionicons-2.0.1/src/information.svg | 10 - .../fusion/external/ionicons-2.0.1/src/ionic.svg | 18 - .../ionicons-2.0.1/src/ios-alarm-outline.svg | 21 - .../external/ionicons-2.0.1/src/ios-alarm.svg | 14 - .../ionicons-2.0.1/src/ios-albums-outline.svg | 11 - .../external/ionicons-2.0.1/src/ios-albums.svg | 11 - .../src/ios-americanfootball-outline.svg | 24 - .../ionicons-2.0.1/src/ios-americanfootball.svg | 21 - .../ionicons-2.0.1/src/ios-analytics-outline.svg | 24 - .../external/ionicons-2.0.1/src/ios-analytics.svg | 17 - .../external/ionicons-2.0.1/src/ios-arrow-back.svg | 7 - .../external/ionicons-2.0.1/src/ios-arrow-down.svg | 7 - .../ionicons-2.0.1/src/ios-arrow-forward.svg | 7 - .../external/ionicons-2.0.1/src/ios-arrow-left.svg | 7 - .../ionicons-2.0.1/src/ios-arrow-right.svg | 7 - .../ionicons-2.0.1/src/ios-arrow-thin-down.svg | 9 - .../ionicons-2.0.1/src/ios-arrow-thin-left.svg | 9 - .../ionicons-2.0.1/src/ios-arrow-thin-right.svg | 9 - .../ionicons-2.0.1/src/ios-arrow-thin-up.svg | 9 - .../external/ionicons-2.0.1/src/ios-arrow-up.svg | 7 - .../external/ionicons-2.0.1/src/ios-at-outline.svg | 26 - .../fusion/external/ionicons-2.0.1/src/ios-at.svg | 24 - .../ionicons-2.0.1/src/ios-barcode-outline.svg | 15 - .../external/ionicons-2.0.1/src/ios-barcode.svg | 10 - .../ionicons-2.0.1/src/ios-baseball-outline.svg | 35 - .../external/ionicons-2.0.1/src/ios-baseball.svg | 27 - .../ionicons-2.0.1/src/ios-basketball-outline.svg | 25 - .../external/ionicons-2.0.1/src/ios-basketball.svg | 21 - .../ionicons-2.0.1/src/ios-bell-outline.svg | 13 - .../external/ionicons-2.0.1/src/ios-bell.svg | 11 - .../ionicons-2.0.1/src/ios-body-outline.svg | 27 - .../external/ionicons-2.0.1/src/ios-body.svg | 17 - .../ionicons-2.0.1/src/ios-bolt-outline.svg | 8 - .../external/ionicons-2.0.1/src/ios-bolt.svg | 7 - .../ionicons-2.0.1/src/ios-book-outline.svg | 13 - .../external/ionicons-2.0.1/src/ios-book.svg | 12 - .../ionicons-2.0.1/src/ios-bookmarks-outline.svg | 13 - .../external/ionicons-2.0.1/src/ios-bookmarks.svg | 13 - .../ionicons-2.0.1/src/ios-box-outline.svg | 13 - .../fusion/external/ionicons-2.0.1/src/ios-box.svg | 10 - .../ionicons-2.0.1/src/ios-briefcase-outline.svg | 11 - .../external/ionicons-2.0.1/src/ios-briefcase.svg | 13 - .../ionicons-2.0.1/src/ios-browsers-outline.svg | 12 - .../external/ionicons-2.0.1/src/ios-browsers.svg | 10 - .../ionicons-2.0.1/src/ios-calculator-outline.svg | 19 - .../external/ionicons-2.0.1/src/ios-calculator.svg | 9 - .../ionicons-2.0.1/src/ios-calendar-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-calendar.svg | 12 - .../ionicons-2.0.1/src/ios-camera-outline.svg | 17 - .../external/ionicons-2.0.1/src/ios-camera.svg | 13 - .../ionicons-2.0.1/src/ios-cart-outline.svg | 16 - .../external/ionicons-2.0.1/src/ios-cart.svg | 14 - .../ionicons-2.0.1/src/ios-chatboxes-outline.svg | 10 - .../external/ionicons-2.0.1/src/ios-chatboxes.svg | 10 - .../ionicons-2.0.1/src/ios-chatbubble-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-chatbubble.svg | 11 - .../ionicons-2.0.1/src/ios-checkmark-empty.svg | 10 - .../ionicons-2.0.1/src/ios-checkmark-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-checkmark.svg | 10 - .../ionicons-2.0.1/src/ios-circle-filled.svg | 18 - .../ionicons-2.0.1/src/ios-circle-outline.svg | 13 - .../ionicons-2.0.1/src/ios-clock-outline.svg | 12 - .../external/ionicons-2.0.1/src/ios-clock.svg | 10 - .../ionicons-2.0.1/src/ios-close-empty.svg | 13 - .../ionicons-2.0.1/src/ios-close-outline.svg | 20 - .../external/ionicons-2.0.1/src/ios-close.svg | 16 - .../src/ios-cloud-download-outline.svg | 19 - .../ionicons-2.0.1/src/ios-cloud-download.svg | 12 - .../ionicons-2.0.1/src/ios-cloud-outline.svg | 12 - .../src/ios-cloud-upload-outline.svg | 20 - .../ionicons-2.0.1/src/ios-cloud-upload.svg | 13 - .../external/ionicons-2.0.1/src/ios-cloud.svg | 9 - .../src/ios-cloudy-night-outline.svg | 24 - .../ionicons-2.0.1/src/ios-cloudy-night.svg | 21 - .../ionicons-2.0.1/src/ios-cloudy-outline.svg | 17 - .../external/ionicons-2.0.1/src/ios-cloudy.svg | 14 - .../ionicons-2.0.1/src/ios-cog-outline.svg | 29 - .../fusion/external/ionicons-2.0.1/src/ios-cog.svg | 23 - .../src/ios-color-filter-outline.svg | 25 - .../ionicons-2.0.1/src/ios-color-filter.svg | 29 - .../ionicons-2.0.1/src/ios-color-wand-outline.svg | 17 - .../external/ionicons-2.0.1/src/ios-color-wand.svg | 16 - .../ionicons-2.0.1/src/ios-compose-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-compose.svg | 13 - .../ionicons-2.0.1/src/ios-contact-outline.svg | 13 - .../external/ionicons-2.0.1/src/ios-contact.svg | 13 - .../ionicons-2.0.1/src/ios-copy-outline.svg | 11 - .../external/ionicons-2.0.1/src/ios-copy.svg | 12 - .../ionicons-2.0.1/src/ios-crop-strong.svg | 12 - .../external/ionicons-2.0.1/src/ios-crop.svg | 12 - .../ionicons-2.0.1/src/ios-download-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-download.svg | 11 - .../external/ionicons-2.0.1/src/ios-drag.svg | 11 - .../ionicons-2.0.1/src/ios-email-outline.svg | 8 - .../external/ionicons-2.0.1/src/ios-email.svg | 11 - .../ionicons-2.0.1/src/ios-eye-outline.svg | 18 - .../fusion/external/ionicons-2.0.1/src/ios-eye.svg | 13 - .../ionicons-2.0.1/src/ios-fastforward-outline.svg | 8 - .../ionicons-2.0.1/src/ios-fastforward.svg | 7 - .../ionicons-2.0.1/src/ios-filing-outline.svg | 9 - .../external/ionicons-2.0.1/src/ios-filing.svg | 11 - .../ionicons-2.0.1/src/ios-film-outline.svg | 9 - .../external/ionicons-2.0.1/src/ios-film.svg | 11 - .../ionicons-2.0.1/src/ios-flag-outline.svg | 13 - .../external/ionicons-2.0.1/src/ios-flag.svg | 11 - .../ionicons-2.0.1/src/ios-flame-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-flame.svg | 11 - .../ionicons-2.0.1/src/ios-flask-outline.svg | 19 - .../external/ionicons-2.0.1/src/ios-flask.svg | 17 - .../ionicons-2.0.1/src/ios-flower-outline.svg | 75 - .../external/ionicons-2.0.1/src/ios-flower.svg | 38 - .../ionicons-2.0.1/src/ios-folder-outline.svg | 11 - .../external/ionicons-2.0.1/src/ios-folder.svg | 13 - .../ionicons-2.0.1/src/ios-football-outline.svg | 20 - .../external/ionicons-2.0.1/src/ios-football.svg | 14 - .../src/ios-game-controller-a-outline.svg | 26 - .../ionicons-2.0.1/src/ios-game-controller-a.svg | 19 - .../src/ios-game-controller-b-outline.svg | 35 - .../ionicons-2.0.1/src/ios-game-controller-b.svg | 23 - .../ionicons-2.0.1/src/ios-gear-outline.svg | 40 - .../external/ionicons-2.0.1/src/ios-gear.svg | 17 - .../ionicons-2.0.1/src/ios-glasses-outline.svg | 12 - .../external/ionicons-2.0.1/src/ios-glasses.svg | 11 - .../ionicons-2.0.1/src/ios-grid-view-outline.svg | 8 - .../external/ionicons-2.0.1/src/ios-grid-view.svg | 11 - .../ionicons-2.0.1/src/ios-heart-outline.svg | 15 - .../external/ionicons-2.0.1/src/ios-heart.svg | 9 - .../external/ionicons-2.0.1/src/ios-help-empty.svg | 12 - .../ionicons-2.0.1/src/ios-help-outline.svg | 22 - .../external/ionicons-2.0.1/src/ios-help.svg | 12 - .../ionicons-2.0.1/src/ios-home-outline.svg | 11 - .../external/ionicons-2.0.1/src/ios-home.svg | 10 - .../ionicons-2.0.1/src/ios-infinite-outline.svg | 17 - .../external/ionicons-2.0.1/src/ios-infinite.svg | 16 - .../ionicons-2.0.1/src/ios-information-empty.svg | 12 - .../ionicons-2.0.1/src/ios-information-outline.svg | 17 - .../ionicons-2.0.1/src/ios-information.svg | 11 - .../ionicons-2.0.1/src/ios-ionic-outline.svg | 18 - .../ionicons-2.0.1/src/ios-keypad-outline.svg | 28 - .../external/ionicons-2.0.1/src/ios-keypad.svg | 20 - .../ionicons-2.0.1/src/ios-lightbulb-outline.svg | 17 - .../external/ionicons-2.0.1/src/ios-lightbulb.svg | 16 - .../ionicons-2.0.1/src/ios-list-outline.svg | 23 - .../external/ionicons-2.0.1/src/ios-list.svg | 11 - .../ionicons-2.0.1/src/ios-location-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-location.svg | 8 - .../ionicons-2.0.1/src/ios-locked-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-locked.svg | 12 - .../ionicons-2.0.1/src/ios-loop-strong.svg | 18 - .../external/ionicons-2.0.1/src/ios-loop.svg | 22 - .../ionicons-2.0.1/src/ios-medical-outline.svg | 10 - .../external/ionicons-2.0.1/src/ios-medical.svg | 8 - .../ionicons-2.0.1/src/ios-medkit-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-medkit.svg | 13 - .../external/ionicons-2.0.1/src/ios-mic-off.svg | 14 - .../ionicons-2.0.1/src/ios-mic-outline.svg | 12 - .../fusion/external/ionicons-2.0.1/src/ios-mic.svg | 12 - .../ionicons-2.0.1/src/ios-minus-empty.svg | 9 - .../ionicons-2.0.1/src/ios-minus-outline.svg | 16 - .../external/ionicons-2.0.1/src/ios-minus.svg | 10 - .../ionicons-2.0.1/src/ios-monitor-outline.svg | 7 - .../external/ionicons-2.0.1/src/ios-monitor.svg | 10 - .../ionicons-2.0.1/src/ios-moon-outline.svg | 15 - .../external/ionicons-2.0.1/src/ios-moon.svg | 13 - .../ionicons-2.0.1/src/ios-more-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-more.svg | 11 - .../ionicons-2.0.1/src/ios-musical-note.svg | 9 - .../ionicons-2.0.1/src/ios-musical-notes.svg | 9 - .../ionicons-2.0.1/src/ios-navigate-outline.svg | 12 - .../external/ionicons-2.0.1/src/ios-navigate.svg | 10 - .../ionicons-2.0.1/src/ios-nutrition-outline.svg | 29 - .../external/ionicons-2.0.1/src/ios-nutrition.svg | 17 - .../ionicons-2.0.1/src/ios-paper-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-paper.svg | 8 - .../ionicons-2.0.1/src/ios-paperplane-outline.svg | 8 - .../external/ionicons-2.0.1/src/ios-paperplane.svg | 10 - .../ionicons-2.0.1/src/ios-partlysunny-outline.svg | 33 - .../ionicons-2.0.1/src/ios-partlysunny.svg | 28 - .../ionicons-2.0.1/src/ios-pause-outline.svg | 10 - .../external/ionicons-2.0.1/src/ios-pause.svg | 10 - .../ionicons-2.0.1/src/ios-paw-outline.svg | 43 - .../fusion/external/ionicons-2.0.1/src/ios-paw.svg | 26 - .../ionicons-2.0.1/src/ios-people-outline.svg | 44 - .../external/ionicons-2.0.1/src/ios-people.svg | 29 - .../ionicons-2.0.1/src/ios-person-outline.svg | 22 - .../external/ionicons-2.0.1/src/ios-person.svg | 13 - .../ionicons-2.0.1/src/ios-personadd-outline.svg | 25 - .../external/ionicons-2.0.1/src/ios-personadd.svg | 16 - .../ionicons-2.0.1/src/ios-photos-outline.svg | 10 - .../external/ionicons-2.0.1/src/ios-photos.svg | 10 - .../ionicons-2.0.1/src/ios-pie-outline.svg | 16 - .../fusion/external/ionicons-2.0.1/src/ios-pie.svg | 11 - .../ionicons-2.0.1/src/ios-pint-outline.svg | 17 - .../external/ionicons-2.0.1/src/ios-pint.svg | 12 - .../ionicons-2.0.1/src/ios-play-outline.svg | 9 - .../external/ionicons-2.0.1/src/ios-play.svg | 9 - .../external/ionicons-2.0.1/src/ios-plus-empty.svg | 9 - .../ionicons-2.0.1/src/ios-plus-outline.svg | 18 - .../external/ionicons-2.0.1/src/ios-plus.svg | 10 - .../ionicons-2.0.1/src/ios-pricetag-outline.svg | 11 - .../external/ionicons-2.0.1/src/ios-pricetag.svg | 11 - .../ionicons-2.0.1/src/ios-pricetags-outline.svg | 12 - .../external/ionicons-2.0.1/src/ios-pricetags.svg | 16 - .../ionicons-2.0.1/src/ios-printer-outline.svg | 12 - .../external/ionicons-2.0.1/src/ios-printer.svg | 17 - .../ionicons-2.0.1/src/ios-pulse-strong.svg | 12 - .../external/ionicons-2.0.1/src/ios-pulse.svg | 12 - .../ionicons-2.0.1/src/ios-rainy-outline.svg | 20 - .../external/ionicons-2.0.1/src/ios-rainy.svg | 17 - .../ionicons-2.0.1/src/ios-recording-outline.svg | 15 - .../external/ionicons-2.0.1/src/ios-recording.svg | 14 - .../ionicons-2.0.1/src/ios-redo-outline.svg | 11 - .../external/ionicons-2.0.1/src/ios-redo.svg | 10 - .../ionicons-2.0.1/src/ios-refresh-empty.svg | 10 - .../ionicons-2.0.1/src/ios-refresh-outline.svg | 15 - .../external/ionicons-2.0.1/src/ios-refresh.svg | 11 - .../external/ionicons-2.0.1/src/ios-reload.svg | 11 - .../src/ios-reverse-camera-outline.svg | 20 - .../ionicons-2.0.1/src/ios-reverse-camera.svg | 15 - .../ionicons-2.0.1/src/ios-rewind-outline.svg | 8 - .../external/ionicons-2.0.1/src/ios-rewind.svg | 7 - .../ionicons-2.0.1/src/ios-rose-outline.svg | 29 - .../external/ionicons-2.0.1/src/ios-rose.svg | 18 - .../ionicons-2.0.1/src/ios-search-strong.svg | 10 - .../external/ionicons-2.0.1/src/ios-search.svg | 10 - .../ionicons-2.0.1/src/ios-settings-strong.svg | 14 - .../external/ionicons-2.0.1/src/ios-settings.svg | 24 - .../ionicons-2.0.1/src/ios-shuffle-strong.svg | 18 - .../external/ionicons-2.0.1/src/ios-shuffle.svg | 20 - .../src/ios-skipbackward-outline.svg | 8 - .../ionicons-2.0.1/src/ios-skipbackward.svg | 7 - .../ionicons-2.0.1/src/ios-skipforward-outline.svg | 8 - .../ionicons-2.0.1/src/ios-skipforward.svg | 7 - .../external/ionicons-2.0.1/src/ios-snowy.svg | 26 - .../ionicons-2.0.1/src/ios-speedometer-outline.svg | 24 - .../ionicons-2.0.1/src/ios-speedometer.svg | 28 - .../external/ionicons-2.0.1/src/ios-star-half.svg | 8 - .../ionicons-2.0.1/src/ios-star-outline.svg | 8 - .../external/ionicons-2.0.1/src/ios-star.svg | 7 - .../ionicons-2.0.1/src/ios-stopwatch-outline.svg | 15 - .../external/ionicons-2.0.1/src/ios-stopwatch.svg | 13 - .../ionicons-2.0.1/src/ios-sunny-outline.svg | 27 - .../external/ionicons-2.0.1/src/ios-sunny.svg | 26 - .../ionicons-2.0.1/src/ios-telephone-outline.svg | 17 - .../external/ionicons-2.0.1/src/ios-telephone.svg | 12 - .../ionicons-2.0.1/src/ios-tennisball-outline.svg | 19 - .../external/ionicons-2.0.1/src/ios-tennisball.svg | 25 - .../src/ios-thunderstorm-outline.svg | 22 - .../ionicons-2.0.1/src/ios-thunderstorm.svg | 17 - .../ionicons-2.0.1/src/ios-time-outline.svg | 36 - .../external/ionicons-2.0.1/src/ios-time.svg | 27 - .../ionicons-2.0.1/src/ios-timer-outline.svg | 11 - .../external/ionicons-2.0.1/src/ios-timer.svg | 12 - .../ionicons-2.0.1/src/ios-toggle-outline.svg | 22 - .../external/ionicons-2.0.1/src/ios-toggle.svg | 16 - .../ionicons-2.0.1/src/ios-trash-outline.svg | 17 - .../external/ionicons-2.0.1/src/ios-trash.svg | 12 - .../ionicons-2.0.1/src/ios-undo-outline.svg | 11 - .../external/ionicons-2.0.1/src/ios-undo.svg | 10 - .../ionicons-2.0.1/src/ios-unlocked-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-unlocked.svg | 12 - .../ionicons-2.0.1/src/ios-upload-outline.svg | 14 - .../external/ionicons-2.0.1/src/ios-upload.svg | 10 - .../ionicons-2.0.1/src/ios-videocam-outline.svg | 12 - .../external/ionicons-2.0.1/src/ios-videocam.svg | 11 - .../ionicons-2.0.1/src/ios-volume-high.svg | 19 - .../external/ionicons-2.0.1/src/ios-volume-low.svg | 7 - .../ionicons-2.0.1/src/ios-wineglass-outline.svg | 15 - .../external/ionicons-2.0.1/src/ios-wineglass.svg | 11 - .../ionicons-2.0.1/src/ios-world-outline.svg | 22 - .../external/ionicons-2.0.1/src/ios-world.svg | 29 - .../fusion/external/ionicons-2.0.1/src/ipad.svg | 10 - .../fusion/external/ionicons-2.0.1/src/iphone.svg | 13 - .../fusion/external/ionicons-2.0.1/src/ipod.svg | 13 - .../app/fusion/external/ionicons-2.0.1/src/jet.svg | 14 - .../app/fusion/external/ionicons-2.0.1/src/key.svg | 14 - .../fusion/external/ionicons-2.0.1/src/knife.svg | 9 - .../fusion/external/ionicons-2.0.1/src/laptop.svg | 10 - .../fusion/external/ionicons-2.0.1/src/leaf.svg | 12 - .../fusion/external/ionicons-2.0.1/src/levels.svg | 16 - .../external/ionicons-2.0.1/src/lightbulb.svg | 21 - .../fusion/external/ionicons-2.0.1/src/link.svg | 15 - .../fusion/external/ionicons-2.0.1/src/load-a.svg | 17 - .../fusion/external/ionicons-2.0.1/src/load-b.svg | 20 - .../fusion/external/ionicons-2.0.1/src/load-c.svg | 21 - .../fusion/external/ionicons-2.0.1/src/load-d.svg | 28 - .../external/ionicons-2.0.1/src/location.svg | 11 - .../ionicons-2.0.1/src/lock-combination.svg | 28 - .../fusion/external/ionicons-2.0.1/src/locked.svg | 11 - .../fusion/external/ionicons-2.0.1/src/log-in.svg | 14 - .../fusion/external/ionicons-2.0.1/src/log-out.svg | 17 - .../fusion/external/ionicons-2.0.1/src/loop.svg | 14 - .../fusion/external/ionicons-2.0.1/src/magnet.svg | 14 - .../fusion/external/ionicons-2.0.1/src/male.svg | 10 - .../app/fusion/external/ionicons-2.0.1/src/man.svg | 12 - .../app/fusion/external/ionicons-2.0.1/src/map.svg | 30 - .../fusion/external/ionicons-2.0.1/src/medkit.svg | 12 - .../fusion/external/ionicons-2.0.1/src/merge.svg | 13 - .../fusion/external/ionicons-2.0.1/src/mic-a.svg | 15 - .../fusion/external/ionicons-2.0.1/src/mic-b.svg | 17 - .../fusion/external/ionicons-2.0.1/src/mic-c.svg | 8 - .../external/ionicons-2.0.1/src/minus-circled.svg | 9 - .../external/ionicons-2.0.1/src/minus-round.svg | 8 - .../fusion/external/ionicons-2.0.1/src/minus.svg | 7 - .../fusion/external/ionicons-2.0.1/src/model-s.svg | 33 - .../fusion/external/ionicons-2.0.1/src/monitor.svg | 12 - .../fusion/external/ionicons-2.0.1/src/more.svg | 12 - .../fusion/external/ionicons-2.0.1/src/mouse.svg | 24 - .../external/ionicons-2.0.1/src/music-note.svg | 10 - .../external/ionicons-2.0.1/src/navicon-round.svg | 14 - .../fusion/external/ionicons-2.0.1/src/navicon.svg | 11 - .../external/ionicons-2.0.1/src/navigate.svg | 7 - .../fusion/external/ionicons-2.0.1/src/network.svg | 12 - .../external/ionicons-2.0.1/src/no-smoking.svg | 33 - .../fusion/external/ionicons-2.0.1/src/nuclear.svg | 18 - .../fusion/external/ionicons-2.0.1/src/outlet.svg | 16 - .../external/ionicons-2.0.1/src/paintbrush.svg | 18 - .../external/ionicons-2.0.1/src/paintbucket.svg | 12 - .../external/ionicons-2.0.1/src/paper-airplane.svg | 13 - .../external/ionicons-2.0.1/src/paperclip.svg | 13 - .../fusion/external/ionicons-2.0.1/src/pause.svg | 12 - .../external/ionicons-2.0.1/src/person-add.svg | 13 - .../external/ionicons-2.0.1/src/person-stalker.svg | 18 - .../fusion/external/ionicons-2.0.1/src/person.svg | 10 - .../external/ionicons-2.0.1/src/pie-graph.svg | 11 - .../app/fusion/external/ionicons-2.0.1/src/pin.svg | 11 - .../external/ionicons-2.0.1/src/pinpoint.svg | 11 - .../fusion/external/ionicons-2.0.1/src/pizza.svg | 20 - .../fusion/external/ionicons-2.0.1/src/plane.svg | 10 - .../fusion/external/ionicons-2.0.1/src/planet.svg | 21 - .../fusion/external/ionicons-2.0.1/src/play.svg | 8 - .../external/ionicons-2.0.1/src/playstation.svg | 27 - .../external/ionicons-2.0.1/src/plus-circled.svg | 10 - .../external/ionicons-2.0.1/src/plus-round.svg | 9 - .../fusion/external/ionicons-2.0.1/src/plus.svg | 7 - .../fusion/external/ionicons-2.0.1/src/podium.svg | 11 - .../fusion/external/ionicons-2.0.1/src/pound.svg | 11 - .../fusion/external/ionicons-2.0.1/src/power.svg | 15 - .../external/ionicons-2.0.1/src/pricetag.svg | 13 - .../external/ionicons-2.0.1/src/pricetags.svg | 18 - .../fusion/external/ionicons-2.0.1/src/printer.svg | 14 - .../external/ionicons-2.0.1/src/pull-request.svg | 16 - .../external/ionicons-2.0.1/src/qr-scanner.svg | 12 - .../fusion/external/ionicons-2.0.1/src/quote.svg | 16 - .../external/ionicons-2.0.1/src/radio-waves.svg | 25 - .../fusion/external/ionicons-2.0.1/src/record.svg | 7 - .../fusion/external/ionicons-2.0.1/src/refresh.svg | 15 - .../external/ionicons-2.0.1/src/reply-all.svg | 12 - .../fusion/external/ionicons-2.0.1/src/reply.svg | 9 - .../external/ionicons-2.0.1/src/ribbon-a.svg | 14 - .../external/ionicons-2.0.1/src/ribbon-b.svg | 18 - .../external/ionicons-2.0.1/src/sad-outline.svg | 28 - .../app/fusion/external/ionicons-2.0.1/src/sad.svg | 20 - .../external/ionicons-2.0.1/src/scissors.svg | 23 - .../fusion/external/ionicons-2.0.1/src/search.svg | 10 - .../external/ionicons-2.0.1/src/settings.svg | 18 - .../fusion/external/ionicons-2.0.1/src/share.svg | 11 - .../fusion/external/ionicons-2.0.1/src/shuffle.svg | 11 - .../external/ionicons-2.0.1/src/skip-backward.svg | 15 - .../external/ionicons-2.0.1/src/skip-forward.svg | 15 - .../ionicons-2.0.1/src/social-android-outline.svg | 29 - .../external/ionicons-2.0.1/src/social-android.svg | 22 - .../ionicons-2.0.1/src/social-angular-outline.svg | 11 - .../external/ionicons-2.0.1/src/social-angular.svg | 11 - .../ionicons-2.0.1/src/social-apple-outline.svg | 20 - .../external/ionicons-2.0.1/src/social-apple.svg | 14 - .../ionicons-2.0.1/src/social-bitcoin-outline.svg | 27 - .../external/ionicons-2.0.1/src/social-bitcoin.svg | 14 - .../ionicons-2.0.1/src/social-buffer-outline.svg | 24 - .../external/ionicons-2.0.1/src/social-buffer.svg | 18 - .../ionicons-2.0.1/src/social-chrome-outline.svg | 17 - .../external/ionicons-2.0.1/src/social-chrome.svg | 22 - .../ionicons-2.0.1/src/social-codepen-outline.svg | 26 - .../external/ionicons-2.0.1/src/social-codepen.svg | 26 - .../ionicons-2.0.1/src/social-css3-outline.svg | 12 - .../external/ionicons-2.0.1/src/social-css3.svg | 14 - .../src/social-designernews-outline.svg | 18 - .../ionicons-2.0.1/src/social-designernews.svg | 18 - .../ionicons-2.0.1/src/social-dribbble-outline.svg | 15 - .../ionicons-2.0.1/src/social-dribbble.svg | 26 - .../ionicons-2.0.1/src/social-dropbox-outline.svg | 13 - .../external/ionicons-2.0.1/src/social-dropbox.svg | 13 - .../ionicons-2.0.1/src/social-euro-outline.svg | 19 - .../external/ionicons-2.0.1/src/social-euro.svg | 12 - .../ionicons-2.0.1/src/social-facebook-outline.svg | 9 - .../ionicons-2.0.1/src/social-facebook.svg | 8 - .../src/social-foursquare-outline.svg | 22 - .../ionicons-2.0.1/src/social-foursquare.svg | 20 - .../ionicons-2.0.1/src/social-freebsd-devil.svg | 22 - .../ionicons-2.0.1/src/social-github-outline.svg | 24 - .../external/ionicons-2.0.1/src/social-github.svg | 14 - .../ionicons-2.0.1/src/social-google-outline.svg | 19 - .../external/ionicons-2.0.1/src/social-google.svg | 20 - .../src/social-googleplus-outline.svg | 18 - .../ionicons-2.0.1/src/social-googleplus.svg | 17 - .../src/social-hackernews-outline.svg | 12 - .../ionicons-2.0.1/src/social-hackernews.svg | 9 - .../ionicons-2.0.1/src/social-html5-outline.svg | 13 - .../external/ionicons-2.0.1/src/social-html5.svg | 9 - .../src/social-instagram-outline.svg | 12 - .../ionicons-2.0.1/src/social-instagram.svg | 18 - .../src/social-javascript-outline.svg | 27 - .../ionicons-2.0.1/src/social-javascript.svg | 17 - .../ionicons-2.0.1/src/social-linkedin-outline.svg | 22 - .../ionicons-2.0.1/src/social-linkedin.svg | 13 - .../ionicons-2.0.1/src/social-markdown.svg | 14 - .../external/ionicons-2.0.1/src/social-nodejs.svg | 26 - .../external/ionicons-2.0.1/src/social-octocat.svg | 28 - .../src/social-pinterest-outline.svg | 14 - .../ionicons-2.0.1/src/social-pinterest.svg | 15 - .../external/ionicons-2.0.1/src/social-python.svg | 21 - .../ionicons-2.0.1/src/social-reddit-outline.svg | 26 - .../external/ionicons-2.0.1/src/social-reddit.svg | 18 - .../ionicons-2.0.1/src/social-rss-outline.svg | 16 - .../external/ionicons-2.0.1/src/social-rss.svg | 12 - .../external/ionicons-2.0.1/src/social-sass.svg | 35 - .../ionicons-2.0.1/src/social-skype-outline.svg | 26 - .../external/ionicons-2.0.1/src/social-skype.svg | 20 - .../ionicons-2.0.1/src/social-snapchat-outline.svg | 42 - .../ionicons-2.0.1/src/social-snapchat.svg | 31 - .../ionicons-2.0.1/src/social-tumblr-outline.svg | 13 - .../external/ionicons-2.0.1/src/social-tumblr.svg | 10 - .../external/ionicons-2.0.1/src/social-tux.svg | 53 - .../ionicons-2.0.1/src/social-twitch-outline.svg | 13 - .../external/ionicons-2.0.1/src/social-twitch.svg | 9 - .../ionicons-2.0.1/src/social-twitter-outline.svg | 19 - .../external/ionicons-2.0.1/src/social-twitter.svg | 12 - .../ionicons-2.0.1/src/social-usd-outline.svg | 44 - .../external/ionicons-2.0.1/src/social-usd.svg | 24 - .../ionicons-2.0.1/src/social-vimeo-outline.svg | 23 - .../external/ionicons-2.0.1/src/social-vimeo.svg | 18 - .../ionicons-2.0.1/src/social-whatsapp-outline.svg | 25 - .../ionicons-2.0.1/src/social-whatsapp.svg | 18 - .../ionicons-2.0.1/src/social-windows-outline.svg | 17 - .../external/ionicons-2.0.1/src/social-windows.svg | 17 - .../src/social-wordpress-outline.svg | 16 - .../ionicons-2.0.1/src/social-wordpress.svg | 20 - .../ionicons-2.0.1/src/social-yahoo-outline.svg | 10 - .../external/ionicons-2.0.1/src/social-yahoo.svg | 8 - .../ionicons-2.0.1/src/social-yen-outline.svg | 9 - .../external/ionicons-2.0.1/src/social-yen.svg | 8 - .../ionicons-2.0.1/src/social-youtube-outline.svg | 22 - .../external/ionicons-2.0.1/src/social-youtube.svg | 12 - .../ionicons-2.0.1/src/soup-can-outline.svg | 28 - .../external/ionicons-2.0.1/src/soup-can.svg | 16 - .../external/ionicons-2.0.1/src/speakerphone.svg | 19 - .../external/ionicons-2.0.1/src/speedometer.svg | 15 - .../fusion/external/ionicons-2.0.1/src/spoon.svg | 10 - .../fusion/external/ionicons-2.0.1/src/star.svg | 7 - .../external/ionicons-2.0.1/src/stats-bars.svg | 12 - .../fusion/external/ionicons-2.0.1/src/steam.svg | 20 - .../fusion/external/ionicons-2.0.1/src/stop.svg | 8 - .../external/ionicons-2.0.1/src/thermometer.svg | 11 - .../external/ionicons-2.0.1/src/thumbsdown.svg | 13 - .../external/ionicons-2.0.1/src/thumbsup.svg | 13 - .../external/ionicons-2.0.1/src/toggle-filled.svg | 11 - .../fusion/external/ionicons-2.0.1/src/toggle.svg | 12 - .../external/ionicons-2.0.1/src/transgender.svg | 12 - .../fusion/external/ionicons-2.0.1/src/trash-a.svg | 10 - .../fusion/external/ionicons-2.0.1/src/trash-b.svg | 13 - .../fusion/external/ionicons-2.0.1/src/trophy.svg | 16 - .../external/ionicons-2.0.1/src/tshirt-outline.svg | 11 - .../fusion/external/ionicons-2.0.1/src/tshirt.svg | 8 - .../external/ionicons-2.0.1/src/umbrella.svg | 18 - .../external/ionicons-2.0.1/src/university.svg | 11 - .../external/ionicons-2.0.1/src/unlocked.svg | 10 - .../fusion/external/ionicons-2.0.1/src/upload.svg | 9 - .../app/fusion/external/ionicons-2.0.1/src/usb.svg | 22 - .../external/ionicons-2.0.1/src/videocamera.svg | 11 - .../external/ionicons-2.0.1/src/volume-high.svg | 15 - .../external/ionicons-2.0.1/src/volume-low.svg | 11 - .../external/ionicons-2.0.1/src/volume-medium.svg | 13 - .../external/ionicons-2.0.1/src/volume-mute.svg | 14 - .../fusion/external/ionicons-2.0.1/src/wand.svg | 17 - .../external/ionicons-2.0.1/src/waterdrop.svg | 11 - .../fusion/external/ionicons-2.0.1/src/wifi.svg | 16 - .../external/ionicons-2.0.1/src/wineglass.svg | 21 - .../fusion/external/ionicons-2.0.1/src/woman.svg | 13 - .../fusion/external/ionicons-2.0.1/src/wrench.svg | 11 - .../fusion/external/ionicons-2.0.1/src/xbox.svg | 21 - .../app/fusion/external/utils/js/browserCheck.js | 24 - .../scripts/controllers/nbook-framecontroller.js | 34 - .../scripts/controllers/nbookController.js | 179 - .../scripts/controllers/notebookFrameController.js | 65 - .../scripts/view-models/notebook-frame.html | 85 - .../scripts/view-models/notebook-viz.html | 26 - .../scripts/view-models/notebook.htm | 54 - .../scripts/view-models/notebookInputs.html | 90 - .../fusion/scripts/controllers/adminController.js | 65 - .../fusion/scripts/controllers/admin_menu_edit.js | 230 - .../fusion/scripts/controllers/ase-controller.js | 22 - .../scripts/controllers/broadcast-controller.js | 79 - .../controllers/broadcast-list-controller.js | 120 - .../controllers/collaborate-list-controller.js | 63 - .../controllers/fn_menu_add_popup_controller.js | 281 - .../scripts/controllers/jcs-admin-controller.js | 83 - .../scripts/controllers/modelpopupController.js | 40 - .../scripts/controllers/post-search-controller.js | 202 - .../scripts/controllers/profile-controller.js | 286 - .../controllers/profile-search-controller.js | 80 - .../scripts/controllers/profileController.js | 38 - .../fusion/scripts/controllers/role-controller.js | 226 - .../controllers/role-function-list-controller.js | 157 - .../scripts/controllers/role-list-controller.js | 102 - .../controllers/rolefunctionpopupController.js | 84 - .../controllers/rolepopupmodelController.js | 205 - .../scripts/controllers/self-profile-controller.js | 284 - .../scripts/controllers/usage-list-controller.js | 41 - .../scripts/controllers/workflows/workflowApp.js | 24 - .../controllers/workflows/workflowController.js | 509 - .../controllers/workflows/workflowRouting.js | 26 - .../webapp/app/fusion/scripts/directives/footer.js | 30 - .../webapp/app/fusion/scripts/directives/header.js | 504 - .../app/fusion/scripts/directives/leftMenu.js | 203 - .../app/fusion/scripts/services/adminService.js | 160 - .../app/fusion/scripts/services/headerService.js | 89 - .../app/fusion/scripts/services/leftMenuService.js | 54 - .../app/fusion/scripts/services/profileService.js | 98 - .../app/fusion/scripts/services/userInfoService.js | 51 - .../app/fusion/scripts/socket/peerBroadcast.js | 122 - .../app/fusion/scripts/utils/page-resource.js | 95 - .../scripts/view-models/admin-page/admin.html | 115 - .../scripts/view-models/admin-page/profile.html | 50 - .../app/fusion/scripts/view-models/footer.html | 42 - .../app/fusion/scripts/view-models/header.html | 186 - .../app/fusion/scripts/view-models/left_menu.html | 41 - .../view-models/profile-page/admin_menu_edit.html | 175 - .../view-models/profile-page/broadcast.html | 61 - .../view-models/profile-page/broadcast_list.html | 71 - .../view-models/profile-page/collaborate_list.html | 57 - .../view-models/profile-page/jcs_admin.html | 87 - .../view-models/profile-page/popup_modal.html | 282 - .../profile-page/popup_modal_fn_menu_add.html | 155 - .../profile-page/popup_modal_fn_menu_edit.html | 148 - .../view-models/profile-page/popup_modal_role.html | 82 - .../profile-page/popup_modal_rolefunction.html | 46 - .../view-models/profile-page/post_search.html | 139 - .../view-models/profile-page/profile_detail.html | 188 - .../view-models/profile-page/profile_search.html | 72 - .../scripts/view-models/profile-page/role.html | 118 - .../profile-page/role_function_list.html | 88 - .../view-models/profile-page/role_list.html | 61 - .../view-models/profile-page/self_profile.html | 183 - .../view-models/profile-page/usage_list.html | 64 - .../view-models/workflows/workflow-landing.html | 130 - .../view-models/workflows/workflow-listing.html | 85 - .../view-models/workflows/workflow-new.html | 108 - .../view-models/workflows/workflow-preview.html | 36 - .../view-models/workflows/workflow-remove.html | 38 - .../view-models/workflows/workflow-schedule.html | 116 - .../fusion/scripts/webrtc/RTCMultiConnection.js | 6788 --- .../main/webapp/app/fusion/styles/fusion-sunny.css | 362 - .../app/fusion/styles/workflows/workflows.css | 50 - .../drools/controller/drools-list-controller.js | 62 - .../drools/controller/drools-view-controller.js | 64 - .../drools/controller/droolsController.js | 30 - .../app/fusionapp/drools/services/droolsService.js | 76 - .../fusionapp/drools/view-models/droolsList.html | 47 - .../drools/view-models/droolsSinglePage.html | 92 - .../fusionapp/drools/view-models/droolsView.html | 61 - .../scripts/controller/sample-page-controller.js | 80 - .../controller/sample-page-iframe-controller.js | 23 - .../scripts/controller/sampleController.js | 30 - .../app/fusionapp/scripts/view-models/sample.html | 60 - .../scripts/view-models/sampleWithIframe.html | 22 - .../scripts/view-models/singlePageSample.html | 87 - .../main/webapp/static/fusion/css/fusion-sunny.css | 362 - .../main/webapp/static/fusion/css/jquery-ui.css | 1225 - .../fusion/css/layout/layout-default-latest.css | 224 - .../src/main/webapp/static/fusion/images/Rlogo.jpg | Bin 3173 -> 0 bytes .../src/main/webapp/static/fusion/images/Thumbs.db | Bin 102912 -> 0 bytes .../webapp/static/fusion/images/action_icon.png | Bin 2388 -> 0 bytes .../static/fusion/images/action_list_spacer.gif | Bin 73 -> 0 bytes .../main/webapp/static/fusion/images/active.png | Bin 682 -> 0 bytes .../src/main/webapp/static/fusion/images/add.png | Bin 352 -> 0 bytes .../static/fusion/images/add_tool_button.png | Bin 31105 -> 0 bytes .../main/webapp/static/fusion/images/addicon.png | Bin 463 -> 0 bytes .../static/fusion/images/application_window_bg.jpg | Bin 914 -> 0 bytes .../webapp/static/fusion/images/backButton.png | Bin 816 -> 0 bytes .../webapp/static/fusion/images/blueButton.png | Bin 1468 -> 0 bytes .../main/webapp/static/fusion/images/bubble.png | Bin 662 -> 0 bytes .../src/main/webapp/static/fusion/images/cache.png | Bin 1081 -> 0 bytes .../main/webapp/static/fusion/images/calendar.gif | Bin 929 -> 0 bytes .../main/webapp/static/fusion/images/chevron.png | Bin 252 -> 0 bytes .../static/fusion/images/close_container.gif | Bin 85 -> 0 bytes .../webapp/static/fusion/images/collapsed-icon.png | Bin 1379 -> 0 bytes .../main/webapp/static/fusion/images/column-bg.png | Bin 165 -> 0 bytes .../webapp/static/fusion/images/customers-add.png | Bin 755 -> 0 bytes .../static/fusion/images/customers-search.png | Bin 976 -> 0 bytes .../main/webapp/static/fusion/images/customers.png | Bin 749 -> 0 bytes .../main/webapp/static/fusion/images/decrypted.png | Bin 628 -> 0 bytes .../webapp/static/fusion/images/error_type.gif | Bin 398 -> 0 bytes .../static/fusion/images/excelicon_multi.gif | Bin 1028 -> 0 bytes .../webapp/static/fusion/images/expanded-icon.png | Bin 1372 -> 0 bytes .../main/webapp/static/fusion/images/file-add.png | Bin 675 -> 0 bytes .../webapp/static/fusion/images/file_save-all.png | Bin 610 -> 0 bytes .../webapp/static/fusion/images/filter_icon.png | Bin 29069 -> 0 bytes .../webapp/static/fusion/images/folder_add.png | Bin 772 -> 0 bytes .../webapp/static/fusion/images/folder_closed.png | Bin 559 -> 0 bytes .../webapp/static/fusion/images/folder_delete.png | Bin 767 -> 0 bytes .../webapp/static/fusion/images/folder_edit.png | Bin 829 -> 0 bytes .../webapp/static/fusion/images/folder_open.png | Bin 632 -> 0 bytes .../webapp/static/fusion/images/folder_user.png | Bin 887 -> 0 bytes .../main/webapp/static/fusion/images/funnel.png | Bin 543 -> 0 bytes .../main/webapp/static/fusion/images/fusion.gif | Bin 8821 -> 0 bytes .../webapp/static/fusion/images/grayButton.png | Bin 1361 -> 0 bytes .../static/fusion/images/gray_add_tool_button.png | Bin 30883 -> 0 bytes .../webapp/static/fusion/images/headerChatIcon.png | Bin 465 -> 0 bytes .../static/fusion/images/icon_remove_all.gif | Bin 982 -> 0 bytes .../main/webapp/static/fusion/images/inactive.png | Bin 842 -> 0 bytes .../main/webapp/static/fusion/images/info_type.gif | Bin 291 -> 0 bytes .../webapp/static/fusion/images/leftButton.png | Bin 681 -> 0 bytes .../webapp/static/fusion/images/loading_bar.gif | Bin 28954 -> 0 bytes .../webapp/static/fusion/images/login_button.gif | Bin 1222 -> 0 bytes .../src/main/webapp/static/fusion/images/m1.gif | Bin 636 -> 0 bytes .../src/main/webapp/static/fusion/images/mail.png | Bin 449 -> 0 bytes .../src/main/webapp/static/fusion/images/map.png | Bin 611 -> 0 bytes .../static/fusion/images/no_favorites_star.png | Bin 2794 -> 0 bytes .../main/webapp/static/fusion/images/note-add.png | Bin 589 -> 0 bytes .../webapp/static/fusion/images/note-search.png | Bin 876 -> 0 bytes .../src/main/webapp/static/fusion/images/note.png | Bin 583 -> 0 bytes .../src/main/webapp/static/fusion/images/notes.png | Bin 673 -> 0 bytes .../main/webapp/static/fusion/images/offline.png | Bin 3483 -> 0 bytes .../webapp/static/fusion/images/offlineMsg.gif | Bin 1004 -> 0 bytes .../main/webapp/static/fusion/images/online.png | Bin 888 -> 0 bytes .../src/main/webapp/static/fusion/images/page.gif | Bin 131 -> 0 bytes .../webapp/static/fusion/images/pagination.png | Bin 724 -> 0 bytes .../static/fusion/images/panel-e-w-toggle.png | Bin 459 -> 0 bytes .../static/fusion/images/panel-n-s-toggle.png | Bin 335 -> 0 bytes .../src/main/webapp/static/fusion/images/pix.gif | Bin 49 -> 0 bytes .../main/webapp/static/fusion/images/printer.gif | Bin 1036 -> 0 bytes .../main/webapp/static/fusion/images/profile.png | Bin 462 -> 0 bytes .../static/fusion/images/results-first-active.png | Bin 545 -> 0 bytes .../fusion/images/results-first-disabled.png | Bin 421 -> 0 bytes .../static/fusion/images/results-last-active.png | Bin 541 -> 0 bytes .../static/fusion/images/results-last-disabled.png | Bin 421 -> 0 bytes .../static/fusion/images/results-next-active.png | Bin 416 -> 0 bytes .../static/fusion/images/results-next-disabled.png | Bin 326 -> 0 bytes .../static/fusion/images/results-prev-active.png | Bin 421 -> 0 bytes .../static/fusion/images/results-prev-disabled.png | Bin 322 -> 0 bytes .../webapp/static/fusion/images/resultset_last.png | Bin 506 -> 0 bytes .../static/fusion/images/resultset_previous.png | Bin 381 -> 0 bytes .../webapp/static/fusion/images/return_to_top.gif | Bin 846 -> 0 bytes .../webapp/static/fusion/images/rightButton.png | Bin 731 -> 0 bytes .../webapp/static/fusion/images/search_profile.png | Bin 880 -> 0 bytes .../main/webapp/static/fusion/images/sort_asc.gif | Bin 57 -> 0 bytes .../main/webapp/static/fusion/images/sort_desc.gif | Bin 58 -> 0 bytes .../main/webapp/static/fusion/images/spacer.gif | Bin 43 -> 0 bytes .../webapp/static/fusion/images/success_type.gif | Bin 260 -> 0 bytes .../main/webapp/static/fusion/images/swoosh.gif | Bin 14250 -> 0 bytes .../main/webapp/static/fusion/images/tab-hm.png | Bin 249 -> 0 bytes .../main/webapp/static/fusion/images/tab-v-hm.png | Bin 317 -> 0 bytes .../src/main/webapp/static/fusion/images/tab.png | Bin 343 -> 0 bytes .../main/webapp/static/fusion/images/table-add.png | Bin 3314 -> 0 bytes .../webapp/static/fusion/images/table-delete.png | Bin 3342 -> 0 bytes .../webapp/static/fusion/images/table-edit.png | Bin 3348 -> 0 bytes .../src/main/webapp/static/fusion/images/table.png | Bin 496 -> 0 bytes .../main/webapp/static/fusion/images/tabs-bg.png | Bin 147 -> 0 bytes .../webapp/static/fusion/images/toolButton.gif | Bin 414 -> 0 bytes .../webapp/static/fusion/images/toolButton.png | Bin 531 -> 0 bytes .../main/webapp/static/fusion/images/toolbar.png | Bin 171 -> 0 bytes .../src/main/webapp/static/fusion/images/users.png | Bin 938 -> 0 bytes .../webapp/static/fusion/images/warning_type.gif | Bin 1055 -> 0 bytes .../main/webapp/static/fusion/images/webphone.ico | Bin 241 -> 0 bytes .../webapp/static/fusion/images/whiteButton.png | Bin 1430 -> 0 bytes .../main/webapp/static/fusion/raptor/css/ral.css | 1437 - .../webapp/static/fusion/raptor/d3/js/intro.js | 1 - .../static/fusion/raptor/ebz/report_run.html | 67 - .../webapp/static/fusion/raptor/ebz/report_run.js | 293 - .../static/fusion/raptor/ebz/report_search.html | 34 - .../static/fusion/raptor/ebz/report_search.js | 136 - .../static/fusion/raptor/js/other_scripts.js | 331 - .../webapp/static/fusion/raptor/uigrid/ui-grid.js | 26735 ------------ .../webapp/static/fusion/sample/css/welcome.css | 169 - .../sdk-app/src/main/webapp/static/js/search.js | 829 - .../java/org/openecomp/portalapp/SanityTest.java | 20 - .../controller/CollaborationControllerTest.java | 27 - .../openecomp/portalapp/controller/NetMapTest.java | 19 - .../portalapp/service/ProfileServiceTest.java | 37 - .../core/MockApplicationContextTestSuite.java | 126 - .../services/WorkflowScheduleServiceTest.java | 41 - ecomp-sdk/sdk-workflow/.gitignore | 1 - ecomp-sdk/sdk-workflow/README.md | 7 - ecomp-sdk/sdk-workflow/pom.xml | 111 - .../controller/NotebookController.java | 54 - .../controller/NotebookTestController.java | 56 - .../controller/RNoteBookController.java | 84 - .../domain/RNoteBookCredentials.java | 93 - .../service/RNoteBookIntegrationServiceImpl.java | 144 - .../workflow/dao/HibernateConfiguration.java | 20 - .../portalsdk/workflow/models/Workflow.java | 202 - .../services/WorkflowScheduleExecutor.java | 108 - .../workflow/services/WorkflowService.java | 35 - ecomp-sdk/thirdparty/.gitignore | 1 - ecomp-sdk/thirdparty/README.md | 23 - ecomp-sdk/thirdparty/pom.xml | 93 - .../core/onboarding/client/ECOMPSSOFilter.java | 77 - .../core/onboarding/client/SecureServlet.java | 61 - .../core/onboarding/client/UnSecureServlet.java | 61 - .../core/onboarding/crossapi/CipherUtil.java | 125 - .../core/onboarding/crossapi/ECOMPSSO.java | 238 - .../onboarding/crossapi/IPortalRestAPIService.java | 133 - .../onboarding/crossapi/IPortalUebAPIService.java | 46 - .../onboarding/crossapi/PortalAPIException.java | 49 - .../onboarding/crossapi/PortalAPIResponse.java | 58 - .../onboarding/crossapi/PortalApiConstants.java | 62 - .../onboarding/crossapi/PortalApiProperties.java | 98 - .../onboarding/crossapi/PortalRestAPIProxy.java | 498 - .../crossapi/PortalTimeoutBindingListener.java | 52 - .../onboarding/crossapi/PortalTimeoutHandler.java | 419 - .../core/onboarding/crossapi/PortalTimeoutVO.java | 63 - .../onboarding/crossapi/SessionCommunication.java | 161 - .../onboarding/crossapi/UserContextListener.java | 52 - .../onboarding/crossapi/UserSessionListener.java | 84 - .../core/onboarding/rest/FavoritesClient.java | 51 - .../core/onboarding/rest/FunctionalMenuClient.java | 54 - .../core/onboarding/rest/RestWebServiceClient.java | 178 - .../portalsdk/core/onboarding/ueb/Consumer.java | 164 - .../core/onboarding/ueb/FunctionalMenu.java | 61 - .../portalsdk/core/onboarding/ueb/Helper.java | 64 - .../portalsdk/core/onboarding/ueb/Publisher.java | 124 - .../core/onboarding/ueb/PublisherList.java | 77 - .../core/onboarding/ueb/TopicManager.java | 121 - .../core/onboarding/ueb/UebException.java | 65 - .../portalsdk/core/onboarding/ueb/UebManager.java | 358 - .../portalsdk/core/onboarding/ueb/UebMsg.java | 119 - .../portalsdk/core/onboarding/ueb/UebMsgTypes.java | 28 - .../onboarding/ueb/WaitingRequestersQueueList.java | 73 - .../portalsdk/core/restful/domain/EcompRole.java | 87 - .../portalsdk/core/restful/domain/EcompUser.java | 197 - .../core/restful/domain/SharedContext.java | 300 - 4480 files changed, 458113 insertions(+), 301201 deletions(-) delete mode 100644 ecomp-sdk/LICENSE.txt create mode 100644 ecomp-sdk/epsdk-analytics/.gitignore create mode 100644 ecomp-sdk/epsdk-analytics/README.md create mode 100644 ecomp-sdk/epsdk-analytics/license/licenses.properties create mode 100644 ecomp-sdk/epsdk-analytics/license/my_license/header.txt create mode 100644 ecomp-sdk/epsdk-analytics/license/my_license/license.txt create mode 100644 ecomp-sdk/epsdk-analytics/pom.xml create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/AntBuild.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/RaptorObject.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/config/ConfigLoader.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Action.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionHandler.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionMapping.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Controller.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ErrorHandler.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardProcessor.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequence.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceCrossTab.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceDashboard.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceLinear.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedCrossTab.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedHive.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinear.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinearDatamining.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorException.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorRuntimeException.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorSchedularException.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/error/ReportSQLException.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/error/UserAccessException.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserDefinedException.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/error/ValidationException.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/Line.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineCollection.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineInfo.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/ColorProperties.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GMapProperties.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GeoCoordinate.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/MapConstant.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/NovaMap.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/layer/SwingLayer.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/Node.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeCollection.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeInfo.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/MapUtils.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/SwingWorker.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/DataCache.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportHandler.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportLoader.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/SearchHandler.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/base/ChartSeqComparator.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameColLookup.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameList.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameLookup.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameSql.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameValue.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/NameComparator.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderBySeqComparator.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderSeqComparator.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportSecurity.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportWrapper.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DBColumnInfo.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DrillDownParamDef.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/definition/Marker.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportDefinition.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportLogEntry.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportMap.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportSchedule.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/SecurityEntry.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableJoin.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableSource.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ColumnEditJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ColumnJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/DefinitionJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ElementJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/FormEditJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/IdNameBooleanJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ImportJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ListJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/MessageJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/NameBooleanJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/QueryJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/QueryResultJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/SearchFieldJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/WizardJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PageEvent.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfBean.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfReportHandler.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/BarChartOptions.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CategoryAxisJSON.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartD3Helper.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSON.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSONHelper.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartWebRuntime.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CommonChartOptions.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ErrorJSONRuntime.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FlexTimeSeriesChartOptions.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormField.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormatProcessor.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/Item.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/LookupDBInfo.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/RangeAxisJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportFormFields.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportJSONRuntime.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportParamDateValueParser.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportParamValues.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportParamValuesForPDFExcel.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportRuntime.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/TimeSeriesChartOptions.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/VisualManager.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/ReportSearchResult.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/ReportSearchResultJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResult.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResultColumn.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResultField.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResultJSON.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResultRow.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/scheduler/SchedulerUtil.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/scheduler/SendEmail.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/scheduler/SendNotifications.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/AppUtils.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/system/ConnectionUtils.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/DbUtils.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/ExecuteQuery.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/Globals.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/IAppUtils.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/IDbUtils.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/RDbUtils.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/system/RemDbUtils.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/AntBuild.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/AppUtils.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/DbUtils.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/RemoteDbUtils.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/AdapterSessionFactoryContainer.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/DateUtils.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/FusionAdapter.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/IdName.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/Item.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/Lookup.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/RaptorAdapter.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/SpringContext.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/controller/FileServletController.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/domain/CR_Report.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/domain/QuickLink.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/domain/RaptorSearch.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/domain/ReportInfo.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/service/RaptorService.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/service/RaptorServiceImpl.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/web/RaptorController.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/web/RaptorControllerAsync.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/web/ReportsSearchListController.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/AppConstants.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/DataSet.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/ExcelColorDef.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/HtmlStripper.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/util/Log.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/util/RemDbInfo.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/util/SQLCorrector.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/Scheduler.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/Utils.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/XSSFilter.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/jar/ExtractJar.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/upgrade/SystemUpgrade.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ColumnHeader.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ColumnHeaderRow.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/view/ColumnVisual.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/CrossTabColumnValues.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/CrossTabOrderManager.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/CrossTabTotalValue.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/DataRow.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/DataValue.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/view/HtmlFormatter.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ReportColumnHeaderRows.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ReportData.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ReportDataRows.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ReportRowHeaderCols.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/RowHeader.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/RowHeaderCol.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ChartAdditionalOptions.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ChartDrillFormfield.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ChartDrillOptions.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ColFilterList.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ColFilterType.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/CustomReportType.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DashboardEditorList.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DashboardEditorReport.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DashboardReports.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DashboardReportsNew.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DataColumnList.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DataColumnType.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DataSourceList.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DataSourceType.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DataminingOptions.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/FormFieldList.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/FormFieldType.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/FormatList.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/FormatType.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/JavascriptItemType.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/JavascriptList.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/Marker.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ObjectFactory.java (100%) rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/PDFAdditionalOptions.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/PredefinedValueList.java create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ReportMap.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/Reports.java (100%) create mode 100644 ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/SemaphoreList.java rename ecomp-sdk/{sdk-analytics => epsdk-analytics}/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/SemaphoreType.java (100%) create mode 100644 ecomp-sdk/epsdk-app-common/.gitignore create mode 100644 ecomp-sdk/epsdk-app-common/README.md create mode 100644 ecomp-sdk/epsdk-app-common/db-scripts/EcompSdkDDLMySql_1707_Common.sql create mode 100644 ecomp-sdk/epsdk-app-common/db-scripts/EcompSdkDMLMySql_1707_Common.sql create mode 100644 ecomp-sdk/epsdk-app-common/db-scripts/readme.txt create mode 100644 ecomp-sdk/epsdk-app-common/pom.xml create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/AdminController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/AngularAdminController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/CacheAdminController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/FavoritesController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/FnMenuController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/FuncMenuController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/LogoutController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/ManifestController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/MenuListController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/PostSearchController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/ProfileController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/ProfileSearchController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/RoleController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/RoleFunctionListController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/RoleListController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/SDKLoginController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/SingleSignOnController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/UsageListController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/UserProfileController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/WelcomeController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/core/package-info.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/AngularSinglePageController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/BroadcastController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/BroadcastListController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/CallflowController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/CamundaCockpitController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/CollaborateListController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/CollaborationController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/DS2SampleController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/ElasticSearchController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/ElementModelController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/LeafletMapContoller.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/NetMapController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/PostDroolsController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/ReportDashboardController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/SamplePageController.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/controller/sample/package-info.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/model/Result.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/scheduler/LogJob.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/scheduler/LogRegistry.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/service/IAdminAuthExtension.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/service/OnBoardingApiServiceImpl.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/openecomp/portalapp/util/CustomLoggingFilter.java create mode 100644 ecomp-sdk/epsdk-app-common/src/main/webapp/app/fusion/external/d3/js/intro.js create mode 100644 ecomp-sdk/epsdk-app-common/src/test/java/org/openecomp/portalapp/SanityTest.java create mode 100644 ecomp-sdk/epsdk-app-common/src/test/java/org/openecomp/portalapp/controller/CollaborationControllerTest.java create mode 100644 ecomp-sdk/epsdk-app-common/src/test/java/org/openecomp/portalapp/controller/NetMapTest.java create mode 100644 ecomp-sdk/epsdk-app-common/src/test/java/org/openecomp/portalapp/core/MockApplicationContextTestSuite.java create mode 100644 ecomp-sdk/epsdk-app-common/src/test/java/org/openecomp/portalapp/service/ProfileServiceTest.java create mode 100644 ecomp-sdk/epsdk-app-common/src/test/java/org/openecomp/portalapp/workflow/services/WorkflowScheduleServiceTest.java create mode 100644 ecomp-sdk/epsdk-app-os/.gitignore create mode 100644 ecomp-sdk/epsdk-app-os/README.md create mode 100644 ecomp-sdk/epsdk-app-os/db-scripts/EcompSdkDDLMySql_1707_OS.sql create mode 100644 ecomp-sdk/epsdk-app-os/db-scripts/EcompSdkDMLMySql_1707_OS.sql create mode 100644 ecomp-sdk/epsdk-app-os/db-scripts/EcompSdkMySql_Rollback_1707_to_1610.2_OS.sql create mode 100644 ecomp-sdk/epsdk-app-os/db-scripts/EcompSdkMySql_Upgrade_1610.2_to_1707_OS.sql create mode 100644 ecomp-sdk/epsdk-app-os/db-scripts/readme.txt create mode 100644 ecomp-sdk/epsdk-app-os/distribution.xml create mode 100644 ecomp-sdk/epsdk-app-os/pom.xml create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/openecomp/portalapp/conf/ExternalAppConfig.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/openecomp/portalapp/conf/ExternalAppInitializer.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/openecomp/portalapp/conf/HibernateMappingLocations.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/openecomp/portalapp/lm/FusionLicenseManagerImpl.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/openecomp/portalapp/lm/LicenseableClassImpl.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/openecomp/portalapp/login/LoginStrategyImpl.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/openecomp/portalapp/scheduler/Register.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/openecomp/portalapp/scheduler/RegistryAdapter.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/openecomp/portalapp/service/AdminAuthExtension.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/resources/logback.xml create mode 100644 ecomp-sdk/epsdk-app-os/src/main/resources/portal.properties create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/conf/system.properties create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/defs/definitions.xml create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/fusion/conf/fusion.properties create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/fusion/jsp/ds2/footer.jsp create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/fusion/jsp/ds2/header.jsp create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/fusion/jsp/ds2/left-menu.jsp rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/WEB-INF/fusion/orm/RNoteBookIntegration.hbm.xml (100%) rename ecomp-sdk/{sdk-app/src/main/webapp => epsdk-app-os/src/main/webapp/WEB-INF}/index.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/jsp/login.jsp create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/jsp/login_external.jsp create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/web.xml create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/font_icons.css create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/external/ds2/css/digital-ng-library/ionicons.css rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1 => epsdk-app-os/src/main/webapp/app/fusion/external/ds2/css}/fonts/ionicons.eot (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1 => epsdk-app-os/src/main/webapp/app/fusion/external/ds2/css}/fonts/ionicons.svg (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1 => epsdk-app-os/src/main/webapp/app/fusion/external/ds2/css}/fonts/ionicons.ttf (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1 => epsdk-app-os/src/main/webapp/app/fusion/external/ds2/css}/fonts/ionicons.woff (100%) create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/DS2-controllers/ds-profile/post-controller.js create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/DS2-controllers/samplePage-route.js create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/DS2-services/postSearch.js create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/post.html create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/profile_searchDS2.html create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/self_profile.html create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/samplePage.html create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/DS2-view-models/footer.html create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/utils/page-resource-ds2.js create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/view-models/footer.html rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/styles => epsdk-app-os/src/main/webapp/static/fusion/css}/att_angular_gridster/sandbox-gridster.css (100%) create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/css/att_angular_gridster/ui-gridster.css create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/css/fusion-sunny.css rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/images/att_angular_gridster/grips.png (100%) create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/images/ecomp-login-550x360.jpg create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/images/ecomp-login.jpg rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/images/ecomp.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/images/ecomp_trans.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/scripts => epsdk-app-os/src/main/webapp/static/fusion/js}/att_angular_gridster/angular-gridster.js (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/scripts => epsdk-app-os/src/main/webapp/static/fusion/js}/att_angular_gridster/ui-gridster-tpls.js (100%) create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/sample/css/flexslider.css create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.eot create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.svg create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.ttf create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.woff rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-os/src/main/webapp/static/fusion/sample/css}/images/blank.gif (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/css/scribble.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/css/slider.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/css/spacegallery.css (100%) create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/sample/css/welcome.css rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/area_chart.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/bar_chart.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/d3_gauges_demo.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/data/speedometer2.csv (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/data/speedometer3.csv (100%) create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/sample/html/data/worddata.csv rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/donut_d3.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/js/area_chart.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/js/donut.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/js/gauges.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/js/line_chart.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/js/pie_chart.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/js/worddata.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/line_chart.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/html/pie_chart.html (100%) create mode 100644 ecomp-sdk/epsdk-app-os/src/main/webapp/static/fusion/sample/html/wordcloud.html rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/Calendar-16x16.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-os/src/main/webapp/static/fusion/sample}/images/arrow-next.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-os/src/main/webapp/static/fusion/sample}/images/arrow-prev.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/carousel/slide_b_drive_test_map.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/carousel/slide_b_eppt_county.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/carousel/slide_b_eppt_regression.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/carousel/slide_b_ios_throughput.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/carousel/slide_b_lata_map.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/carousel/slide_b_lata_map_legend.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/carousel/slide_b_nova_sdn_map.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-os/src/main/webapp/static/fusion/sample}/images/copyicon.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-os/src/main/webapp/static/fusion/sample}/images/deleteicon.gif (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-os/src/main/webapp/static/fusion/sample}/images/example-frame.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-os/src/main/webapp/static/fusion/sample}/images/loading.gif (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/1_mon.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/2_tue.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/3_wed.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/4_thu.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/5_fri.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/6_sat.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/7_sun.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/BH_DLSTX_IN.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/BH_DLSTX_OUT.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat_Def.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat_Priority.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/js/FusionCharts.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/js/charts.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/js/eye.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/js/jquery.flexslider-min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/js/scribble.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/js/slides.min.jquery.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/js/spacegallery.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/js/utils.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/css/bootstrap.min.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/css/custom.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/css/jquery.jOrgChart.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/css/prettify.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/example.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/example_vsp.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/images/bkgd.png (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/images/raspberry.jpg (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/jquery.jOrgChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-os}/src/main/webapp/static/fusion/sample/org_chart/prettify.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/.gitignore create mode 100644 ecomp-sdk/epsdk-app-overlay/README.md create mode 100644 ecomp-sdk/epsdk-app-overlay/pom.xml rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/resources/att-rules.drl (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/resources/cache.ccf (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/resources/mchange-log.properties (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/resources/state-rules.drl (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/conf/quartz.properties create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/conf/raptor.properties create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/conf/raptor_app_fusion.properties rename ecomp-sdk/{sdk-app/src/main/webapp/WEB-INF/fusion/jsp/.gitignore => epsdk-app-overlay/src/main/webapp/WEB-INF/conf/raptor_db_fusion.properties} (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/conf/raptor_pdf.properties create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/conf/sql.properties create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/conf/sql.properties.oracle create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/conf/fusion.properties create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/defs/definitions.xml rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/scripts/controllers/dummy.txt => epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/.gitignore} (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/broadcast.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/broadcast_list.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/jsp/data_out.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ds2/template.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/loginSnippet.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_noheader_nofooter.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_report_embedded.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/es_search_demo.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/frame_insert.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/jsp/include.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/meta.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/jsp/popup_modal.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_role.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_rolefunction.html (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/sequence/details.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/webrtc/collaboration.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/orm/Fusion.hbm.xml (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/orm/Workflow.hbm.xml (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/custom_header_include.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/custom_js_include.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/date_end_field_run_sql.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/date_start_field_run_sql.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/default_field_run_sql.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/disclaimer.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/error_include.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/error_page.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/footer.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_drill_down_report.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/popup_import_semaphore.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/popup_semaphore.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/popup_sql.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/popup_table_cols.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/popup_testrun_sql.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/report_download_csv.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/report_download_pdf.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/report_download_xls.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/report_ebz.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_import.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/report_sample.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/report_search.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_wizard.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/test_field_run_sql.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/test_run_sql.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/tree/folderNav.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/tree/testTree.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_adhoc_schedule.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_chart.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_add_multi.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_edit.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_list.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_order_all.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_data_forecasting.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_definition.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_edit.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_list.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_edit.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_list.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_javascript.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_log.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_map.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_run.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_formfield_include.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_multiple.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only_from_search.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_edit.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_list.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_order_all.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_sql_def.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_edit.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_list.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/fusion/raptor/wizard_user_access.jsp (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/jsp/error.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/leafletMap.jsp create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/login_external_ng.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/WEB-INF/jsp/net_map.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/web.xml create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-animate.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-animate.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-animate.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-aria.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-aria.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-aria.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-csp.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-loader.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-loader.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-loader.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-message-format.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-message-format.min.js rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/external/angular-1.5 => epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8}/angular-message-format.min.js.map (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-messages.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-messages.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-messages.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-mocks.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-resource.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-resource.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-resource.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-route.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-route.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-route.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-sanitize.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-sanitize.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-sanitize.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-scenario.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-touch.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-touch.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-touch.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular.min.js.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/errors.json create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_aa-dj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_aa-er.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_aa-et.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_aa.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_af-na.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_af-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_af.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_agq-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_agq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ak-gh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ak.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_am-et.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_am.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-001.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-ae.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-bh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-dj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-dz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-eg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-eh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-er.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-il.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-iq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-jo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-km.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-kw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-lb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-ly.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-ma.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-mr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-om.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-ps.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-qa.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-sa.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-sd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-so.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-ss.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-sy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-td.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-tn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar-ye.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ar.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_as-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_as.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_asa-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_asa.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ast-es.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ast.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_az-cyrl-az.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_az-cyrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_az-latn-az.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_az-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_az.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bas-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bas.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_be-by.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_be.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bem-zm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bem.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bez-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bez.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bg-bg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bm-latn-ml.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bm-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bm-ml.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bn-bd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bn-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bo-cn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bo-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_br-fr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_br.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_brx-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_brx.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bs-cyrl-ba.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bs-cyrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bs-latn-ba.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bs-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_bs.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_byn-er.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_byn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ca-ad.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ca-es-valencia.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ca-es.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ca-fr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ca-it.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ca.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_cgg-ug.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_cgg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_chr-us.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_chr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ckb-arab-iq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ckb-arab-ir.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ckb-arab.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ckb-iq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ckb-ir.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ckb-latn-iq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ckb-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ckb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_cs-cz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_cs.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_cy-gb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_cy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_da-dk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_da-gl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_da.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dav-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dav.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_de-at.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_de-be.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_de-ch.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_de-de.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_de-li.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_de-lu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_de.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dje-ne.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dje.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dsb-de.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dsb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dua-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dua.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dyo-sn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dyo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dz-bt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_dz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ebu-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ebu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ee-gh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ee-tg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ee.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_el-cy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_el-gr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_el.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-001.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-150.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ag.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ai.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-as.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-au.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-bb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-be.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-bm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-bs.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-bw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-bz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ca.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-cc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ck.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-cx.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-dg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-dm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-er.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-fj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-fk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-fm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-gb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-gd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-gg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-gh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-gi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-gm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-gu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-gy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-hk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ie.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-im.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-io.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-iso.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-je.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-jm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ki.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-kn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ky.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-lc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-lr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ls.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-mg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-mh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-mo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-mp.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ms.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-mt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-mu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-mw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-my.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-na.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-nf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ng.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-nr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-nu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-nz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-pg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ph.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-pk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-pn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-pr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-pw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-rw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-sb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-sc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-sd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-sg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-sh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-sl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ss.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-sx.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-sz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-tc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-tk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-to.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-tt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-tv.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ug.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-um.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-us.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-vc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-vg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-vi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-vu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-ws.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-zm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en-zw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_en.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_eo-001.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_eo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-419.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-ar.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-bo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-cl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-co.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-cr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-cu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-do.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-ea.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-ec.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-es.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-gq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-gt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-hn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-ic.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-mx.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-ni.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-pa.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-pe.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-ph.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-pr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-py.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-sv.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-us.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-uy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es-ve.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_es.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_et-ee.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_et.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_eu-es.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_eu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ewo-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ewo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fa-af.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fa-ir.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fa.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ff-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ff-gn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ff-mr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ff-sn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ff.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fi-fi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fil-ph.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fil.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fo-fo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-be.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-bf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-bi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-bj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-bl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-ca.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-cd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-cf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-cg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-ch.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-ci.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-dj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-dz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-fr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-ga.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-gf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-gn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-gp.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-gq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-ht.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-km.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-lu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-ma.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-mc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-mf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-mg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-ml.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-mq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-mr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-mu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-nc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-ne.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-pf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-pm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-re.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-rw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-sc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-sn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-sy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-td.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-tg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-tn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-vu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-wf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr-yt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fur-it.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fur.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fy-nl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_fy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ga-ie.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ga.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gd-gb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gl-es.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gsw-ch.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gsw-fr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gsw-li.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gsw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gu-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_guz-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_guz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gv-im.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_gv.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ha-latn-gh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ha-latn-ne.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ha-latn-ng.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ha-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ha.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_haw-us.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_haw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_he-il.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_he.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hi-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hr-ba.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hr-hr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hsb-de.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hsb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hu-hu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hy-am.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_hy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ia-fr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ia.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_id-id.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_id.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ig-ng.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ig.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ii-cn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ii.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_is-is.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_is.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_it-ch.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_it-it.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_it-sm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_it.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_iw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ja-jp.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ja.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_jgo-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_jgo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_jmc-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_jmc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ka-ge.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ka.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kab-dz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kab.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kam-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kam.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kde-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kde.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kea-cv.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kea.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_khq-ml.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_khq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ki-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ki.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kk-cyrl-kz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kk-cyrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kkj-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kkj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kl-gl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kln-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kln.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_km-kh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_km.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kn-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ko-kp.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ko-kr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ko.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kok-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kok.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ks-arab-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ks-arab.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ks.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ksb-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ksb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ksf-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ksf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ksh-de.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ksh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kw-gb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_kw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ky-cyrl-kg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ky-cyrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ky.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lag-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lag.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lb-lu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lg-ug.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lkt-us.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lkt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ln-ao.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ln-cd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ln-cf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ln-cg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ln.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lo-la.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lt-lt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lu-cd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_luo-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_luo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_luy-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_luy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lv-lv.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_lv.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mas-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mas-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mas.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mer-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mer.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mfe-mu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mfe.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mg-mg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mgh-mz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mgh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mgo-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mgo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mk-mk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ml-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ml.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mn-cyrl-mn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mn-cyrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mr-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ms-latn-bn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ms-latn-my.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ms-latn-sg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ms-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ms.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mt-mt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mua-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_mua.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_my-mm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_my.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_naq-na.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_naq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nb-no.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nb-sj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nb.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nd-zw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ne-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ne-np.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ne.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nl-aw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nl-be.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nl-bq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nl-cw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nl-nl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nl-sr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nl-sx.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nmg-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nmg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nn-no.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nnh-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nnh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_no-no.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_no.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nr-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nso-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nso.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nus-sd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nus.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nyn-ug.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_nyn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_om-et.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_om-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_om.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_or-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_or.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_os-ge.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_os-ru.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_os.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pa-arab-pk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pa-arab.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pa-guru-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pa-guru.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pa.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pl-pl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ps-af.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ps.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt-ao.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt-br.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt-cv.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt-gw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt-mo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt-mz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt-pt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt-st.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt-tl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_pt.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_qu-bo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_qu-ec.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_qu-pe.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_qu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rm-ch.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rn-bi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ro-md.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ro-ro.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ro.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rof-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rof.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ru-by.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ru-kg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ru-kz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ru-md.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ru-ru.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ru-ua.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ru.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rw-rw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rwk-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_rwk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sah-ru.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sah.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_saq-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_saq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sbp-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sbp.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_se-fi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_se-no.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_se-se.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_se.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_seh-mz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_seh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ses-ml.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ses.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sg-cf.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_shi-latn-ma.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_shi-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_shi-tfng-ma.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_shi-tfng.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_shi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_si-lk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_si.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sk-sk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sl-si.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_smn-fi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_smn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sn-zw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_so-dj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_so-et.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_so-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_so-so.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_so.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sq-al.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sq-mk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sq-xk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-cyrl-ba.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-cyrl-me.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-cyrl-rs.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-cyrl-xk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-cyrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-latn-ba.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-latn-me.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-latn-rs.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-latn-xk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ss-sz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ss-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ss.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ssy-er.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ssy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_st-ls.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_st-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_st.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sv-ax.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sv-fi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sv-se.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sv.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sw-cd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sw-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sw-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sw-ug.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_sw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_swc-cd.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_swc.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ta-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ta-lk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ta-my.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ta-sg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ta.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_te-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_te.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_teo-ke.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_teo-ug.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_teo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tg-cyrl-tj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tg-cyrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_th-th.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_th.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ti-er.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ti-et.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ti.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tig-er.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tig.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tn-bw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tn-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_to-to.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_to.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tr-cy.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tr-tr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ts-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ts.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_twq-ne.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_twq.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tzm-latn-ma.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tzm-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_tzm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ug-arab-cn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ug-arab.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ug.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_uk-ua.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_uk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ur-in.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ur-pk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ur.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_uz-arab-af.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_uz-arab.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_uz-cyrl-uz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_uz-cyrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_uz-latn-uz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_uz-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_uz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vai-latn-lr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vai-latn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vai-vaii-lr.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vai-vaii.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vai.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ve-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_ve.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vi-vn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vo-001.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vun-tz.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_vun.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_wae-ch.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_wae.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_wal-et.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_wal.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_xh-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_xh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_xog-ug.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_xog.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_yav-cm.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_yav.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_yi-001.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_yi.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_yo-bj.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_yo-ng.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_yo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zgh-ma.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zgh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-cn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hans-cn.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hans-hk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hans-mo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hans-sg.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hans.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hant-hk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hant-mo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hant-tw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hant.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-hk.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh-tw.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zh.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zu-za.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/i18n/angular-locale_zu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/version.json create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/version.txt create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-bootstrap/index.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-bootstrap/ui-bootstrap-csp.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-bootstrap/ui-bootstrap-tpls.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-bootstrap/ui-bootstrap-tpls.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-bootstrap/ui-bootstrap.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-bootstrap/ui-bootstrap.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-gridster/dist/angular-gridster.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-gridster/dist/angular-gridster.min.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-gridster/dist/angular-gridster.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-gridster/src/angular-gridster.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-gridster/src/angular-gridster.less create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui-grid/index.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui-grid/ui-grid.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui-grid/ui-grid.eot create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui-grid/ui-grid.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui-grid/ui-grid.min.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui-grid/ui-grid.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui-grid/ui-grid.svg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui-grid/ui-grid.ttf create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui-grid/ui-grid.woff rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/angular-ui/ui-bootstrap-tpls-1.1.2.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/angular-ui/ui-bootstrap-tpls-1.2.4.min.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-ui/ui-sortable/v0.13.4/sortable.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/README.md create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/b2b-angular.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/style/images/horse_shoe.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/style/images/icon-flyout.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/style/images/treebg.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/css/b2b-angular/style/images/widget-thumbnail.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/js/b2b-angular/b2b-library.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/js/b2b-angular/style/images/horse_shoe.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/js/b2b-angular/style/images/icon-flyout.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/js/b2b-angular/style/images/treebg.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/js/b2b-angular/style/images/widget-thumbnail.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/b2b/js/b2b-angular/styles/images/icon-flyout.png rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/bootstrap/bs.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/css/nv.d3.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/cie.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/colorbrewer.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/core.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/crossfilter.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/crossfilter.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/d3.geom.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/d3.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/d3.layout.cloud.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/d3.layout.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/d3.v2.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/d3.v2.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/d3.v3.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/fisheye.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/hive.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/horizon.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/interactiveLayer.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/d3/js/intro.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/axis-min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/axis.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/axis.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/backup/bullet.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/backup/bulletChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/boilerplate.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/bullet.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/bulletChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/cumulativeLineChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/discreteBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/discreteBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/distribution.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/historicalBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/historicalBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/indentedTree.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/legend.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/line.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/lineChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/linePlusBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/linePlusBarWithFocusChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/lineWithFisheye.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/lineWithFisheyeChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/lineWithFocusChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/multiBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/multiBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/multiBarHorizontal.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/multiBarHorizontalChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/multiBarTimeSeries.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/multiBarTimeSeriesChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/multiChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/ohlcBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/parallelCoordinates.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/pie.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/pieChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/scatter.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/scatterChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/scatterPlusLineChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/sparkline.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/sparklinePlus.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/stackedArea.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/models/stackedAreaChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/nv.d3.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/nv.d3.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/outro.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/sankey.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/tooltip.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/external/d3/js/utils.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/ds2/js/appDS2.js rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/scripts/directives/dummy.txt => epsdk-app-overlay/src/main/webapp/app/fusion/external/ebz/copyrighted-material-removed.txt} (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/gis/js/local.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/javascript-detect-element-resize/detect-element-resize.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/javascript-detect-element-resize/jquery.resize.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/jquery/.bower.json create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/jquery/dist/jquery.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/jquery/dist/jquery.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/jquery/dist/jquery.min.map create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/leaflet-0.7.3/leaflet.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/leaflet-0.7.3/leaflet.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/lodash/4.5.1/lodash.js rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/sample => epsdk-app-overlay/src/main/webapp/app/fusion/external/samples}/css/images/blank.gif (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/css/scribble.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/css/slider.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/css/spacegallery.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/area_chart.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/bar_chart.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/busy_hour_traffic.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/d3_gauges_demo.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/data/speedometer2.csv create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/data/speedometer3.csv rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/sample => epsdk-app-overlay/src/main/webapp/app/fusion/external/samples}/html/data/worddata.csv (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/donut_d3.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/js/area_chart.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/js/donut.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/js/gauges.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/js/line_chart.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/js/pie_chart.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/js/worddata.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/line_chart.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/pie_chart.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/html/traffic_distribution.html rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/sample => epsdk-app-overlay/src/main/webapp/app/fusion/external/samples}/html/wordcloud.html (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/Calendar-16x16.png rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/sample => epsdk-app-overlay/src/main/webapp/app/fusion/external/samples}/images/arrow-next.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/sample => epsdk-app-overlay/src/main/webapp/app/fusion/external/samples}/images/arrow-prev.png (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/carousel/slide_b_drive_test_map.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/carousel/slide_b_eppt_county.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/carousel/slide_b_eppt_regression.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/carousel/slide_b_ios_throughput.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/carousel/slide_b_lata_map.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/carousel/slide_b_lata_map_legend.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/carousel/slide_b_nova_sdn_map.png rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/sample => epsdk-app-overlay/src/main/webapp/app/fusion/external/samples}/images/copyicon.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/sample => epsdk-app-overlay/src/main/webapp/app/fusion/external/samples}/images/deleteicon.gif (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/sample => epsdk-app-overlay/src/main/webapp/app/fusion/external/samples}/images/example-frame.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/sample => epsdk-app-overlay/src/main/webapp/app/fusion/external/samples}/images/loading.gif (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/1_mon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/2_tue.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/3_wed.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/4_thu.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/5_fri.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/6_sat.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/7_sun.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/BH_DLSTX_IN.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/BH_DLSTX_OUT.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/BH_Nat.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/BH_Nat_Def.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/images/tunnels/BH_Nat_Priority.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/js/FusionCharts.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/js/charts.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/js/eye.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/js/scribble.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/js/slides.min.jquery.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/js/spacegallery.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/js/utils.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/css/bootstrap.min.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/css/custom.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/css/jquery.jOrgChart.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/css/prettify.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/example.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/example_vsp.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/images/bkgd.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/images/raspberry.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/jquery.jOrgChart.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/samples/org_chart/prettify.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/showdown/0.3.4/showdown.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/utils/js/browserCheck.js rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/scripts/utils => epsdk-app-overlay/src/main/webapp/app/fusion/fonts}/dummy.txt (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/controllers/nbook-framecontroller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/controllers/nbookController.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/controllers/notebookFrameController.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/notebook-integration/scripts/dependency/angular.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-frame.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-viz.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook.htm create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebookInputs.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-closed-cloop.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-menu-edit.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-route.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-whitelist.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate-list-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate/collaborate.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate/workflowController.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborateList-route.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaboration-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-profile/self-profile-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-import-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-router.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-run-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-search-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-step-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-sample/drools-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-sample/nbook-framecontroller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-sample/notebook-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-sample/notebookFrameController.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-workflows/workflowApp.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-workflows/workflowController.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-workflows/workflowRouting.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/fn-menu-add-popup-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/profile-route.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/profile-search-controller-DS2.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/sampleProfileController.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/usage-list-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/welcome-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/welcome-route.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-directives/b2b-leftnav-ext.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-directives/ds2Header.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-directives/ds2LeftMenu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-directives/footer.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/error_modal.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/success_modal.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/success_modalpopup.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/adminMenuService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/adminService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-modal/modalService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-profile/selfProfileService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-raptor-report/raptorReportFactory.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-raptor-report/stepFormFactory.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-sample-page/droolsService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/headerServiceDS2.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/leftMenuServiceDS2.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/manifestService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/modalService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/modalServiceDS2.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/profileServiceDS2.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/sampleService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/userInfoServiceDS2.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-landing.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-listing.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-new.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-preview.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-remove.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-schedule.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/b2b-leftnav-ext.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin-menu-edit.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin_closed_loop.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/collaborate-list.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/collaboration.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/jcs_admin.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/admin-menu-del-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-region-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/clearItem-region-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/collaborate-list-toggle-profile-active-status.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fn-menu-edit.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fnmenu-add.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-child-add-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-confirm-activation.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-delete-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-add-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-role-del-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-add.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-del-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-edit.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-child-roles-modal.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-modal.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role-function.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role_list.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/usage.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-add-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-add.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-del-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/profile.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/all-reports.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/directive/dynamicform.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/directive/step-form-directive.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-del-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-formfield-del-confirm.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-col-edit.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-formfield-edit.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-test-run-sql.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-import.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-run.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-search.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step1.json create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step2.json create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step3.json create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step4.json create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step5.json create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/report-step.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/drools-list.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/drools.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/frame_insert.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-frame.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-page.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-viz.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2Header.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2Left_menu.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/loginSnippet.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-content.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-sample.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome.html rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/js => epsdk-app-overlay/src/main/webapp/app/fusion/scripts}/att_angular_gridster/angular-gridster.js (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/js => epsdk-app-overlay/src/main/webapp/app/fusion/scripts}/att_angular_gridster/ui-gridster-tpls.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/admin-closed-cloop.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/admin-whitelist.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/ase-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/broadcast-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/broadcast-list-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/collaborate-list-controller.js rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/scripts/view-models => epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers}/dummy.txt (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/modelpopupController.js rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/drools/controller => epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives}/dummy.txt (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/footer.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/header.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/leftMenu.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/scripts/jquery.resize.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/scripts/layout/debug.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/scripts/layout/jquery-latest.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/scripts/layout/jquery-ui-latest.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/scripts/layout/jquery.layout-latest.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/scripts/modalService.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/scripts/moment.min.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/network/net_map.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/services/adminService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/services/headerService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/services/leftMenuService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/services/profileService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/services/userInfoService.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/socket/peerBroadcast.js rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/drools/directives => epsdk-app-overlay/src/main/webapp/app/fusion/scripts/utils}/dummy.txt (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/scripts/utils/sandbox-resources.html (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/drools/utils => epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models}/dummy.txt (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/header.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/left_menu.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/admin_closed_loop.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast_list.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_add.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_edit.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_role.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_rolefunction.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/customWidgetSettings.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/dataModel.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/demo.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/demo.less create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/directives.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/explicitSave.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.less create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index_original.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/layouts.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/report_whitelist.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/resize.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/configurableWidgetModalOptions.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/customSettingsTemplate.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/fluid.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/layouts.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/r-cloud.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/raptor-report.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/resizable.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/view.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/widgetSpecificSettings.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/vendor.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/vendor.less create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/angular-markdown-directive/markdown.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/WidgetSettingsCtrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/WidgetSettingsRaptorReportCtrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-raptor-report-template.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-rcloud-notebook-template.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/altDashboard.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.less create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.spec.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-raptor-report-template.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-template.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/SaveChangesModal.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/SaveChangesModalCtrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.spec.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/DashboardWidgetCtrl.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/DashboardWidgetCtrl.spec.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/widget.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/widget.spec.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/DashboardState.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/LayoutStorage.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/LayoutStorage.spec.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetDataModel.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetDefCollection.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetModel.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetModel.spec.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/report-dashboard.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/webrtc/RTCMultiConnection.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/scripts/webrtc/getSourceId.html (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/css => epsdk-app-overlay/src/main/webapp/app/fusion/styles}/att_angular_gridster/sandbox-gridster.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/styles/att_angular_gridster/ui-gridster.css (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/ecomp.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/fusion-sunny.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/global.css rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/styles/jquery-ui.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/app/fusion/styles/layout/layout-default-latest.css (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/workflows/bs-workflow.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/workflows/workflows.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/drools-list-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/drools-view-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/droolsController.js rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/drools/view-models => epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller}/dummy.txt (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/external => epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/directives}/dummy.txt (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/services/droolsService.js rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/fonts => epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/utils}/dummy.txt (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsList.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsSinglePage.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsView.html rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/images => epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models}/dummy.txt (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/scripts/controller => epsdk-app-overlay/src/main/webapp/app/fusionapp/external}/dummy.txt (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/scripts/directives => epsdk-app-overlay/src/main/webapp/app/fusionapp/fonts}/dummy.txt (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7450-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7450-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7750-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7750-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/apn-dns-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/apn-dns-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atcf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atcf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atgw-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atgw-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/bgcf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/bgcf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/com-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/cpm-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/cpm-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/default-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-epc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-epc-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-ims-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-ims-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dslam-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dslam-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/eatf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/eatf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ecscf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ecscf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/emsc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enb-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enb-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enum-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enum-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/esmlc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/esmlc-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ettcs-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ettcs-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/gmlc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/gmlc-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hlr-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hlr-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-epc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-epc-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-ims-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-ims-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/icscf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/icscf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ipag-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ipag-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/isbc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/isbc-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/iwf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/iwf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/lrf-rdf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/lrf-rdf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/lrg-rdf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgc8-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgc8-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgcf-emsc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgcf-emsc-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgw-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgw-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mind-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mind-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mme-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mme-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mrf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mrf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/msc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/msn-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/msn-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/multi-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7450-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7450-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750a-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750a-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750b-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750b-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750c-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750c-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750d-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750d-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/nb-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/nb-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pas-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pas-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcef-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcef-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcrf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcrf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcscf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcscf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pgw-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pgw-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/plrf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/plrf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/psap-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pstn-tdm-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pstn-tdm-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rg-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rg-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rnc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rnc-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sbc-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sbc-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sccas-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sccas-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/scscf-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/scscf-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sdg-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sdg-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgsns4-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgsns4-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgw-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgw-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/siad-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/siad-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7-gport-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7-gport-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7gport-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7gport-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/switch-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/tas-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/tas-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/transcoder-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/transcoder-text.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ue-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/uephone-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/usp-dns-icon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/usp-dns-text.png rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/scripts/utils => epsdk-app-overlay/src/main/webapp/app/fusionapp/images}/dummy.txt (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/scripts/view-models => epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller}/dummy.txt (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sample-page-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sample-page-iframe-controller.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sampleController.js rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusionapp/styles => epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/directives}/dummy.txt (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/utils/dummy.txt create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/view-models/dummy.txt create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/view-models/sampleWithIframe.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/styles/dummy.txt create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/index.jsp rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/manifest.jsp (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/att_angular_gridster/sandbox-gridster.css rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/css/att_angular_gridster/ui-gridster.css (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/fusion-sunny.css rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/css/nv.d3.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/cie.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/colorbrewer.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/core.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/crossfilter.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/crossfilter.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/d3.geom.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/d3.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/d3.layout.cloud.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/d3.layout.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/d3.v2.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/d3.v2.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/d3.v3.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/fisheye.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/hive.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/horizon.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/interactiveLayer.js (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/app/fusion/external => epsdk-app-overlay/src/main/webapp/static/fusion}/d3/js/intro.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/axis-min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/axis.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/axis.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/backup/bullet.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/backup/bulletChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/boilerplate.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/bullet.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/bulletChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/cumulativeLineChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/discreteBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/discreteBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/distribution.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/historicalBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/historicalBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/indentedTree.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/legend.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/line.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/lineChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/linePlusBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/linePlusBarWithFocusChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/lineWithFisheye.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/lineWithFisheyeChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/lineWithFocusChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/multiBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/multiBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontal.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontalChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeries.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeriesChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/multiChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/ohlcBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/parallelCoordinates.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/pie.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/pieChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/scatter.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/scatterChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/scatterPlusLineChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/sparkline.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/sparklinePlus.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/stackedArea.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/models/stackedAreaChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/nv.d3.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/nv.d3.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/outro.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/sankey.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/tooltip.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/d3/js/utils.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/gis/js/local.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/att_angular_gridster/angular-gridster.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/att_angular_gridster/ui-gridster-tpls.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/js/jquery.resize.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/js/layout/debug.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/js/layout/jquery-latest.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/js/layout/jquery-ui-latest.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/js/layout/jquery.layout-latest.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/js/moment.min.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Entries create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Repository create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Root create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Tag rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/Style.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/bd_quantum_raptor.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/calendar.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/dashboard.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/drupal.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/form-field-tooltip.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/mobile_raptor.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/novamap.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/picker.css (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/ral.css rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/css/raptor.css (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/tree/context-menu.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/tree/drag-drop-folder-tree.css rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/css/nv.d3.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/cie.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/colorbrewer.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/core.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/d3.geom.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/d3.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/d3.layout.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/fisheye.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/hive.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/horizon.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/interactiveLayer.js (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-overlay/src/main/webapp/static/fusion/raptor}/d3/js/intro.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/axis-min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/axis.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/axis.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/boilerplate.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/bullet.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/bulletChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/cumulativeLineChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/distribution.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/indentedTree.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/legend.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/line.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/lineChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarWithFocusChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheye.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheyeChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFocusChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/multiBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontal.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontalChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeries.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeriesChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/multiChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/ohlcBar.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/parallelCoordinates.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js.bak (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/pieChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/scatter.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/scatterChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/scatterPlusLineChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/sparkline.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/sparklinePlus.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/stackedArea.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/models/stackedAreaChart.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/nv.d3.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/outro.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/sankey.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/tooltip.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/d3/js/utils.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dashed-canvas.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/data.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-canvas.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined_bak_color.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-dev.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-externs.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-gviz.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-interaction-model.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-layout.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options-reference.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-base.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-install.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-tickers.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-utils.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/dygraph.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/excanvas.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/interaction.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/interaction.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/interaction_sun.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/moment.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/phantom-driver.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/phantom-perf.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/plugins/README (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/plugins/annotations.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/plugins/axes.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/plugins/chart-labels.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/plugins/grid.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/plugins/legend.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/plugins/range-selector.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/rgbcolor/rgbcolor.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/stacktrace.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/strftime/Doxyfile (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime-min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/ebz/dynamicform.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/ebz/moment.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/ebz/multiselect.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/ebz/quick_links.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.html (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_run.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_run.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_search.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_search.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/ATT_Business_logo.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/RAPTOR_BANNER.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/accessicon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/active.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/addbtn.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/ajax-loader.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_add.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_add_edge.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_add_multiple.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_add_one.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_back.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_cancel.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_left.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_left2.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_next.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_plus.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_reorder_all.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_reorder_all.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_right.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_right2.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_save.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/att-globe1.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/button_import.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calendar_icon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calendar_icon_nav.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calendar_icon_nav1.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calender_icon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columnblankdown.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columnblankup.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columndown.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columnup.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/crosshairs.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/csv_icon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/deleteicon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/downloadicon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/excel2007.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/excel2007.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/excelicon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/excelicon_multi.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/green-arrow-right.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/green-arrow.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/grnarrowdn.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/grnarrowup.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/h.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/inactive.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/loader.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/loading.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/lookup_arrow.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/blue.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/green.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/lightblue.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/map_iphone.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/orange.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/pink.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/purple.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/red.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/yellow.png rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-overlay/src/main/webapp/static/fusion/raptor}/images/minus.gif (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-overlay/src/main/webapp/static/fusion/raptor}/images/modify_icon.gif (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/page.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/pdficon_large.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/pdficon_small.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/pen_paper.gif rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion => epsdk-app-overlay/src/main/webapp/static/fusion/raptor}/images/plus.gif (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/popupicon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/position.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/printer.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/progress.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/question_mark.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/quickhelp_dk.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/quickhelp_lt.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/r_back.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/raptor.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/raptor_logo.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/raptor_logo.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/required.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/shareicon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/sv.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tab_left.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tab_left_sel.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tab_right.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tab_right_sel.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/test_run.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/text.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/context-menu-gradient.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_folder.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_minus.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_plus.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_sheet.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_sheet_crosstab.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_sheet_dashboard.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_sheet_graph.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dragDrop_ind1.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dragDrop_ind2.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_close.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_dots.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_folder.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_lastsub.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_open.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_sub.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/grnarrowleft.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/grnarrowright.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/txt_icon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/uF033.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/uF034.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/uF035.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/uF036.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/BorderLayout-24x24.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/Calendar-16x16.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/DeleteCross-16x16.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/addbtn.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/button_import.png rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/copyicon-highlighted.png (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/copyicon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/cross-small.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/csv_icon.gif rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/csv_icon.jpg (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/csv_icon.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/deleteicon-highlighted.gif (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/deleteicon-highlighted.png (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/deleteicon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/downloadicon.gif rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/editicon.gif (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/excel2007.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/excelicon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/excelicon_multi.gif rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/executeicon.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/file_import.png (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/pdficon_small.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/pen_paper.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/pencil-small.png rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/report-add.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/report-favorite.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/report-my.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/report-public.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/report.png (100%) rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/reports.png (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/search.gif rename ecomp-sdk/{sdk-app/src/main/webapp/static/fusion/images => epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img}/search.png (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/tick-small.png rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/CalendarPopup.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/ajax.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/ajax_dynamic_content.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/cingular_button.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/drupal.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/editabledropdown.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/form-field-tooltip.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/gmap.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/jquery.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/jquery.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/label_quantum.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/nova_button.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/other_scripts.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/persist_table_header.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/projected_overlay.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/prototype-1.6.0.3.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/raptor.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/rounded-corners.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/js/script.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/ajax.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/context-menu.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/drag-drop-folder-tree.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.css (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.eot (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.svg (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.ttf (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.woff (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/fusion/raptor/uigrid/vfs_fonts.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/flexslider.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.eot create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.svg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.ttf create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.woff create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/images/blank.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/scribble.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/slider.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/spacegallery.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/welcome.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/area_chart.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/bar_chart.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/d3_gauges_demo.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/speedometer2.csv create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/speedometer3.csv create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/worddata.csv create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/donut_d3.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/area_chart.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/donut.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/gauges.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/line_chart.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/pie_chart.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/worddata.min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/line_chart.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/pie_chart.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/wordcloud.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/Calendar-16x16.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/arrow-next.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/arrow-prev.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_drive_test_map.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_eppt_county.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_eppt_regression.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_ios_throughput.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_lata_map.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_lata_map_legend.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_nova_sdn_map.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/copyicon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/deleteicon.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/example-frame.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/loading.gif create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/1_mon.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/2_tue.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/3_wed.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/4_thu.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/5_fri.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/6_sat.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/7_sun.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/BH_DLSTX_IN.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/BH_DLSTX_OUT.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat_Def.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat_Priority.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/FusionCharts.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/charts.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/eye.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/jquery.flexslider-min.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/scribble.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/slides.min.jquery.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/spacegallery.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/utils.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/bootstrap.min.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/custom.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/jquery.jOrgChart.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/prettify.css create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/example.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/example_vsp.html create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/images/bkgd.png create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/images/raspberry.jpg create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/jquery.jOrgChart.js create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/prettify.js rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/js/jquery-1.10.2.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/js/jquery-ui.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/js/jquery.mask.min.js (100%) rename ecomp-sdk/{sdk-app => epsdk-app-overlay}/src/main/webapp/static/js/modalService.js (100%) create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/js/search.js create mode 100644 ecomp-sdk/epsdk-core/.gitignore create mode 100644 ecomp-sdk/epsdk-core/README.md create mode 100644 ecomp-sdk/epsdk-core/license/licenses.properties create mode 100644 ecomp-sdk/epsdk-core/license/my_license/header.txt create mode 100644 ecomp-sdk/epsdk-core/license/my_license/license.txt create mode 100644 ecomp-sdk/epsdk-core/pom.xml create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/FusionObject.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/auth/LoginStrategy.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/LoginBean.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/command/PostDroolsBean.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/PostSearchBean.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/UserRowBean.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/support/SearchBase.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/support/SearchResult.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/AppConfig.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/AppInitializer.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/conf/Configurable.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/HibernateConfiguration.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/HibernateMappingLocatable.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/controller/FusionBaseController.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedBaseController.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedRESTfulBaseController.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/controller/UnRestrictedBaseController.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/dao/AbstractDao.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDao.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDaoImpl.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/dao/hibernate/ModelOperationsCommon.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/support/FusionDao.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/App.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/AuditLog.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/BroadcastMessage.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/DomainVo.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/FnMenu.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/FusionVo.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/LoginBean.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/Lookup.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/LuCountry.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/LuState.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/LuTimeZone.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/Menu.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/MenuData.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/Profile.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/Role.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/RoleFunction.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessible.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessibleKey.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/User.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UserApp.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/UserAppId.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/sessionmgt/TimeoutVO.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/support/Attribute.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/support/CollaborateList.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Container.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Domain.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/DomainVo.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Element.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/ElementDetails.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/support/FusionCommand.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Layout.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/NameValueId.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/support/Position.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/domain/support/Size.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleService.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleServiceImpl.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/FusionExceptionResolver.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/SessionExpiredException.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/UrlAccessRestrictedException.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionException.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionRuntimeException.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/interceptor/ResourceInterceptor.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/interceptor/SessionTimeoutInterceptor.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/interfaces/SecurityInterface.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/listener/ApplicationContextListener.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/listener/CollaborateListBindingListener.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/listener/UserSessionListener.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/FusionLicenseManager.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/FusionLicenseManagerUtils.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/LicenseableClass.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/AuditLog.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAdvice.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAspect.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/logging/aspect/MetricsLog.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/logging/format/AlarmSeverityEnum.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/logging/format/AppMessagesEnum.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/logging/format/ApplicationCodes.properties (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/logging/format/AuditLogFormatter.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorCodesEnum.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorSeverityEnum.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorTypeEnum.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/logic/EELFLoggerDelegate.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/menu/MenuBuilder.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/menu/MenuProperties.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/AbstractCacheManager.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheEventHandler.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheManager.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/support/FusionCacheManager.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/client/AppContextManager.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/onboarding/session/TestClass.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/onboarding/sso/TestClass.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/restful/client/HttpStatusAndResponse.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/PortalRestClientBase.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/SharedContextRestClient.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/scheduler/CoreRegister.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/scheduler/CronRegistry.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/scheduler/Registerable.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/AppService.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AppServiceImpl.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AuditService.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AuditServiceImpl.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/BroadcastService.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/BroadcastServiceImpl.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/DataAccessService.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/DataAccessServiceImpl.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ElementLinkService.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ElementMapService.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/FnMenuService.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/FnMenuServiceImpl.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/LdapService.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LdapServiceImpl.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LoginService.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LoginServiceImpl.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsService.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsServiceImpl.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostSearchService.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostSearchServiceImpl.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/ProfileService.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ProfileServiceImpl.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/RoleService.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceImpl.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceNonSpringImpl.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/UserProfileService.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/UserProfileServiceImpl.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallService.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallServiceImpl.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/support/FusionService.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocator.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocatorImpl.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/util/CacheManager.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/EncDecUtilTest.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/util/JSONUtil.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/SystemProperties.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/util/UsageUtils.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/YamlUtils.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/web/socket/PeerBroadcastSocket.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/web/socket/WebRTCSocket.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/AppUtils.java rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/web/support/ControllerProperties.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/web/support/FeedbackMessage.java (100%) rename ecomp-sdk/{quantum => epsdk-core}/src/main/java/org/openecomp/portalsdk/core/web/support/JsonMessage.java (100%) create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/MessagesList.java create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/UserUtils.java create mode 100644 ecomp-sdk/epsdk-core/src/test/java/org/openecomp/fusion/core/MockApplicationContextTestSuite.java create mode 100644 ecomp-sdk/epsdk-core/src/test/java/org/openecomp/fusion/core/MockHibernateMappingLocations.java create mode 100644 ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/MockApplicationContextTestSuite.java create mode 100644 ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/MockHibernateMappingLocations.java create mode 100644 ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/controller/sessionmgt/PortalCommunicationTest.java create mode 100644 ecomp-sdk/epsdk-fw/.gitignore create mode 100644 ecomp-sdk/epsdk-fw/README.md create mode 100644 ecomp-sdk/epsdk-fw/pom.xml create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunicationService.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/exception/PortalAPIException.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/PortalTimeoutBindingListener.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/PortalTimeoutHandler.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/UserContextListener.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/UserSessionListener.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/CipherUtil.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/PortalApiConstants.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/PortalApiProperties.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/SSOFilter.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/SSOUtil.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/PortalTimeoutVO.java create mode 100644 ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java create mode 100644 ecomp-sdk/epsdk-workflow/.gitignore create mode 100644 ecomp-sdk/epsdk-workflow/README.md create mode 100644 ecomp-sdk/epsdk-workflow/pom.xml create mode 100644 ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookController.java create mode 100644 ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookTestController.java create mode 100644 ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookController.java rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookFEController.java (100%) create mode 100644 ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/domain/RNoteBookCredentials.java rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/rnotebookintegration/exception/RNotebookIntegrationException.java (100%) rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationService.java (100%) create mode 100644 ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationServiceImpl.java rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/controllers/WorkflowController.java (100%) rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAO.java (100%) rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAOImpl.java (100%) rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/domain/WorkflowSchedule.java (100%) create mode 100644 ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/Workflow.java rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/models/WorkflowLite.java (100%) rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleJob.java (100%) rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleRegistry.java (100%) create mode 100644 ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleExecutor.java rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleService.java (100%) rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleServiceImpl.java (100%) create mode 100644 ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowService.java rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowServiceImpl.java (100%) rename ecomp-sdk/{sdk-workflow => epsdk-workflow}/src/main/resources/RNoteBookIntegration.hbm.xml (100%) delete mode 100644 ecomp-sdk/quantum/.gitignore delete mode 100644 ecomp-sdk/quantum/README.md delete mode 100644 ecomp-sdk/quantum/pom.xml delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/FusionObject.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/LoginBean.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/PostSearchBean.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/UserRowBean.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/support/SearchBase.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/support/SearchResult.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/AppConfig.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/AppInitializer.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/HibernateConfiguration.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/HibernateMappingLocatable.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/AdminAuthGenericController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/AngularAdminController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/BroadcastController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/BroadcastListController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CacheAdminController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CollaborateListController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CollaborationController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ElementModelController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ExternalLoginController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FavoritesController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FnMenuController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FuncMenuController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/LogoutController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/MenuListController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/PostSearchController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ProfileController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ProfileSearchController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleFunctionListController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleListController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/SingleSignOnController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/UsageListController.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDaoImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/support/FusionDao.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/AuditLog.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/BroadcastMessage.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/FnMenu.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/LoginBean.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/Lookup.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/LuCountry.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/LuState.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/LuTimeZone.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/Menu.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/MenuData.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/Role.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/RoleFunction.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessible.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessibleKey.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/User.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UserApp.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/sessionmgt/TimeoutVO.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Container.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Domain.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/DomainVo.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Element.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/ElementDetails.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Layout.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/NameValueId.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/FusionExceptionResolver.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/SessionExpiredException.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/UrlAccessRestrictedException.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionRuntimeException.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/interceptor/ResourceInterceptor.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/listener/ApplicationContextListener.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/AuditLog.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAdvice.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorCodesEnum.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/logic/EELFLoggerDelegate.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/menu/MenuBuilder.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/menu/MenuProperties.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/AbstractCacheManager.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/support/FusionCacheManager.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/client/AppContextManager.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/client/OnBoardingApiServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/PortalRestClientBase.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/SharedContextRestClient.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/scheduler/CronRegistry.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AppServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AuditService.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AuditServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/BroadcastService.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/BroadcastServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/DataAccessServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ElementLinkService.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ElementMapService.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/FnMenuServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LdapServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LoginService.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LoginServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostSearchService.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostSearchServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ProfileServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceNonSpringImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/UserProfileService.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/UserProfileServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallServiceImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocatorImpl.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/CipherUtil.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/EncDecUtilTest.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/EncTest.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/SystemProperties.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/YamlUtils.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/AppUtils.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/MessagesList.java delete mode 100644 ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/UserUtils.java delete mode 100644 ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/MockApplicationContextTestSuite.java delete mode 100644 ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/MockHibernateMappingLocations.java delete mode 100644 ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/controller/sessionmgt/PortalCommunicationTest.java delete mode 100644 ecomp-sdk/sdk-analytics/.gitignore delete mode 100644 ecomp-sdk/sdk-analytics/README.md delete mode 100644 ecomp-sdk/sdk-analytics/pom.xml delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/AntBuild.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/config/ConfigLoader.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Action.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionHandler.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionMapping.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Controller.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ErrorHandler.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardProcessor.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequence.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceCrossTab.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceDashboard.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceLinear.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedCrossTab.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedHive.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinear.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinearDatamining.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserDefinedException.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GMapProperties.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/layer/SwingLayer.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/MapUtils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/DataCache.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportHandler.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportLoader.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/SearchHandler.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameColLookup.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameList.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameLookup.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameSql.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameValue.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/NameComparator.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportSecurity.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportWrapper.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportDefinition.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportMap.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/SecurityEntry.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PageEvent.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfReportHandler.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartD3Helper.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartGen.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSON.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartWebRuntime.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CommonChartOptions.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ErrorJSONRuntime.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormField.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormatProcessor.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/RangeAxisJSON.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportFormFields.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportJSONRuntime.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportParamDateValueParser.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportParamValues.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ReportRuntime.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/VisualManager.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/ReportSearchResult.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/ReportSearchResultJSON.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResult.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResultColumn.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResultField.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResultJSON.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/search/SearchResultRow.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/scheduler/SchedulerUtil.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/scheduler/SendEmail.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/scheduler/SendNotifications.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/AppUtils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/DbUtils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/ExecuteQuery.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/Globals.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/IAppUtils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/IDbUtils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/RDbUtils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/AntBuild.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/AppUtils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/DbUtils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/RemoteDbUtils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/AdapterSessionFactoryContainer.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/FusionAdapter.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/IdName.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/Lookup.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/adapter/RaptorAdapter.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/domain/CR_Report.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/service/RaptorService.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/service/RaptorServiceImpl.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/web/RaptorController.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/web/RaptorControllerAsync.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/system/fusion/web/ReportsSearchListController.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/AppConstants.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/DataSet.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/ExcelColorDef.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/HtmlStripper.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/Scheduler.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/Utils.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/XSSFilter.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/util/upgrade/SystemUpgrade.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ColumnHeader.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ColumnHeaderRow.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/CrossTabColumnValues.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/CrossTabOrderManager.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/CrossTabTotalValue.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/DataRow.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/DataValue.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ReportColumnHeaderRows.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ReportData.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ReportDataRows.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/ReportRowHeaderCols.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/RowHeader.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/view/RowHeaderCol.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ChartDrillOptions.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ColFilterList.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DashboardEditorList.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DashboardReports.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DashboardReportsNew.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DataColumnList.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/DataSourceList.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/FormFieldList.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/FormatList.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/JavascriptList.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/PredefinedValueList.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/ReportMap.java delete mode 100644 ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/xmlobj/SemaphoreList.java delete mode 100644 ecomp-sdk/sdk-app/.gitignore delete mode 100644 ecomp-sdk/sdk-app/README.md delete mode 100644 ecomp-sdk/sdk-app/db-scripts/EcompSdkDDLMySql_1610_Complete_OS.sql delete mode 100644 ecomp-sdk/sdk-app/db-scripts/EcompSdkDMLMySql_1610_Complete_OS.sql delete mode 100644 ecomp-sdk/sdk-app/distribution.xml delete mode 100644 ecomp-sdk/sdk-app/pom.xml delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/conf/ExternalAppConfig.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/conf/ExternalAppInitializer.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/conf/HibernateMappingLocations.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/controller/AngularSinglePageController.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/controller/CallflowController.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/controller/ElasticSearchController.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/controller/LeafletMapContoller.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/controller/PostDroolsController.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/controller/UserProfileController.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/controller/WelcomeController.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/model/Result.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/scheduler/LogJob.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/scheduler/LogRegistry.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/scheduler/Register.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/scheduler/RegistryAdapter.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/service/AdminAuthExtension.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/uebhandler/InitUebHandler.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/uebhandler/MainUebHandler.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/uebhandler/WidgetNotificationHandler.java delete mode 100644 ecomp-sdk/sdk-app/src/main/java/org/openecomp/portalapp/util/CustomLoggingFilter.java delete mode 100644 ecomp-sdk/sdk-app/src/main/resources/logback.xml delete mode 100644 ecomp-sdk/sdk-app/src/main/resources/portal.properties delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/conf/quartz.properties delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/conf/raptor.properties delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/conf/raptor_app_fusion.properties delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/conf/raptor_db_fusion.properties delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/conf/raptor_pdf.properties delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/conf/sql.properties delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/conf/system.properties delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/defs/definitions.xml delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/conf/fusion.properties delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/defs/definitions.xml delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/broadcast.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/broadcast_list.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/collaborateList.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/loginSnippet.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_noheader_nofooter.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_report_embedded.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/es_search_demo.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/frame_insert.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/jcs_admin.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/meta.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/post_search.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/profile.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/profile_search.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role_function_list.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role_list.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/usage_list.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/webrtc/collaboration.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_drill_down_report.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_import.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_wizard.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/leafletMap.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/login_external.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/user_profile.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/welcome.jsp delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/web.xml delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-animate.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-animate.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-animate.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-aria.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-aria.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-aria.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-csp.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-loader.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-loader.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-loader.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-message-format.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-message-format.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-messages.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-messages.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-messages.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-mocks.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-resource.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-resource.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-resource.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-route.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-route.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-route.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-sanitize.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-sanitize.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-sanitize.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-scenario.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-touch.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-touch.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-touch.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular.min.js.map delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/errors.json delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/version.json delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/version.txt delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/angular-animate.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/angular-cookies.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/angular-route.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/angular-route.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/angular-sanitize.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/angular-touch.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/angular.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/app.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/checklist-model.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/checklist-model.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/gestures.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/ng_base.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/angular_js/ui-charts-tpls.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/ebz_header/footer.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/ebz_header/header.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/ebz_header/portal_ebz_header.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/fn-ebz.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/images/no_favorites_star.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/js/attHeaderSnippet.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/js/footer.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/att-abs-tpls.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/att-abs-tpls.min.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/base.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/btn.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/demo.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/dtpk.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/frms.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/ie/backgroundsize.min.htc delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/images/upanddown.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/pages/iconography.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/sldr.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/style.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ebz/sandbox/styles/tbs.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/.gitignore delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/LICENSE delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/bower.json delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/component.json delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/composer.json delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/css/ionicons.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/css/ionicons.min.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/less/_ionicons-font.less delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/less/_ionicons-icons.less delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/less/_ionicons-variables.less delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/less/ionicons.less delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/alert-circled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/alert.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-add-contact.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-add.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-alarm.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-archive.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-arrow-back.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-arrow-down-left.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-arrow-down-right.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-arrow-forward.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-arrow-up-left.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-arrow-up-right.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-battery.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-book.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-calendar.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-call.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-camera.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-chat.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-checkmark.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-clock.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-close.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-contact.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-contacts.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-data.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-developer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-display.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-download.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-drawer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-dropdown.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-earth.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-folder.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-forums.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-friends.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-hand.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-image.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-inbox.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-information.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-keypad.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-lightbulb.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-locate.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-location.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-mail.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-microphone.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-mixer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-more.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-note.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-playstore.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-printer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-promotion.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-reminder.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-remove.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-search.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-send.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-settings.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-share.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-social-user.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-social.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-sort.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-stair-drawer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-star.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-stopwatch.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-storage.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-system-back.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-system-home.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-system-windows.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-timer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-trash.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-user-menu.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-volume.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/android-wifi.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/aperture.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/archive.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-down-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-down-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-down-c.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-expand.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-graph-down-left.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-graph-down-right.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-graph-up-left.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-graph-up-right.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-left-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-left-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-left-c.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-move.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-resize.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-return-left.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-return-right.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-right-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-right-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-right-c.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-shrink.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-swap.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-up-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-up-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/arrow-up-c.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/asterisk.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/at.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/bag.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/battery-charging.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/battery-empty.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/battery-full.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/battery-half.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/battery-low.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/beaker.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/beer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/bluetooth.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/bonfire.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/bookmark.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/briefcase.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/bug.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/calculator.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/calendar.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/camera.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/card.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/cash.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chatbox-working.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chatbox.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chatboxes.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chatbubble-working.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chatbubble.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chatbubbles.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/checkmark-circled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/checkmark-round.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/checkmark.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chevron-down.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chevron-left.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chevron-right.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/chevron-up.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/clipboard.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/clock.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/close-circled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/close-round.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/close.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/closed-captioning.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/cloud.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/code-download.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/code-working.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/code.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/coffee.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/compass.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/compose.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/connection-bars.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/contrast.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/cube.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/disc.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/document-text.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/document.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/drag.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/earth.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/edit.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/egg.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/eject.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/email.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/eye-disabled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/eye.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/female.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/filing.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/film-marker.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/fireball.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/flag.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/flame.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/flash-off.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/flash.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/flask.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/folder.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/fork-repo.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/fork.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/forward.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/funnel.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/game-controller-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/game-controller-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/gear-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/gear-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/grid.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/hammer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/happy.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/headphone.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/heart-broken.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/heart.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/help-buoy.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/help-circled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/help.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/home.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/icecream.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/icon-social-google-plus-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/icon-social-google-plus.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/image.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/images.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/information-circled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/information.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ionic.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-alarm-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-alarm.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-albums-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-albums.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-americanfootball-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-americanfootball.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-analytics-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-analytics.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-back.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-down.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-forward.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-left.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-right.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-thin-down.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-thin-left.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-thin-right.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-thin-up.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-arrow-up.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-at-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-at.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-barcode-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-barcode.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-baseball-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-baseball.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-basketball-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-basketball.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-bell-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-bell.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-bolt-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-bolt.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-bookmarks-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-bookmarks.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-box-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-box.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-briefcase-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-briefcase.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-browsers-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-browsers.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-calculator-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-calculator.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-calendar-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-calendar.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-camera-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-camera.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cart-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cart.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-chatboxes-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-chatboxes.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-chatbubble-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-chatbubble.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-checkmark-empty.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-checkmark-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-checkmark.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-circle-filled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-circle-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-clock-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-clock.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-close-empty.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-close-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-close.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloud-download-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloud-download.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloud-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloud-upload-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloud-upload.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloud.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloudy-night-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloudy-night.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloudy-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cloudy.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cog-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-cog.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-compose-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-compose.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-contact-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-contact.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-copy-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-copy.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-download-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-download.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-drag.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-email-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-email.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-expand.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-eye-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-eye.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-fastforward-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-fastforward.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-filing-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-filing.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-film-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-film.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-flag-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-flag.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-folder-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-folder.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-football-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-football.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-gear-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-gear.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-glasses-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-glasses.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-heart-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-heart.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-help-empty.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-help-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-help.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-home-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-home.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-infinite-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-infinite.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-information-empty.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-information-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-information.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-ionic-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-keypad-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-keypad.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-lightbulb-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-lightbulb.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-location-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-location.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-locked-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-locked.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-loop-strong.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-loop.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-medkit-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-medkit.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-mic-off.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-mic-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-mic.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-minus-empty.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-minus-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-minus.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-monitor-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-monitor.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-moon-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-moon.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-more-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-more.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-musical-note.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-musical-notes.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-navigate-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-navigate.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-paper-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-paper.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-paperplane-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-paperplane.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-partlysunny-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-partlysunny.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pause-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pause.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-paw-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-paw.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-people-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-people.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-person-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-person.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-personadd-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-personadd.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-photos-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-photos.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pie-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pie.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-play-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-play.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-plus-empty.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-plus-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-plus.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pricetag-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pricetag.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pricetags-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pricetags.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-printer-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-printer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pulse-strong.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-pulse.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-rainy-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-rainy.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-recording-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-recording.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-redo-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-redo.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-refresh-empty.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-refresh-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-refresh.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-reload.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-reverse-camera-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-reverse-camera.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-rewind-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-rewind.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-search-strong.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-search.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-settings-strong.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-settings.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-shrink.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-skipbackward-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-skipbackward.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-skipforward-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-skipforward.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-snowy.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-speedometer-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-speedometer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-star-half.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-star-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-star.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-stopwatch-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-stopwatch.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-sunny-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-sunny.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-telephone-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-telephone.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-tennisball-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-tennisball.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-thunderstorm-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-thunderstorm.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-time-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-time.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-timer-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-timer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-toggle-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-toggle.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-trash-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-trash.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-undo-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-undo.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-unlocked-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-unlocked.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-upload-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-upload.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-videocam-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-videocam.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-volume-high.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-volume-low.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-wineglass-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-wineglass.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-world-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ios7-world.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ipad.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/iphone.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ipod.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/jet.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/key.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/knife.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/laptop.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/leaf.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/levels.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/lightbulb.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/link.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/load-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/load-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/load-c.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/load-d.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/location.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/locked.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/log-in.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/log-out.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/loop.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/magnet.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/male.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/man.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/map.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/medkit.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/merge.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/mic-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/mic-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/mic-c.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/minus-circled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/minus-round.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/minus.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/model-s.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/monitor.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/more.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/mouse.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/music-note.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/navicon-round.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/navicon.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/navigate.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/network.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/no-smoking.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/nuclear.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/outlet.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/paper-airplane.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/paperclip.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/pause.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/person-add.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/person-stalker.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/person.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/pie-graph.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/pin.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/pinpoint.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/pizza.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/plane.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/planet.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/play.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/playstation.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/plus-circled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/plus-round.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/plus.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/podium.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/pound.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/power.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/pricetag.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/pricetags.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/printer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/pull-request.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/qr-scanner.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/quote.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/radio-waves.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/record.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/refresh.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/reply-all.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/reply.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ribbon-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/ribbon-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/sad.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/scissors.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/search.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/settings.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/share.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/shuffle.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/skip-backward.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/skip-forward.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-android-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-android.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-apple-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-apple.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-bitcoin-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-bitcoin.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-buffer-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-buffer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-designernews-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-designernews.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-dribbble-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-dribbble.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-dropbox-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-dropbox.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-facebook-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-facebook.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-foursquare-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-foursquare.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-freebsd-devil.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-github-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-github.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-google-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-google.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-googleplus-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-googleplus.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-hackernews-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-hackernews.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-instagram-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-instagram.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-linkedin-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-linkedin.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-pinterest-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-pinterest.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-reddit-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-reddit.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-rss-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-rss.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-skype-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-skype.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-tumblr-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-tumblr.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-tux.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-twitter-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-twitter.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-usd-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-usd.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-vimeo-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-vimeo.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-windows-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-windows.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-wordpress-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-wordpress.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-yahoo-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-yahoo.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-youtube-outline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/social-youtube.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/speakerphone.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/speedometer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/spoon.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/star.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/stats-bars.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/steam.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/stop.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/thermometer.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/thumbsdown.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/thumbsup.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/toggle-filled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/toggle.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/trash-a.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/trash-b.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/trophy.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/umbrella.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/university.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/unlocked.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/upload.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/usb.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/videocamera.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/volume-high.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/volume-low.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/volume-medium.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/volume-mute.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/wand.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/waterdrop.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/wifi.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/wineglass.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/woman.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/wrench.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/png/512/xbox.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/readme.md delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/scss/_ionicons-font.scss delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/scss/_ionicons-icons.scss delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/scss/_ionicons-variables.scss delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/scss/ionicons.scss delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/alert-circled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/alert.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-add-circle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-add.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-alarm-clock.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-alert.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-apps.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-archive.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-back.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-down.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-dropdown-circle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-dropdown.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-dropleft-circle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-dropleft.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-dropright-circle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-dropright.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-dropup-circle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-dropup.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-forward.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-arrow-up.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-attach.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-bar.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-bicycle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-boat.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-bookmark.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-bulb.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-bus.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-calendar.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-call.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-camera.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-cancel.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-car.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-cart.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-chat.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-checkbox-blank.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-checkbox-outline-blank.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-checkbox-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-checkbox.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-checkmark-circle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-clipboard.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-close.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-cloud-circle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-cloud-done.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-cloud-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-cloud.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-color-palette.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-compass.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-contact.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-contacts.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-contract.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-create.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-delete.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-desktop.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-document.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-done-all.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-done.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-download.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-drafts.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-exit.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-expand.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-favorite-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-favorite.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-film.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-folder-open.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-folder.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-funnel.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-globe.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-hand.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-hangout.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-happy.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-home.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-image.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-laptop.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-list.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-locate.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-lock.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-mail.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-map.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-menu.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-microphone-off.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-microphone.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-more-horizontal.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-more-vertical.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-navigate.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-notifications-none.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-notifications-off.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-notifications.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-open.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-options.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-people.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-person-add.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-person.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-phone-landscape.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-phone-portrait.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-pin.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-plane.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-playstore.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-print.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-radio-button-off.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-radio-button-on.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-refresh.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-remove-circle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-remove.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-restaurant.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-sad.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-search.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-send.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-settings.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-share-alt.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-share.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-star-half.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-star-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-star.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-stopwatch.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-subway.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-sunny.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-sync.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-textsms.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-time.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-train.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-unlock.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-upload.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-volume-down.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-volume-mute.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-volume-off.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-volume-up.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-walk.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-warning.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-watch.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/android-wifi.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/aperture.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/archive.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-down-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-down-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-down-c.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-expand.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-graph-down-left.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-graph-down-right.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-graph-up-left.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-graph-up-right.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-left-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-left-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-left-c.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-move.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-resize.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-return-left.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-return-right.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-right-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-right-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-right-c.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-shrink.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-swap.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-up-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-up-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/arrow-up-c.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/asterisk.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/at.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/backspace-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/backspace.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/bag.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/battery-charging.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/battery-empty.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/battery-full.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/battery-half.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/battery-low.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/beaker.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/beer.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/bluetooth.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/bonfire.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/bookmark.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/bowtie.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/briefcase.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/bug.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/calculator.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/calendar.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/camera.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/card.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/cash.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chatbox-working.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chatbox.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chatboxes.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chatbubble-working.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chatbubble.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chatbubbles.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/checkmark-circled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/checkmark-round.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/checkmark.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chevron-down.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chevron-left.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chevron-right.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/chevron-up.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/clipboard.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/clock.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/close-circled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/close-round.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/close.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/closed-captioning.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/cloud.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/code-download.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/code-working.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/code.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/coffee.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/compass.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/compose.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/connection-bars.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/contrast.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/crop.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/cube.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/disc.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/document-text.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/document.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/drag.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/earth.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/easel.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/edit.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/egg.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/eject.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/email-unread.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/email.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/erlenmeyer-flask-bubbles.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/erlenmeyer-flask.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/eye-disabled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/eye.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/female.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/filing.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/film-marker.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/fireball.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/flag.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/flame.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/flash-off.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/flash.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/folder.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/fork-repo.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/fork.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/forward.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/funnel.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/gear-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/gear-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/grid.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/hammer.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/happy-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/happy.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/headphone.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/heart-broken.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/heart.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/help-buoy.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/help-circled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/help.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/home.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/icecream.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/image.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/images.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/information-circled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/information.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ionic.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-alarm-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-alarm.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-albums-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-albums.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-americanfootball-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-americanfootball.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-analytics-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-analytics.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-back.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-down.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-forward.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-left.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-right.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-thin-down.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-thin-left.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-thin-right.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-thin-up.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-arrow-up.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-at-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-at.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-barcode-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-barcode.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-baseball-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-baseball.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-basketball-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-basketball.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-bell-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-bell.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-body-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-body.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-bolt-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-bolt.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-book-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-book.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-bookmarks-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-bookmarks.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-box-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-box.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-briefcase-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-briefcase.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-browsers-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-browsers.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-calculator-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-calculator.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-calendar-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-calendar.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-camera-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-camera.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cart-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cart.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-chatboxes-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-chatboxes.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-chatbubble-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-chatbubble.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-checkmark-empty.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-checkmark-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-checkmark.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-circle-filled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-circle-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-clock-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-clock.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-close-empty.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-close-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-close.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloud-download-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloud-download.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloud-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloud-upload-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloud-upload.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloud.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloudy-night-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloudy-night.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloudy-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cloudy.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cog-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-cog.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-color-filter-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-color-filter.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-color-wand-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-color-wand.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-compose-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-compose.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-contact-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-contact.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-copy-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-copy.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-crop-strong.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-crop.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-download-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-download.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-drag.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-email-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-email.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-eye-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-eye.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-fastforward-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-fastforward.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-filing-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-filing.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-film-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-film.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-flag-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-flag.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-flame-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-flame.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-flask-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-flask.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-flower-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-flower.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-folder-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-folder.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-football-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-football.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-game-controller-a-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-game-controller-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-game-controller-b-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-game-controller-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-gear-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-gear.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-glasses-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-glasses.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-grid-view-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-grid-view.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-heart-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-heart.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-help-empty.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-help-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-help.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-home-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-home.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-infinite-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-infinite.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-information-empty.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-information-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-information.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-ionic-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-keypad-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-keypad.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-lightbulb-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-lightbulb.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-list-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-list.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-location-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-location.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-locked-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-locked.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-loop-strong.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-loop.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-medical-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-medical.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-medkit-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-medkit.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-mic-off.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-mic-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-mic.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-minus-empty.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-minus-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-minus.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-monitor-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-monitor.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-moon-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-moon.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-more-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-more.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-musical-note.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-musical-notes.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-navigate-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-navigate.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-nutrition-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-nutrition.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-paper-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-paper.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-paperplane-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-paperplane.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-partlysunny-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-partlysunny.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pause-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pause.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-paw-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-paw.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-people-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-people.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-person-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-person.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-personadd-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-personadd.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-photos-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-photos.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pie-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pie.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pint-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pint.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-play-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-play.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-plus-empty.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-plus-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-plus.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pricetag-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pricetag.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pricetags-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pricetags.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-printer-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-printer.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pulse-strong.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-pulse.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-rainy-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-rainy.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-recording-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-recording.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-redo-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-redo.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-refresh-empty.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-refresh-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-refresh.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-reload.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-reverse-camera-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-reverse-camera.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-rewind-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-rewind.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-rose-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-rose.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-search-strong.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-search.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-settings-strong.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-settings.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-shuffle-strong.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-shuffle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-skipbackward-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-skipbackward.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-skipforward-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-skipforward.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-snowy.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-speedometer-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-speedometer.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-star-half.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-star-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-star.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-stopwatch-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-stopwatch.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-sunny-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-sunny.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-telephone-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-telephone.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-tennisball-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-tennisball.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-thunderstorm-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-thunderstorm.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-time-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-time.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-timer-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-timer.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-toggle-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-toggle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-trash-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-trash.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-undo-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-undo.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-unlocked-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-unlocked.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-upload-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-upload.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-videocam-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-videocam.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-volume-high.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-volume-low.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-wineglass-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-wineglass.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-world-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ios-world.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ipad.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/iphone.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ipod.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/jet.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/key.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/knife.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/laptop.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/leaf.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/levels.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/lightbulb.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/link.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/load-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/load-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/load-c.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/load-d.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/location.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/lock-combination.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/locked.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/log-in.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/log-out.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/loop.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/magnet.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/male.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/man.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/map.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/medkit.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/merge.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/mic-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/mic-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/mic-c.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/minus-circled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/minus-round.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/minus.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/model-s.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/monitor.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/more.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/mouse.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/music-note.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/navicon-round.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/navicon.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/navigate.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/network.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/no-smoking.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/nuclear.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/outlet.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/paintbrush.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/paintbucket.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/paper-airplane.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/paperclip.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/pause.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/person-add.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/person-stalker.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/person.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/pie-graph.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/pin.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/pinpoint.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/pizza.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/plane.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/planet.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/play.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/playstation.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/plus-circled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/plus-round.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/plus.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/podium.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/pound.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/power.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/pricetag.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/pricetags.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/printer.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/pull-request.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/qr-scanner.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/quote.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/radio-waves.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/record.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/refresh.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/reply-all.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/reply.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ribbon-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/ribbon-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/sad-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/sad.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/scissors.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/search.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/settings.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/share.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/shuffle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/skip-backward.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/skip-forward.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-android-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-android.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-angular-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-angular.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-apple-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-apple.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-bitcoin-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-bitcoin.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-buffer-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-buffer.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-chrome-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-chrome.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-codepen-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-codepen.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-css3-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-css3.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-designernews-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-designernews.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-dribbble-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-dribbble.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-dropbox-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-dropbox.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-euro-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-euro.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-facebook-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-facebook.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-foursquare-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-foursquare.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-freebsd-devil.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-github-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-github.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-google-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-google.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-googleplus-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-googleplus.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-hackernews-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-hackernews.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-html5-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-html5.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-instagram-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-instagram.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-javascript-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-javascript.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-linkedin-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-linkedin.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-markdown.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-nodejs.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-octocat.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-pinterest-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-pinterest.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-python.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-reddit-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-reddit.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-rss-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-rss.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-sass.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-skype-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-skype.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-snapchat-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-snapchat.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-tumblr-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-tumblr.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-tux.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-twitch-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-twitch.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-twitter-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-twitter.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-usd-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-usd.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-vimeo-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-vimeo.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-whatsapp-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-whatsapp.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-windows-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-windows.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-wordpress-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-wordpress.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-yahoo-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-yahoo.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-yen-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-yen.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-youtube-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/social-youtube.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/soup-can-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/soup-can.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/speakerphone.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/speedometer.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/spoon.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/star.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/stats-bars.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/steam.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/stop.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/thermometer.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/thumbsdown.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/thumbsup.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/toggle-filled.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/toggle.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/transgender.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/trash-a.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/trash-b.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/trophy.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/tshirt-outline.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/tshirt.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/umbrella.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/university.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/unlocked.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/upload.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/usb.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/videocamera.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/volume-high.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/volume-low.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/volume-medium.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/volume-mute.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/wand.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/waterdrop.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/wifi.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/wineglass.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/woman.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/wrench.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/ionicons-2.0.1/src/xbox.svg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/utils/js/browserCheck.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/controllers/nbook-framecontroller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/controllers/nbookController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/controllers/notebookFrameController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-frame.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-viz.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook.htm delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebookInputs.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/adminController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/admin_menu_edit.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/ase-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/broadcast-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/broadcast-list-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/collaborate-list-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/fn_menu_add_popup_controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/jcs-admin-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/modelpopupController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/post-search-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profile-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profile-search-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profileController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-function-list-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-list-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/rolefunctionpopupController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/rolepopupmodelController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/self-profile-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/usage-list-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowApp.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowRouting.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/footer.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/header.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/leftMenu.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/adminService.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/headerService.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/leftMenuService.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/profileService.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/userInfoService.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/socket/peerBroadcast.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/utils/page-resource.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/admin-page/admin.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/admin-page/profile.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/footer.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/header.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/left_menu.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/admin_menu_edit.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast_list.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/collaborate_list.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/jcs_admin.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_add.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_edit.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_role.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_rolefunction.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/post_search.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/profile_detail.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/profile_search.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role_function_list.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role_list.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/self_profile.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/usage_list.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-landing.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-listing.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-new.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-preview.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-remove.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-schedule.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/webrtc/RTCMultiConnection.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/fusion-sunny.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/workflows/workflows.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/drools-list-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/drools-view-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/droolsController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/services/droolsService.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsList.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsSinglePage.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsView.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sample-page-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sample-page-iframe-controller.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sampleController.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/sample.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/sampleWithIframe.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/singlePageSample.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/fusion-sunny.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/jquery-ui.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/layout/layout-default-latest.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/Rlogo.jpg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/Thumbs.db delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/action_icon.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/action_list_spacer.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/active.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/add.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/add_tool_button.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/addicon.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/application_window_bg.jpg delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/backButton.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/blueButton.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/bubble.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/cache.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/calendar.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/chevron.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/close_container.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/collapsed-icon.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/column-bg.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/customers-add.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/customers-search.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/customers.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/decrypted.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/error_type.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/excelicon_multi.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/expanded-icon.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/file-add.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/file_save-all.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/filter_icon.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_add.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_closed.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_delete.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_edit.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_open.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_user.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/funnel.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/fusion.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/grayButton.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/gray_add_tool_button.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/headerChatIcon.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/icon_remove_all.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/inactive.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/info_type.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/leftButton.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/loading_bar.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/login_button.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/m1.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/mail.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/map.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/no_favorites_star.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/note-add.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/note-search.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/note.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/notes.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/offline.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/offlineMsg.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/online.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/page.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/pagination.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/panel-e-w-toggle.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/panel-n-s-toggle.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/pix.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/printer.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/profile.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-first-active.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-first-disabled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-last-active.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-last-disabled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-next-active.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-next-disabled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-prev-active.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-prev-disabled.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/resultset_last.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/resultset_previous.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/return_to_top.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/rightButton.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/search_profile.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/sort_asc.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/sort_desc.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/spacer.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/success_type.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/swoosh.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/tab-hm.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/tab-v-hm.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/tab.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/table-add.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/table-delete.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/table-edit.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/table.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/tabs-bg.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/toolButton.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/toolButton.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/toolbar.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/users.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/warning_type.gif delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/webphone.ico delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/whiteButton.png delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/ral.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/intro.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_run.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_run.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_search.html delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_search.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/other_scripts.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.js delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/fusion/sample/css/welcome.css delete mode 100644 ecomp-sdk/sdk-app/src/main/webapp/static/js/search.js delete mode 100644 ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/SanityTest.java delete mode 100644 ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/controller/CollaborationControllerTest.java delete mode 100644 ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/controller/NetMapTest.java delete mode 100644 ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/service/ProfileServiceTest.java delete mode 100644 ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalsdk/core/MockApplicationContextTestSuite.java delete mode 100644 ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleServiceTest.java delete mode 100644 ecomp-sdk/sdk-workflow/.gitignore delete mode 100644 ecomp-sdk/sdk-workflow/README.md delete mode 100644 ecomp-sdk/sdk-workflow/pom.xml delete mode 100644 ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookController.java delete mode 100644 ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookTestController.java delete mode 100644 ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookController.java delete mode 100644 ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/domain/RNoteBookCredentials.java delete mode 100644 ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationServiceImpl.java delete mode 100644 ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/HibernateConfiguration.java delete mode 100644 ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/Workflow.java delete mode 100644 ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleExecutor.java delete mode 100644 ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowService.java delete mode 100644 ecomp-sdk/thirdparty/.gitignore delete mode 100644 ecomp-sdk/thirdparty/README.md delete mode 100644 ecomp-sdk/thirdparty/pom.xml delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/ECOMPSSOFilter.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/SecureServlet.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/UnSecureServlet.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/CipherUtil.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/ECOMPSSO.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIException.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiConstants.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiProperties.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutBindingListener.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutHandler.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutVO.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunication.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserContextListener.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserSessionListener.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java delete mode 100644 ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java diff --git a/ecomp-sdk/LICENSE.txt b/ecomp-sdk/LICENSE.txt deleted file mode 100644 index 880bbc9d..00000000 --- a/ecomp-sdk/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * ============LICENSE_START=========================================================== - * ==================================================================================== - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * ==================================================================================== - * Licensed 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. - * ==================================================================================== - * ECOMP and OpenECOMP are trademarks and service marks of AT&T Intellectual Property. - */ \ No newline at end of file diff --git a/ecomp-sdk/README.md b/ecomp-sdk/README.md index f3a52dcb..7af36cb6 100644 --- a/ecomp-sdk/README.md +++ b/ecomp-sdk/README.md @@ -1,15 +1,17 @@ -ECOMP Portal SDK -================ +# ECOMP Portal SDK This is the parent Maven project for the following -ECOMP Portal SDK maven child projects: +ECOMP Portal SDK child Maven projects: * SDK Framework library * SDK Core library * SDK Analytics library * SDK Workflow library +* SDK Common Application library +* SDK Common Overlay Web Application -This area also includes the ECOMP Portal SDK web application, which -is a sample web app to build and deploy to a Tomcat instance. +This area also includes ECOMP Portal SDK web application projects +for AT&T internal use and open source distribution, but they are +not child Maven projects. Release notes are published in each project. diff --git a/ecomp-sdk/epsdk-analytics/.gitignore b/ecomp-sdk/epsdk-analytics/.gitignore new file mode 100644 index 00000000..aa0c881b --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/.gitignore @@ -0,0 +1,5 @@ +/target +/bin/ +/.settings/ +.project +.classpath diff --git a/ecomp-sdk/epsdk-analytics/README.md b/ecomp-sdk/epsdk-analytics/README.md new file mode 100644 index 00000000..be0b376c --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/README.md @@ -0,0 +1,16 @@ +# ECOMP Portal SDK Analytics + +## Overview + +This is the Maven project for the ECOMP Portal SDK Analytics library, +which is distributed as epsdk-analytics-N.N.N.jar. This library +requires Hibernate and Spring, and provides data-visualization +features including charts, maps and reports ("Raptor"). + +## Release Notes + +Version 1.1.0 +- [Portal-7] Improvements added as part of the rebasing process + +Version 1.0.0 +- Initial release diff --git a/ecomp-sdk/epsdk-analytics/license/licenses.properties b/ecomp-sdk/epsdk-analytics/license/licenses.properties new file mode 100644 index 00000000..4b0e28e7 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/license/licenses.properties @@ -0,0 +1 @@ +my_license=My license diff --git a/ecomp-sdk/epsdk-analytics/license/my_license/header.txt b/ecomp-sdk/epsdk-analytics/license/my_license/header.txt new file mode 100644 index 00000000..c026b6b7 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/license/my_license/header.txt @@ -0,0 +1,11 @@ +Licensed 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. diff --git a/ecomp-sdk/epsdk-analytics/license/my_license/license.txt b/ecomp-sdk/epsdk-analytics/license/my_license/license.txt new file mode 100644 index 00000000..bf326153 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/license/my_license/license.txt @@ -0,0 +1,4 @@ +name=my_license +description= +licenseURL= +headerURL= \ No newline at end of file diff --git a/ecomp-sdk/epsdk-analytics/pom.xml b/ecomp-sdk/epsdk-analytics/pom.xml new file mode 100644 index 00000000..41be4f28 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/pom.xml @@ -0,0 +1,209 @@ + + + 4.0.0 + + + org.openecomp.ecompsdkos + epsdk-project + 1.1.0-SNAPSHOT + + + + epsdk-analytics + + jar + ECOMP Portal SDK Analytics + Provides analytics features for SDK applications + https://wiki.onap.org/display/DW/Portal + + + + + + + + + + + + + + org.openecomp.ecompsdkos + epsdk-core + ${project.version} + + + + com.fasterxml.jackson.core + jackson-annotations + 2.6.3 + + + com.fasterxml.jackson.core + jackson-core + 2.6.3 + + + com.fasterxml.jackson.core + jackson-databind + 2.6.3 + + + + + commons-codec + commons-codec + 1.10 + + + commons-lang + commons-lang + 2.6 + + + javax.servlet + javax.servlet-api + 3.1.0 + + + + com.lowagie + itext + 2.0.8 + + + + org.slf4j + jcl-over-slf4j + 1.7.12 + + + org.springframework + spring-core + ${springframework.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-orm + ${springframework.version} + + + org.springframework + spring-web + ${springframework.version} + + + org.springframework + spring-webmvc + ${springframework.version} + + + + org.apache.poi + poi + 3.5-FINAL + + + commons-logging + commons-logging + + + log4j + log4j + + + + + org.apache.poi + poi-ooxml + 3.5-FINAL + + + commons-logging + commons-logging + + + log4j + log4j + + + + + org.apache.poi + poi-scratchpad + 3.5-FINAL + + + commons-logging + commons-logging + + + log4j + log4j + + + + + org.apache.poi + poi-contrib + 3.5-FINAL + + + commons-logging + commons-logging + + + log4j + log4j + + + + + + diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/AntBuild.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/AntBuild.java new file mode 100644 index 00000000..7065c9b9 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/AntBuild.java @@ -0,0 +1,91 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics; + +import java.io.IOException; +import java.net.URL; +import java.util.Iterator; +import java.util.Map; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +/** + * @author sundar + * This class is used to get version and Build information when + * user run "java -jar raptor_classes.jar" command. + */ +public class AntBuild { + + public static String buildNum = ""; + + public static void main(String[] args) { + System.out.println("Jar (raptor_classes.jar) Information: "); + readManifest(); + } + + public static void readManifest() { + try { + Class clazz = AntBuild.class; + String classContainer = clazz.getProtectionDomain().getCodeSource().getLocation().toString(); + URL manifestUrl = new URL("jar:" + classContainer + "!/META-INF/MANIFEST.MF"); + Manifest manifest = new Manifest(manifestUrl.openStream()); + + //JarFile jar = new JarFile("../lib/raptor_classes.jar"); + //Manifest manifest = jar.getManifest(); + + Attributes attribs = manifest.getMainAttributes(); + Iterator it = attribs.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + Attributes.Name attributeName = (Attributes.Name) entry.getKey(); + String attributeValue = (String) entry.getValue(); + if (attributeName.toString().equals("Created-By")) + System.out.println("Java HotSpot(TM) Client VM " + " : " + attributeValue); + else if (attributeName.toString().equals("Java-Version")) + System.out.println("Java Version " + " : " + attributeValue); + else if (attributeName.toString().equals("Java-Runtime-Version")) + System.out.println("Java Runtime Version " + " : " + attributeValue); + else if (attributeName.toString().equals("Ant-Version")) + System.out.println(attributeName.toString() + " : " + attributeValue); + else { + if(attributeName.toString().startsWith("Raptor")) { + if (attributeName.toString().startsWith("Raptor-Build-Version")) + buildNum = attributeValue; + System.out.println(attributeName.toString() + " : " + attributeValue); + } + } + } + + } catch (IOException e) { + System.err.println("Cannot read jar-file manifest: " + + e.getMessage()); + } + } + + public static String getBuildNum() { + if (buildNum.length()>0) + return buildNum; + else { + readManifest(); + return buildNum; + } + } +} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/RaptorObject.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/RaptorObject.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/RaptorObject.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/RaptorObject.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/config/ConfigLoader.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/config/ConfigLoader.java new file mode 100644 index 00000000..2aa8b7bd --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/config/ConfigLoader.java @@ -0,0 +1,193 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.config; + +import java.io.*; +import java.util.*; +import javax.servlet.*; + +import org.openecomp.portalsdk.analytics.controller.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class ConfigLoader { + // public static final String RAPTOR_ACTION_MAP = + // "raptor_action_map.properties"; + + private static final String P_FILE_EXTENSION = ".properties"; + + public static final String RAPTOR_PROPERTIES = "raptor"; + + public static final String SQL_PROPERTIES = "sql"; + + public static final String APP_PROPERTIES = "raptor_app"; + + public static final String DB_PROPERTIES = "raptor_db"; + + private static String configFilesPath = "/WEB-INF/conf/"; + + public static final String RAPTOR_PDF_PROPERTIES = "raptor_pdf"; + + // private static String internalFilesPath = + // "/WEB-INF/classes/org/openecomp/portalsdk/analytics/config"; // Used for internal files that + // are not supposed to be modified by the user; may be unavailable in some + // cases - so defaults are expected + + private static String raptorActionMapString = + "report.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_run.jsp \n" + + "mobile.report.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |mobile_report_run.jsp \n" + + "report.dashrep1.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDashRep1 |report_run_dashrep1.jsp \n" + + "report.dashrep2.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDashRep2 |report_run_dashrep2.jsp \n" + + "report.dashrep3.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDashRep3 |report_run_dashrep3.jsp \n" + + "report.dashrep4.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDashRep4 |report_run_dashrep4.jsp \n" + + "report.download |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_xls.jsp \n" + + "report.download.excel2007 |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_xlsx.jsp \n" + + "report.download.page |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_page_xls.jsp \n" + + "report.csv.download |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_csv.jsp \n" + + "report.text.download |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_txt.jsp \n" + + "report.search |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearch |report_search.jsp \n" + + "report.search.execute |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearchExecute |report_search \n" + + "report.search.user |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearchUser |report_search.jsp \n" + + "report.search.public |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearchPublic |report_search.jsp \n" + + "report.search.favorite |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearchFavorites |report_search.jsp \n" + + "report.wizard |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportWizard |report_wizard \n" + + "report.create |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportCreate |report_wizard \n" + + "report.import |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_import \n" + + "report.import.save |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportImportSave |report_wizard \n" + + "report.copy |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportCopy |report_wizard \n" + + "report.copy.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportCopy |raptor_wizard_container.jsp \n" + + "report.edit |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportEdit |report_wizard \n" + + "report.delete |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDelete |report_search \n" + + "report.popup.field |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportFormFieldPopup |popup_field.jsp \n" + + "report.popup.map |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportValuesMapDefPopup |popup_map.jsp \n" + + "report.popup.drilldown.table |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_drill_down_table.jsp \n" + + "report.popup.drilldown.report|org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDrillDownToReportDefPopup|popup_drill_down_report \n" + + "report.popup.import.semaphore|org.openecomp.portalsdk.analytics.controller.ActionHandler|importSemaphorePopup |popup_import_semaphore \n" + + "report.popup.semaphore |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_semaphore \n" + + "report.popup.semaphore.save |org.openecomp.portalsdk.analytics.controller.ActionHandler|saveSemaphorePopup |popup_semaphore \n" + + "report.popup.filter.col |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_filter_col.jsp \n" + + "report.popup.filter.data |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportFilterDataPopup |popup_filter_data.jsp \n" + + "report.popup.sql |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportShowSQLPopup |popup_sql \n " + + "report.run.popup |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_run_popup.jsp \n" + + "report.popup.test.cond |org.openecomp.portalsdk.analytics.controller.ActionHandler|testSchedCondPopup |popup_sql \n" + + "report.popup.testrun.sql |org.openecomp.portalsdk.analytics.controller.ActionHandler|testRunSQLPopup |popup_testrun_sql \n" + + "report.test.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |test_run_sql \n" + + "report.field.testrun.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |test_field_run_sql \n" + + "report.field.default.testrun.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |default_field_run_sql \n" + + "report.field.date.start.testrun.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |date_start_field_run_sql \n" + + "report.field.date.end.testrun.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |date_end_field_run_sql \n" + + "report.popup.table.cols |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_table_cols \n" + + "refresh.cache |org.openecomp.portalsdk.analytics.controller.ActionHandler|refreshCache |message.jsp \n" + + "report.message |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |message.jsp \n" + + "report.download.pdf |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_pdf.jsp \n" + + "report.popup.pdfconfig |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_pdf_config.jsp \n" + + "download.all |org.openecomp.portalsdk.analytics.controller.ActionHandler|downloadAll |close.jsp \n" + + "download.all.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_download_flat_file.jsp \n" + + "download.data.file |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |download_data_file.jsp \n" + + "popup.calendar |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |gtm_calendar.jsp \n" + + "report.folderlist |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |folder_report_list.jsp \n" + + "report.folderlist_iframe |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |folder_report_list_iframe.jsp \n" + + "report.childDropDown |org.openecomp.portalsdk.analytics.controller.ActionHandler|getChildDropDown |raptor_childdropdown.jsp \n" + + "report.create.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_create_container.jsp \n" + + "report.search.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_container.jsp \n" + + "report.search.execute.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_execute_container.jsp \n" + + "report.search.user.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_user_container.jsp \n" + + "report.search.public.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_public_container.jsp \n" + + "report.search.favorite.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_favorite_container.jsp \n" + + "report.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_run_container.jsp \n" + + "report.formfields.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|formFieldRun |report_run_container.jsp \n" + + "report.run.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_run.jsp \n" + + "report.schedule.multiple |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |wizard_schedule_multiple.jsp \n" + + "report.schedule.submit |org.openecomp.portalsdk.analytics.controller.ActionHandler|processSchedule |wizard_schedule_only.jsp \n" + + "report.schedule.report.submit |org.openecomp.portalsdk.analytics.controller.ActionHandler|processScheduleReportList |wizard_schedule_only.jsp \n" + + "report.schedule.report.submit_wmenu |org.openecomp.portalsdk.analytics.controller.ActionHandler|processScheduleReportList |wizard_schedule_only_from_search.jsp \n" + + "report.schedule_only |org.openecomp.portalsdk.analytics.controller.ActionHandler|processSchedule |wizard_schedule_only \n" + + "report.schedule_only_from_search |org.openecomp.portalsdk.analytics.controller.ActionHandler|processSchedule |wizard_schedule_only_from_search.jsp \n" + + "report.schedule_delete |org.openecomp.portalsdk.analytics.controller.ActionHandler|processScheduleDelete |report_run_container.jsp \n" + + "report.schedule.submit_from_search |org.openecomp.portalsdk.analytics.controller.ActionHandler|processSchedule |wizard_schedule_only_from_search.jsp \n" + + "report.dashboard.detail |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |dashboard_report_run_detail.jsp \n" + + "report.csv.download.direct |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_csv.jsp \n" + + "report.csv.download.direct |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_csv.jsp \n" + + "report.download.csv.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_csv \n" + + "report.download.excel2007.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_xlsx.jsp \n" + + "report.download.excel.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_xls.jsp \n" + + "report.download.pdf.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_pdf.jsp \n" + + "report.download.page.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_page_xls.jsp \n" + + "report.data.remove.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|removeReportDataFromSession |report_run_container.jsp \n" + + "report.dashboard.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_dashboard_run_container.jsp \n" + + "chart.force.cluster |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |force_cluster.jsp \n" + + "chart.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportChartRun |report_run_container.jsp \n" + + "chart.json |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportChartRun |report_run_container.jsp \n" + + "chart.data.json |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportChartDataRun |report_run_container.jsp \n" + + "quicklinks.json |org.openecomp.portalsdk.analytics.controller.ActionHandler|getQuickLinksJSON |report_run_container.jsp \n" + + "embed.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_embed_run_container.zul \n" + + "schedule.edit |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |wizard_adhoc_schedule.zul \n" + + "chart.annotations.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |plugin_chart_annotation.jsp \n" + + "chart.annotations.exec |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |chart_annotations.jsp \n" + + "chart.mini |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |chart_minified.jsp \n" + + "report.olap.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_olap_run_container.jsp \n" + + "report.hive.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_hive_run_container.jsp \n" + + ; + + private ConfigLoader() { + } + + public static void setConfigFilesPath(String path) { + configFilesPath = path; + } // setConfigFilesPath + + public static Properties getProperties(ServletContext servletContext, String propertiesFile) + throws IOException { + return getProperties(servletContext, propertiesFile, null); + } // getProperties + + public static Properties getProperties(ServletContext servletContext, + String propertiesFile, String systemTypeExtension) throws IOException { + Properties p = new Properties(); + p.load(servletContext.getResourceAsStream(configFilesPath + propertiesFile + + ((systemTypeExtension == null) ? "" : "_" + systemTypeExtension) + + P_FILE_EXTENSION)); + return p; + } // getProperties + + public static ActionMapping loadRaptorActionMapping(ServletContext servletContext) + throws IOException { + ActionMapping actionMapping = new ActionMapping(); + + String pLine = null; + // BufferedReader pFile = new BufferedReader(new + // InputStreamReader(servletContext.getResourceAsStream(internalFilesPath+RAPTOR_ACTION_MAP))); + BufferedReader pFile = new BufferedReader(new StringReader(raptorActionMapString)); + while ((pLine = pFile.readLine()) != null) + if (pLine.trim().length() > 0) + try { + actionMapping.addAction(Action.parse(pLine)); + } catch (Exception e) { + Log + .write("[ConfigLoader.loadRaptorActionMapping] Error - unable to parse action [" + + pLine + "]"); + } + pFile.close(); + + return actionMapping; + } // loadRaptorActionMapping + +} // ConfigLoader + diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Action.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Action.java new file mode 100644 index 00000000..853901fb --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Action.java @@ -0,0 +1,91 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.system.*; + +public class Action extends org.openecomp.portalsdk.analytics.RaptorObject { + private String action = null; + + private String controllerClass = null; + + private String controllerMethod = null; + + private String jspName = null; + + private Action() { + } + + public Action(String action, String controllerClass, String controllerMethod, + String jspName) { + setAction(action); + setControllerClass(controllerClass); + setControllerMethod(controllerMethod); + setJspName(jspName); + } // Action + + public static Action parse(String configFileEntry) { + Action a = new Action(); + + StringTokenizer st = new StringTokenizer(configFileEntry, "| \t", false); + // if(st.hasMoreTokens()) + a.setAction(st.nextToken()); + a.setControllerClass(st.nextToken()); + a.setControllerMethod(st.nextToken()); + a.setJspName(st.nextToken()); + + return a; + } // parse + + public String getAction() { + return action; + } + + public String getControllerClass() { + return controllerClass; + } + + public String getControllerMethod() { + return controllerMethod; + } + + public String getJspName() { + return jspName; + } + + private void setAction(String action) { + this.action = action; + } + + private void setControllerClass(String controllerClass) { + this.controllerClass = controllerClass; + } + + private void setControllerMethod(String controllerMethod) { + this.controllerMethod = controllerMethod; + } + + private void setJspName(String jspName) { + this.jspName = jspName; + } + +} // Action diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionHandler.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionHandler.java new file mode 100644 index 00000000..d030c994 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionHandler.java @@ -0,0 +1,2417 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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. + * ================================================================================ + */ +/* =========================================================================================== + * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) + * Raptor : This tool is used to generate different kinds of reports with lot of utilities + * =========================================================================================== + * + * ------------------------------------------------------------------------------------------- + * ActionHandler.java - This class is used to call actions related to reports. + * ------------------------------------------------------------------------------------------- + * + * + * + * Changes + * ------- + * 31-Aug-2009 : Version 8.5.1 (Sundar);
  • reportFormFieldPopup iterates form field collections.
+ * 18-Aug-2009 : Version 8.5.1 (Sundar);
  • request Object is passed to prevent caching user/roles - Datamining/Hosting.
+ * 13-Aug-2009 : Version 8.5 (Sundar);
  • reportFormFieldPopup is changed to have effect on textfield with popup.
+ * 06-Aug-2009 : Version 9.0 (Sundar);
  • reportFormFieldPopupB is changed.
+ * 29-Jul-2009 : Version 8.4 (Sundar);
  • Previously report data for dashboard stored only page level data. This has been changed to show all the data up to the maximum specified.
+ * 27-Jul-2009 : Version 8.4 (Sundar);
  • Bug due to not showing back button after child report in drilldown is navigated more than + * one page is resolved.
+ * 14-Jul-2009 : Version 8.4 (Sundar);
  • Dashboard reports can now be generated excel as separate sheets or group together in PDF. + * They can also be scheduled.
+ * + */ +package org.openecomp.portalsdk.analytics.controller; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.error.RaptorRuntimeException; +import org.openecomp.portalsdk.analytics.error.RaptorSchedularException; +import org.openecomp.portalsdk.analytics.error.ReportSQLException; +import org.openecomp.portalsdk.analytics.error.UserDefinedException; +import org.openecomp.portalsdk.analytics.error.ValidationException; +import org.openecomp.portalsdk.analytics.model.DataCache; +import org.openecomp.portalsdk.analytics.model.ReportHandler; +import org.openecomp.portalsdk.analytics.model.ReportLoader; +import org.openecomp.portalsdk.analytics.model.SearchHandler; +import org.openecomp.portalsdk.analytics.model.base.IdNameColLookup; +import org.openecomp.portalsdk.analytics.model.base.IdNameList; +import org.openecomp.portalsdk.analytics.model.base.IdNameSql; +import org.openecomp.portalsdk.analytics.model.base.ReportSecurity; +import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; +import org.openecomp.portalsdk.analytics.model.definition.ReportSchedule; +import org.openecomp.portalsdk.analytics.model.runtime.ChartWebRuntime; +import org.openecomp.portalsdk.analytics.model.runtime.ErrorJSONRuntime; +import org.openecomp.portalsdk.analytics.model.runtime.FormField; +import org.openecomp.portalsdk.analytics.model.runtime.FormatProcessor; +import org.openecomp.portalsdk.analytics.model.runtime.ReportFormFields; +import org.openecomp.portalsdk.analytics.model.runtime.ReportJSONRuntime; +import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; +import org.openecomp.portalsdk.analytics.model.runtime.VisualManager; +import org.openecomp.portalsdk.analytics.model.search.ReportSearchResultJSON; +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.system.ConnectionUtils; +import org.openecomp.portalsdk.analytics.system.DbUtils; +import org.openecomp.portalsdk.analytics.system.Globals; +import org.openecomp.portalsdk.analytics.system.fusion.domain.QuickLink; +import org.openecomp.portalsdk.analytics.util.AppConstants; +import org.openecomp.portalsdk.analytics.util.DataSet; +import org.openecomp.portalsdk.analytics.util.Utils; +import org.openecomp.portalsdk.analytics.view.DataRow; +import org.openecomp.portalsdk.analytics.view.DataValue; +import org.openecomp.portalsdk.analytics.view.ReportData; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; +import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +public class ActionHandler extends org.openecomp.portalsdk.analytics.RaptorObject { + + //private static Log debugLogger = LogFactory.getLog(ActionHandler.class.getName()); + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ActionHandler.class); + + private void preserveReportRuntimeAsBackup(HttpServletRequest request) { + HttpSession session = request.getSession(); + ArrayList repAl = null; + + if(session.getAttribute(AppConstants.DRILLDOWN_REPORTS_LIST)!=null) + repAl = ((ArrayList)session.getAttribute(AppConstants.DRILLDOWN_REPORTS_LIST)); + int index = Integer.parseInt(nvl((String) session.getAttribute(AppConstants.DRILLDOWN_INDEX), "0")); + int form_index = Integer.parseInt(nvl((String) session.getAttribute(AppConstants.FORM_DRILLDOWN_INDEX), "0")); + int flag = 0; + if(repAl ==null || repAl.size() <= 0) { + //session.setAttribute(AppConstants.SI_BACKUP_FOR_REP_ID, ((ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID()); + //session.setAttribute(AppConstants.SI_REPORT_RUN_BACKUP, request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)); + repAl = new ArrayList(); + repAl.add((ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)); + + } else { + if(Globals.getMaxDrillDownLevel() < repAl.size()) { + repAl.remove(0); + if(index > 0) index--; + } else if(index < repAl.size()) + repAl.remove(index); + repAl.add(index, (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)); + } + index = index + 1; + // needed to differentiate form and report index to store form parameters for ZK + form_index = form_index + 1; + session.setAttribute(AppConstants.FORM_DRILLDOWN_INDEX, Integer.toString(form_index)); + session.setAttribute(AppConstants.DRILLDOWN_INDEX, Integer.toString(index)); + request.getSession().setAttribute(AppConstants.DRILLDOWN_REPORTS_LIST, repAl); + } // preserveReportRuntimeAsBackup + + private void clearReportRuntimeBackup(HttpServletRequest request) { +// debugLogger.debug("in Action Handler clear is been called."); + HttpSession session = request.getSession(); + session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); + session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); + request.removeAttribute(AppConstants.DRILLDOWN_INDEX); + request.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); + Enumeration enum1 = session.getAttributeNames(); + String attributeName = ""; + while(enum1.hasMoreElements()) { + attributeName = enum1.nextElement(); + if(attributeName.startsWith("parent_")) { + session.removeAttribute(attributeName); + } + } + //request.getSession().removeAttribute(AppConstants.SI_REPORT_RUN_BACKUP); + //request.getSession().removeAttribute(AppConstants.SI_BACKUP_FOR_REP_ID); + } // clearReportRuntimeBackup + + private boolean isDashboardInDrillDownList(HttpServletRequest request) throws RaptorException { + ArrayList aL = (ArrayList) request.getSession().getAttribute( + AppConstants.DRILLDOWN_REPORTS_LIST); + ReportRuntime rr = null; + if(aL ==null || aL.size() <= 0) { + return false; + } else { + for (int i =0; i0 ? --index : 0; + form_index = form_index>0 ? --form_index : 0; + request.setAttribute(AppConstants.DRILLDOWN_INDEX, Integer.toString(index)); + session.setAttribute(AppConstants.DRILLDOWN_INDEX, Integer.toString(index)); + request.setAttribute(AppConstants.FORM_DRILLDOWN_INDEX, Integer.toString(form_index)); + session.setAttribute(AppConstants.FORM_DRILLDOWN_INDEX, Integer.toString(form_index)); + + rr = (ReportRuntime)aL.get(index); + request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); + //clearReportRuntimeBackup(request); + //} + return rr; + } // getReportRuntimeFromBackup + + public String reportRun(HttpServletRequest request, String nextPage) { + String action = nvl(request.getParameter(AppConstants.RI_ACTION), request.getParameter("action")); + ReportRuntime rr = null; + String userId = null; + String formFields = ""; + ReportData rd = null; + boolean isEmailAttachment = false; + boolean fromDashboard = AppUtils.getRequestFlag(request,"fromDashboard"); + request.getSession().setAttribute("login_id", AppUtils.getUserBackdoorLoginId(request)); + + boolean rDisplayContent = AppUtils.getRequestFlag(request, + AppConstants.RI_DISPLAY_CONTENT) + || AppUtils.getRequestFlag(request, "noFormFields"); + + try { + //if "refresh=Y" is in request parameter, session variables are removed. + if(AppUtils.getRequestFlag(request, AppConstants.RI_REFRESH)) { + removeVariablesFromSession(request); + } + + + long currentTime = System.currentTimeMillis(); + request.setAttribute("triggeredStartTime", new Long(currentTime)); + String actionKey = nvl(request.getParameter(AppConstants.RI_ACTION), request.getParameter("action")); + String pdfAttachmentKey = AppUtils.getRequestNvlValue(request, "pdfAttachmentKey"); + String parent = ""; + int parentFlag = 0; + if(!nvl(request.getParameter("parent"), "").equals("N")) parent = nvl(request.getParameter("parent"), ""); + if(parent.startsWith("parent_")) parentFlag = 1; + + if (pdfAttachmentKey.length()<=0) { + if(actionKey.equals("report.download.page") || actionKey.equals("report.download") || actionKey.equals("report.download.pdf") || actionKey.equals("report.download.excel2007") || actionKey.equals("report.csv.download") || actionKey.equals("report.text.download")) { + if(parentFlag == 1) rr = (ReportRuntime) request.getSession().getAttribute(parent+"_rr"); + if(rr==null) + rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); //changing session to request + if(!(rr!=null && fromDashboard)) { + userId = AppUtils.getUserID(request); + boolean isFromReportLog = AppUtils.getRequestFlag(request, "fromReportLog"); + int downloadLimit = 0; + if(rr!=null) + downloadLimit = (rr.getMaxRowsInExcelDownload()>0)?rr.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); + if(actionKey.equals("report.csv.download")) + downloadLimit = Globals.getCSVDownloadLimit(); + + if(rr!=null && rr.getReportType().equals(AppConstants.RT_LINEAR)) { + String sql_whole = rr.getReportDataSQL(userId, downloadLimit, request); + request.setAttribute(AppConstants.RI_REPORT_SQL_WHOLE, sql_whole); + } else if(rr!=null && rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { + rd = rr.loadReportData(-1, userId, downloadLimit,request, false); /* TODO: should be changed to true */ + request.getSession().setAttribute(AppConstants.RI_REPORT_DATA, rd); + } + if(!isFromReportLog) { + if(pdfAttachmentKey!=null && pdfAttachmentKey.length()>0) { + if(actionKey.equals("report.download")) { + rr.logReportExecutionTime(userId, "",AppConstants.RLA_SCHEDULED_DOWNLOAD_EXCEL, formFields); + } else if (actionKey.equals("report.download.pdf")) { + rr.logReportExecutionTime(userId, "",AppConstants.RLA_SCHEDULED_DOWNLOAD_PDF, formFields); + } else if (actionKey.equals("report.download.excel2007")) { + rr.logReportExecutionTime(userId, "",AppConstants.RLA_SCHEDULED_DOWNLOAD_EXCELX, formFields); + } + } else { + if(actionKey.equals("report.download") ) { + rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_EXCEL, formFields); + } else if (actionKey.equals("report.download.pdf")) { + rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_PDF, formFields); + } else if (actionKey.equals("report.csv.download")) { + rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_CSV, formFields); + } else if (actionKey.equals("report.text.download")) { + rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_TEXT, formFields); + } else if (actionKey.equals("report.download.page")) { + rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_PAGE_EXCEL, formFields); + } else if (actionKey.equals("report.download.excel2007")) { + rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_EXCELX, formFields); + } + } + } + return nextPage; + } + + } + }// pdfAttachmentKey + String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); + rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); //changing session to request + + String reportIDFromSession = (rr!=null)?rr.getReportID():""; + logger.debug(EELFLoggerDelegate.debugLogger, ("in Action Handler ********** " + reportID + " " + reportIDFromSession + " "+ actionKey)); +// ReportRuntime rr = (ReportRuntime) request.getAttribute(AppConstants.SI_REPORT_RUNTIME); + logger.debug(EELFLoggerDelegate.debugLogger, ("^^^^^^^^^^^^^^report ID from session " + ((rr!=null)?rr.getReportID():"no report id in session"))); + // if(rr!=null && !(rr.getReportID().equals(reportID))) { +// rr = null; +// request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, null); +// } + + ReportHandler rh1 = new ReportHandler(); + ReportRuntime rr1 = null; + + //debugLogger.debug("Report ID B4 rr1 in ActionHandler " + // + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); + + + //try { + boolean isGoBackAction = AppUtils.getRequestFlag(request, AppConstants.RI_GO_BACK); + + if (AppUtils.getRequestFlag(request, AppConstants.RI_SHOW_BACK_BTN) && !isGoBackAction) { + // debugLogger.debug("Preserving report"); + if(!reportID.equals(reportIDFromSession)) + preserveReportRuntimeAsBackup(request); + } + + if(reportID !=null) + rr1 = rh1.loadReportRuntime(request, reportID, true, 1); + //} catch(Exception e) { + + // } +// debugLogger.debug("Report ID After rr1 in ActionHandler " +// + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); + if(rr1!=null && rr1.getReportType().equals(AppConstants.RT_DASHBOARD)) { + int DASH=7; + int requestFlag = DASH; + ReportHandler rh = new ReportHandler(); + // Added below statement to add parent dashboard report id in session. + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REP_ID, reportID); + //rr = null; + // get dashboard HTML from report runtime. getListOfReportsFromDashBoardHTML + String strHTML = rr1.getDashboardLayoutHTML(); + + //System.out.println("StrHTML " + strHTML); + // call getListOfReportsFromDashBoardHTML returns HashMap + + TreeMap treeMap = getListOfReportsFromDashBoardHTML(strHTML); + //System.out.println("Size " + hashMap.size()); + Set set = treeMap.entrySet(); + String value = ""; + + HashMap reportsRuntimeMap = new HashMap(); + HashMap reportDataMap = new HashMap(); + HashMap reportChartDataMap = new HashMap(); + // displayTypeMap differentiates whether report need to be displayed as data or chart + HashMap reportDisplayTypeMap = new HashMap(); + + userId = null; + userId = AppUtils.getUserID(request); + int pageNo = -1; + //int downloadLimit = (rr1.getMaxRowsInExcelDownload()>0)?rr1.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); + int downloadLimit = 0; + int rep_idx = 0; + int widthFlag = 0; + int heightFlag = 0; + ReportRuntime rrDashboardReports = null; + Integer intObj = null; + ReportRuntime similiarReportRuntime = null; + rd = null; + DataSet ds = null; + String reportIDFromMap = null; + int record = 0; + boolean buildReportdata = true; + + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + record++; + Map.Entry entry = (Entry) iter.next(); + //System.out.println("Key "+ entry.getKey()); + //System.out.println("Value "+ entry.getValue()); + reportIDFromMap = entry.getValue().toString().substring(1); + // The below line is used to optimize, so that if there is already same report id it wouldn't go through the whole process + similiarReportRuntime = getSimiliarReportRuntime(reportsRuntimeMap, reportIDFromMap); + if(similiarReportRuntime != null ) { + rrDashboardReports = (ReportRuntime) getSimiliarReportRuntime(reportsRuntimeMap, reportIDFromMap).clone(); + intObj = getKey(reportsRuntimeMap,reportIDFromMap); + } else { + rrDashboardReports = rh.loadReportRuntime(request, reportIDFromMap, true, requestFlag); + } + if(entry.getValue().toString().toLowerCase().startsWith("c")) { + rrDashboardReports.setDisplayMode(ReportRuntime.DISPLAY_CHART_ONLY); + } else { + rrDashboardReports.setDisplayMode(ReportRuntime.DISPLAY_DATA_ONLY); + } + + downloadLimit = (rrDashboardReports.getMaxRowsInExcelDownload()>0)?rrDashboardReports.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); + if (new Integer(nvl(rrDashboardReports.getDataContainerWidth(),"100")).intValue() >100) widthFlag = 1; + if (new Integer(nvl(rrDashboardReports.getDataContainerHeight(),"100")).intValue() >100) heightFlag = 1; + + if(record == 1) { + if(rrDashboardReports.getReportFormFields()!=null && rrDashboardReports.getReportFormFields().size()>0) { + buildReportdata = false; + if(rDisplayContent) buildReportdata = true; + } + } + + if(buildReportdata) { + if(similiarReportRuntime != null ) { + rd = (ReportData) reportDataMap.get(intObj); + ds = (DataSet) reportChartDataMap.get(intObj); + } else { + if (!rrDashboardReports.getReportType().equals(AppConstants.RT_HIVE)) + rd = rrDashboardReports.loadReportData(pageNo, userId, downloadLimit,request, false /*download*/); + else + rd = rrDashboardReports.loadHiveLinearReportData(rrDashboardReports.getReportSQL(), userId, 2,request); + ds = rrDashboardReports.loadChartData(userId,request); + } + } + + + long totalTime = System.currentTimeMillis() - currentTime; + formFields = AppUtils.getRequestNvlValue(request, "formFields"); + if(buildReportdata) { + rrDashboardReports.logReportRun(userId, String.valueOf(totalTime),formFields); + rrDashboardReports.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_EXECUTION_TIME, formFields); + } + + /*reportsRuntimeMap.put(new Integer(entry.getKey().toString()), rrDashboardReports); + reportDataMap.put(new Integer(entry.getKey().toString()), rd); + reportChartDataMap.put(new Integer(entry.getKey().toString()), ds); + reportDisplayTypeMap.put(new Integer(entry.getKey().toString()), entry.getValue().toString().substring(0,1));*/ + + reportsRuntimeMap.put(new Integer(entry.getKey().toString())+"_"+rrDashboardReports.getReportID(), rrDashboardReports); + reportDisplayTypeMap.put(new Integer(entry.getKey().toString())+"_"+rrDashboardReports.getReportID(), entry.getValue().toString().substring(0,1)); + if(buildReportdata) { + reportDataMap.put(new Integer(entry.getKey().toString())+"_"+rrDashboardReports.getReportID(), rd); + reportChartDataMap.put(new Integer(entry.getKey().toString())+"_"+rrDashboardReports.getReportID(), ds); + } + + } + + /*if(widthFlag ==1) request.getSession().setAttribute("extendedWidth", "Y"); + else request.getSession().removeAttribute("extendedWidth"); + if(heightFlag ==1) request.getSession().setAttribute("extendedHeight", "Y"); + else request.getSession().removeAttribute("extendedHeight"); + */ + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP, new TreeMap(reportsRuntimeMap)); + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP, new TreeMap(reportDisplayTypeMap)); + if(buildReportdata) { + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP, new TreeMap(reportDataMap)); + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP, new TreeMap(reportChartDataMap)); + } +// debugLogger.debug("I am inside this if " + rr1.getReportType() + " "+rr1.getReportID()); + request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr1); //changing session to request + //request.setAttribute(AppConstants.SI_REPORT_RUNTIME, rr1); + if((String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!= null || rr1.getReportType().equals(AppConstants.RT_DASHBOARD)) { + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME, rr1); + } + + return "raptor/report_dashboard_run_container.jsp"; + } else { + fromDashboard = AppUtils.getRequestFlag(request,"fromDashboard"); + if(isDashboardInDrillDownList(request)) fromDashboard= true; + + if(!fromDashboard) { + request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); + request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); + request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP); + request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); + request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_REP_ID); + request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME); + request.getSession().removeAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP); + request.getSession().removeAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP); + } + //String pdfAttachmentKey = AppUtils.getRequestValue(request, "pdfAttachmentKey"); + String report_email_sent_log_id = AppUtils.getRequestValue(request, "log_id"); + logger.debug(EELFLoggerDelegate.debugLogger, ("Email PDF" + pdfAttachmentKey+" "+ report_email_sent_log_id)); + + //email pdf attachment specific + if(nvl(pdfAttachmentKey).length()>0 && report_email_sent_log_id !=null) + isEmailAttachment = true; + if(isEmailAttachment) { + /* String query = "Select user_id, rep_id from CR_REPORT_EMAIL_SENT_LOG" + + " where rownum = 1" + + " and gen_key='"+pdfAttachmentKey.trim()+"'" + + " and log_id ="+report_email_sent_log_id.trim() + + " and (sysdate - sent_date) < 1 ";*/ + + + String query = Globals.getDownloadAllEmailSent(); + query = query.replace("[pdfAttachmentKey.trim()]", pdfAttachmentKey.trim()); + query = query.replace("[report_email_sent_log_id.trim()]", report_email_sent_log_id.trim()); + + DataSet ds = DbUtils.executeQuery(query, 1); + if(!ds.isEmpty()) { + userId = ds.getString(0,"user_id"); + reportID = ds.getString(0, "rep_id"); + request.setAttribute("schedule_email_userId", userId); + } else { + request.setAttribute("message", "This link has expired, please login and regenerate the report"); + return "raptor/message.jsp"; + } + } else userId = AppUtils.getUserID(request); +// debugLogger.debug("Report ID b4 showbutton in ActionHandler " +// + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); +// debugLogger.debug("Report ID " + reportID + " " + reportIDFromSession); + + // Scheduling Dashoard report + if(reportID !=null && nvl(pdfAttachmentKey).length()>0) + rr = rh1.loadReportRuntime(request, reportID, true, 1); + if(rr!=null && rr.getReportType().equals(AppConstants.RT_DASHBOARD) && nvl(pdfAttachmentKey).length()>0) { + int DASH=7; + int requestFlag = DASH; + ReportHandler rh = new ReportHandler(); + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REP_ID, reportID); + //rr = null; + // get dashboard HTML from report runtime. getListOfReportsFromDashBoardHTML + String strHTML = rr.getDashboardLayoutHTML(); + //System.out.println("StrHTML " + strHTML); + // call getListOfReportsFromDashBoardHTML returns HashMap + + TreeMap treeMap = getListOfReportsFromDashBoardHTML(strHTML); + //System.out.println("Size " + hashMap.size()); + Set set = treeMap.entrySet(); + String value = ""; + + HashMap reportsRuntimeMap = new HashMap(); + HashMap reportDataMap = new HashMap(); + HashMap reportChartDataMap = new HashMap(); + HashMap reportDisplayTypeMap = new HashMap(); + + userId = null; + userId = AppUtils.getUserID(request); + int pageNo = -1; + int downloadLimit = 0; + int rep_idx = 0; + int widthFlag = 0; + int heightFlag = 0; + ReportRuntime rrDashboardReports = null; + Integer intObj = null; + ReportRuntime similiarReportRuntime = null; + rd = null; + DataSet ds = null; + String reportIDFromMap = null; + int record = 0; + boolean buildReportdata = true; + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + record++; + Map.Entry entry = (Entry) iter.next(); + + reportIDFromMap = entry.getValue().toString().substring(1); + similiarReportRuntime = getSimiliarReportRuntime(reportsRuntimeMap, reportIDFromMap); + if(similiarReportRuntime != null ) { + rrDashboardReports = getSimiliarReportRuntime(reportsRuntimeMap, reportIDFromMap); + intObj = getKey(reportsRuntimeMap,reportIDFromMap); + } else { + rrDashboardReports = rh.loadReportRuntime(request, reportIDFromMap, true, requestFlag); + } + + downloadLimit = (rrDashboardReports.getMaxRowsInExcelDownload()>0)?rrDashboardReports.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); + + if (new Integer(nvl(rrDashboardReports.getDataContainerWidth(),"100")).intValue() >100) widthFlag = 1; + if (new Integer(nvl(rrDashboardReports.getDataContainerHeight(),"100")).intValue() >100) heightFlag = 1; + if(record == 1) { + if(rrDashboardReports.getReportFormFields()!=null && rrDashboardReports.getReportFormFields().size()>0) { + buildReportdata = false; + if(rDisplayContent) buildReportdata = true; + } + } + if(buildReportdata) { + if(similiarReportRuntime != null ) { + rd = (ReportData) reportDataMap.get(intObj); + ds = (DataSet) reportChartDataMap.get(intObj); + } else { + + if (!rrDashboardReports.getReportType().equals(AppConstants.RT_HIVE)) + rd = rrDashboardReports.loadReportData(pageNo, userId, downloadLimit,request, false /*download*/); + else + rd = rrDashboardReports.loadHiveLinearReportData(rrDashboardReports.getReportSQL(), userId, 2,request); + ds = rrDashboardReports.loadChartData(userId,request); + } + } + + + + long totalTime = System.currentTimeMillis() - currentTime; + formFields = AppUtils.getRequestNvlValue(request, "formFields"); + + rrDashboardReports.logReportRun(userId, String.valueOf(totalTime),formFields); + rrDashboardReports.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_EXECUTION_TIME, formFields); + + reportsRuntimeMap.put(new Integer(entry.getKey().toString()), rrDashboardReports); + reportDisplayTypeMap.put(new Integer(entry.getKey().toString()), entry.getValue().toString().substring(0,1)); + if(buildReportdata) { + reportDataMap.put(new Integer(entry.getKey().toString()), rd); + reportChartDataMap.put(new Integer(entry.getKey().toString()), ds); + //reportDisplayTypeMap.put(new Integer(entry.getKey().toString()), entry.getValue().toString().substring(0,1)); + } + } + + /*if(widthFlag ==1) request.getSession().setAttribute("extendedWidth", "Y"); + else request.getSession().removeAttribute("extendedWidth"); + if(heightFlag ==1) request.getSession().setAttribute("extendedHeight", "Y"); + else request.getSession().removeAttribute("extendedHeight"); + */ + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP, new TreeMap(reportsRuntimeMap)); + request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); //changing session to request + if(buildReportdata) { + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP, new TreeMap(reportDisplayTypeMap)); + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP, new TreeMap(reportDataMap)); + request.getSession().setAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP, new TreeMap(reportChartDataMap)); + } + //request.setAttribute(AppConstants.SI_REPORT_RUNTIME, rr1); + //return nextPage; + } else { + + // Ends + + +// debugLogger.debug("Action Handler *****************" + new java.util.Date()+ " " + isGoBackAction); + ReportHandler rh = new ReportHandler(); + //rr = null; // COMMENT THIS LINE + boolean resetParams = AppUtils.getRequestFlag(request, + AppConstants.RI_RESET_PARAMS); + boolean resetAction = AppUtils.getRequestFlag(request, + AppConstants.RI_RESET_ACTION); + boolean refresh = false; + if (resetAction) { + rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); + resetParams=true; + refresh = true; + if(rr!=null) { + rr.setParamValues(request, resetParams,refresh); + request.getSession().removeAttribute(AppConstants.RI_REPORT_DATA); + rr.resetVisualSettings(); + } + return nextPage; + } + + /*if (isGoBackAction) { +// debugLogger.debug("Report back in action handler " + ((ReportRuntime) request.getSession().getAttribute( +// AppConstants.SI_REPORT_RUN_BACKUP))!=null?((ReportRuntime) request.getSession().getAttribute( +// AppConstants.SI_REPORT_RUN_BACKUP)).getReportID():((ReportRuntime) request.getSession().getAttribute( +// AppConstants.SI_REPORT_RUN_BACKUP))); + rr = null; + rr = getReportRuntimeFromBackup(request); + if (rr == null) + throw new Exception("[ActionHandler.reportRun] Report backup not found"); + reportID = rr.getReportID(); + } else {*/ + + logger.debug(EELFLoggerDelegate.debugLogger, ("Ocurring during Schedule ")); + //TODO differentiate Schedule with other actions +// if(isEmailAttachment) { +// +// } else { +// +// } + rr = rh.loadReportRuntime(request, reportID); + //setParamValues called for Drilldown to display formfield + //rr.setParamValues(request, false,true); + + //} // else + + ArrayList aL = (ArrayList)request.getSession().getAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); + ReportRuntime aLR = null; + if(aL != null) { +// for (int i = 1; i < aL.size(); i++) { +// aLR = (ReportRuntime) aL.get(i); +// if (!aLR.getReportID().equals(reportID)) { +// request.setAttribute(AppConstants.RI_SHOW_BACK_BTN, "Y"); +// } +// } +// if(reportID.equals(reportIDFromSession)) { + aLR = (ReportRuntime) aL.get(0); + if (aLR!=null && !aLR.getReportID().equals(reportID)) { + request.setAttribute(AppConstants.RI_SHOW_BACK_BTN, "Y"); + } +// } + } + + if(rDisplayContent) + rr.setDisplayFlags(true, true); + + if (rr.getDisplayContent()) { + int pageNo = 0; + if (isGoBackAction) + pageNo = rr.getCachedPageNo(); + else { + try { + pageNo = Integer.parseInt(AppUtils.getRequestNvlValue(request, AppConstants.RI_NEXT_PAGE)); + } catch (Exception e) { + } + + String vAction = AppUtils.getRequestNvlValue(request, + AppConstants.RI_VISUAL_ACTION); + String vCoId = AppUtils.getRequestNvlValue(request, + AppConstants.RI_DETAIL_ID); + if (vAction.equals(AppConstants.VA_HIDE)) + rr.hideColVisual(vCoId); + else if (vAction.equals(AppConstants.VA_SHOW)) + rr.showColVisual(vCoId); + else if (vAction.equals(AppConstants.VA_SORT)) { + rr.sortColVisual(vCoId); + pageNo = 0; + } // else + } // else + + int downloadLimit = (rr.getMaxRowsInExcelDownload()>0)?rr.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); + if(isEmailAttachment) { + String limit = nvl(request.getParameter("download_limit"),"1000"); + downloadLimit = Integer.parseInt(limit); + } + //if (action.startsWith("mobile")) rr.setPageSize(5); + long reportTime = System.currentTimeMillis(); + if (!rr.getReportType().equals(AppConstants.RT_HIVE)) + rd = rr.loadReportData(pageNo, userId, downloadLimit,request,false /*download*/); + else + rd = rr.loadHiveLinearReportData(rr.getReportSQL(), userId, 2,request); + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] ------->Time Taken for the loading report data --- " + (System.currentTimeMillis() - reportTime))); + ReportData rd_whole = null; + boolean hideReportMap = rr.isDisplayOptionHideMap()||AppUtils.getRequestNvlValue(request, "noMap").equals("Y"); +/* if (Globals.getMapAllowedYN().equals("Y") && !hideReportMap && rr.getReportMap()!=null){ + rd_whole = rr.loadReportData(-1, userId, downloadLimit,request); + } +*/ + request.getSession().setAttribute(AppConstants.RI_REPORT_DATA, rd); + //if (Globals.getMapAllowedYN().equals("Y") && !hideReportMap && (rr.getReportMap()!=null && rr.getReportMap().getLatColumn()!=null && rr.getReportMap().getLongColumn()!=null)) { + if(rr!=null && rr.getReportType().equals(AppConstants.RT_LINEAR)) { + String sql_whole = rr.getReportDataSQL(userId, downloadLimit, request); + request.setAttribute(AppConstants.RI_REPORT_SQL_WHOLE, sql_whole); + } else if(rr.getReportType().equals(AppConstants.RT_HIVE)) { + String sql_whole = rr.getReportSQL(); + request.setAttribute(AppConstants.RI_REPORT_SQL_WHOLE, sql_whole); + } + //} + //request.setAttribute(AppConstants.RI_REPORT_DATA_WHOLE, rd_whole); + // if(rr.getReportDataSize() > Globals.getFlatFileLowerLimit() && rr.getReportDataSize() <= Globals.getFlatFileUpperLimit() ) { + // rr.setFlatFileName(rh.saveFlatFile(request, rd, rr + // .getParamNameValuePairs(), rr.getReportName(), rr.getReportDescr())); + // } + //if(actionKey!=null && actionKey.equals("report.download")) { +// rr.setExcelPageFileName(rh.saveAsExcelFile(request, rd, rr +// .getParamNameValuePairs(), rr.getReportName(), rr.getReportDescr())); + //} + if (!rr.getReportType().equals(AppConstants.RT_HIVE)) { + long currentChartTime = System.currentTimeMillis(); + DataSet chartDS = rr.loadChartData(userId,request); + if(chartDS != null) + request.getSession().setAttribute(AppConstants.RI_CHART_DATA, rr.loadChartData(userId,request)); + else + request.getSession().removeAttribute(AppConstants.RI_CHART_DATA); + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] ------->Time Taken for the loading chart data --- " + (System.currentTimeMillis() - currentChartTime))); + } + +/* if((String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) { + request.getSession().setAttribute("FirstDashReport", rr); + } +*/ + } + request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); //changing session to request + request.getSession().setAttribute(AppConstants.RI_REPORT_DATA, rd); + } // else + long totalTime = System.currentTimeMillis() - currentTime; + formFields = AppUtils.getRequestNvlValue(request, "formFields"); + request.setAttribute(AppConstants.RLA_EXECUTION_TIME, "" + totalTime); + + + boolean isFromReportLog = AppUtils.getRequestFlag(request, "fromReportLog"); + if(!isFromReportLog) { + if(pdfAttachmentKey!=null && pdfAttachmentKey.length()>0) { + if(actionKey.equals("report.download")) { + rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_SCHEDULED_DOWNLOAD_EXCEL, formFields); + } else if (actionKey.equals("report.download.pdf")) { + rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_SCHEDULED_DOWNLOAD_PDF, formFields); + } + } else { + if(actionKey.equals("report.download") ) { + rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_DOWNLOAD_EXCEL, formFields); + } else if (actionKey.equals("report.download.pdf")) { + rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_DOWNLOAD_PDF, formFields); + } else if (actionKey.equals("report.csv.download")) { + rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_DOWNLOAD_CSV, formFields); + } else if (actionKey.equals("report.text.download")) { + rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_DOWNLOAD_TEXT, formFields); + } else { + + //rr.logReportRun(userId, String.valueOf(totalTime),formFields); + if(rd!=null && !action.equals("report.run.container")) + rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_EXECUTION_TIME, formFields); + } + } + } else { + rr.logReportExecutionTimeFromLogList(userId, String.valueOf(totalTime),formFields); + } + +/* if((String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) { + reportID = (String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID); + ReportRuntime rrDash = rh1.loadReportRuntime(request, reportID, true, 1); + request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rrDash); + } +*/ + if(rr.isDrillDownURLInPopupPresent()) { + request.getSession().setAttribute("parent_"+rr.getReportID()+"_rr", rr); + request.getSession().setAttribute("parent_"+rr.getReportID()+"_rd", rd); + } + + if(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { + return "raptor/report_crosstab_run_container.jsp"; + } else if (rr.getReportType().equals(AppConstants.RT_HIVE) && !isEmailAttachment) { + return "raptor/report_hive_run_container.jsp"; + } + } // else + + boolean isEmbedded = false; + Object temp = request.getSession().getAttribute("isEmbedded"); + if(temp!=null){ + isEmbedded = (boolean)temp; + } + if(isEmbedded && !action.equals("chart.run")){ + HashMap embeddedReportsRuntimeMap = null; + HashMap embeddedReportsDataMap = null; + if(request.getSession().getAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP)!= null){ + embeddedReportsRuntimeMap = (HashMap)request.getSession().getAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP); + } else { + embeddedReportsRuntimeMap = new HashMap(); + } + if(request.getSession().getAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP)!= null){ + embeddedReportsDataMap = (HashMap)request.getSession().getAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP); + } else { + embeddedReportsDataMap = new HashMap(); + } + embeddedReportsRuntimeMap.put(rr.getReportID(), rr); + embeddedReportsDataMap.put(rr.getReportID(), rd); + + + request.getSession().setAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP, embeddedReportsRuntimeMap); + request.getSession().setAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP, embeddedReportsDataMap); + + } + + ReportJSONRuntime reportJSONRuntime = rr.createReportJSONRuntime(request, rd); + ObjectMapper mapper = new ObjectMapper(); + //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); + //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + String jsonInString = ""; + try { + jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(reportJSONRuntime); + } catch (Exception ex) { + ex.printStackTrace(); + + } + return jsonInString; + } catch (RaptorException e) { + try { + e.printStackTrace(); + + if(rr!=null) { // when user tries report they don't have access this should not throw exception that's why this if is added. + if(isEmailAttachment) + rr.logReportExecutionTime(userId, "", "Scheduled: " + AppConstants.RLA_ERROR, formFields); + else + rr.logReportExecutionTime(userId, "", "On Demand: " + AppConstants.RLA_ERROR, formFields); + } + + ErrorJSONRuntime errorJSONRuntime = new ErrorJSONRuntime(); + errorJSONRuntime.setErrormessage(e.getMessage()); + errorJSONRuntime.setStacktrace(getStackTrace(e)); + ObjectMapper mapper = new ObjectMapper(); + //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); + //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + String jsonInString = ""; + try { + jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(errorJSONRuntime); + } catch (Exception ex) { + ex.printStackTrace(); + + } + return jsonInString; + + } catch (RaptorException ex) { + nextPage = (new ErrorHandler()).processFatalError(request, ex); + ErrorJSONRuntime errorJSONRuntime = new ErrorJSONRuntime(); + errorJSONRuntime.setErrormessage(ex.getMessage()); + errorJSONRuntime.setStacktrace(getStackTrace(ex)); + ObjectMapper mapper = new ObjectMapper(); + //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); + //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + String jsonInString = ""; + try { + jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(errorJSONRuntime); + } catch (Exception ex1) { + ex1.printStackTrace(); + } + return jsonInString; + } + //nextPage = (new ErrorHandler()).processFatalError(request, e); + } catch (Throwable t) { + t.printStackTrace(); + ErrorJSONRuntime errorJSONRuntime = new ErrorJSONRuntime(); + errorJSONRuntime.setErrormessage(t.toString()); + errorJSONRuntime.setStacktrace(getStackTrace(t)); + ObjectMapper mapper = new ObjectMapper(); + //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); + //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + String jsonInString = ""; + try { + jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(errorJSONRuntime); + } catch (Exception ex) { + ex.printStackTrace(); + + } + return jsonInString; + + } + //return nextPage; + } // reportRun + + public static String getStackTrace(Throwable aThrowable) { + Writer result = new StringWriter(); + PrintWriter printWriter = new PrintWriter(result); + aThrowable.printStackTrace(printWriter); + return result.toString(); + } + + /** + * The below method is used to optimize, so that if there is already same report id in hashMap it wouldn't go through the whole process again. + **/ + private ReportRuntime getSimiliarReportRuntime(HashMap reportsRuntimeMap, String reportID) { + Set set = reportsRuntimeMap.entrySet(); + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + if (((ReportRuntime) entry.getValue()).getReportID().equals(reportID)) { + return (ReportRuntime) entry.getValue(); + } + } + return null; + } + + private Integer getKey(HashMap reportsRuntimeMap, String reportID) { + Set set = reportsRuntimeMap.entrySet(); + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + if (((ReportRuntime) entry.getValue()).getReportID().equals(reportID)) { + return new Integer(((String) entry.getKey()).substring(2)); + } + } + return null; + } + + public String reportSearch(HttpServletRequest request, String nextPage) { + return reportSearchExecute(request, nextPage); + } // reportSearch + + public String reportSearchUser(HttpServletRequest request, String nextPage) { + removeVariablesFromSession(request); + request.setAttribute(AppConstants.RI_USER_REPORTS, "Y"); + return reportSearchExecute(request, nextPage); + } // reportSearchUser + + public String reportSearchPublic(HttpServletRequest request, String nextPage) { + removeVariablesFromSession(request); + request.setAttribute(AppConstants.RI_PUBLIC_REPORTS, "Y"); + return reportSearchExecute(request, nextPage); + } // reportSearchPublic + + public String reportSearchFavorites(HttpServletRequest request, String nextPage) { + removeVariablesFromSession(request); + request.setAttribute(AppConstants.RI_FAVORITE_REPORTS, "Y"); + return reportSearchExecute(request, nextPage); + } // reportSearchFavorites + + public String reportSearchExecute(HttpServletRequest request, String nextPage) { + removeVariablesFromSession(request); + try { + SearchHandler sh = new SearchHandler(); + ReportSearchResultJSON sr = sh.loadReportSearchResult(request); + return sr.getJSONString(); + //request.setAttribute(AppConstants.RI_SEARCH_RESULT, sr); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // reportSearchExecute + + public String reportChartRun(HttpServletRequest request, String nextPage) { + ChartWebRuntime cwr = new ChartWebRuntime(); + return cwr.generateChart(request, false); //no data + } // reportSearchExecute + + public String reportChartDataRun(HttpServletRequest request, String nextPage) { + ChartWebRuntime cwr = new ChartWebRuntime(); + return cwr.generateChart(request); //data + } // reportSearchExecute + + + // public String reportRunExecute(HttpServletRequest request, String nextPage) { +// try { +// ReportRunHandler rh = new ReportRunHandler(); +// ReportRunResultJSON sr = rh.loadReportRunResult(request); +// return sr.getJSONString(); +// //request.setAttribute(AppConstants.RI_SEARCH_RESULT, sr); +// } catch (RaptorException e) { +// nextPage = (new ErrorHandler()).processFatalError(request, e); +// } +// +// return nextPage; +// } + + public String getQuickLinksJSON(HttpServletRequest request, String nextPage) { + String jsonInString = null; + try { + ArrayList quickLinks = ReportLoader.getQuickLinksJSON(request, request.getParameter("quick_links_menu_id"),true); + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(quickLinks); + + } catch (Exception e) { + e.printStackTrace(); + } + return jsonInString; + } + + public String processScheduleReportList(HttpServletRequest request, String nextPage) { + String reportID = ""; + reportID = AppUtils.getRequestNvlValue(request, "schedule_reports"); + if (nvl(reportID).length()<=0) + reportID = AppUtils.getRequestNvlValue(request, AppConstants.RI_REPORT_ID); + // Added for form field chaining in schedule tab so that setParamValues() is called + request.setAttribute(AppConstants.SCHEDULE_ACTION, "Y"); + + try { + boolean isAdmin = AppUtils.isAdminUser(request); + boolean check = ReportLoader.doesUserCanScheduleReport(request, null); + + logger.debug(EELFLoggerDelegate.debugLogger, ("^^^^^^^^^^^^^Check " + check + " Admin "+ isAdmin)); + + if(check || isAdmin) { + if(reportID.length()>0) { + ReportHandler rh = new ReportHandler(); + ReportDefinition rdef = rh.loadReportDefinition(request, reportID); + request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); + ReportSchedule reportSchedule = null; + if(rdef!=null) { + reportSchedule = new ReportSchedule(reportID, AppUtils.getUserID(request), false, request); + } + request.getSession().setAttribute(AppConstants.SI_REPORT_SCHEDULE, reportSchedule); + } + } else { + //String message = "You have reached your schedule limit. Please visit this page again after removing your old schedules in \"My Schedule\" section."; + String message = "You have reached the scheduled report limit for your Login ID. Please remove any old schedule requests in the \"My Scheduled Reports\" screen before attempting to schedule any additional reports."; + nextPage = (new ErrorHandler()).processFatalError(request, new RaptorSchedularException(message)); + } + + } catch(Exception ex) { ex.printStackTrace();} + return nextPage; + } + + public String processSchedule(HttpServletRequest request, String nextPage) { + + // Added for form field chaining in schedule tab so that setParamValues() is called + + request.setAttribute(AppConstants.SCHEDULE_ACTION, "Y"); + if(request.getSession().getAttribute(AppConstants.SI_REPORT_SCHEDULE)!=null && (!AppUtils.getRequestNvlValue(request, AppConstants.RI_ACTION).equals("report.schedule_only_from_search"))) { + String action = nvl(request.getParameter(AppConstants.RI_WIZARD_ACTION), + AppConstants.WA_BACK); + String scheduleID = ""; + scheduleID = AppUtils.getRequestValue(request, AppConstants.RI_SCHEDULE_ID); + ReportSchedule reportSchedule = null; + + if( nvl(scheduleID).length() <= 0) { + reportSchedule = (ReportSchedule) request.getSession().getAttribute(AppConstants.SI_REPORT_SCHEDULE); + scheduleID = reportSchedule.getScheduleID(); + } + + String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); + try { + boolean isAdmin = AppUtils.isAdminUser(request); + boolean check = ReportLoader.doesUserCanScheduleReport(request, scheduleID); + if(!isAdmin && !check) { + String message = "You have reached the scheduled report limit for your Login ID. Please remove any old schedule requests in the My Scheduled Reports screen before attempting to schedule any additional reports."; + nextPage = (new ErrorHandler()).processFatalError(request, new RaptorSchedularException(message)); + return nextPage; + } + + } catch (Exception ex) { ex.printStackTrace();} + if(reportSchedule == null) reportSchedule = new ReportSchedule(reportID, scheduleID, AppUtils.getUserID(request), request); + String formFields = ""; + formFields = reportSchedule.getFormFields(); + formFields = (formFields.length()>1)?formFields.substring(1):formFields; + String formFieldsArr[] = formFields.split("&"); + String sessionParams[] = Globals.getSessionParamsForScheduling().split(","); + + for (int i=0; i1)?formFields.substring(1):formFields; + String formFieldsArr[] = formFields.split("&"); + String sessionParams[] = Globals.getSessionParamsForScheduling().split(","); + + for (int i=0; i 0) + ws.performGoToStep(goToStep); + else + ws.performAction(action, rdef); + } catch (ValidationException ve) { + (new ErrorHandler()).processError(request, ve); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } catch (Throwable t) { + t.printStackTrace(); + } + + return nextPage; + } // reportWizard + + public String refreshCache ( HttpServletRequest request, String nextPage ) { + //DataCache.refreshReportTableSources(); + removeVariablesFromSession(request); + DataCache.refreshAll(); + Globals.getAppUtils().resetUserCache(); + request.setAttribute("message", "Cache Refreshed"); + return nextPage; + } + public String reportCreate(HttpServletRequest request, String nextPage) { + try { + removeVariablesFromSession(request); + ReportDefinition rdef = ReportDefinition.createBlank(request); + + request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); + // request.setAttribute(AppConstants.RI_CUR_STEP, + // AppConstants.WS_DEFINITION); + DataCache.refreshReportTableSources(); + request.getSession().removeAttribute("remoteDB"); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // reportCreate + + public String reportImportSave(HttpServletRequest request, String nextPage) { + try { + String reportXML = nvl(AppUtils.getRequestValue(request, "reportXML")).trim(); + + ReportHandler rh = new ReportHandler(); + ReportDefinition rdef = rh.createReportDefinition(request, "-1", reportXML); + rdef.updateReportDefType(); + rdef.generateWizardSequence(request); + rdef.setReportName("Import: " + rdef.getReportName()); + rdef.clearAllDrillDowns(); + + request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); + } catch (RaptorException e) { + request.setAttribute("error_extra_msg", "Unable to parse XML. Nested error: "); + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // reportImportSave + + private String reportLoad(HttpServletRequest request, String nextPage, boolean asCopy) { + try { + String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); + + ReportHandler rh = new ReportHandler(); + ReportDefinition rdef = rh.loadReportDefinition(request, reportID); + if (asCopy) + rdef.setAsCopy(request); + else + rdef.checkUserWriteAccess(request); + + rdef.getWizardSequence().performGoToStep(AppConstants.WS_DEFINITION); + request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); + // request.setAttribute(AppConstants.RI_CUR_STEP, + // AppConstants.WS_DEFINITION); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // reportLoad + + public String reportCopy(HttpServletRequest request, String nextPage) { + return reportLoad(request, nextPage, true); + } // reportCopy + + public String reportEdit(HttpServletRequest request, String nextPage) { + return reportLoad(request, nextPage, false); + } // reportEdit + + public String reportDelete(HttpServletRequest request, String nextPage) { + try { + String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); + try { + int i = Integer.parseInt(reportID); + } catch(NumberFormatException ex) { + throw new UserDefinedException("Not a valid report id"); + } + String userID = AppUtils.getUserID(request); + + (new ReportSecurity(reportID)).checkUserDeleteAccess(request); + + ReportLoader.deleteReportRecord(reportID); + + return "{\"deleted\":true}"; + //nextPage = reportSearchExecute(request, nextPage); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + //return nextPage; + return "{\"deleted\":false}"; + } // reportDelete + + private String generateSearchString(HttpServletRequest request) { + String searchString = AppUtils.getRequestNvlValue(request, AppConstants.RI_SEARCH_STRING); + boolean containFlag = AppUtils.getRequestFlag(request, AppConstants.RI_CONTAIN_FLAG); + return (searchString.length() > 0) ? ((containFlag ? "%" : "") + searchString + "%"):""; + } // generateSearchString + + public String reportFormFieldPopup(HttpServletRequest request, String nextPage) { + try { + ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( + AppConstants.SI_REPORT_RUNTIME); + + FormField ff = rr.getFormField(request.getParameter(AppConstants.RI_FIELD_NAME)); + ReportFormFields rff = rr.getReportFormFields(); + + int idx = 0; + FormField ff1 = null; + Map fieldNameMap = new HashMap(); + int countOfFields = 0 ; + String userId = AppUtils.getUserID(request); + IdNameList lookup = ff.getLookupList(); + String oldSQL = lookup.getOldSql(); + + if(AppUtils.getRequestFlag(request, AppConstants.RI_TEXTFIELD_POP)) { + for(rff.resetNext(); rff.hasNext(); idx++) { + ff1 = rff.getNext(); + fieldNameMap.put(ff1.getFieldName(), ff1.getFieldDisplayName()); + countOfFields++; + } + + + //List formParameter = new ArrayList(); + String formField = ""; + HashMap valuesMap = new HashMap(); + for(int i = 0 ; i < rff.size(); i++) { + formField = ((FormField)rff.getFormField(i)).getFieldName(); + if(request.getParameterValues(formField) != null && request.getParameterValues(formField).length > 1 ) { + String[] vals = (String[]) request.getParameterValues(formField); + String value = ""; + StringBuffer valueBuf = new StringBuffer(); + for(int ii = 0 ; ii < vals.length; ii++) { + if(ii == 0) valueBuf.append("("); + valueBuf.append(vals[ii]); + if(ii == vals.length-1) valueBuf.append(")"); + else valueBuf.append(","); + } + value = valueBuf.toString(); + valuesMap.put(fieldNameMap.get(formField), value); + } else if(request.getParameter(formField) != null) { + valuesMap.put(fieldNameMap.get(formField), request.getParameter(formField)); + } + } + if(countOfFields != 0) { + IdNameSql lu = (IdNameSql) lookup; + String SQL = (oldSQL==null)?lu.getSql():oldSQL; + oldSQL = SQL; + Set set = valuesMap.entrySet(); + String value = ""; + StringBuffer valueBuf = new StringBuffer(); + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + if(entry.getValue() instanceof String[]) { + String[] vals = (String[]) entry.getValue(); + for(int i = 0 ; i < vals.length; i++) { + if(i == 0) valueBuf.append("("); + valueBuf.append(vals[i]); + if(i == vals.length-1) valueBuf.append(")"); + else valueBuf.append(","); + } + value = valueBuf.toString(); + } else { + value = (String) entry.getValue(); + } + // added so empty string would be treated as null value if not given in single quotes. + if(value==null || value.trim().length()<=0) value="NULL"; + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", Utils.oracleSafe(value)); + } + if(request.getParameter(ff.getFieldName())!=null) { + lookup = new IdNameSql(-1,SQL,null); + lookup.setOldSql(oldSQL); + } + else { + lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); + lookup.setOldSql(oldSQL); + } + //lookup.loadData("0"); + } + if(lookup instanceof IdNameSql) ((IdNameSql)lookup).setDataSizeUsedinPopup(-3); // -3 indicates to run the count sql for pagination. + } + if(lookup instanceof IdNameSql) { + ((IdNameSql)lookup).loadUserData(request.getParameter(AppConstants.RI_NEXT_PAGE), + nvl(generateSearchString(request),"%"), rr.getDBInfo(),userId); + } + + int dataSizeForPopUp = 0; + if(lookup instanceof IdNameSql) { + dataSizeForPopUp = ((IdNameSql)lookup).getDataSizeUsedinPopup(); + } else + dataSizeForPopUp = lookup.getDataSize(); + + ff.setLookupList(lookup); + request.setAttribute("lookupList", lookup); + if(dataSizeForPopUp >= 0) + request.getSession().setAttribute(AppConstants.SI_DATA_SIZE_FOR_TEXTFIELD_POPUP, ""+dataSizeForPopUp); + } catch (RaptorException e) { + e.printStackTrace(); + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + return nextPage; + } // reportFormFieldPopup + + public String reportValuesMapDefPopup(HttpServletRequest request, String nextPage) { + try { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String colName = AppUtils.getRequestNvlValue(request, "colName"); + String colType = nvl(AppUtils.getRequestValue(request, "colType"), + AppConstants.CT_CHAR); + String displayName = AppUtils.getRequestNvlValue(request, "displayName"); + String displayFormat = AppUtils.getRequestNvlValue(request, "displayFormat"); + String tableId = AppUtils.getRequestNvlValue(request, "tableId"); + String dbInfo = rdef.getDBInfo(); + if (Utils.isNull(dbInfo)) { + dbInfo = (String) request.getSession().getAttribute("remoteDB"); + } + /*String query = "SELECT x FROM (SELECT DISTINCT " + + (colType.equals(AppConstants.CT_DATE) ? ("TO_CHAR(" + colName + ", '" + + nvl(displayFormat, AppConstants.DEFAULT_DATE_FORMAT) + "')") + : colName) + " x FROM " + + rdef.getTableById(tableId).getTableName() + " WHERE " + colName + + " IS NOT NULL ORDER BY 1) xx WHERE ROWNUM <= " + + Globals.getDefaultPageSize();*/ + + + String q1 = Globals.getReportValuesMapDefA(); + + String q2 = Globals.getReportValuesMapDefB(); + q2 = q2.replace("[colName]", colName); + q2 = q2.replace("[nvl(displayFormat, AppConstants.DEFAULT_DATE_FORMAT)]", nvl(displayFormat, AppConstants.DEFAULT_DATE_FORMAT)); + + String q3 = Globals.getReportValuesMapDefC(); + q3 = q3.replace("[colName]", colName); + + String q4 = Globals.getReportValuesMapDefD(); + q4 = q4.replace("[rdef.getTableById(tableId).getTableName()]", rdef.getTableById(tableId).getTableName()); + q4 = q4.replace("[colName]", colName); + q4 = q4.replace("[Globals.getDefaultPageSize()]", String.valueOf(Globals.getDefaultPageSize())); + + String query = q1 + (colType.equals(AppConstants.CT_DATE) ? q2 : q3) + q4; + + DataSet ds = ConnectionUtils.getDataSet(query, dbInfo); + request.setAttribute(AppConstants.RI_DATA_SET, ds); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // reportValuesMapDefPopup + + public String reportDrillDownToReportDefPopup(HttpServletRequest request, String nextPage) { + try { + // ReportDefinition rdef = (ReportDefinition) + // request.getSession().getAttribute(AppConstants.SI_REPORT_DEFINITION); + String ddReportID = AppUtils + .getRequestNvlValue(request, AppConstants.RI_REPORT_ID); + ReportRuntime ddRr = (new ReportHandler()).loadReportRuntime(request, ddReportID, + false); + if (ddRr != null) + request.setAttribute(AppConstants.RI_FORM_FIELDS, ddRr.getReportFormFields()); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // reportDrillDownToReportDefPopup + + public String reportFilterDataPopup(HttpServletRequest request, String nextPage) { + try { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String colId = AppUtils.getRequestNvlValue(request, AppConstants.RI_COLUMN_ID); + IdNameColLookup lookup = null; + String dbInfo = rdef.getDBInfo(); + if (Utils.isNull(dbInfo)) { + dbInfo = (String) request.getSession().getAttribute("remoteDB"); + } + if (!AppUtils.getRequestFlag(request, AppConstants.RI_RESET_PARAMS)) + lookup = (IdNameColLookup) request.getSession().getAttribute( + AppConstants.SI_COLUMN_LOOKUP); + if (lookup == null || (!colId.equals(lookup.getColId()))) { + DataColumnType dct = rdef.getColumnById(colId); + lookup = new IdNameColLookup(colId, rdef.getTableById(dct.getTableId()) + .getTableName(), dct.getColName(), rdef.getSelectExpr(dct), dct + .getColName() + + (dct.getColType().equals(AppConstants.CT_DATE) ? " DESC" : "")); + request.getSession().setAttribute(AppConstants.SI_COLUMN_LOOKUP, lookup); + } // if + + lookup.loadData(nvl(request.getParameter(AppConstants.RI_NEXT_PAGE), "0"), + generateSearchString(request), dbInfo); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // reportFilterDataPopup + + public String reportShowSQLPopup(HttpServletRequest request, String nextPage) { + try { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + String reportSQL = rdef.generateSQL(AppUtils.getUserID(request),request); + + String[] sqlClause = { "SELECT ", "FROM ", "WHERE ", "GROUP BY ", "HAVING ", + "ORDER BY " }; + + int idxNext = 0; + StringBuffer sb = new StringBuffer(); + while (idxNext < sqlClause.length) { + sb.append(""); + if (idxNext > 0) + sb.append("    "); + sb.append(sqlClause[idxNext]); + sb.append("
\n"); + + int clauseStartPos = reportSQL.indexOf(sqlClause[idxNext]) + + sqlClause[idxNext].length(); + do + idxNext++; + while ((idxNext < sqlClause.length) + && (reportSQL.indexOf(sqlClause[idxNext]) < 0)); + + String clauseContent = null; + if (idxNext < sqlClause.length) + clauseContent = reportSQL.substring(clauseStartPos, reportSQL + .indexOf(sqlClause[idxNext]) - 1); + else + clauseContent = reportSQL.substring(clauseStartPos); + + while (clauseContent.length() > 0) { + int braketCount = 0; + StringBuffer nextToken = new StringBuffer(); + for (int i = 0; i < clauseContent.length(); i++) { + char ch = clauseContent.charAt(i); + nextToken.append(ch); + if (ch == '(') + braketCount++; + else if (ch == ')') + braketCount--; + else if (ch == ',') + if (braketCount == 0) + break; + } // for %> + + sb.append("        "); + sb.append(nextToken.toString()); + sb.append("
\n"); + + if (nextToken.length() < clauseContent.length()) + clauseContent = clauseContent.substring(nextToken.length() + 1); + else + clauseContent = ""; + } // while + } // while + + request.setAttribute(AppConstants.RI_FORMATTED_SQL, sb.toString()); + request.setAttribute(AppConstants.RI_PAGE_TITLE, "Generated SQL"); + request.setAttribute(AppConstants.RI_PAGE_SUBTITLE, "Generated SQL for report " + + rdef.getReportName()); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // reportShowSQLPopup + + public String testSchedCondPopup(HttpServletRequest request, String nextPage) { + try { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String sql = AppUtils.getRequestNvlValue(request, AppConstants.RI_FORMATTED_SQL); + + request.setAttribute("msg_align", " align=center"); + request.setAttribute(AppConstants.RI_PAGE_TITLE, "Test Scheduler Condition"); + // request.setAttribute(AppConstants.RI_PAGE_SUBTITLE, ...); + //String query = "SELECT 1 FROM DUAL WHERE EXISTS (" + sql + ")"; + + String query = Globals.getTestSchedCondPopup(); + query = query.replace("[sql]", sql); + + DataSet ds = null; + String remoteDb = request.getParameter("remoteDbPrefix"); + String remoteDbPrefix = (remoteDb != null && !remoteDb.equalsIgnoreCase("null")) ? remoteDb + : rdef.getDBInfo(); + ds = ConnectionUtils.getDataSet(sql, remoteDbPrefix); + // if ( (remoteDbPrefix!=null) && + // (!remoteDbPrefix.equals(AppConstants.DB_LOCAL))) { + // Globals.getRDbUtils().setDBPrefix(remoteDbPrefix); + // ds = RemDbUtils.executeQuery(query); + // } + // else + // ds = DbUtils.executeQuery(query); + if (ds.getRowCount() == 0) + request + .setAttribute(AppConstants.RI_FORMATTED_SQL, + "
Condition NOT satisfied - email notification will NOT be send.

"); + else + request + .setAttribute(AppConstants.RI_FORMATTED_SQL, + "
Condition satisfied - email notification will be send.

"); + } catch (Exception e) { + // nextPage = (new ErrorHandler()).processFatalError(request, e); + request.setAttribute(AppConstants.RI_FORMATTED_SQL, "
SQL ERROR " + + e.getMessage() + "
Email notification will NOT be send.

"); + } + + return nextPage; + } // testSchedCondPopup + + public String testRunSQLPopup(HttpServletRequest request, String nextPage) { + String sql = AppUtils.getRequestNvlValue(request, AppConstants.RI_FORMATTED_SQL); + if(nvl(sql).length()<=0) { + sql = AppUtils.getRequestNvlValue(request, "reportSQL"); + } + + + boolean chkFormFieldSQL = AppUtils.getRequestNvlValue(request, + AppConstants.RI_CHK_FIELD_SQL).equals("Y"); + try { + if (!sql.trim().toUpperCase().startsWith("SELECT")) + throw new UserDefinedException( + "Invalid statement - the SQL must start with the keyword SELECT"); + + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + if (!chkFormFieldSQL) { + if (rdef.getFormFieldList() != null) + for (Iterator iter = rdef.getFormFieldList().getFormField().iterator(); iter + .hasNext();) { + FormFieldType fft = (FormFieldType) iter.next(); + String fieldId = fft.getFieldId(); + String fieldDisplay = rdef.getFormFieldDisplayName(fft); + /* + * if(paramValues.isParameterMultiValue(fieldId)) + * generatedSQL = Utils.replaceInString(generatedSQL, + * fieldDisplay, nvl(formatListValue((String) + * paramValues.get(fieldId), null, false, false, null), + * "NULL")); else + */ + sql = Utils.replaceInString(sql, fieldDisplay, "NULL"); + } // for + } // if + DataSet ds = null; + String remoteDb = request.getParameter("remoteDbPrefix"); + String remoteDbPrefix = (remoteDb != null && !remoteDb.equalsIgnoreCase("null")) ? remoteDb + : rdef.getDBInfo(); + String userId = AppUtils.getUserID(request); + sql = Utils.replaceInString(sql, "[LOGGED_USERID]", userId); + String[] reqParameters = Globals.getRequestParams().split(","); + String[] sessionParameters = Globals.getSessionParams().split(","); + javax.servlet.http.HttpSession session = request.getSession(); + logger.debug(EELFLoggerDelegate.debugLogger, ("B4 testRunSQL " + sql)); + if(request != null ) { + for (int i = 0; i < reqParameters.length; i++) { + if(!reqParameters[i].startsWith("ff")) + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); + else + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + } + } + if(session != null ) { + for (int i = 0; i < sessionParameters.length; i++) { + //if(!sessionParameters[i].startsWith("ff")) + //sql = Utils.replaceInString(sql, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i].toUpperCase()) ); + //else { + logger.debug(EELFLoggerDelegate.debugLogger, (" Session " + " sessionParameters[i] " + sessionParameters[i] + " " + (String)session.getAttribute(sessionParameters[i]))); + sql = Utils.replaceInString(sql, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); + //} + } + } + logger.debug(EELFLoggerDelegate.debugLogger, ("After testRunSQL " + sql)); + + ds = ConnectionUtils.getDataSet(sql, remoteDbPrefix, true); + // if ( (remoteDbPrefix!=null) && + // (!remoteDbPrefix.equals(AppConstants.DB_LOCAL))) { + // Globals.getRDbUtils().setDBPrefix(remoteDbPrefix); + // ds = RemDbUtils.executeQuery(sql, + // Globals.getDefaultPageSize()+1); + // } + // else + // ds = DbUtils.executeQuery(sql, Globals.getDefaultPageSize()+1); + if (chkFormFieldSQL && ds.getRowCount() > 0) { + String id = ds.getString(0, "id"); + String name = ds.getString(0, "name"); + } // if + + request.setAttribute(AppConstants.RI_DATA_SET, ds); + } catch (RaptorException e) { + request.setAttribute(AppConstants.RI_EXCEPTION, e); + } + + return nextPage; + } // testRunSQLPopup + + public String importSemaphorePopup(HttpServletRequest request, String nextPage) { + try { + (new WizardProcessor()).processImportSemaphorePopup(request); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // importSemaphorePopup + + public String saveSemaphorePopup(HttpServletRequest request, String nextPage) { + try { + (new WizardProcessor()).processSemaphorePopup(request); + } catch (RaptorException e) { + nextPage = (new ErrorHandler()).processFatalError(request, e); + } + + return nextPage; + } // saveSemaphorePopup + + public String gotoJsp(HttpServletRequest request, String nextPage) { + return nextPage; + } // gotoJsp + + public String downloadAll(HttpServletRequest request, String nextPage) throws InterruptedException, IOException, Exception { + String emailId = null; + String pdfAttachmentKey = AppUtils.getRequestValue(request, "pdfAttachmentKey"); + boolean isFromSchedule = nvl(pdfAttachmentKey).length()>0; + if(!isFromSchedule) + emailId = AppUtils.getUserEmail(request); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd"); + java.util.Date currDate = new java.util.Date(); + String timestamp = sdf.format(currDate); + String dateStr = sdf1.format(currDate); + + String userId = null; + if(!isFromSchedule) + userId = AppUtils.getUserID(request); + else + userId = AppUtils.getRequestValue(request, "user_id"); + Runtime runtime = Runtime.getRuntime(); + ReportRuntime rr = null; + if(!isFromSchedule) { + rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); + if(rr!=null) AppUtils.getUserEmail(request); + } + String scheduleId = ""; + + if(isFromSchedule) { + String reportID = null; + String report_email_sent_log_id = AppUtils.getRequestValue(request, "log_id"); + /*String query = "Select user_id, rep_id from CR_REPORT_EMAIL_SENT_LOG" + + " where rownum = 1" + + " and gen_key='"+pdfAttachmentKey.trim()+"'" + + " and log_id ="+report_email_sent_log_id.trim() + + " and (sysdate - sent_date) < 1 ";*/ + + String query = Globals.getDownloadAllEmailSent(); + query = query.replace("[pdfAttachmentKey.trim()]", pdfAttachmentKey.trim()); + query = query.replace("[report_email_sent_log_id.trim()]", report_email_sent_log_id.trim()); + + DataSet ds = DbUtils.executeQuery(query, 1); + if(!ds.isEmpty()) { + userId = ds.getString(0,"user_id"); + reportID = ds.getString(0, "rep_id"); + request.setAttribute("schedule_email_userId", userId); + } else { + request.setAttribute("message", "This link has expired, please login and regenerate the report"); + return "raptor/message.jsp"; + } + + ReportHandler rh1 = new ReportHandler(); + + if(reportID !=null && nvl(pdfAttachmentKey).length()>0) { + rr = rh1.loadReportRuntime(request, reportID, true, 1); + rr.loadReportData(-1, userId, 1000 ,request, false /*download*/); + } + + String d_sql = Globals.getDownloadAllGenKey(); + d_sql = d_sql.replace("[pdfAttachmentKey]", pdfAttachmentKey); + + //ds = DbUtils.executeQuery("select schedule_id from cr_report_email_sent_log u where U.GEN_KEY = '"+ pdfAttachmentKey + "'"); + + ds = DbUtils.executeQuery(d_sql); + for (int i = 0; i < ds.getRowCount(); i++) { + scheduleId = ds.getString(i,0); + } + } + logger.debug(EELFLoggerDelegate.debugLogger, ("SQL2:\n"+ rr.getCachedSQL())); + String fileName = rr.getReportID()+"_"+userId+"_"+timestamp; + boolean flag = false; + logger.debug(EELFLoggerDelegate.debugLogger, (""+Utils.isDownloadFileExists(rr.getReportID()+"_"+userId+"_"+dateStr))); + // if(Utils.isDownloadFileExists(rr.getReportID()+"_"+userId+"_"+dateStr)) { + // flag = true; + // } + + if(flag){ + String strFileName = Utils.getLatestDownloadableFile(rr.getReportID()+"_"+userId+"_"+dateStr); + //debugLogger.debug("File Name " + strFileName); + StringBuffer messageBuffer = new StringBuffer(""); + messageBuffer.append("Download data file using the following link
"); + messageBuffer.append("click here.

"); + request.setAttribute("message", messageBuffer.toString()); + } + else if(!flag) { + String whole_fileName = (Globals.getShellScriptDir() +AppConstants.SHELL_QUERY_DIR+ fileName+AppConstants.FT_SQL); + String whole_columnsfileName = (Globals.getShellScriptDir() +AppConstants.SHELL_QUERY_DIR+ fileName+AppConstants.FT_COLUMNS); + + logger.debug(EELFLoggerDelegate.debugLogger, ("FILENAME "+whole_fileName)); + + List l = rr.getAllColumns(); + StringBuffer allColumnsBuffer = new StringBuffer(); + DataColumnType dct = null; + + for (Iterator iter = l.iterator(); iter.hasNext();) { + dct = (DataColumnType) iter.next(); + allColumnsBuffer.append(dct.getDisplayName()); + if(iter.hasNext()) + allColumnsBuffer.append("|"); + } + try { + PrintWriter xmlOut = new PrintWriter(new BufferedWriter(new FileWriter(new File(whole_columnsfileName)))); + xmlOut.println(allColumnsBuffer.toString()); + xmlOut.flush(); + xmlOut.close(); + } catch (IOException e) {e.printStackTrace();} + try { + PrintWriter xmlOut = new PrintWriter(new BufferedWriter(new FileWriter(new File(whole_fileName)))); + logger.debug(EELFLoggerDelegate.debugLogger, ("**************************")); + logger.debug(EELFLoggerDelegate.debugLogger, (rr.getWholeSQL())); + logger.debug(EELFLoggerDelegate.debugLogger, ("************************")); + logger.debug(EELFLoggerDelegate.debugLogger, ("************************")); + logger.debug(EELFLoggerDelegate.debugLogger, (rr.parseReportSQL(rr.getWholeSQL()))); + xmlOut.println(rr.parseReportSQL(rr.getWholeSQL())); + //xmlOut.println("******************"); + //xmlOut.println(rr.getWholeSQL()); + xmlOut.flush(); + xmlOut.close(); + } catch (IOException e) {e.printStackTrace();} + + StringBuffer command = new StringBuffer(Globals.getShellScriptDir() + AppConstants.SHELL_SCRIPTS_DIR); + if(nvl(emailId).length()>0) { + command.append(AppConstants.SHELL_SCRIPT_NAME + " " + (fileName+AppConstants.FT_SQL)); + command.append(" "+emailId); + } + else if (nvl(scheduleId).length()>0) { + command.append(AppConstants.SCHEDULE_SHELL_SCRIPT_NAME + " " + (fileName+AppConstants.FT_SQL)); + command.append(" " + scheduleId); + } + logger.debug(EELFLoggerDelegate.debugLogger, ("Command " + command)); + Process downloadProcess = runtime.exec(command.toString()); + logger.debug(EELFLoggerDelegate.debugLogger, ("Command Executed ")); + //Connection connection = DbUtils.getConnection(); + Enumeration enum1 = rr.getParamKeys(); + String value = "", key = ""; + String paramStr = ""; + StringBuffer paramBuffer = new StringBuffer(); + if(enum1!=null) { + for (; enum1.hasMoreElements();) { + key = (String) enum1.nextElement(); + value = rr.getParamValue(key); + paramBuffer.append(key+":"+value+" "); + } + paramStr = paramBuffer.toString(); + } + + StringBuffer retrieveUserEmailQry = null; + ArrayList userEmailList = new ArrayList(); + if(nvl(scheduleId).length()>0) { + /*retrieveUserEmailQry = new StringBuffer(); + retrieveUserEmailQry.append(" SELECT "); + retrieveUserEmailQry.append(" au.user_id "); + retrieveUserEmailQry.append(" FROM "); + retrieveUserEmailQry.append(" (SELECT rs.schedule_id, rs.rep_id FROM cr_report_schedule rs WHERE rs.enabled_yn='Y' AND rs.run_date IS NOT NULL "); + retrieveUserEmailQry.append(" AND rs.schedule_id = " + scheduleId + " ) x, cr_report r, app_user au "); + retrieveUserEmailQry.append(" WHERE "); + retrieveUserEmailQry.append("x.rep_id = r.rep_id "); + retrieveUserEmailQry.append(" AND au.user_id IN (SELECT rsu.user_id FROM cr_report_schedule_users rsu WHERE rsu.schedule_id = x.schedule_id and rsu.schedule_id = " + scheduleId ); + retrieveUserEmailQry.append(" UNION "); + retrieveUserEmailQry.append(" SELECT ur.user_id FROM fn_user_role ur "); + retrieveUserEmailQry.append(" WHERE ur.role_id IN "); + retrieveUserEmailQry.append(" (SELECT rsu2.role_id FROM cr_report_schedule_users rsu2 "); + retrieveUserEmailQry.append(" WHERE rsu2.schedule_id = x.schedule_id and "); + retrieveUserEmailQry.append(" rsu2.schedule_id = "+ scheduleId + ")) ");*/ + + String r_sql = Globals.getDownloadAllRetrieve(); + r_sql = r_sql.replace("[scheduleId]", scheduleId); + + // DataSet ds = DbUtils.executeQuery(retrieveUserEmailQry.toString()); + DataSet ds = DbUtils.executeQuery(r_sql); + + for (int i = 0; i < ds.getRowCount(); i++) { + userEmailList.add(ds.getString(i, 0)); + } + + } + // String insertQry = "insert into cr_report_dwnld_log (user_id,rep_id,file_name,dwnld_start_time,filter_params) values (?,?,?,?,?)"; + String insertQry = Globals.getDownloadAllInsert(); + + + Connection connection = null; + PreparedStatement pst = null; + try { + connection = DbUtils.getConnection(); + pst = connection.prepareStatement(insertQry); + if(nvl(emailId).length()>0){ + pst.setInt(1, Integer.parseInt(userId)); + pst.setInt(2, Integer.parseInt(rr.getReportID())); + pst.setString(3, fileName+AppConstants.FT_ZIP); + pst.setTimestamp(4,new java.sql.Timestamp(currDate.getTime())); + pst.setString(5,paramStr); + pst.execute(); + connection.commit(); + } else { + for (int i = 0; i < userEmailList.size(); i++) { + pst.setInt(1, Integer.parseInt((String)userEmailList.get(i))); + pst.setInt(2, Integer.parseInt(rr.getReportID())); + pst.setString(3, fileName+AppConstants.FT_ZIP); + pst.setTimestamp(4,new java.sql.Timestamp(currDate.getTime())); + pst.setString(5,paramStr); + pst.execute(); + connection.commit(); + } + } + pst.close(); + connection.close(); + logger.debug(EELFLoggerDelegate.debugLogger, ("Data inserted")); + } catch (SQLException ex) { + throw new RaptorException(ex); + } catch (ReportSQLException ex) { + throw new RaptorException(ex); + } catch (Exception ex) { + throw new RaptorException (ex); + } finally { + try { + if(connection!=null) + connection.close(); + if(pst!=null) + pst.close(); + } catch (SQLException ex) { + throw new RaptorException(ex); + } + } + //DbUtils.commitTransaction(connection); + //DbUtils.clearConnection(connection); + + + +// debugLogger.debug("|"+downloadProcess.toString() + "|"); +// if (downloadProcess == null) +// throw new Exception("unable to create a process for command:" + +// command); +// int retCode= 1; +// try { +// retCode= downloadProcess.waitFor(); +// } catch (InterruptedException e){ +// e.printStackTrace(); +// } +// debugLogger.debug("retCode " + retCode); +// Process child = rtime.exec("/bin/bash"); +// BufferedWriter outCommand = new BufferedWriter(new +// OutputStreamWriter(child.getOutputStream())); +// outCommand.write(Globals.getShellScriptName()); +// outCommand.flush(); +// int retCode = child.waitFor(); +// debugLogger.debug("RetCode " + retCode); + //request.setAttribute("message", "Shell Script is running in the background. You'll get an email once it is done"); + } + + return nextPage; + } + public String getChildDropDown(HttpServletRequest request, String nextPage) throws RaptorRuntimeException { + + if(request.getParameter("firstTime") != null) { return nextPage; } + + /*ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( + AppConstants.SI_REPORT_RUNTIME); + + String c_master = request.getParameter("c_master"); + java.util.HashMap valuesMap = Globals.getRequestParamtersMap(request); + request.setAttribute("c_master", c_master); + + int idx = 0; + ReportFormFields rff = rr.getReportFormFields(); + FormField ff = null; + for(rff.resetNext(); rff.hasNext(); idx++) { + ff = rff.getNext(); + + + if(ff.getDependsOn() != null && ff.getDependsOn().trim() != "") + { + String val = request.getParameter(ff.getFieldName()); + request.setAttribute(ff.getFieldName(), ff.getHtml(val, valuesMap, rr)); + } + + } + */ + return nextPage; + + } + + private void removeVariablesFromSession(HttpServletRequest request) { + HttpSession session = request.getSession(); + session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); + session.removeAttribute(AppConstants.DRILLDOWN_INDEX); + session.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); + session.removeAttribute(AppConstants.SI_BACKUP_FOR_REP_ID); + session.removeAttribute(AppConstants.SI_COLUMN_LOOKUP); + session.removeAttribute(AppConstants.SI_DASHBOARD_REP_ID); + session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); + session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME); + session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); + session.removeAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP); + session.removeAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); + session.removeAttribute(AppConstants.SI_DATA_SIZE_FOR_TEXTFIELD_POPUP); + session.removeAttribute(AppConstants.SI_MAP); + session.removeAttribute(AppConstants.SI_MAP_OBJECT); + session.removeAttribute(AppConstants.SI_REPORT_DEFINITION); + session.removeAttribute(AppConstants.SI_REPORT_RUNTIME); + session.removeAttribute(AppConstants.SI_REPORT_RUN_BACKUP); + session.removeAttribute(AppConstants.SI_REPORT_SCHEDULE); + session.removeAttribute(AppConstants.RI_REPORT_DATA); + session.removeAttribute(AppConstants.RI_CHART_DATA); + session.removeAttribute(AppConstants.SI_FORMFIELD_INFO); + session.removeAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); + session.removeAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP); + session.removeAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP); + Enumeration enum1 = session.getAttributeNames(); + String attributeName = ""; + while(enum1.hasMoreElements()) { + attributeName = enum1.nextElement(); + if(attributeName.startsWith("parent_")) { + session.removeAttribute(attributeName); + } + } + } + + + private TreeMap getListOfReportsFromDashBoardHTML(String htmlString) { + //String sourcestring = "
[Report#123][Report#124]
[Report#125][Report#126]
"; + String sourcestring = htmlString; + //Pattern re = Pattern.compile("([a-z]+)\\[([a-z]+)([=<>]+)([a-z]+)\\]",Pattern.CASE_INSENSITIVE); + //Pattern re = Pattern.compile("\\[([R][e][p][o][r][t][#])[(*)]\\]"); + Pattern re = Pattern.compile("\\[(.*?)\\]"); //\\[(.*?)\\] + Matcher m = re.matcher(sourcestring); + HashMap hashReports = new HashMap(); + int mIdx = 0; + while (m.find()){ + for( int groupIdx = 0; groupIdx < m.groupCount(); groupIdx++ ){ + String str = m.group(groupIdx); + //System.out.println(str); + hashReports.put(new String(Integer.toString(mIdx+1)), (str.substring(1).toLowerCase().startsWith("chart")?"c":"d") + str.substring(str.indexOf("#")+1, str.length()-1)); + } + mIdx++; + } + // Sorting HashMap based on Keys + /*List mapKeys = new ArrayList(hashReports.keySet()); + List mapValues = new ArrayList(hashReports.values()); + hashReports.clear(); + hashReports = null; + hashReports = new HashMap(); + + TreeSet sortedSet = new TreeSet(mapKeys); + Object[] sortedArray = sortedSet.toArray(); + int size = sortedArray.length; + for (int i=0; i iter = reportCols.iterator(); iter.hasNext();) { + + DataColumnType dc = (DataColumnType) iter.next(); + if (colNames.length() > 0) + colNames.append(", "); + colNames.append(dc.getColId()); + if (dc.isVisible()) { + //TODO: Drilldown URL + //sql = reportRuntime.parseReportSQLForDrillDownParams(sql, dc, request); + } + } + + DataSet ds = null; + // try { + String dbInfo = reportRuntime.getDBInfo(); + if(maxRows == 1) + sql += " limit "+ maxRows; + System.out.println("SQL getReportData()- " + sql); + ds = ConnectionUtils.getDataSet(sql, dbInfo); + int totalRows = 0; + /*if (reportRuntime.getReportDataSize() < 0) {*/ + //String countSQL = "SELECT count(*) FROM (" + sql + ") x"; + String dbType = ""; + + if (dbInfo!=null && (!dbInfo.equals(AppConstants.DB_LOCAL))) { + try { + org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); + dbType = remDbInfo.getDBType(dbInfo); + } catch (Exception ex) { + throw new RaptorException(ex); + } + } + + totalRows = ds.getRowCount(); + /*}*/ + ReportData rd = new ReportData(0, true); + + if(totalRows > 0) { + // Already defined changed for modifying request parameters + //List reportCols = getAllColumns(); + Vector visibleCols = new Vector(reportCols.size()); + Vector formatProcessors = new Vector(reportCols.size()); + + // ColumnHeaderRow chr = new ColumnHeaderRow(); + // rd.reportColumnHeaderRows.addColumnHeaderRow(chr); + // chr.setRowHeight("30"); + int count =0 ; + + /* ADDED */ + ReportFormFields rff = reportRuntime.getReportFormFields(); + ReportFormFields childReportFormFields = null; + String fieldDisplayName = ""; + String fieldValue = ""; + + for (int c = 0; c < reportCols.size(); c++) { + if(reportCols.get(c)!=null) { + DataColumnType dct = (DataColumnType) reportCols.get(c); + if(nvl(dct.getDependsOnFormField()).length()>0 && nvl(dct.getDependsOnFormField()).indexOf("[")!=-1) { + for(int i = 0 ; i < rff.size(); i++) { + fieldDisplayName = "["+((FormField)rff.getFormField(i)).getFieldDisplayName()+"]"; + fieldValue = ""; + //if(dct.getOriginalDisplayName()==null) dct.setOriginalDisplayName(dct.getDisplayName()); + if (dct.getDependsOnFormField().equals(fieldDisplayName)) { + fieldValue = nvl(request.getParameter(((FormField)rff.getFormField(i)).getFieldName())); + + if (fieldValue.length()>0) { + if(!fieldValue.toUpperCase().equals("Y")) + dct.setDisplayName(fieldValue); + if(!dct.isVisible()) + dct.setVisible(true); + } else { + dct.setVisible(false); + } + } + } + } + } + } + + /* ADDED */ + String displayName = ""; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + + DataColumnType dc = (DataColumnType) iter.next(); + + formatProcessors.add(count,new FormatProcessor( + reportRuntime.getSemaphoreById(dc.getSemaphoreId()), dc.getColType(), dc + .getColFormat(), reportRuntime.getReportDefType().equals( + AppConstants.RD_SQL_BASED))); + + /* TODO: Add Drilldown URL */ + if (nvl(dc.getDrillDownURL()).length() > 0) { + childReportFormFields = reportRuntime.getChildReportFormFields(request,dc.getDrillDownURL()); + } + if (dc.isVisible()) { + visibleCols.add(count,dc); + //if(dc.getColId().startsWith("group")) { + for (int d = 0; d < reportCols.size(); d++) { + if(reportCols.get(d)!=null) { + DataColumnType dct1 = (DataColumnType) reportCols.get(d); + if(dct1.getColId().equals(dc.getColId()+"_name") && ds.getRowCount()>0) { + displayName = ds.getString(0,dct1.getColId()); + dc.setDisplayName(displayName); + } + } + } + //} + + VisualManager visualManager = reportRuntime.getVisualManager(); + rd.createColumn(dc.getColId(), dc.getDisplayName(), dc.getDisplayWidthInPxls(),dc.getDisplayHeaderAlignment(), + visualManager.isColumnVisible(dc.getColId()), visualManager + .getSortByColId().equals(dc.getColId()) ? visualManager + .getSortByAscDesc() : null, true, dc.getLevel()!=null?dc.getLevel():0, dc.getStart()!=null?dc.getStart():0, dc.getColspan()!=null?dc.getColspan():0, dc.isIsSortable()!=null?dc.isIsSortable():false); + // chr.addColumnHeader(new ColumnHeader(dc.getDisplayName(), + // (dc.getDisplayWidth()>100)?"10%":(""+dc.getDisplayWidth()+"%"))); + } // if + else { + visibleCols.add(count,null); + rd.createColumn(dc.getColId(), AppConstants.HIDDEN, dc.getDisplayWidthInPxls(), dc.getDisplayHeaderAlignment(), + false, null,false,dc.getLevel()!=null?dc.getLevel():0, dc.getStart()!=null?dc.getStart():0, dc.getColspan()!=null?dc.getColspan():0, dc.isIsSortable()!=null?dc.isIsSortable():false); +// formatProcessors.add(count,null); + } + count++; + } // for + + // Utils._assert(chr.size()==ds.getColumnCount(), + // "[ReportRuntime.loadLinearReportData] The number of visible columns + // does not match the number of data columns"); + //TODO: This should be optimized to accept -1 for flat file download + if(maxRows > totalRows) maxRows = totalRows; + ArrayList reportDataList = new ArrayList(); + for (int r = 0; r < maxRows; r++) { + DataRow dr = new DataRow(); + rd.reportDataRows.addDataRow(dr); + + for (int c = 0; c < reportCols.size(); c++) { + if(reportCols.get(c)!=null) { + DataColumnType dct = (DataColumnType) reportCols.get(c); + //Modified since ds is null. + DataValue dv = new DataValue(); + + if(ds.getRowCount()>0){ + if(ds.getColumnIndex(dct.getColId())!= -1) { + dr.addDataValue(dv); + dv.setDisplayValue(ds.getString(r, dct.getColId())); + } else { + continue; + } + + } else { + dv.setDisplayValue(""); + } + dv.setColName(dct.getColName()); + dv.setColId(dct.getColId()); + dv.setNowrap(nvl(dct.getNowrap(),"null").equals("false")?"null":nvl(dct.getNowrap(),"null")); + + //Add Drilldown URL to dv + if (nvl(dct.getDrillDownURL()).length() > 0) { + + if(dv.getDisplayValue().length() > 0) { + dv.setDrillDownURL(reportRuntime.parseDrillDownURL(r, /* c, */ds, dct, request, childReportFormFields)); + dv.setDrillDowninPoPUp(dct.isDrillinPoPUp()!=null?dct.isDrillinPoPUp():false); + } + + if (dv.getDisplayValue().length() == 0) { + //dv.setDisplayValue("[NULL]"); + dv.setDisplayValue(""); + } + } // if + + StringBuffer indentation = new StringBuffer(""); + if(dct.getIndentation()!=null && dct.getIndentation()>0) { + for (int indent=0; indent< dct.getIndentation(); indent++) { + indentation.append("\t"); + } + dv.setNowrap("true"); + } + dv.setIndentation(indentation.toString()); + + if(dct.isVisible()) { + + dv.setVisible(true); + dv.setAlignment(dct.getDisplayAlignment()); + dv.setDisplayTotal(dct.getDisplayTotal()); + dv.setDisplayName(dct.getDisplayName()); + +// if (nvl(dct.getDrillDownURL()).length() > 0) { + +// if(dv.getDisplayValue().length() > 0) { + //TODO: Below Drilldown URL +// dv.setDrillDownURL(reportRuntime.parseDrillDownURL(r, /* c, */ds, dct,request, childReportFormFields)); +// dv.setDrillDowninPoPUp(dct.isDrillinPoPUp()); +// } +// +// if (dv.getDisplayValue().length() == 0) { +// //dv.setDisplayValue("[NULL]"); +// dv.setDisplayValue(""); +// } +// } // if + + } else { + dv.setVisible(false); + dv.setHidden(true); + } + //System.out.println("in Linear report b4" + dr.getFormatId() + dr.getBgColorHtml() + dv.getDisplayValue()); + + if(dr.getFormatId()!=null) + ((FormatProcessor) formatProcessors.get(c)).setHtmlFormatters(dv, dr, true); + else + ((FormatProcessor) formatProcessors.get(c)).setHtmlFormatters(dv, dr, false); + + //System.out.println("in Linear report After" + dr.getFormatId() + dr.getBgColorHtml() + dv.getDisplayValue()); + } // if reportCols + } // for + reportDataList.add(dr); + } // for + + rd.setReportDataList(reportDataList); + //Only if rownumber options is needed + //rd.addRowNumbers(pageNo, getPageSize()); + DataRow colDataTotalsLinear = null; + if (colDataTotalsLinear == null) + colDataTotalsLinear = reportRuntime.generateColumnDataTotalsLinear(new ArrayList(reportCols), AppUtils.getUserID(request), + reportRuntime.getDbInfo(),request); + + if(colDataTotalsLinear!=null) + rd.setColumnDataTotalsLinear(colDataTotalsLinear, "Total"); + // Please note the below function doesn't set the visibility for dv since this is set in this function. - Sundar + rd.applyVisibility(); + } + return rd; + } // loadLinearReportData + + public String formFieldRun(HttpServletRequest request, String nextPage) { + ReportRuntime rr = null; + rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); + if(rr!=null) { + ReportJSONRuntime reportJSONRuntime = rr.createFormFieldJSONRuntime(request); + ObjectMapper mapper = new ObjectMapper(); + //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); + //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + String jsonInString = ""; + try { + jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(reportJSONRuntime); + } catch (Exception ex) { + ex.printStackTrace(); + + } + return jsonInString; + } + + return ""; + } + +} // ActionHandler diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionMapping.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionMapping.java new file mode 100644 index 00000000..723b5fd1 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionMapping.java @@ -0,0 +1,34 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +public class ActionMapping extends HashMap { + + public void addAction(Action action) { + put(action.getAction(), action); + } // addAction + + public Action getAction(String actionKey) { + return (Action) get(actionKey); + } // getAction + +} // ActionMapping diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Controller.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Controller.java new file mode 100644 index 00000000..c233b4a0 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Controller.java @@ -0,0 +1,125 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; +import java.lang.reflect.*; +import javax.servlet.*; +import javax.servlet.http.*; + +import org.openecomp.portalsdk.analytics.controller.*; +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.error.RaptorRuntimeException; +import org.openecomp.portalsdk.analytics.model.runtime.ReportParamValues; +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +public class Controller extends org.openecomp.portalsdk.analytics.RaptorObject { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(Controller.class); + public Controller() { + } + + public String processRequest(HttpServletRequest request) { + String actionKey = nvl(request.getParameter(AppConstants.RI_ACTION), "report.run"); + + return processRequest(actionKey, request); + } // processRequest + + public String processRequest(String actionKey, HttpServletRequest request) { + Action action = null; + try { + action = Globals.getRaptorActionMapping().getAction(actionKey); + if (action == null) + throw new RaptorRuntimeException("Action not found"); + } catch (RaptorException e) { + logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey + + "]. RaptorException: " + e.getMessage())); +// if (actionKey.equals("system_upgrade")) // System override +// return att.raptor.util.upgrade.SystemUpgrade.upgradeDB(request); + + return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( + "[Controller.processRequest]Invalid raptor action [" + actionKey + + "]. Exception: " + e.getMessage())); + } + + try { + Class[] paramTypes = new Class[2]; + paramTypes[0] = Class.forName("javax.servlet.http.HttpServletRequest"); + paramTypes[1] = Class.forName("java.lang.String"); + + Class handlerClass = Class.forName(action.getControllerClass()); + Object handler = handlerClass.newInstance(); + Method handlerMethod = handlerClass.getMethod(action.getControllerMethod(), + paramTypes); + + Object[] paramValues = new Object[2]; + paramValues[0] = request; + paramValues[1] = action.getJspName(); + + return (String) handlerMethod.invoke(handler, paramValues); + } catch (ClassNotFoundException e) { + logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey + + "]. ClassNotFoundException: " + e.getMessage())); + return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( + "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " + + e.getMessage())); + } catch (IllegalAccessException e) { + logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey + + "]. IllegalAccessException: " + e.getMessage())); + return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( + "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " + + e.getMessage())); + }catch (InstantiationException e) { + logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey + + "]. InstantiationException: " + e.getMessage())); + return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( + "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " + + e.getMessage())); + }catch (NoSuchMethodException e) { + logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey + + "]. NoSuchMethodException: " + e.getMessage())); + return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( + "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " + + e.getMessage())); + }catch (InvocationTargetException e) { + logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey + + "]. InvocationTargetException: " + e.getMessage())); + return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( + "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " + + e.getMessage())); + } + } // processRequest + + public void handleRequest(HttpServletRequest request, HttpServletResponse response, + ServletContext servletContext) throws Exception { + String actionKey = nvl(request.getParameter(AppConstants.RI_ACTION), request.getParameter("action")); + + handleRequest(actionKey, request, response, servletContext); + } // handleRequest + + public void handleRequest(String actionKey, HttpServletRequest request, + HttpServletResponse response, ServletContext servletContext) throws Exception { + servletContext.getRequestDispatcher("/" + processRequest(actionKey, request)).forward( + request, response); + } // handleRequest + +} // Controller diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ErrorHandler.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ErrorHandler.java new file mode 100644 index 00000000..75d88d0f --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ErrorHandler.java @@ -0,0 +1,151 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.*; +import javax.servlet.http.*; + +import org.openecomp.portalsdk.analytics.error.*; +import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; +import org.openecomp.portalsdk.analytics.model.runtime.ErrorJSONRuntime; +import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; +import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +public class ErrorHandler extends org.openecomp.portalsdk.analytics.RaptorObject { + + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ErrorHandler.class); + + public ErrorHandler() { + } + + public void processError(HttpServletRequest request, String errorMsg) { + //Log.write(errorMsg, 2); + logger.error(EELFLoggerDelegate.debugLogger, (errorMsg)); + ArrayList error_list = (ArrayList) request.getAttribute(AppConstants.RI_ERROR_LIST); + if (error_list == null) + error_list = new ArrayList(1); + error_list.add(errorMsg); + request.setAttribute(AppConstants.RI_ERROR_LIST, error_list); + } // processError + + public void processError(HttpServletRequest request, RaptorException e) { + processError(request, "Exception: " + e.getMessage()); + } // processError + + private String getSessionLog(HttpServletRequest request) { + String[] sessionVariablesToLog = Globals.getLogVariablesInSession().split(","); + StringBuffer sessionLogStrBuf = new StringBuffer("\n"); + sessionLogStrBuf.append("***** ADDITIONAL INFORMATION ******"); + HttpSession session = request.getSession(); + ReportRuntime rr = (ReportRuntime) session.getAttribute(AppConstants.SI_REPORT_RUNTIME); + ReportDefinition rdef = (ReportDefinition) session.getAttribute(AppConstants.SI_REPORT_DEFINITION); + if(rr!=null) { + sessionLogStrBuf.append("\nWHILE RUNNING"); + sessionLogStrBuf.append("\nReport Id="+rr.getReportID()+";\t"); + sessionLogStrBuf.append("Report Name="+rr.getReportName()+";\t\n"); + } else if (rdef != null) { + sessionLogStrBuf.append("\nWHILE CREATING/UPDATING"); + sessionLogStrBuf.append("\nReport Id="+rdef.getReportID()+";\t"); + sessionLogStrBuf.append("Report Name="+rdef.getReportName()+";\t\n"); + } + for (int i = 0; i < sessionVariablesToLog.length; i++) { + if(session.getAttribute(sessionVariablesToLog[i])!=null) + sessionLogStrBuf.append(sessionVariablesToLog[i]+"="+(String)session.getAttribute(sessionVariablesToLog[i])+";\t"); + } + sessionLogStrBuf.append("\n***********************************"); + sessionLogStrBuf.append("\n"); + return sessionLogStrBuf.toString(); + } + public String processFatalError(HttpServletRequest request, RaptorException e) { + //Log.write("Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage()), 1); + logger.error(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage())+" "+ getSessionLog(request) + e.getMessage()),AlarmSeverityEnum.MAJOR); + if (e instanceof ReportSQLException) { + String errorSQL = ((ReportSQLException) e).getReportSQL(); + if (nvl(errorSQL).length() > 0) + request.setAttribute("c_error_sql", errorSQL); + } // if + AppUtils.processErrorNotification(request, e); + + request.setAttribute(AppConstants.RI_EXCEPTION, e); + return AppUtils.getErrorPage(); + } // processFatalError + + public String processFatalErrorJSON(HttpServletRequest request, RaptorException e) { + //Log.write("Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage()), 1); + logger.error(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage())+" "+ getSessionLog(request) + e.getMessage()),AlarmSeverityEnum.MAJOR); + if (e instanceof ReportSQLException) { + String errorSQL = ((ReportSQLException) e).getReportSQL(); + if (nvl(errorSQL).length() > 0) + request.setAttribute("c_error_sql", errorSQL); + } // if + //AppUtils.processErrorNotification(request, e); + + request.setAttribute(AppConstants.RI_EXCEPTION, e); + ErrorJSONRuntime errorJSONRuntime = new ErrorJSONRuntime(); + errorJSONRuntime.setErrormessage(e.toString()); + errorJSONRuntime.setStacktrace(getStackTrace(e)); + ObjectMapper mapper = new ObjectMapper(); + //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); + //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + String jsonInString = ""; + try { + jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(errorJSONRuntime); + } catch (Exception ex) { + ex.printStackTrace(); + + } + return jsonInString; + } // processFatalError + + public static String getStackTrace(Throwable aThrowable) { + Writer result = new StringWriter(); + PrintWriter printWriter = new PrintWriter(result); + aThrowable.printStackTrace(printWriter); + return result.toString(); + } + public String processFatalErrorWMenu(HttpServletRequest request, RaptorException e) { + //Log.write("Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage()), 1); + logger.error(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage())+" "+ getSessionLog(request) + e.getMessage()),AlarmSeverityEnum.MAJOR); + if (e instanceof ReportSQLException) { + String errorSQL = ((ReportSQLException) e).getReportSQL(); + if (nvl(errorSQL).length() > 0) + request.setAttribute("c_error_sql", errorSQL); + } // if + AppUtils.processErrorNotification(request, e); + + request.setAttribute(AppConstants.RI_EXCEPTION, e); + return AppUtils.getErrorPageWMenu(); + } // processFatalError + +} // ErrorHandler + diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardProcessor.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardProcessor.java new file mode 100644 index 00000000..b193ec4b --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardProcessor.java @@ -0,0 +1,2356 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.error.ValidationException; +import org.openecomp.portalsdk.analytics.model.ReportHandler; +import org.openecomp.portalsdk.analytics.model.ReportLoader; +import org.openecomp.portalsdk.analytics.model.base.IdNameValue; +import org.openecomp.portalsdk.analytics.model.base.OrderBySeqComparator; +import org.openecomp.portalsdk.analytics.model.base.OrderSeqComparator; +import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; +import org.openecomp.portalsdk.analytics.model.definition.ReportSchedule; +import org.openecomp.portalsdk.analytics.model.runtime.FormField; +import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.system.DbUtils; +import org.openecomp.portalsdk.analytics.system.Globals; +import org.openecomp.portalsdk.analytics.util.AppConstants; +import org.openecomp.portalsdk.analytics.util.DataSet; +import org.openecomp.portalsdk.analytics.util.XSSFilter; +import org.openecomp.portalsdk.analytics.xmlobj.ChartDrillFormfield; +import org.openecomp.portalsdk.analytics.xmlobj.ColFilterType; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; +import org.openecomp.portalsdk.analytics.xmlobj.DataSourceType; +import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; +import org.openecomp.portalsdk.analytics.xmlobj.FormatType; +import org.openecomp.portalsdk.analytics.xmlobj.JavascriptItemType; +import org.openecomp.portalsdk.analytics.xmlobj.Marker; +import org.openecomp.portalsdk.analytics.xmlobj.ObjectFactory; +import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreType; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +/**
+ * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting)
+ *
+ * + * --------------------------------------------------------------------------------------------------
+ * WizardProcessor.java - This class is used to process the user input provided in the wizard.
+ * It is called in creation as well as updation process. It builds report xml via JAXB using user
+ * input. This is vital one, to store meta information of each report
+ * ---------------------------------------------------------------------------------------------------
+ * + * + * Change Log

+ * + * 31-Aug-2009 : Version 8.5.1 (Sundar);
  • For Time Series multi series property is exposed.
+ * 28-Aug-2009 : Version 8.5.1 (Sundar);
  • If user login id is null, it would display user name when user is added for schedule.
+ * 18-Aug-2009 : Version 8.5.1 (Sundar);
  • request Object is passed to prevent caching user/roles - Datamining/Hosting.
+ * 12-Aug-2009 : Version 8.5 (Sundar);
  • For Line Charts too options are captured and rendering is customized.
+ * 29-Jul-2009 : Version 8.4 (Sundar);
  • Maximum Excel Download size would be persisted if changed.
+ * 14-Jul-2009 : Version 8.4 (Sundar);
  • Schedule feature is added to Dashboard Reports.
+ * 29-Jun-2009 : Version 8.4 (Sundar);
  • Options for Compare to Previous year Chart are processed.
  • + *
  • In the Bar chart Last Occuring Series/Category can be plotted as Bar or Line Renderer.
  • + *
+ * 22-Jun-2009 : Version 8.4 (Sundar);
  • processChart method is modified to accommodate creating + * Bar Charts, Time Difference Charts and adding generic chart options.
+ * + */ + +public class WizardProcessor extends org.openecomp.portalsdk.analytics.RaptorObject { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(WizardProcessor.class); + + public WizardProcessor() { + } + + private String adjustDataType(String oracleDataType) { + return oracleDataType.equals("VARCHAR2") ? AppConstants.CT_CHAR : oracleDataType; + // Probably should be expanded to convert any CHAR or VARCHAR type to + // CT_CHAR, number type to CT_NUMBER and date to CT_DATE + } // adjustDataType + + public void persistReportDefinition(HttpServletRequest request, ReportDefinition rdef) + throws RaptorException { + ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( + AppConstants.SI_REPORT_RUNTIME); + if (rr != null && rr.getReportID().equals(rdef.getReportID())) + request.getSession().removeAttribute(AppConstants.SI_REPORT_RUNTIME); + rdef.persistReport(request); + } // persistReportDefinition + + public void processWizardStep(HttpServletRequest request) throws Exception { + String action = nvl(request.getParameter(AppConstants.RI_WIZARD_ACTION), + AppConstants.WA_BACK); + + String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); + ReportDefinition rdef = (new ReportHandler()).loadReportDefinition(request, reportID); + request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); + + String curStep = rdef.getWizardSequence().getCurrentStep(); + String curSubStep = rdef.getWizardSequence().getCurrentSubStep(); + if (AppUtils.getRequestNvlValue(request, "showDashboardOptions").length()<=0) + request.setAttribute("showDashboardOptions", "F"); + logger.debug(EELFLoggerDelegate.debugLogger, ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^curStep " + curStep + " " + curSubStep + " " + action)); + boolean reportUpdated = false; + if (!action.equals(AppConstants.WA_BACK)) { + if (curStep.equals(AppConstants.WS_DEFINITION)) { + reportUpdated = processDefinition(request); + } else if (curStep.equals(AppConstants.WS_SQL)) { + if (action.equals(AppConstants.WA_VALIDATE)) + reportUpdated = processValidateSQL(request); + } else if (curStep.equals(AppConstants.WS_TABLES)) { + if (curSubStep.equals(AppConstants.WSS_ADD)) + reportUpdated = processTableAdd(request); + else if (curSubStep.equals(AppConstants.WSS_EDIT)) + reportUpdated = processTableEdit(request); + else if (action.equals(AppConstants.WA_DELETE)) + reportUpdated = processTableDelete(request); + } else if (curStep.equals(AppConstants.WS_COLUMNS)) { + if (curSubStep.equals(AppConstants.WSS_ADD) + || curSubStep.equals(AppConstants.WSS_EDIT) || action.equals(AppConstants.WA_SAVE) || action.equals(AppConstants.WA_NEXT)) { + reportUpdated = processColumnAddEdit(request, curSubStep + .equals(AppConstants.WSS_EDIT) || curSubStep + .equals(AppConstants.WA_MODIFY)); + //reportUpdated = processColumnAddEdit(request, true); + } + else if (curSubStep.equals(AppConstants.WSS_ADD_MULTI)) + reportUpdated = processColumnAddMulti(request); + else if (curSubStep.equals(AppConstants.WSS_ORDER_ALL)) + reportUpdated = processColumnOrderAll(request); + else if (action.equals(AppConstants.WA_DELETE)) + reportUpdated = processColumnDelete(request); + else if (action.equals(AppConstants.WA_MOVE_UP)) + reportUpdated = processColumnMoveUp(request); + else if (action.equals(AppConstants.WA_MOVE_DOWN)) + reportUpdated = processColumnMoveDown(request); + } else if (curStep.equals(AppConstants.WS_FORM_FIELDS)) { + if (curSubStep.equals(AppConstants.WSS_ADD) + || curSubStep.equals(AppConstants.WSS_EDIT)) + reportUpdated = processFormFieldAddEdit(request, curSubStep + .equals(AppConstants.WSS_EDIT), action); + else if (action.equals(AppConstants.WA_DELETE)) + reportUpdated = processFormFieldDelete(request); + else if (action.equals(AppConstants.WA_MOVE_UP)) + reportUpdated = processFormFieldMoveUp(request); + else if (action.equals(AppConstants.WA_MOVE_DOWN)) + reportUpdated = processFormFieldMoveDown(request); + else if (action.equals(AppConstants.WSS_ADD_BLANK)) + reportUpdated = processFormFieldBlank(request); + else if (action.equals(AppConstants.WSS_INFO_BAR)) + reportUpdated = processFormFieldInfoBar(request); + } else if (curStep.equals(AppConstants.WS_FILTERS)) { + if (curSubStep.equals(AppConstants.WSS_ADD) + || curSubStep.equals(AppConstants.WSS_EDIT)) + reportUpdated = processFilterAddEdit(request, curSubStep + .equals(AppConstants.WSS_EDIT)); + else if (action.equals(AppConstants.WA_DELETE)) + reportUpdated = processFilterDelete(request); + } else if (curStep.equals(AppConstants.WS_SORTING)) { + if (curSubStep.equals(AppConstants.WSS_ADD) + || curSubStep.equals(AppConstants.WSS_EDIT)) + reportUpdated = processSortAddEdit(request, curSubStep + .equals(AppConstants.WSS_EDIT)); + else if (curSubStep.equals(AppConstants.WSS_ORDER_ALL)) + reportUpdated = processSortOrderAll(request); + else if (action.equals(AppConstants.WA_DELETE)) + reportUpdated = processSortDelete(request); + else if (action.equals(AppConstants.WA_MOVE_UP)) + reportUpdated = processSortMoveUp(request); + else if (action.equals(AppConstants.WA_MOVE_DOWN)) + reportUpdated = processSortMoveDown(request); + } else if (curStep.equals(AppConstants.WS_JAVASCRIPT)) { + if (action.equals(AppConstants.WSS_ADD)) + reportUpdated = processAddJavascriptElement(request); + else if (action.equals(AppConstants.WA_SAVE)) + reportUpdated = processSaveJavascriptElement(request); + else if (action.equals(AppConstants.WA_DELETE)) + reportUpdated = processDeleteJavascriptElement(request); + else + reportUpdated = processJavascript(request); + } else if (curStep.equals(AppConstants.WS_CHART)) { + reportUpdated = processChart(request, action); + } else if (curStep.equals(AppConstants.WS_USER_ACCESS)) { + reportUpdated = processUserAccess(request, action); + } else if (curStep.equals(AppConstants.WS_REPORT_LOG)) { + if (action.equals(AppConstants.WA_DELETE_USER)) + reportUpdated = processClearLog(request); + } else if (curStep.equals(AppConstants.WS_SCHEDULE)) { + reportUpdated = processSchedule(request, action); + } else if(curStep.equals(AppConstants.WS_DATA_FORECASTING)) { + reportUpdated = processForecasting(request, action); + } + /****For Report Maps - Start*****/ + else if (curStep.equals(AppConstants.WS_MAP)) { + reportUpdated = processMap(request, action); + } + /****For Report Maps - End*****/ + + // else + } + if (reportUpdated) + persistReportDefinition(request, rdef); + } // processWizardStep + + public void processImportSemaphorePopup(HttpServletRequest request) throws RaptorException { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String importReportId = AppUtils + .getRequestNvlValue(request, AppConstants.RI_REPORT_ID); + ReportRuntime rr = (new ReportHandler()).loadReportRuntime(request, importReportId, + false); + + ArrayList importedList = new ArrayList(); + if (rr.getSemaphoreList() != null) + for (Iterator iter = rr.getSemaphoreList().getSemaphore().iterator(); iter + .hasNext();) { + SemaphoreType sem = rdef.addSemaphore(new ObjectFactory(), + (SemaphoreType) iter.next()); + importedList + .add(new IdNameValue(sem.getSemaphoreId(), sem.getSemaphoreName())); + } // for + + if (importedList.size() > 0) { + request.setAttribute(AppConstants.RI_DATA_SET, importedList); + persistReportDefinition(request, rdef); + } // if + } // processImportSemaphorePopup + + public void processSemaphorePopup(HttpServletRequest request) throws RaptorException { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String semaphoreId = AppUtils.getRequestNvlValue(request, "semaphoreId"); + String semaphoreName = AppUtils.getRequestNvlValue(request, "semaphoreName"); + String semaphoreType = AppUtils.getRequestNvlValue(request, "semaphoreType"); + + SemaphoreType semaphore = rdef.getSemaphoreById(semaphoreId); + if (semaphore == null) { + semaphore = rdef.addSemaphoreType(new ObjectFactory(), semaphoreName, + semaphoreType, null); + semaphoreId = semaphore.getSemaphoreId(); + request.setAttribute("semaphoreId", semaphoreId); + } else { + rdef.deleteSemaphore(semaphore); + semaphore.setSemaphoreName(semaphoreName); + semaphore.setSemaphoreType(semaphoreType); + + rdef.setSemaphore(semaphore); + } + + String[] formatId = request.getParameterValues("formatId"); + String[] lessThanValue = request.getParameterValues("lessThanValue"); + String[] expression = request.getParameterValues("expression"); + String[] bold = request.getParameterValues("bold"); + String[] italic = request.getParameterValues("italic"); + String[] underline = request.getParameterValues("underline"); + String[] bgColor = request.getParameterValues("bgColor"); + String[] fontColor = request.getParameterValues("fontColor"); + String[] fontFace = request.getParameterValues("fontFace"); + String[] fontSize = request.getParameterValues("fontSize"); + //String[] anyFmt = request.getParameterValues("anyFmt"); + + // String[] alignment = request.getParameterValues("alignment"); + + for (int i = 0; i < lessThanValue.length; i++) + if (i == 0 || nvl(lessThanValue[i]).length() > 0) { + FormatType fmt = null; + if (i == 0 || nvl(formatId[i]).length() > 0) + fmt = rdef.getSemaphoreFormatById(semaphore, nvl(formatId[i])); + if (fmt == null) + fmt = rdef.addEmptyFormatType(new ObjectFactory(), semaphore); + + fmt.setLessThanValue(nvl(lessThanValue[i])); + fmt.setExpression(nvl(expression[i])); + fmt.setBold(bold[i].equals("Y")); + fmt.setItalic(italic[i].equals("Y")); + fmt.setUnderline(underline[i].equals("Y")); + fmt.setBgColor(bgColor[i]); + fmt.setFontColor(fontColor[i]); + fmt.setFontFace(fontFace[i]); + fmt.setFontSize(fontSize[i]); + //fmt.setAnyFmt((anyFmt[i]!=null)?anyFmt[i].startsWith("Y"):false); + // fmt.setAlignment(alignment[i]); + } else if (nvl(formatId[i]).length() > 0) + rdef.deleteFormatType(semaphore, formatId[i]); + + persistReportDefinition(request, rdef); + } // processSemaphorePopup + + private boolean processDefinition(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String reportName = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportName")); + String reportDescr = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportDescr")); + String folderId = AppUtils.getRequestNvlValue(request, "folder_id"); + boolean isAllowSchedule = (AppUtils.getRequestNvlValue(request, "allowSchedule").length()<=0?"N":AppUtils.getRequestNvlValue(request, "allowSchedule")).startsWith("Y"); + boolean isColumnGroup = (AppUtils.getRequestNvlValue(request, "multiGroupColumn").length()<=0?"N":AppUtils.getRequestNvlValue(request, "multiGroupColumn")).startsWith("Y"); + boolean isTopDown = (AppUtils.getRequestNvlValue(request, "topDown").length()<=0?"N":AppUtils.getRequestNvlValue(request, "topDown")).startsWith("Y"); + boolean isSizedByContent= (AppUtils.getRequestNvlValue(request, "sizedByContent").length()<=0?"N":AppUtils.getRequestNvlValue(request, "sizedByContent")).startsWith("Y"); + boolean reportsInNewWindow = false; + boolean hideFormFieldAfterRun = false; + + /*recurrance in schedule tab - Start*/ + String isOneTimeScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isOneTimeScheduleAllowed"),"N"); + String isHourlyScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isHourlyScheduleAllowed"),"N"); + String isDailyScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isDailyScheduleAllowed"),"N"); + String isDailyMFScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isDailyMFScheduleAllowed"),"N"); + String isWeeklyScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isWeeklyScheduleAllowed"),"N"); + String isMonthlyScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isMonthlyScheduleAllowed"),"N"); + //System.out.println("//////////// + isOneTimeScheduleAllowed : " + isOneTimeScheduleAllowed); + /*recurrance in schedule tab - End*/ + + + if (reportDescr.length() > 1000) + reportDescr = reportDescr.substring(0, 1000); + boolean reportUpdated; + + String reportType = AppUtils.getRequestNvlValue(request, "reportType"); + + + + //rdef.setReportName(reportName); + //rdef.setReportDescr(reportDescr); + //rdef.setReportType(reportType); + rdef.setFolderId(folderId); +// debugLogger.debug("setting folder ID = " + folderId); + if(reportType.equals(AppConstants.RT_DASHBOARD)) { + rdef.setReportName(reportName); + rdef.setReportDescr(reportDescr); + rdef.setReportType(reportType); + String dashboardLayoutHTML = AppUtils.getRequestNvlValue(request, "dashboardLayoutHTML"); + rdef.setDashboardLayoutHTML(dashboardLayoutHTML); + String dataContainerHeight = nvl(AppUtils.getRequestValue(request, "heightContainer"), "auto"); + String dataContainerWidth = nvl(AppUtils.getRequestValue(request, "widthContainer"), "auto"); + rdef.setDataContainerHeight(dataContainerHeight); + rdef.setDataContainerWidth(dataContainerWidth); + rdef.setAllowSchedule(isAllowSchedule?"Y":"N"); + + + /* + String numDashCols = AppUtils.getRequestNvlValue(request, "numDashCols"); + String reports1 = AppUtils.getRequestNvlValue(request, "reports1"); + String reports2 = AppUtils.getRequestNvlValue(request, "reports2"); + String reports3 = AppUtils.getRequestNvlValue(request, "reports3"); + String reports4 = AppUtils.getRequestNvlValue(request, "reports4"); + String repBgColor1 = AppUtils.getRequestNvlValue(request, "repBgColor1"); + String repBgColor2 = AppUtils.getRequestNvlValue(request, "repBgColor2"); + String repBgColor3 = AppUtils.getRequestNvlValue(request, "repBgColor3"); + String repBgColor4 = AppUtils.getRequestNvlValue(request, "repBgColor4"); + + //List reports = rdef.getDashBoardReports(); + rdef.setNumDashCols(numDashCols); + DashboardReports reportsList = new DashboardReportsImpl(); + + String reports[] = new String[]{reports1, reports2, reports3, reports4}; + String repBgColors[] = new String[]{repBgColor1, repBgColor2, repBgColor3, repBgColor4}; + for (int i = 0; i < reports.length; i++) { + Reports report = new ReportsImpl(); + report.setReportId(reports[i]); + report.setBgcolor(repBgColors[i]); + reportsList.getReportsList().add(report); + } + + + + rdef.setDashBoardReports(reportsList); + */ + reportUpdated = true; + +// reportUpdated = (!(reportName.equals(nvl(rdef.getReportName())) +// && reportDescr.equals(nvl(rdef.getReportDescr())) +// && reportType.equals(nvl(rdef.getReportType())) +// && numDashCols.equals(nvl(rdef.getNumDashCols())))); +//// && rdef.getR + + if (rdef.getWizardSequence() instanceof WizardSequence) + rdef.generateWizardSequence(request); + + } else { + + if (AppUtils.getRequestNvlValue(request, "reportType").equals(AppConstants.RT_CROSSTAB) || rdef.getReportType().equals(AppConstants.RT_CROSSTAB)) { + + String widthNo = AppUtils.getRequestNvlValue(request, "widthNo"); + if(nvl(widthNo).endsWith("px")) + rdef.setWidthNoColumn(widthNo); + else + rdef.setWidthNoColumn(widthNo+"px"); + } + + String dataGridAlign = AppUtils.getRequestNvlValue(request, "dataGridAlign"); + if(nvl(dataGridAlign).length()>0) { + rdef.setDataGridAlign(dataGridAlign); + } else { + rdef.setDataGridAlign("left"); + } + + String pdfImgLogo = AppUtils.getRequestNvlValue(request, "pdfImg"); + if(nvl(pdfImgLogo).length()>0) + rdef.setPdfImg(pdfImgLogo); + else + rdef.setPdfImg(null); + String emptyMessage = AppUtils.getRequestNvlValue(request, "emptyMessage"); + if(nvl(emptyMessage).length()>0) + rdef.setEmptyMessage(emptyMessage); + else + rdef.setEmptyMessage(""); + String formHelp = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "formHelp")); + //String rDashboardType = nvl(AppUtils.getRequestValue(request, "showDashboardOptions"), "N"); + //rdef.setDashboardType(rDashboardType.equals("Y")); + int excelDownloadSize = 500; + try { + excelDownloadSize = Integer.parseInt(AppUtils.getRequestValue(request, "excelDownloadSize")); + } catch (NumberFormatException ex) {} + if(AppUtils.getRequestNvlValue(request, "excelDownloadSize").length()>0) + rdef.setMaxRowsInExcelDownload(Integer.parseInt(AppUtils.getRequestValue(request, "excelDownloadSize"))); + if(AppUtils.getRequestNvlValue(request, "reportInNewWindow").length()>0) + reportsInNewWindow = AppUtils.getRequestNvlValue(request,"reportInNewWindow").equals("Y"); + if(AppUtils.getRequestNvlValue(request, "hideFormFieldsAfterRun").length()>0) + hideFormFieldAfterRun = AppUtils.getRequestNvlValue(request,"hideFormFieldsAfterRun").equals("Y"); + + + if(AppUtils.getRequestNvlValue(request, "displayFolderTree").length()>0) + rdef.setDisplayFolderTree(AppUtils.getRequestNvlValue(request,"displayFolderTree").equals("Y")); + else + rdef.setDisplayFolderTree(false); + String dataSource = AppUtils.getRequestNvlValue(request, "dataSource"); + String dbType = Globals.getDBType(); + String schemaSql = Globals.getRemoteDbSchemaSqlWithWhereClause(); + schemaSql = schemaSql.replace("[schema_id]", dataSource); + DataSet ds = null; + try { + ds = DbUtils.executeQuery(schemaSql); + + String prefix = "", desc = ""; + + for (int i = 0; i < ds.getRowCount(); i++) { + dbType = ds.getItem(i, 2); + } + } + catch (Exception e) {} + + int pageSize = Globals.getDefaultPageSize(); + try { + pageSize = Integer.parseInt(AppUtils.getRequestValue(request, "pageSize")); + } catch (NumberFormatException e) { + } + String rApproved = nvl(AppUtils.getRequestValue(request, "menuApproved"), "N"); + String menuID = ""; + String[] menuIDs = request.getParameterValues("menuID"); + if (menuIDs != null) + for (int i = 0; i < menuIDs.length; i++) + menuID += (menuID.length() == 0 ? "" : "|") + menuIDs[i]; + /* else + menuID = "";*/ + +// boolean additionalFieldsShown = AppUtils.getRequestNvlValue(request, +// "additionalFieldsShown").equals("Y"); + boolean rRCSDisabled = AppUtils.getRequestNvlValue(request, "runtimeColSortDisabled").equals("Y"); + String reportDefType = AppUtils.getRequestNvlValue(request, "reportDefType"); + String dataContainerHeight = nvl(AppUtils.getRequestValue(request, "heightContainer"), "auto"); + String dataContainerWidth = nvl(AppUtils.getRequestValue(request, "widthContainer"), "auto"); + + String displayOptions = nvl(AppUtils.getRequestValue(request, "hideForm"), "N") + + nvl(AppUtils.getRequestValue(request, "hideChart"), "N") + + nvl(AppUtils.getRequestValue(request, "hideData"), "N") + + nvl(AppUtils.getRequestValue(request, "hideBtns"), "N") + + nvl(AppUtils.getRequestValue(request, "hideMap"), "N") + + nvl(AppUtils.getRequestValue(request, "hideExcelIcons"), "N") + + nvl(AppUtils.getRequestValue(request, "hidePDFIcons"), "N"); +/* StringBuffer dashboardOptions = new StringBuffer(""); + dashboardOptions.append((nvl(AppUtils.getRequestValue(request, "hide"),"chart").equals("chart"))?"Y":"N"); + dashboardOptions.append((nvl(AppUtils.getRequestValue(request, "hide"),"").equals("data"))?"Y":"N"); + dashboardOptions.append((nvl(AppUtils.getRequestValue(request, "hideBtns"),"").equals("Y"))?"Y":"N");*/ + + String numFormCols = nvl(AppUtils.getRequestValue(request, "numFormCols"), "1"); + String reportTitle = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportTitle")); + String reportSubTitle = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportSubTitle")); + String reportHeader = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportHeader")); + String reportFooter = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportFooter")); + + int frozenColumns = 0; + try { + frozenColumns = Integer.parseInt(AppUtils.getRequestValue(request, "frozenColumns")); + } catch (NumberFormatException ex) { + + } + +/* reportUpdated = (!(reportName.equals(nvl(rdef.getReportName())))) + && (!(reportDescr.equals(nvl(rdef.getReportDescr())))) + && (!(formHelp.equals(nvl(rdef.getFormHelpText())))) + && (!(reportType.equals(nvl(rdef.getReportType())))) + && (pageSize != rdef.getPageSize()) && + // rPublic.equals(rdef.isPublic()?"Y":"N")&& + (!(menuID.equals(nvl(rdef.getMenuID())))) + && (!(rApproved.equals(rdef.isMenuApproved()))) && (additionalFieldsShown ? ((!(rRCSDisabled + .equals(rdef.isRuntimeColSortDisabled()))) + && (!(displayOptions.equals(nvl(rdef.getDisplayOptions())))) + && (!(dashboardOptions.equals(nvl(rdef.getDashboardOptions())))) + && (!(numFormCols.equals(nvl(rdef.getNumFormCols())))) + && (!(reportTitle.equals(nvl(rdef.getReportTitle())))) + && (!(reportSubTitle.equals(nvl(rdef.getReportSubTitle())))) + && (!(reportHeader.equals(nvl(rdef.getReportHeader())))) && (!(reportFooter + .equals(nvl(rdef.getReportFooter()))))&& (reportsInNewWindow != rdef.isReportInNewWindow())):true); +*/ +/* reportUpdated = rRCSDisabled ==(rdef.isRuntimeColSortDisabled() + && displayOptions.equals(nvl(rdef.getDisplayOptions())) + //&& dashboardOptions.equals(nvl(rdef.getDashboardOptions())) + && numFormCols.equals(nvl(rdef.getNumFormCols())) + && reportTitle.equals(nvl(rdef.getReportTitle())) + && reportSubTitle.equals(nvl(rdef.getReportSubTitle())) + && reportHeader.equals(nvl(rdef.getReportHeader())) + && reportsInNewWindow == rdef.isReportInNewWindow() + && reportFooter.equals(nvl(rdef.getReportFooter()))) + ;*/ + + + /*reportUpdated = (!(reportName.equals(nvl(rdef.getReportName())) + && reportDescr.equals(nvl(rdef.getReportDescr())) + && formHelp.equals(nvl(rdef.getFormHelpText())) + && reportType.equals(nvl(rdef.getReportType())) + && (pageSize == rdef.getPageSize()) + && excelDownloadSize == rdef.getMaxRowsInExcelDownload() + && reportsInNewWindow == rdef.isReportInNewWindow() + && displayOptions.equals(rdef.getDisplayOptions()) + && dataContainerHeight.equals(rdef.getDataContainerHeight()) + && dataContainerWidth.equals(rdef.getDataContainerWidth()) + && (isAllowSchedule ==(rdef.isAllowSchedule())) + // rPublic.equals(rdef.isPublic()?"Y":"N")&& + && menuID.equals(nvl(rdef.getMenuID())) + && rApproved.equals(rdef.isMenuApproved() ? "Y" : "N") && (rRCSDisabled + == ((rdef.isRuntimeColSortDisabled()) + && displayOptions.equals(nvl(rdef.getDisplayOptions())) + //&& dashboardOptions.equals(nvl(rdef.getDashboardOptions())) + && numFormCols.equals(nvl(rdef.getNumFormCols())) + && reportTitle.equals(nvl(rdef.getReportTitle())) + && reportSubTitle.equals(nvl(rdef.getReportSubTitle())) + && isOneTimeScheduleAllowed.equals(nvl(rdef.getIsOneTimeScheduleAllowed())) + && isHourlyScheduleAllowed.equals(nvl(rdef.getIsHourlyScheduleAllowed())) + && isDailyScheduleAllowed.equals(nvl(rdef.getIsDailyScheduleAllowed())) + && isDailyMFScheduleAllowed.equals(nvl(rdef.getIsDailyMFScheduleAllowed())) + && isWeeklyScheduleAllowed.equals(nvl(rdef.getIsWeeklyScheduleAllowed())) + && isMonthlyScheduleAllowed.equals(nvl(rdef.getIsMonthlyScheduleAllowed())) + && reportHeader.equals(nvl(rdef.getReportHeader())) && reportFooter + .equals(nvl(rdef.getReportFooter())))) + )); */ + rdef.setReportName(reportName); + rdef.setReportDescr(reportDescr); + rdef.setFormHelpText(formHelp); + rdef.setReportType(reportType); + rdef.setPageSize(pageSize); + rdef.setDBInfo(dataSource); + rdef.setDBType(dbType); + rdef.setDisplayOptions(displayOptions); + rdef.setDataContainerHeight(dataContainerHeight); + rdef.setDataContainerWidth(dataContainerWidth); + rdef.setAllowSchedule(isAllowSchedule?"Y":"N"); + rdef.setMultiGroupColumn(isColumnGroup?"Y":"N"); + rdef.setTopDown(isTopDown?"Y":"N"); + rdef.setSizedByContent(isSizedByContent?"Y":"N"); + // rdef.setPublic(rPublic.equals("Y")); + rdef.setMenuID(menuID); + rdef.setMenuApproved(rApproved.equals("Y")); + if (reportDefType.length() > 0) + rdef.setReportDefType(reportDefType); +/* if(rdef.isDashboardType()) { + rdef.setDashboardOptions(dashboardOptions.toString()); + }*/ + rdef.setHideFormFieldAfterRun(hideFormFieldAfterRun); + rdef.setReportInNewWindow(reportsInNewWindow); + rdef.setRuntimeColSortDisabled(rRCSDisabled); + rdef.setNumFormCols(numFormCols); + rdef.setReportTitle(reportTitle); + rdef.setReportSubTitle(reportSubTitle); + rdef.setReportHeader(reportHeader); + rdef.setReportFooter(reportFooter); + rdef.setIsOneTimeScheduleAllowed(isOneTimeScheduleAllowed); + rdef.setIsHourlyScheduleAllowed(isHourlyScheduleAllowed); + rdef.setIsDailyScheduleAllowed(isDailyScheduleAllowed); + rdef.setIsDailyMFScheduleAllowed(isDailyMFScheduleAllowed); + rdef.setIsWeeklyScheduleAllowed(isWeeklyScheduleAllowed); + rdef.setIsMonthlyScheduleAllowed(isMonthlyScheduleAllowed); + rdef.setFrozenColumns(frozenColumns); + + } // if + + if (rdef.getWizardSequence() instanceof WizardSequence) + rdef.generateWizardSequence(request); + + + /* + * if(formHelp.length()>255) formHelp = formHelp.substring(0, 255); + */ + + + // String rPublic = nvl(AppUtils.getRequestValue(request, "public"), + // "N"); + // String menuID = AppUtils.getRequestNvlValue(request, "menuID"); + +// boolean dashboardOptionsShown = AppUtils.getRequestNvlValue(request, +// "dashboardOptionsShown").equals("Y"); + + reportUpdated = true; + + if (rdef.getReportID().equals("-1")) + // Always need to persist new report - in case it is a copy + reportUpdated = true; + + return reportUpdated; + } // processDefinition + + private boolean processTableAdd(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String tableName = AppUtils.getRequestNvlValue(request, "tableName").toUpperCase(); + String tableId = rdef.getUniqueTableId(tableName); + + String joinTableExpr = null; + String joinTableId = null; + + DataSourceType joinTable = + rdef.getTableById(AppUtils.getRequestValue(request, "joinTableName")); + if (joinTable != null) { + String joinTableName = joinTable.getTableName(); + joinTableId = joinTable.getTableId(); + + String joinExpr = AppUtils.getRequestNvlValue(request, "joinExpr").toUpperCase(); + + joinTableExpr = joinExpr.replaceAll("\\["+tableName+"\\]", tableId); + joinTableExpr = joinTableExpr.replaceAll("\\["+joinTableName+"\\]", joinTableId); +// debugLogger.debug("joinExpr : "+joinExpr+"\njoinTableExpr : "+ joinTableExpr); + } + + rdef.addDataSourceType(new ObjectFactory(), tableId, tableName, AppUtils + .getRequestNvlValue(request, "tablePK"), AppUtils.getRequestNvlValue(request, + "displayName"), joinTableId, joinTableExpr, null); + + rdef.setOuterJoin(rdef.getTableById(tableId), AppUtils.getRequestNvlValue(request, + "outerJoin")); + rdef.resetCache(true); + + return true; + } // processTableAdd + + private boolean processTableEdit(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + DataSourceType dst = rdef.getTableById(AppUtils.getRequestNvlValue(request, + AppConstants.RI_DETAIL_ID)); + + String displayName = XSSFilter.filterRequest(AppUtils.getRequestNvlValue(request, "displayName")); + String outerJoin = AppUtils.getRequestNvlValue(request, "outerJoin"); + + String tableName = AppUtils.getRequestNvlValue(request, "tableName").toUpperCase(); + String joinTableId = AppUtils.getRequestNvlValue(request, "joinTableName"); + + String joinExpr = AppUtils.getRequestNvlValue(request, "joinExpr").toUpperCase(); + + String joinTableExpr = null; + if(joinExpr.length()!=0){ + joinTableExpr = joinExpr.replaceAll("\\["+tableName+"\\]", rdef.getTableByDBName(tableName).getTableId()); + joinTableExpr = joinTableExpr.replaceAll("\\["+rdef.getTableById(joinTableId).getTableName().toUpperCase()+"\\]", joinTableId); + dst.setRefDefinition(joinTableExpr); + } + boolean reportUpdated = (!displayName.equals(nvl(dst.getDisplayName())) || + !outerJoin.equals(rdef.getOuterJoinType(dst)) || + !(joinExpr.length()==0)); + + dst.setDisplayName(displayName); + rdef.setOuterJoin(dst, outerJoin); + if (reportUpdated) + rdef.resetCache(true); + + return true; // reportUpdated; + } // processTableEdit + + + private boolean processTableDelete(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef.deleteDataSourceType(AppUtils.getRequestNvlValue(request, + AppConstants.RI_DETAIL_ID)); + return true; + } // processTableDelete + + private boolean processColumnAddEdit(HttpServletRequest request, boolean isEdit) + throws Exception { + if(!isEdit) { + return true; + } + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + DataColumnType currColumn = null; + + String tableId = null; + String colName = null; + String dataType = null; + if (isEdit) { + currColumn = rdef.getColumnById(AppUtils.getRequestNvlValue(request, + AppConstants.RI_DETAIL_ID)); + + if(currColumn!=null) { + tableId = currColumn.getTableId(); + colName = currColumn.getDbColName(); // currColumn.getColName(); + dataType = currColumn.getDbColType(); + } + } else { + String colData = AppUtils.getRequestNvlValue(request, "columnDetails"); + if(nvl(colData).length()>0) { + tableId = colData.substring(0, colData.indexOf('|')); + colName = colData.substring(tableId.length() + 1, + colData.indexOf('|', tableId.length() + 1)).toUpperCase(); + dataType = colData.substring(tableId.length() + colName.length() + 2); + } + } // else + + String exprFormula = AppUtils.getRequestNvlValue(request, "exprFormula"); + + String colNameValue = null; + if (exprFormula.length() > 0) + if (exprFormula.equals("_exprText_")) + colNameValue = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestValue(request, "exprText")); + else if (exprFormula.equals("COUNT(*)")) + colNameValue = exprFormula; + else + colNameValue = exprFormula + " " + colName + ")"; + else + colNameValue = colName; + + int displayWidth = -1; + try { + displayWidth = Integer.parseInt(AppUtils.getRequestValue(request, "displayWidth")); + } catch (NumberFormatException e) { + } + + String sColId = isEdit ? currColumn.getColId() : (nvl(colName).length()>0?rdef.getUniqueColumnId(colName):null); + String drillDownParams = AppUtils.getRequestValue(request, "drillDownParams"); + if (drillDownParams != null) { + // Replacing references to [this] with [col_id] + while (drillDownParams.indexOf("[this]") >= 0) { + int startIdx = drillDownParams.indexOf("[this]"); + StringBuffer sb = new StringBuffer(); + + if (startIdx > 0) + sb.append(drillDownParams.substring(0, startIdx)); + sb.append("[" + sColId + "]"); + if (startIdx + 6 < drillDownParams.length() - 1) + sb.append(drillDownParams.substring(startIdx + 5)); + drillDownParams = sb.toString(); + } // while + } // if + + String crossTabValue = null; + boolean isVisible = AppUtils.getRequestFlag(request, "visible"); + boolean isSortable = AppUtils.getRequestFlag(request, "sortable"); + String nowrap = AppUtils.getRequestNvlValue(request, "nowrap"); + int indentation = 0; + try { + indentation = Integer.parseInt(AppUtils.getRequestNvlValue(request, "indentation")); + }catch (NumberFormatException e) { + } + String dependsOnFormField = AppUtils.getRequestNvlValue(request, "dependsOnFormField"); + boolean isGroupBreak = AppUtils.getRequestFlag(request, "groupBreak"); + String groupByPosStr = AppUtils.nvls(AppUtils.getRequestValue(request, "groupByPos"), "0"); + int groupByPos = Integer.parseInt(groupByPosStr); + currColumn.setGroupByPos(groupByPos); + + if(groupByPos > 0) { + String subTotalCustomText = AppUtils.nvls(AppUtils.getRequestValue(request, "subTotalCustomText"), "Sub Total"); + currColumn.setSubTotalCustomText(subTotalCustomText); + + boolean hideRepeatedKey = AppUtils.getRequestFlag(request, "hideRepeatedKeys"); + currColumn.setHideRepeatedKey(hideRepeatedKey); + } + + String displayTotal = AppUtils.getRequestNvlValue(request, "displayTotal"); + String widthInPxls = AppUtils.getRequestNvlValue(request, "widthInPxls"); + + if (rdef.getReportType().equals(AppConstants.RT_CROSSTAB)) { + + + + crossTabValue = AppUtils.getRequestValue(request, "crossTabValue"); + isVisible = nvl(crossTabValue).equals(AppConstants.CV_ROW) + || nvl(crossTabValue).equals(AppConstants.CV_COLUMN) + || nvl(crossTabValue).equals(AppConstants.CV_VALUE); + isGroupBreak = nvl(crossTabValue).equals(AppConstants.CV_ROW) + || nvl(crossTabValue).equals(AppConstants.CV_COLUMN); + + if (nvl(crossTabValue).equals(AppConstants.CV_VALUE)) + displayTotal += "|" + + AppUtils.getRequestNvlValue(request, "displayTotalPerRow"); + else + displayTotal = ""; + } // if + + String displayName = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "displayName")); + String colType = AppUtils.getRequestNvlValue(request, "colType"); + String displayFormat = AppUtils.getRequestNvlValue(request, "displayFormat"); + + //HYPERLINK + if(colType.equals(AppConstants.CT_HYPERLINK)) { + String hyperlinkURL = AppUtils.getRequestValue(request, "hyperlinkURL"); + currColumn.setHyperlinkURL(hyperlinkURL); + String anchor = AppUtils.getRequestValue(request, "anchor"); + currColumn.setHyperlinkType(anchor); + if(anchor.equals("IMAGE")) { + String actionImg = AppUtils.getRequestValue(request, "actionImg"); + currColumn.setActionImg(actionImg); + } + } + + + + String displayAlign = AppUtils.getRequestValue(request, "displayAlign"); + String displayHeaderAlign = AppUtils.getRequestValue(request, "displayHeaderAlign"); + String drillDownURL = AppUtils.getRequestValue(request, "drillDownURL"); + String drillDownSuppress = AppUtils.getRequestValue(request, "drillDownSuppress"); + boolean drillDownPopUp = AppUtils.getRequestFlag (request, "drillDownPopUp"); + String semaphoreId = AppUtils.getRequestNvlValue(request, "semaphore"); + String semaphoreType = AppUtils.getRequestNvlValue(request, "semaphoreTypeHidden"); + + String levelStr = AppUtils.getRequestNvlValue(request, "multiGroupColLevel"); + String startColGroup = AppUtils.getRequestNvlValue(request, "startMultiGroup"); + String colGroupColSpan = AppUtils.getRequestNvlValue(request, "colspan"); + int level = 0; + try { + level = Integer.parseInt(levelStr); + }catch (NumberFormatException ex) { + level = 0; + } + int startColGroupInt = 0; + int colGroupColSpanInt = 0; + if(level > 0) { + try { + //startColGroupInt = Integer.parseInt(startColGroup); + colGroupColSpanInt = Integer.parseInt(colGroupColSpan); + } catch (NumberFormatException ex) { + + } + } + currColumn.setLevel(level); + if(level > 0) { + currColumn.setStart(startColGroupInt); + currColumn.setColspan(colGroupColSpanInt); + } + + String targetColumnId = (semaphoreType.indexOf("|")!= -1 ? semaphoreType.substring(semaphoreType.indexOf("|")+1):""); + DataColumnType targetColumn = rdef.getColumnById(targetColumnId); + + SemaphoreType semaphore = rdef.getSemaphoreById(semaphoreId); + rdef.deleteSemaphore(semaphore); + if(nvl(semaphoreType).length() > 0 && semaphoreType.indexOf("|")!=-1) + semaphore.setSemaphoreType(semaphoreType.substring(0,semaphoreType.indexOf("|"))); + if(semaphore!=null) { + semaphore.setComment(currColumn.getColId()); + if(nvl(semaphoreType).length() > 0) + semaphore.setTarget(targetColumnId.length()>0? targetColumnId: ""); + rdef.setSemaphore(semaphore); + } + + + if (isEdit) { + if(nvl(widthInPxls).length()>0) { + if(nvl(widthInPxls).endsWith("px")) + currColumn.setDisplayWidthInPxls(widthInPxls); + else + currColumn.setDisplayWidthInPxls(widthInPxls+"px"); + } else { + currColumn.setDisplayWidthInPxls(""); + } + + currColumn.setCrossTabValue(crossTabValue); + currColumn.setDependsOnFormField(dependsOnFormField); + currColumn.setDisplayName(displayName); + //currColumn.setOriginalDisplayName(displayName); + + if (displayWidth > 0) + currColumn.setDisplayWidth(displayWidth); + currColumn.setDisplayAlignment(displayAlign); + currColumn.setDisplayHeaderAlignment(displayHeaderAlign); + currColumn.setDrillDownURL(drillDownURL); + currColumn.setDrillDownParams(drillDownParams); + currColumn.setDrillDownType(drillDownSuppress); + currColumn.setDrillinPoPUp(drillDownPopUp); + //indentation + currColumn.setIndentation(indentation); + if(drillDownPopUp) { + rdef.setDrillDownURLInPopupPresent(true); + } + /*if(targetColumn!=null) { + currColumn.setSemaphoreId(null); + targetColumn.setSemaphoreId(semaphoreId); + } else */ + currColumn.setSemaphoreId(semaphoreId); + currColumn.setGroupBreak(isGroupBreak); + logger.debug(EELFLoggerDelegate.debugLogger, (" ------------ Display Total ---------- "+ displayTotal)); + currColumn.setDisplayTotal(displayTotal); + //if (currColumn.getDrillDownURL() == null || currColumn.getDrillDownURL().length() == 0) + currColumn.setVisible(isVisible); + currColumn.setIsSortable(isSortable); + currColumn.setNowrap(nowrap); + //else + // currColumn.setVisible(true); + if (rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) { + if(colType!=null) + currColumn.setColType(colType); + displayFormat = AppUtils.getRequestValue(request, "colDataFormat"); + if (displayFormat != null){ + currColumn.setColFormat(displayFormat); + } + if(colType!=null && colType.equals(AppConstants.CT_DATE)) { + boolean enhancedPagination = AppUtils.getRequestFlag(request, "enhancedPagination"); + currColumn.setEnhancedPagination(enhancedPagination); + } + } + if (!rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) { + currColumn.setColName(colNameValue); + if (displayFormat != null) + currColumn.setColFormat(displayFormat); + //currColumn.setVisible(isVisible); + currColumn.setCalculated(exprFormula.length() > 0); + + rdef.adjustColumnType(currColumn); + } // if + + rdef.resetCache(true); + } else + currColumn = rdef.addDataColumnType(new ObjectFactory(), sColId, tableId, colName, + crossTabValue, colNameValue, displayName, displayWidth, displayAlign, rdef + .getAllColumns().size() + 1, isVisible, + (exprFormula.length() > 0), adjustDataType(dataType), displayFormat, + isGroupBreak, -1, null, displayTotal, null, -1, drillDownSuppress, + drillDownURL, drillDownParams, semaphoreId, null); + + if (rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) + rdef.setColumnNoParseDateFlag(currColumn, AppUtils.getRequestFlag(request, + "no_parse_date")); + if(nvl(displayName).length()>0) + return true; + else + return false; + } // processColumnAddEdit + + private boolean processColumnAddMulti(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + List reportCols = rdef.getAllColumns(); + int nCol = reportCols.size() + 1; + + String[] addColumn = request.getParameterValues("addColumn"); + String[] tableId = request.getParameterValues("tableId"); + String[] columnName = request.getParameterValues("columnName"); + String[] columnType = request.getParameterValues("columnType"); + String[] displayName = request.getParameterValues("displayName"); + + for (int i = 0; i < addColumn.length; i++) + if (addColumn[i].equals("Y")) { + int j = 2; + String uniqueDisplayName = displayName[i]; + boolean isUnique = true; + do { + isUnique = true; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) + if (uniqueDisplayName.equals(((DataColumnType) iter.next()) + .getDisplayName())) { + isUnique = false; + uniqueDisplayName = displayName[i] + (j++); + break; + } // if + } while (!isUnique); + + rdef + .addDataColumnType( + new ObjectFactory(), + rdef.getUniqueColumnId(columnName[i]), + tableId[i], + columnName[i], + null, + columnName[i], + uniqueDisplayName, + 10, + "Left", + nCol++, + true, + false, + adjustDataType(columnType[i]), + (columnType[i].equals(AppConstants.CT_DATE) ? AppConstants.DEFAULT_DATE_FORMAT + : null), false, -1, null, null, null, -1, null, null, + null, null, null); + } // if + + return true; + } // processColumnAddMulti + + private boolean processColumnOrderAll(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String[] colId = request.getParameterValues("colId"); + String[] colOrder = request.getParameterValues("colOrder"); + + boolean reportUpdated = false; + for (int i = 0; i < colId.length; i++) { + DataColumnType dct = rdef.getColumnById(nvl(colId[i])); + if (dct == null) + continue; + + int iColOrder = 0; + try { + iColOrder = Integer.parseInt(colOrder[i]); + } catch (NumberFormatException e) { + } + + if (iColOrder > 0) { + dct.setOrderSeq(iColOrder); + reportUpdated = true; + } // if + } // for + + if (reportUpdated) { + List reportCols = rdef.getAllColumns(); + Collections.sort(reportCols, new OrderSeqComparator()); + + int iOrder = 1; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + dct.setOrderSeq(iOrder++); + } // for + + rdef.resetCache(false); + } // if + + return reportUpdated; + } // processColumnOrderAll + + private boolean processColumnDelete(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef.deleteDataColumnType(AppUtils.getRequestNvlValue(request, + AppConstants.RI_DETAIL_ID)); + return true; + } // processColumnDelete + + private boolean processColumnMoveUp(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef.shiftColumnOrderUp(AppUtils + .getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + return true; + } // processColumnMoveUp + + private boolean processColumnMoveDown(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef.shiftColumnOrderDown(AppUtils.getRequestNvlValue(request, + AppConstants.RI_DETAIL_ID)); + return true; + } // processColumnMoveDown + + private boolean processFormFieldAddEdit(HttpServletRequest request, boolean isEdit, + String action) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String fieldName = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "fieldName")); + String multiSelectSize = "0"; + String colId = AppUtils.getRequestNvlValue(request, "fieldColId"); + if (rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) { + String displayFormat = AppUtils.getRequestNvlValue(request, "displayFormat"); + if (displayFormat.length() > 0) + colId += "|" + displayFormat; + } // if + String fieldType = AppUtils.getRequestNvlValue(request, "fieldType"); + String validation = AppUtils.getRequestNvlValue(request, "validation"); + String mandatory = nvl(AppUtils.getRequestValue(request, "mandatory"), "N"); + String defaultValue = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "defaultValue")); + String fieldHelp = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "fieldHelp")); + String fieldSQL = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "fieldSQL")); + String fieldDefaultSQL = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "fieldDefaultSQL")); + String visible = nvl(AppUtils.getRequestValue(request, "visible"),"Y"); + String dependsOn = nvl(AppUtils.getRequestValue(request, "dependsOn"),""); + String rangeStartDate = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "rangeStartDate")); + String rangeEndDate = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "rangeEndDate")); + String rangeStartDateSQL = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "rangeStartDateSQL")); + String rangeEndDateSQL = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "rangeEndDateSQL")); + boolean isGroupFormField = AppUtils.getRequestFlag(request,"isGroupFormField"); + + Calendar start = null; + Calendar end = null; + if (AppUtils.nvl(rangeStartDate).length()>0){ + SimpleDateFormat dtf = new SimpleDateFormat("MM/dd/yyyy"); + start = Calendar.getInstance(); + start.setTime(dtf.parse(rangeStartDate)); + } + if (AppUtils.nvl(rangeEndDate).length()>0){ + SimpleDateFormat dtf = new SimpleDateFormat("MM/dd/yyyy"); + end = Calendar.getInstance(); + end.setTime(dtf.parse(rangeEndDate)); + }/* + * if(fieldHelp.length()>255) fieldHelp = fieldHelp.substring(0, 255); + */ + + boolean reportUpdated = false; + + FormFieldType currField = null; + if (isEdit) { + String fieldId = AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID); + + currField = rdef.getFormFieldById(fieldId); + if (currField != null && nvl(fieldName).length()>0) { + reportUpdated = (!(fieldName.equals(nvl(currField.getFieldName())) + && colId.equals(nvl(currField.getColId())) + && fieldType.equals(nvl(currField.getFieldType())) + && validation.equals(nvl(currField.getValidationType())) + && mandatory.equals(nvl(currField.getMandatory(), "N")) + && defaultValue.equals(nvl(currField.getDefaultValue())) + && fieldSQL.equals(nvl(currField.getFieldSQL())) + && fieldDefaultSQL.equals(nvl(currField.getFieldDefaultSQL())) + && dependsOn.equals(nvl(currField.getDependsOn(), "N")) + && (start == null || (start != null && currField.getRangeStartDate() == null) || (start.equals(currField.getRangeStartDate()))) + && (end == null || (end != null && currField.getRangeEndDate() == null) || (end.equals(currField.getRangeEndDate()))) + && rangeStartDateSQL.equals(nvl(currField.getRangeStartDateSQL())) + && rangeEndDateSQL.equals(nvl(currField.getRangeEndDateSQL())) + && visible.equals(nvl(currField.getVisible(), "Y")) + && isGroupFormField == currField.isGroupFormField() + && fieldHelp.equals(nvl(currField.getComment())))); + + rdef.replaceFormFieldReferences("[" + currField.getFieldName() + "]", "[" + + fieldName + "]"); + + currField.setFieldName(fieldName); + currField.setColId(colId); + currField.setFieldType(fieldType); + currField.setValidationType(validation); + currField.setMandatory(mandatory); + currField.setDefaultValue(defaultValue); + currField.setFieldSQL(fieldSQL); + currField.setFieldDefaultSQL(fieldDefaultSQL); + currField.setComment(fieldHelp); + currField.setVisible(visible); + currField.setDependsOn(dependsOn); + try { + if(start!=null) { + currField.setRangeStartDate(DatatypeFactory.newInstance() + .newXMLGregorianCalendar(start.YEAR, start.MONTH, start.DAY_OF_WEEK, start.HOUR, start.MINUTE, start.SECOND, start.MILLISECOND, start.ZONE_OFFSET)); + } else { + currField.setRangeStartDate(null); + } + if(end!=null) { + currField.setRangeEndDate(DatatypeFactory.newInstance() + .newXMLGregorianCalendar(end.YEAR, end.MONTH, end.DAY_OF_WEEK, end.HOUR, end.MINUTE, end.SECOND, end.MILLISECOND, end.ZONE_OFFSET)); + } else { + currField.setRangeEndDate(null); + } + /*currField.setRangeEndDate(DatatypeFactory.newInstance() + .newXMLGregorianCalendar(end));*/ + } catch (DatatypeConfigurationException ex) { + + } + + currField.setRangeStartDateSQL(rangeStartDateSQL); + currField.setRangeEndDateSQL(rangeEndDateSQL); + currField.setGroupFormField(isGroupFormField); + if(fieldType.equals(FormField.FFT_LIST_MULTI)) { + multiSelectSize = AppUtils.getRequestNvlValue(request, "multiSelectListSize"); + currField.setMultiSelectListSize(multiSelectSize); + } + + + } // if + } else { + reportUpdated = true; + + currField = rdef.addFormFieldType(new ObjectFactory(), fieldName, colId, + fieldType, validation, mandatory, defaultValue, fieldSQL, fieldHelp, start, end, rangeStartDateSQL, rangeEndDateSQL); + + request.setAttribute(AppConstants.RI_DETAIL_ID, currField.getFieldId()); + } // else + + if (action.equals(AppConstants.WA_ADD_USER)) { + reportUpdated = true; + rdef.addFormFieldPredefinedValue(new ObjectFactory(), currField, XSSFilter.filterRequestOnlyScript(AppUtils + .getRequestNvlValue(request, "newPredefinedValue"))); + } else if (action.equals(AppConstants.WA_DELETE_USER)) { + reportUpdated = true; + rdef.deleteFormFieldPredefinedValue(currField, AppUtils.getRequestNvlValue( + request, "delPredefinedValue")); + } + + return reportUpdated; + } // processFormFieldAddEdit + + private boolean processFormFieldDelete(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String fieldId = AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID); + rdef.deleteFormField(fieldId); + + return true; + } // processFormFieldDelete + + private boolean processFormFieldMoveUp(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef.shiftFormFieldUp(AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + return true; + } // processFormFieldMoveUp + + private boolean processFormFieldMoveDown(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef.shiftFormFieldDown(AppUtils + .getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + return true; + } // processFormFieldMoveDown + + private boolean processFormFieldBlank(HttpServletRequest request) throws Exception { + boolean reportUpdated = false; + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + reportUpdated = true; + rdef.addFormFieldBlank(new ObjectFactory()); + return true; + } // processFormFieldMoveDown + + //processFormFieldInfoBar + private boolean processFormFieldInfoBar(HttpServletRequest request) throws Exception { + boolean reportUpdated = false; + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + reportUpdated = true; + rdef.addCustomizedTextForParameters(XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "blueBarField"))); + return true; + } // processFormFieldMoveDown + + + private boolean processForecasting(HttpServletRequest request, String action) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + if(rdef.getDataminingOptions()==null) + rdef.addDataminingOptions(new ObjectFactory()); + + String classifiers = AppUtils.getRequestNvlValue(request, "classifiers"); + rdef.setClassifier(classifiers); + String dateAttrColId = AppUtils.getRequestNvlValue(request, "timeAttribute"); + String timeFormat = AppUtils.getRequestNvlValue(request, "timeFormat"); + if(timeFormat.equals("Default")) timeFormat = "yyyy-MM-dd HH:mm:ss"; + String forecastingPeriod = AppUtils.getRequestNvlValue(request, "forecastingPeriod"); + + String[] forecastCols = request.getParameterValues("forecastCol"); + List reportCols = rdef.getAllColumns(); + DataColumnType dct = null; + Iterator iter = null; + + + + if(dateAttrColId != null) { + for(iter=reportCols.iterator(); iter.hasNext(); ) { + dct = (DataColumnType) iter.next(); + if(dct.getColId().equals(dateAttrColId)) { + dct.setDataMiningCol(AppConstants.DM_DATE_ATTR); + if(timeFormat!=null) rdef.setForecastingTimeFormat(timeFormat); + break; + } + } + } + + if(forecastCols != null) { + for (int i = 0; i < forecastCols.length; i++) { + for(iter=reportCols.iterator(); iter.hasNext(); ) { + dct = (DataColumnType) iter.next(); + if(dct.getColId().equals(forecastCols[i])) { + dct.setDataMiningCol(AppConstants.DM_FORECASTING_ATTR); + } + } + } + rdef.setForecastingPeriod(forecastingPeriod); + } + boolean reportUpdated = true; + + return reportUpdated; + } // processForecasting + + + private boolean processFilterAddEdit(HttpServletRequest request, boolean isEdit) + throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String colId = AppUtils.getRequestNvlValue(request, "filterColId"); + String filterExpr = AppUtils.getRequestNvlValue(request, "filterExpr"); + String argType = (filterExpr.equals("IS NULL") || filterExpr.equals("IS NOT NULL")) ? null + : AppUtils.getRequestNvlValue(request, "argType"); + String argValue = (filterExpr.equals("IS NULL") || filterExpr.equals("IS NOT NULL")) ? null + : AppUtils.getRequestNvlValue(request, "argValue"); + + if (nvl(argType).equals(AppConstants.AT_COLUMN)) { + List reportCols = rdef.getAllColumns(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + if (argValue.equals("[" + dct.getDisplayName() + "]")) { + argValue = dct.getColId(); + break; + } + } // for + } // if + + if (nvl(argType).equals(AppConstants.AT_VALUE) + && (!nvl(argValue).equals(AppConstants.FILTER_MAX_VALUE)) + && (!nvl(argValue).equals(AppConstants.FILTER_MIN_VALUE))) { + // Validating the value by type + DataColumnType currColumn = rdef.getColumnById(colId); + String currColType = currColumn.getColType(); + + try { + String s_sql = Globals.getProcessFilterAddEdit(); + s_sql = s_sql.replace("[argValue]", argValue); + /*DataSet ds = DbUtils.executeQuery("SELECT " + + (currColType.equals(AppConstants.CT_NUMBER) ? ("TO_NUMBER('" + + argValue + "')") + : (currColType.equals(AppConstants.CT_DATE) ? ("TO_DATE('" + + argValue + + "', '" + + nvl(currColumn.getColFormat(), + AppConstants.DEFAULT_DATE_FORMAT) + "')") + : ("'" + argValue + "'"))) + " FROM dual");*/ + + DataSet ds = DbUtils.executeQuery("SELECT " + + (currColType.equals(AppConstants.CT_NUMBER) ? ("TO_NUMBER('" + + argValue + "')") + : (currColType.equals(AppConstants.CT_DATE) ? ("TO_DATE('" + + argValue + + "', '" + + nvl(currColumn.getColFormat(), + AppConstants.DEFAULT_DATE_FORMAT) + "')") + : s_sql))); + } catch (Exception e) { + throw new ValidationException( + "" + + (currColType.equals(AppConstants.CT_NUMBER) ? "Invalid number" + : (currColType.equals(AppConstants.CT_DATE) ? ("Invalid date
Expected date format " + nvl( + currColumn.getColFormat(), + AppConstants.DEFAULT_DATE_FORMAT)) + : "Invalid value
Possible reason: use of single quotes")) + + "
Value: " + argValue); + } + } // if + + if (isEdit) { + int filterPos = -1; + try { + filterPos = Integer.parseInt(AppUtils.getRequestValue(request, "filterPos")); + } catch (NumberFormatException e) { + } + + ColFilterType currFilter = rdef.getFilterById(colId, filterPos); + if (currFilter != null) { + currFilter.setJoinCondition(AppUtils.getRequestValue(request, "filterJoin")); + currFilter.setOpenBrackets(AppUtils.getRequestValue(request, "openBrackets")); + currFilter.setExpression(filterExpr); + // if(argType!=null) + currFilter.setArgType(argType); + // if(argValue!=null) + currFilter.setArgValue(argValue); + currFilter + .setCloseBrackets(AppUtils.getRequestValue(request, "closeBrackets")); + } // if + + rdef.resetCache(true); + } else { + rdef.addColFilterType(new ObjectFactory(), colId, AppUtils.getRequestValue( + request, "filterJoin"), AppUtils.getRequestValue(request, "openBrackets"), + filterExpr, argType, argValue, AppUtils.getRequestValue(request, + "closeBrackets"), null); + } // else + + return true; + } // processFilterAddEdit + + private boolean processFilterDelete(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String filterId = AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID); + String colId = filterId.substring(0, filterId.indexOf('|')); + int filterPos = -1; + try { + filterPos = Integer.parseInt(filterId.substring(colId.length() + 1)); + } catch (NumberFormatException e) { + } + + rdef.removeColumnFilter(colId, filterPos); + + return true; + } // processFilterDelete + + private boolean processSortAddEdit(HttpServletRequest request, boolean isEdit) + throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String sortAscDesc = AppUtils.getRequestNvlValue(request, "sortAscDesc"); + if (isEdit) { + DataColumnType currColumn = rdef.getColumnById(AppUtils.getRequestNvlValue( + request, AppConstants.RI_DETAIL_ID)); + if (currColumn != null) + currColumn.setOrderByAscDesc(sortAscDesc); + rdef.resetCache(true); + } else + rdef.addColumnSort(AppUtils.getRequestNvlValue(request, "sortColId"), sortAscDesc, + rdef.getNumSortColumns() + 1); + + return true; + } // processSortAddEdit + + private boolean processSortOrderAll(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String[] colId = request.getParameterValues("colId"); + String[] sortOrder = request.getParameterValues("sortOrder"); + String[] sortAscDesc = request.getParameterValues("sortAscDesc"); + + boolean reportUpdated = false; + for (int i = 0; i < colId.length; i++) { + DataColumnType dct = rdef.getColumnById(nvl(colId[i])); + if (dct == null) + continue; + + int iSortOrder = 0; + try { + iSortOrder = Integer.parseInt(sortOrder[i]); + } catch (NumberFormatException e) { + } + + if (iSortOrder > 0) { + if (dct.getOrderBySeq() > 0) { + // Update sort + if (dct.getOrderBySeq() != iSortOrder) { + dct.setOrderBySeq(iSortOrder); + reportUpdated = true; + } // if + if (!nvl(dct.getOrderByAscDesc()).equals(nvl(sortAscDesc[i]))) { + dct.setOrderByAscDesc(sortAscDesc[i]); + reportUpdated = true; + } // if + } else { + // Add sort + dct.setOrderBySeq(iSortOrder); + dct.setOrderByAscDesc(sortAscDesc[i]); + reportUpdated = true; + } // else + } else { + if (dct.getOrderBySeq() > 0) { + // Remove sort + dct.setOrderBySeq(0); + dct.setOrderByAscDesc(null); + reportUpdated = true; + } // if + } // else + } // for + + if (reportUpdated) { + List reportCols = rdef.getAllColumns(); + Collections.sort(reportCols, new OrderBySeqComparator()); + int iOrder = 1; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + if (dct.getOrderBySeq() > 0) + dct.setOrderBySeq(iOrder++); + } // for + Collections.sort(reportCols, new OrderSeqComparator()); + + rdef.resetCache(true); + } // if + + return reportUpdated; + } // processSortOrderAll + + private boolean processSortDelete(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef.removeColumnSort(AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + return true; + } // processSortDelete + + private boolean processSortMoveUp(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef + .shiftColumnSortUp(AppUtils.getRequestNvlValue(request, + AppConstants.RI_DETAIL_ID)); + return true; + } // processSortMoveUp + + private boolean processSortMoveDown(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef.shiftColumnSortDown(AppUtils.getRequestNvlValue(request, + AppConstants.RI_DETAIL_ID)); + return true; + } // processSortMoveDown + + private boolean processJavascript (HttpServletRequest request) throws Exception { + processSaveJavascriptElement(request); + return true; + } + + private boolean processSaveJavascriptElement (HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + rdef.setJavascriptElement(AppUtils.getRequestNvlValue(request, AppConstants.RI_JAVASCRIPT)); + String id = AppUtils.getRequestNvlValue(request, AppConstants.RI_JAVASCRIPT_ITEM_ID); + String fieldId = AppUtils.getRequestNvlValue(request, "javascriptFormField-"+id); + if( nvl(fieldId).length()>0 && !(fieldId.startsWith("-1"))) { + + String callableJavascriptText = AppUtils.getRequestNvlValue(request, "callText-"+id); + + logger.debug(EELFLoggerDelegate.debugLogger, ("FieldId " + fieldId + " Call Text " + callableJavascriptText+ " id " + id)); + JavascriptItemType javaScriptType = null; + if(id.length()>0 && id.startsWith("-1")) { + javaScriptType = rdef.addJavascriptType(new ObjectFactory(), id); + javaScriptType.setFieldId(fieldId); + if(!fieldId.equals("os1") || !fieldId.equals("ol1")) + javaScriptType.setId(rdef.getNextIdForJavaScriptElement(new ObjectFactory(), fieldId)); + else { + if(fieldId.equals("os1")) + javaScriptType.setId("os1|1"); + else + javaScriptType.setId("ol1|1"); + } + javaScriptType.setCallText(callableJavascriptText); + } else { + javaScriptType = rdef.addJavascriptType(new ObjectFactory(), id); + javaScriptType.setCallText(callableJavascriptText); + } + } + return true; + } + private boolean processAddJavascriptElement (HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + JavascriptItemType javaScriptType = rdef.addJavascriptType(new ObjectFactory(), ""); + javaScriptType.setId(""); + javaScriptType.setFieldId(""); + javaScriptType.setCallText(""); + + return true; + } + + private boolean processDeleteJavascriptElement (HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + String id = AppUtils.getRequestNvlValue(request, AppConstants.RI_JAVASCRIPT_ITEM_ID); + if(rdef.deleteJavascriptType(id)) + return true; + else + return false; + } + + private boolean processChart(HttpServletRequest request, String action) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + int valueColsCount = rdef.getChartValueColumnsList(AppConstants.CHART_ALL_COLUMNS, null).size(); + + String chartType = AppUtils.getRequestNvlValue(request, "chartType"); + String chartTypeFixed = AppUtils.getRequestValue(request, "chartTypeFixed"); + String legendColId = AppUtils.getRequestNvlValue(request, "legendCol"); + // String valueColId = AppUtils.getRequestNvlValue(request, "valueCol"); + String leftAxisLabel = AppUtils.getRequestValue(request, "leftAxisLabel"); + String rightAxisLabel = AppUtils.getRequestValue(request, "rightAxisLabel"); + String chartWidth = XSSFilter.filterRequest(AppUtils.getRequestNvlValue(request, "chartWidth")); + String chartHeight = XSSFilter.filterRequest(AppUtils.getRequestNvlValue(request, "chartHeight")); + String chartMultiseries = AppUtils.getRequestNvlValue(request, "multiSeries"); + String lastSeriesALineChart = AppUtils.getRequestNvlValue(request, "lastSeriesALineChart"); + String lastSeriesABarChart = AppUtils.getRequestNvlValue(request, "lastSeriesABarChart"); + String overLayItemLabel = "N"; + String chartDisplay = null; + + String multiplePieOrder = null; + String multiplePieLabelDisplay = null; + + String chartOrientation = null; + String secondaryChartRenderer = null; + + String linearRegression = null; + + boolean multiplePieOrderInRunPage = false; + boolean multiplePieLabelDisplayInRunPage = false; + + boolean chartOrientationInRunPage = false; + boolean secondaryChartRendererInRunPage = false; + + boolean chartDisplayInRunPage = false; + + String intervalFromdate = null; + String intervalTodate = null; + String intervalLabel = null; + boolean displayIntervalInputInRunPage = false; + boolean animate = false; + + animate = AppUtils.getRequestNvlValue(request, "animatedOption").equals("animate"); + if(Globals.showAnimatedChartOption()) + rdef.setChartAnimate(animate); + + + String removeColId = ""; + if (action.equals(AppConstants.WA_DELETE_USER)) { + removeColId = AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID); + if(valueColsCount == 2 && !rdef.hasSeriesColumn()) { + rdef.setChartLeftAxisLabel(null); + rdef.setChartRightAxisLabel(null); + + if(chartType.equals(AppConstants.GT_TIME_SERIES) || chartType.equals(AppConstants.GT_PIE_MULTIPLE)) { + chartMultiseries = "N"; + } + } + } + + if(rdef.getChartAdditionalOptions()==null) + rdef.addChartAdditionalOptions(new ObjectFactory()); + + if(rdef.getChartDrillOptions()==null) + rdef.addChartDrillOptions(new ObjectFactory()); + + //clearing already added + if(rdef.getChartDrillOptions().getTargetFormfield()!=null) + rdef.getChartDrillOptions().getTargetFormfield().removeAll(rdef.getChartDrillOptions().getTargetFormfield()); + + + if(chartType.equals(AppConstants.GT_PIE_MULTIPLE)) { + multiplePieOrder = AppUtils.getRequestNvlValue(request, "multiplePieOrder"); + multiplePieLabelDisplay = AppUtils.getRequestNvlValue(request, "multiplePieLabelDisplay"); + chartDisplay = AppUtils.getRequestNvlValue(request, "chartDisplay"); + //if(AppUtils.getRequestNvlValue(request, "multiplePieOrderInRunPage").length()>0) + multiplePieOrderInRunPage = AppUtils.getRequestNvlValue(request,"multiplePieOrderInRunPage").equals("Y"); + //if(AppUtils.getRequestNvlValue(request, "multiplePieLabelDisplayInRunPage").length()>0) + multiplePieLabelDisplayInRunPage = AppUtils.getRequestNvlValue(request,"multiplePieLabelDisplayInRunPage").equals("Y"); + //if(AppUtils.getRequestNvlValue(request, "chartDisplayInRunPage").length()>0) + chartDisplayInRunPage = AppUtils.getRequestNvlValue(request,"chartDisplayInRunPage").equals("Y"); + if(rdef.getChartAdditionalOptions()!=null) { + rdef.setChartMultiplePieOrder(multiplePieOrder+(multiplePieOrderInRunPage?"|Y":"")); + rdef.setChartMultiplePieLabelDisplay(multiplePieLabelDisplay+(multiplePieLabelDisplayInRunPage?"|Y":"")); + rdef.setChartDisplay(chartDisplay+(chartDisplayInRunPage?"|Y":"")); + } + + } + + if(chartType.equals(AppConstants.GT_REGRESSION)) { + linearRegression = AppUtils.getRequestNvlValue(request, "regressionType"); + rdef.setLinearRegressionColor(AppUtils.getRequestNvlValue(request, "valueLinearRegressionColor")); + rdef.setExponentialRegressionColor(AppUtils.getRequestNvlValue(request, "valueExponentialRegressionColor")); + rdef.setCustomizedRegressionPoint(AppUtils.getRequestNvlValue(request, "regressionPointCustomization")); + + if(nvl(linearRegression).length()>0) + rdef.setLinearRegression(linearRegression); + else + rdef.setLinearRegression("Y"); + } + + if(chartType.equals(AppConstants.GT_BAR_3D)) { + chartOrientation = AppUtils.getRequestNvlValue(request, "chartOrientation"); + secondaryChartRenderer = AppUtils.getRequestNvlValue(request, "secondaryChartRenderer"); + chartDisplay = AppUtils.getRequestNvlValue(request, "chartDisplay"); + //if(AppUtils.getRequestNvlValue(request, "chartOrientationInRunPage").length()>0) + chartOrientationInRunPage = AppUtils.getRequestNvlValue(request,"chartOrientationInRunPage").equals("Y"); + //if(AppUtils.getRequestNvlValue(request, "secondaryChartRendererInRunPage").length()>0) + secondaryChartRendererInRunPage = AppUtils.getRequestNvlValue(request,"secondaryChartRendererInRunPage").equals("Y"); + //if(AppUtils.getRequestNvlValue(request, "chartDisplayInRunPage").length()>0) + chartDisplayInRunPage = AppUtils.getRequestNvlValue(request,"chartDisplayInRunPage").equals("Y"); + rdef.setChartOrientation(chartOrientation+(chartOrientationInRunPage?"|Y":"")); + rdef.setSecondaryChartRenderer(secondaryChartRenderer+(secondaryChartRendererInRunPage?"|Y":"")); + rdef.setChartDisplay(chartDisplay+(chartDisplayInRunPage?"|Y":"")); + rdef.setLastSeriesALineChart(nvl(lastSeriesALineChart, "N")); + } + + if(chartType.equals(AppConstants.GT_LINE)) { + chartOrientation = AppUtils.getRequestNvlValue(request, "chartOrientation"); + secondaryChartRenderer = AppUtils.getRequestNvlValue(request, "secondaryChartRenderer"); + chartDisplay = AppUtils.getRequestNvlValue(request, "chartDisplay"); + //if(AppUtils.getRequestNvlValue(request, "chartOrientationInRunPage").length()>0) + chartOrientationInRunPage = AppUtils.getRequestNvlValue(request,"chartOrientationInRunPage").equals("Y"); + //if(AppUtils.getRequestNvlValue(request, "secondaryChartRendererInRunPage").length()>0) + secondaryChartRendererInRunPage = AppUtils.getRequestNvlValue(request,"secondaryChartRendererInRunPage").equals("Y"); + //if(AppUtils.getRequestNvlValue(request, "chartDisplayInRunPage").length()>0) + chartDisplayInRunPage = AppUtils.getRequestNvlValue(request,"chartDisplayInRunPage").equals("Y"); + rdef.setChartOrientation(chartOrientation+(chartOrientationInRunPage?"|Y":"")); + rdef.setSecondaryChartRenderer(secondaryChartRenderer+(secondaryChartRendererInRunPage?"|Y":"")); + rdef.setChartDisplay(chartDisplay+(chartDisplayInRunPage?"|Y":"")); + rdef.setLastSeriesABarChart(nvl(lastSeriesABarChart, "N")); + } + if(chartType.equals(AppConstants.GT_TIME_DIFFERENCE_CHART)) { + intervalFromdate = AppUtils.getRequestNvlValue(request, "intervalFromDate"); + intervalTodate = AppUtils.getRequestNvlValue(request, "intervalToDate"); + intervalLabel = AppUtils.getRequestNvlValue(request, "intervalLabel"); + displayIntervalInputInRunPage = AppUtils.getRequestNvlValue(request,"intervalInputInRunPage").equals("Y"); + rdef.setIntervalFromdate(intervalFromdate+(displayIntervalInputInRunPage?"|Y":"")); + rdef.setIntervalTodate(intervalTodate+(displayIntervalInputInRunPage?"|Y":"")); + rdef.setIntervalLabel(intervalLabel); + } + if(chartType.equals(AppConstants.GT_STACKED_VERT_BAR) || chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR) || chartType.equals(AppConstants.GT_STACKED_VERT_BAR_LINES) + || chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR_LINES)) { + overLayItemLabel = AppUtils.getRequestNvlValue(request, "overlayItemValue"); + rdef.setOverlayItemValueOnStackBar(nvl(overLayItemLabel, "N")); + animate = AppUtils.getRequestNvlValue(request, "animatedOption").equals("animate"); + rdef.setChartAnimate(animate); + } + + rdef.setRangeAxisLowerLimit(AppUtils.getRequestNvlValue(request, "yAxisLowerLimit")); + rdef.setRangeAxisUpperLimit(AppUtils.getRequestNvlValue(request, "yAxisUpperLimit")); + rdef.setLegendLabelAngle(AppUtils.getRequestNvlValue(request,"labelAngle")); + rdef.setLegendPosition(AppUtils.getRequestNvlValue(request,"legendPosition")); + rdef.setMaxLabelsInDomainAxis(AppUtils.getRequestNvlValue(request,"maxLabelsInDomainAxis")); + String chartLegendDisplay = AppUtils.getRequestNvlValue(request,"hideLegend"); + boolean showLegendDisplayOptionsInRunPage = false; + showLegendDisplayOptionsInRunPage = AppUtils.getRequestNvlValue(request,"showLegendDisplayOptionsInRunPage").equals("Y"); + rdef.setChartLegendDisplay(chartLegendDisplay+(showLegendDisplayOptionsInRunPage?"|Y":"")); + rdef.setChartToolTips(AppUtils.getRequestNvlValue(request,"hideTooltips")); + rdef.setDomainAxisValuesAsString(AppUtils.getRequestNvlValue(request,"keepAsString")); + + //System.out.println("KeepAsString " + AppUtils.getRequestNvlValue(request,"keepAsString")); + //System.out.println("From ReportDef " + rdef.keepDomainAxisValueInChartAsString()); + // boolean reportUpdated = (! + // chartType.equals(nvl(rdef.getChartType()))); + rdef.setChartType(chartType); + rdef.setChartTypeFixed(nvl(chartTypeFixed, "N")); + if (nvl(leftAxisLabel).length()>0) + rdef.setChartLeftAxisLabel(leftAxisLabel); + else + rdef.setChartLeftAxisLabel(null); + if (nvl(rightAxisLabel).length()>0) + rdef.setChartRightAxisLabel(rightAxisLabel); + else + rdef.setChartRightAxisLabel(null); + rdef.setChartWidth(nvl(chartWidth, "" + Globals.getDefaultChartWidth())); + rdef.setChartHeight(nvl(chartHeight, "" + Globals.getDefaultChartHeight())); + if(chartType.equals(AppConstants.GT_TIME_SERIES) || chartType.equals(AppConstants.GT_PIE_MULTIPLE)) { + rdef.setChartMultiSeries(chartMultiseries); + } else { + rdef.setChartMultiSeries("N"); + } + + List reportCols = rdef.getAllColumns(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + + if (dct.getColId().equals(legendColId)) { + // reportUpdated = reportUpdated||(! + // nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND)); + dct.setColOnChart(AppConstants.GC_LEGEND); + } else { + // reportUpdated = + // reportUpdated||nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND); + dct.setColOnChart(null); + } + + /* + * if(dct.getColId().equals(valueColId)) { reportUpdated = + * reportUpdated||(dct.getChartSeq()<=0); dct.setChartSeq(1); } + * else { reportUpdated = reportUpdated||(dct.getChartSeq()>0); + */ + dct.setChartSeq(-1); + /* } */ + } // for + + int idx = 1; + List columns = rdef.getAllColumns(); + if(chartType.equals(AppConstants.GT_TIME_SERIES)) { + String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); + String chartGroup = AppUtils.getRequestNvlValue(request, "chartGroup"); + String yAxis = AppUtils.getRequestNvlValue(request, "yAxis"); + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType alldct = (DataColumnType) iterator.next(); + //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); + alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); + } + + String drillDownReportId = AppUtils.getRequestNvlValue(request, "drillDownReport"); + if(!drillDownReportId.equals("-1")) { + ReportRuntime ddRr = (new ReportHandler()).loadReportRuntime(request, drillDownReportId, + false); + if (ddRr != null) + request.setAttribute("CHART_FORMFIELDS", ddRr.getReportFormFields()); + + for(ddRr.getReportFormFields().resetNext(); ddRr.getReportFormFields().hasNext(); ) { + FormField ff = ddRr.getReportFormFields().getNext(); + if(!ff.getFieldType().equals(FormField.FFT_BLANK)) { + String value = AppUtils.getRequestNvlValue(request, "drillDown_"+ff.getFieldName()); + ChartDrillFormfield cdf = new ObjectFactory().createChartDrillFormfield(); + cdf.setFormfield(value); + rdef.getChartDrillOptions().getTargetFormfield().add(cdf); + } + } + } + + } else { + if(chartType.equals(AppConstants.GT_BAR_3D)) { + String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); + String chartGroup = AppUtils.getRequestNvlValue(request, "chartGroup"); + String yAxis = AppUtils.getRequestNvlValue(request, "yAxis"); + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType alldct = (DataColumnType) iterator.next(); + //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); + alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); + } + String drillDownReportId = AppUtils.getRequestNvlValue(request, "drillDownReport"); + rdef.setDrillReportIdForChart(drillDownReportId); + if(drillDownReportId.equals("-1")){ + rdef.setDrillReportIdForChart(""); + } + + if(!drillDownReportId.equals("-1")) { + ReportRuntime ddRr = (new ReportHandler()).loadReportRuntime(request, drillDownReportId, + false); + if (ddRr != null) + request.setAttribute("CHART_FORMFIELDS", ddRr.getReportFormFields()); + + for(ddRr.getReportFormFields().resetNext(); ddRr.getReportFormFields().hasNext(); ) { + FormField ff = ddRr.getReportFormFields().getNext(); + if(!ff.getFieldType().equals(FormField.FFT_BLANK)) { + String value = AppUtils.getRequestNvlValue(request, "drillDown_"+ff.getFieldName()); + ChartDrillFormfield cdf = new ObjectFactory().createChartDrillFormfield(); + cdf.setFormfield(value); + rdef.getChartDrillOptions().getTargetFormfield().add(cdf); + } + } + + String xAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownXAxisFormfield"); + String yAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownYAxisFormfield"); + String seriesAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownSeriesAxisFormfield"); + + if(!xAxisFormField.equals("-1")){ + rdef.setDrillXAxisFormField(xAxisFormField); + + if(!yAxisFormField.equals("-1")) + rdef.setDrillYAxisFormField(yAxisFormField); + if(!seriesAxisFormField.equals("-1")) + rdef.setDrillSeriesFormField(seriesAxisFormField); + } else { + rdef.setDrillXAxisFormField(""); + rdef.setDrillYAxisFormField(""); + rdef.setDrillSeriesFormField(""); + } + } + + } else if(chartType.equals(AppConstants.GT_SCATTER)) { + String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType alldct = (DataColumnType) iterator.next(); + //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); + alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); + } + + }else if(chartType.equals(AppConstants.GT_REGRESSION)) { + String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType alldct = (DataColumnType) iterator.next(); + //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); + alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); + } + }else if(chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR) || chartType.equals(AppConstants.GT_STACKED_VERT_BAR) + || chartType.equals(AppConstants.GT_STACKED_VERT_BAR_LINES) || chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR_LINES)) { + String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType alldct = (DataColumnType) iterator.next(); + //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); + alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); + } + }else if(chartType.equals(AppConstants.GT_LINE)) { + String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType alldct = (DataColumnType) iterator.next(); + //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); + alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); + } + } else if (chartType.equals(AppConstants.GT_TIME_DIFFERENCE_CHART)) { + String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType alldct = (DataColumnType) iterator.next(); + //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); + alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); + } + } else if (chartType.equals(AppConstants.GT_COMPARE_PREVYEAR_CHART)) { + String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType alldct = (DataColumnType) iterator.next(); + //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); + alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); + } + + } else { + if (rdef.hasSeriesColumn()) { + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType alldct = (DataColumnType) iterator.next(); + alldct.setChartSeries(false); + } + } + + String drillDownReportId = AppUtils.getRequestNvlValue(request, "drillDownReport"); + rdef.setDrillReportIdForChart(drillDownReportId); + if(drillDownReportId.equals("-1")){ + rdef.setDrillReportIdForChart(""); + } + + if(!drillDownReportId.equals("-1")) { + ReportRuntime ddRr = (new ReportHandler()).loadReportRuntime(request, drillDownReportId, + false); + if (ddRr != null) + request.setAttribute("CHART_FORMFIELDS", ddRr.getReportFormFields()); + for(ddRr.getReportFormFields().resetNext(); ddRr.getReportFormFields().hasNext(); ) { + FormField ff = ddRr.getReportFormFields().getNext(); + if(!ff.getFieldType().equals(FormField.FFT_BLANK)) { + String value = AppUtils.getRequestNvlValue(request, "drillDown_"+ff.getFieldName()); + ChartDrillFormfield cdf = new ObjectFactory().createChartDrillFormfield(); + cdf.setFormfield(value); + rdef.getChartDrillOptions().getTargetFormfield().add(cdf); + } + } + + String xAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownXAxisFormfield"); + String yAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownYAxisFormfield"); + String seriesAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownSeriesAxisFormfield"); + + if(!xAxisFormField.equals("-1")){ + rdef.setDrillXAxisFormField(xAxisFormField); + + if(!yAxisFormField.equals("-1")) + rdef.setDrillYAxisFormField(yAxisFormField); + if(!seriesAxisFormField.equals("-1")) + rdef.setDrillSeriesFormField(seriesAxisFormField); + } else { + rdef.setDrillXAxisFormField(""); + rdef.setDrillYAxisFormField(""); + rdef.setDrillSeriesFormField(""); + } + } + + } + } + + for (int i = 1; i < Math.max(valueColsCount, 1) + 1; i++) { + //debugLogger.debug("********** " + chartSeries); + if(i==1) { + /* Range Axis is resetted before adding */ + for (Iterator iterator = columns.iterator(); iterator.hasNext();) { + DataColumnType dct = (DataColumnType) iterator.next(); + if(!nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND)) { + dct.setChartSeq(-1); + dct.setChartColor(null); + dct.setColOnChart(null); + dct.setCreateInNewChart(false); + dct.setChartGroup(null); + dct.setYAxis(null); + } + } + + } + String newChartColAxis = AppUtils.getRequestNvlValue(request, "newChart" + i+"Axis"); + String valueColId = AppUtils.getRequestNvlValue(request, "valueCol" + i); + String valueColColor = AppUtils.getRequestNvlValue(request, "valueCol" + i + + "Color"); + String valueColAxis = AppUtils + .getRequestNvlValue(request, "valueCol" + valueColId + "Axis"); + String chartGroup = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "chartGroup" + valueColId + "Axis")); + String yAxisGroup = ""; + yAxisGroup = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "YAxisLabel" + valueColId)); + //debugLogger.debug("^^^^^^^^^^^^^^^^^Chart Group " + chartGroup); + //if(chartType.equals(AppConstants.GT_TIME_SERIES)) { + // debugLogger.debug("**********Outer If " + chartSeries); + //} + + if (valueColId.length() > 0 && (!valueColId.equals(removeColId))) { + DataColumnType dct = rdef.getColumnById(valueColId); + dct.setChartSeq(idx++); + dct.setChartColor(valueColColor); + dct.setColOnChart(valueColAxis.equals("Y") ? "1" : "0"); + if(chartType.equals(AppConstants.GT_TIME_SERIES)) { + dct.setCreateInNewChart(newChartColAxis.equals("Y") ? true : false); + } else + dct.setCreateInNewChart(false); + + if(chartGroup!=null && chartGroup.length()>0) + dct.setChartGroup(chartGroup+"|"+valueColId); + else dct.setChartGroup(""); + if(chartType.equals(AppConstants.GT_TIME_SERIES)) + dct.setYAxis(nvl(yAxisGroup)+"|"+valueColId); + else if (chartType.equals(AppConstants.GT_BAR_3D)) + dct.setYAxis(nvl(yAxisGroup)+"|"+valueColId); + else dct.setYAxis(""); + //} + //else + //dct.setCreateInNewChart(false); + } else if (valueColId.length() > 0 && (valueColId.equals(removeColId))) {// if + DataColumnType dct = rdef.getColumnById(valueColId); + dct.setChartSeq(-1); + dct.setChartColor(null); + dct.setColOnChart(null); + dct.setCreateInNewChart(false); + dct.setChartGroup(null); + dct.setYAxis(null); + } else { // else + DataColumnType dct = rdef.getColumnById(valueColId); + dct.setChartSeq(-1); + dct.setChartColor(null); + dct.setColOnChart(null); + dct.setCreateInNewChart(false); + dct.setChartGroup(null); + dct.setYAxis(null); + } + } // for + + if (action.equals(AppConstants.WA_ADD_USER)) { + String valueColId = AppUtils.getRequestNvlValue(request, "valueColNew"); + String valueColColor = AppUtils.getRequestNvlValue(request, "valueColNewColor"); + String valueColAxis = AppUtils.getRequestNvlValue(request, "valueColNewAxis"); + + if (valueColId.length() > 0) { + DataColumnType dct = rdef.getColumnById(valueColId); + dct.setChartSeq(idx++); + dct.setChartColor(valueColColor); + dct.setColOnChart(valueColAxis.equals("Y") ? "1" : "0"); + } // if + } // for + + return true; // reportUpdated; + } // processChart + + public boolean processAdhocSchedule(HttpServletRequest request, String action) + throws Exception { + ReportSchedule reportSchedule = (ReportSchedule) request.getSession().getAttribute(AppConstants.SI_REPORT_SCHEDULE); + reportSchedule.setScheduleUserID(AppUtils.getUserID(request)); + reportSchedule.setSchedEnabled( + nvl(AppUtils.getRequestValue(request, "schedEnabled"), "N")); + reportSchedule.setStartDate( + AppUtils.getRequestNvlValue(request, "schedStartDate")); + reportSchedule.setEndDate( + AppUtils.getRequestNvlValue(request, "schedEndDate")); + reportSchedule.setEndHour(AppUtils.getRequestNvlValue(request, "schedEndHour")); + reportSchedule.setEndMin(AppUtils.getRequestNvlValue(request, "schedEndMin")); + reportSchedule.setEndAMPM(AppUtils.getRequestNvlValue(request, "schedEndAMPM")); + //schedRunDate + reportSchedule.setRunDate( + AppUtils.getRequestNvlValue(request, "schedRunDate").length()>0?AppUtils.getRequestNvlValue(request, "schedRunDate"):AppUtils.getRequestNvlValue(request, "schedStartDate")); + reportSchedule.setRunHour(AppUtils.getRequestNvlValue(request, "schedHour")); + reportSchedule.setRunMin(AppUtils.getRequestNvlValue(request, "schedMin")); + reportSchedule.setRunAMPM(AppUtils.getRequestNvlValue(request, "schedAMPM")); + reportSchedule.setRecurrence( + AppUtils.getRequestNvlValue(request, "schedRecurrence")); + reportSchedule.setConditional( + nvl(AppUtils.getRequestValue(request, "conditional"), "N")); + reportSchedule.setConditionSQL( + AppUtils.getRequestNvlValue(request, "conditionSQL")); + reportSchedule.setNotify_type( + AppUtils.getRequestNvlValue(request, "notify_type")); + reportSchedule.setDownloadLimit( + AppUtils.getRequestNvlValue(request, "downloadLimit")); + reportSchedule.setFormFields( + AppUtils.getRequestNvlValue(request, "formFields")); + reportSchedule.setAttachmentMode( + AppUtils.getRequestNvlValue(request, "sendAttachment")); + + String userId = AppUtils.getRequestNvlValue(request, "schedEmailAdd"); + String roleId = AppUtils.getRequestNvlValue(request, "schedEmailAddRole"); + int flag = 0; + if ((!(userId.length()>0 || roleId.length()>0) && (reportSchedule.getEmailToUsers().isEmpty() && reportSchedule.getEmailToRoles().isEmpty())) ) { + flag = 1; + } + + if (flag == 1 || (action.equals(AppConstants.WA_ADD_USER) || action.equals(AppConstants.WA_ADD_ROLE)) ) { + String loggedInUserId = AppUtils.getUserID(request); + if (Globals.getUseLoginIdInSchedYN().equals("Y")){ + reportSchedule.addEmailToUser(loggedInUserId, AppUtils.getUserLoginId(request)); + } else + reportSchedule.addEmailToUser(loggedInUserId, (AppUtils.getUserName(loggedInUserId).length()>0?AppUtils.getUserName(loggedInUserId):(AppUtils.getUserLoginId(loggedInUserId).length()>0?AppUtils.getUserLoginId(loggedInUserId):loggedInUserId) )); + } + if (action.equals(AppConstants.WA_ADD_USER)) { + //String userId = AppUtils.getRequestNvlValue(request, "schedEmailAdd"); + String userName = AppUtils.getUserName(userId); + if (Globals.getUseLoginIdInSchedYN().equals("Y")){ + String userLoginId = AppUtils.getUserLoginId(userId); + if (userId.length() > 0 && (userLoginId != null && userLoginId.length() > 0)) + reportSchedule.addEmailToUser(userId, userLoginId); + else { + if (userId.length() > 0 && (userName != null && userName.length() > 0) ) + reportSchedule.addEmailToUser(userId, userName); + else { + reportSchedule.addEmailToUser(userId, userId); + } + } + }else{ + if (userId.length() > 0 && (userName != null && userName.length() > 0) ) + reportSchedule.addEmailToUser(userId, userName); + else { + reportSchedule.addEmailToUser(userId, userId); + } + } + + } else if (action.equals(AppConstants.WA_DELETE_USER)) + reportSchedule.removeEmailToUser( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + else if (action.equals(AppConstants.WA_ADD_ROLE)) { + //String roleId = AppUtils.getRequestNvlValue(request, "schedEmailAddRole"); + String roleName = AppUtils.getRoleName(roleId); + if (roleId.length() > 0 && roleName != null) + reportSchedule.addEmailToRole(roleId, roleName); + } else if (action.equals(AppConstants.WA_DELETE_ROLE)) + reportSchedule.removeEmailToRole( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + request.getSession().setAttribute(AppConstants.SI_REPORT_SCHEDULE, reportSchedule); + return true; + } // processAdhocSchedule + + private boolean processSchedule(HttpServletRequest request, String action) + throws Exception { + // Added for form field chaining in schedule tab so that setParamValues() is called + request.setAttribute(AppConstants.SCHEDULE_ACTION, "Y"); + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + ReportSchedule reportSchedule = rdef.getReportSchedule(); + reportSchedule.setScheduleUserID(AppUtils.getUserID(request)); + reportSchedule.setSchedEnabled( + nvl(AppUtils.getRequestValue(request, "schedEnabled"), "N")); + reportSchedule.setStartDate( + AppUtils.getRequestNvlValue(request, "schedStartDate")); + reportSchedule.setEndDate( + AppUtils.getRequestNvlValue(request, "schedEndDate")); + reportSchedule.setEndHour(AppUtils.getRequestNvlValue(request, "schedEndHour")); + reportSchedule.setEndMin(AppUtils.getRequestNvlValue(request, "schedEndMin")); + reportSchedule.setEndAMPM(AppUtils.getRequestNvlValue(request, "schedEndAMPM")); + //schedRunDate + reportSchedule.setRunDate( + AppUtils.getRequestNvlValue(request, "schedRunDate").length()>0?AppUtils.getRequestNvlValue(request, "schedRunDate"):AppUtils.getRequestNvlValue(request, "schedStartDate")); + reportSchedule.setRunHour(AppUtils.getRequestNvlValue(request, "schedHour")); + reportSchedule.setRunMin(AppUtils.getRequestNvlValue(request, "schedMin")); + reportSchedule.setRunAMPM(AppUtils.getRequestNvlValue(request, "schedAMPM")); + reportSchedule.setRecurrence( + AppUtils.getRequestNvlValue(request, "schedRecurrence")); + reportSchedule.setConditional( + nvl(AppUtils.getRequestValue(request, "conditional"), "N")); + reportSchedule.setConditionSQL( + AppUtils.getRequestNvlValue(request, "conditionSQL")); + reportSchedule.setNotify_type( + AppUtils.getRequestNvlValue(request, "notify_type")); + reportSchedule.setDownloadLimit( + AppUtils.getRequestNvlValue(request, "downloadLimit")); + reportSchedule.setFormFields( + AppUtils.getRequestNvlValue(request, "formFields")); + reportSchedule.setAttachmentMode( + AppUtils.getRequestNvlValue(request, "sendAttachment")); + + reportSchedule.setEncryptMode( + AppUtils.getRequestNvlValue(request, "encryptMode")); + if (action.equals(AppConstants.WA_ADD_USER)) { + String userId = AppUtils.getRequestNvlValue(request, "schedEmailAdd"); + String userName = AppUtils.getUserName(userId); + if (Globals.getUseLoginIdInSchedYN().equals("Y")){ + String userLoginId = AppUtils.getUserLoginId(userId); + if (userId.length() > 0 && (userLoginId != null && userLoginId.length() > 0)) + reportSchedule.addEmailToUser(userId, userLoginId); + else { + if (userId.length() > 0 && (userName != null && userName.length() > 0) ) + reportSchedule.addEmailToUser(userId, userName); + else { + reportSchedule.addEmailToUser(userId, userId); + } + } + }else{ + if (userId.length() > 0 && (userName != null && userName.length() > 0) ) + reportSchedule.addEmailToUser(userId, userName); + else { + reportSchedule.addEmailToUser(userId, userId); + } + } + } else if (action.equals(AppConstants.WA_DELETE_USER)) + reportSchedule.removeEmailToUser( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + else if (action.equals(AppConstants.WA_ADD_ROLE)) { + String roleId = AppUtils.getRequestNvlValue(request, "schedEmailAddRole"); + String roleName = AppUtils.getRoleName(roleId); + if (roleId.length() > 0 && roleName != null) + reportSchedule.addEmailToRole(roleId, roleName); + } else if (action.equals(AppConstants.WA_DELETE_ROLE)) + reportSchedule.removeEmailToRole( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + + return true; + } // processSchedule + + private boolean processUserAccess(HttpServletRequest request, String action) + throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String ownerID = AppUtils.getRequestNvlValue(request, "reportOwner"); + String rPublic = nvl(AppUtils.getRequestValue(request, "public"), "N"); + + boolean reportUpdated = (!(ownerID.equals(nvl(rdef.getOwnerID())) && rPublic + .equals(rdef.isPublic() ? "Y" : "N"))); + + rdef.getReportSecurity().setOwnerID(ownerID); + rdef.setPublic(rPublic.equals("Y")); + + if (action.equals(AppConstants.WA_ADD_USER)) + rdef.getReportSecurity().addUserAccess( + AppUtils.getRequestNvlValue(request, "newUserId"), "Y"); + else if (action.equals(AppConstants.WA_DELETE_USER)) + rdef.getReportSecurity().removeUserAccess( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + else if (action.equals(AppConstants.WA_GRANT_USER)) + rdef.getReportSecurity().updateUserAccess( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID), "N"); + else if (action.equals(AppConstants.WA_REVOKE_USER)) + rdef.getReportSecurity().updateUserAccess( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID), "Y"); + else if (action.equals(AppConstants.WA_ADD_ROLE)) + rdef.getReportSecurity().addRoleAccess( + AppUtils.getRequestNvlValue(request, "newRoleId"), "Y"); + else if (action.equals(AppConstants.WA_DELETE_ROLE)) + rdef.getReportSecurity().removeRoleAccess( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); + else if (action.equals(AppConstants.WA_GRANT_ROLE)) + rdef.getReportSecurity().updateRoleAccess( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID), "N"); + else if (action.equals(AppConstants.WA_REVOKE_ROLE)) + rdef.getReportSecurity().updateRoleAccess( + AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID), "Y"); + + return reportUpdated; + } // processUserAccess + + private boolean processClearLog(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + String user_id = AppUtils.getUserID(request); + // Modified so that only the logged in user entries are erased. - Sundar + ReportLoader.clearReportLogEntries(rdef.getReportID(), user_id); + return false; + } // processClearLog + + private boolean processValidateSQL(HttpServletRequest request) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + String sql = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportSQL")); + request.setAttribute("sqlValidated", "N"); + rdef.parseReportSQL(sql); + request.setAttribute("sqlValidated", "Y"); + + return true; + } // processValidateSQL + + + /*****For Report Maps - Start******/ + private boolean processMap(HttpServletRequest request, String action) throws Exception { + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + + org.openecomp.portalsdk.analytics.xmlobj.ReportMap repMap = rdef.getReportMap(); + //clearing already added + if (repMap != null){ + repMap.getMarkers().removeAll(repMap.getMarkers()); + } + String addressColumn = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "addressColumn0")); + System.out.println(" #$%#$%#$% -- address col = " + addressColumn); + String dataColumn = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "dataColumn0")); + String legendColumn = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "legendColumn")); + //String legendDisplayName = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "dataHeaderL")); + //if(nvl(legendDisplayName).length()<=0) legendDisplayName = legendColumn; + String color = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "markerColor0")); + String isMapAllowed = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "isMapAllowed")); + String useDefaultSize = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "useDefaultSize")); + String height = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "height")); + String width = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "width")); + System.out.println(" #$%#$%#$% -- useDefaultSize="+ useDefaultSize+" height = " + height+" width="+width); + + String addAddress = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "addAddress")); + String latCol = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "latColumn")); + String longCol = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "longColumn")); + String colorCol = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "colorColumn")); + if (isMapAllowed.equals("")) + isMapAllowed = "N"; + if (useDefaultSize.equals("")) + useDefaultSize = "N"; + if (repMap == null) + rdef.setReportMap(new ObjectFactory().createReportMap()); + repMap.setAddressColumn(addressColumn); + repMap.setDataColumn(dataColumn); + repMap.setIsMapAllowedYN(isMapAllowed); + repMap.setUseDefaultSize(useDefaultSize); + repMap.setMarkerColor(color); + repMap.setAddAddressInDataYN(addAddress); + repMap.setLatColumn(latCol); + repMap.setLongColumn(longCol); + repMap.setColorColumn(colorCol); + repMap.setHeight(height.trim()); + repMap.setWidth(width.trim()); + repMap.setLegendColumn(legendColumn); + //repMap.setLegendDisplayName(legendDisplayName); + + Marker m = new ObjectFactory().createMarker(); + m.setAddressColumn(addressColumn); + m.setDataColumn(dataColumn); + repMap.getMarkers().add(m); + String markerCountString = AppUtils.getRequestNvlValue(request, "markerCount"); + int markerCount = 0; + if (markerCountString != null && markerCountString.equals("") == false){ + markerCount = new Integer(markerCountString).intValue(); + } + for (int i = 1; i < markerCount; i ++){ + String additionalAddressColumn = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "addressColumn" + i)); + String additionalDataHeader = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "dataHeader" + i)); + String additionalData = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "dataColumn" + i)); + String additionalColor = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "markerColor" + i)); + if (additionalAddressColumn.equals("1") == false){ + m = new ObjectFactory().createMarker(); + m.setAddressColumn(additionalAddressColumn); + m.setDataHeader(additionalDataHeader); + m.setDataColumn(additionalData); + m.setMarkerColor(additionalColor); + repMap.getMarkers().add(m); + } + } + return true; + } // processMap + /*****For Report Maps - End******/ + + +} // WizardProcessor diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequence.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequence.java new file mode 100644 index 00000000..81308909 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequence.java @@ -0,0 +1,191 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.model.base.*; +import org.openecomp.portalsdk.analytics.model.definition.*; +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class WizardSequence extends Vector { + // private String currentStep = AppConstants.WS_DEFINITION; + private int currentStepIdx = 0; + + private String currentSubStep = ""; + + private int nextElemIdx = 0; + + public void resetNext() { + resetNext(0); + } // resetNext + + public void resetNext(int toPos) { + nextElemIdx = toPos; + } // resetNext + + public boolean hasNext() { + return (nextElemIdx < size()); + } // hasNext + + public String getNext() { + return hasNext() ? getStep(nextElemIdx++) : null; + } // getNext + + // ***************************************************** + + public WizardSequence() { + add(AppConstants.WS_DEFINITION); + } // WizardSequence + + private String getStep(int index) { + return (String) get(index); + } // getStep + + private int getStepIndex(String step) { + for (int i = 0; i < size(); i++) + if (getStep(i).equals(step)) + return i; + + throw new IndexOutOfBoundsException(); + } // getStepIndex + + /* + * private String getInitialStep() { return getStep(0); } // getInitialStep + * + * private String getFinalStep() { return getStep(getStepCount()-1); } // + * getFinalStep + */ + private boolean isInitialStep(int index) { + return (index == 0); + } // isInitialStep + + /* + * private boolean isInitialStep(String step) { return + * isInitialStep(getStepIndex(step)); } // isInitialStep + */ + private boolean isFinalStep(int index) { + if (index == 0) + return false; + + return (index == (getStepCount() - 1)); + } // isFinalStep + + /* + * private boolean isFinalStep(String step) { return + * isFinalStep(getStepIndex(step)); } // isFinalStep + */ + + private int getNextStepIndex(int index) { + return (index == (getStepCount() - 1)) ? index : (index + 1); + } // getNextStep + + /* + * private String getNextStep(String step) { return + * getStep(getNextStepIndex(getStepIndex(step))); } // getNextStep + * + * private String getNextStep(String step, String subStep) { + * if(subStep.length()>0) return step; + * + * return getNextStep(step); } // getNextStep + */ + private int getPrevStepIndex(int index) { + return (index == 0) ? index : (index - 1); + } // getPrevStepIndex + + /* + * private String getPrevStep(String step) { return + * getStep(getPrevStepIndex(getStepIndex(step))); } // getPrevStep + * + * private String getPrevStep(String step, String subStep) { + * if(subStep.length()>0) return step; + * + * return getPrevStep(step); } // getPrevStep + */ + // ***************************************************** + public int getStepCount() { + return size(); + } // getStepCount + + public int getCurrentStepIndex() { + return currentStepIdx + 1; + } // getCurrentStepIndex + + public String getCurrentStep() { + return getStep(currentStepIdx); + } // getCurrentStep + + public String getCurrentSubStep() { + return currentSubStep; + } // getCurrentSubStep + + public boolean isInitialStep() { + return isInitialStep(currentStepIdx); + } // isInitialStep + + public boolean isFinalStep() { + return isFinalStep(currentStepIdx); + } // isFinalStep + + public void performAction(String action, ReportDefinition rdef) { + if (action.equals(AppConstants.WA_BACK)) + if (currentSubStep.length() > 0) + currentSubStep = ""; + else + currentStepIdx = getPrevStepIndex(currentStepIdx); + else if (action.equals(AppConstants.WA_NEXT)) { + if (currentSubStep.length() > 0) + currentSubStep = ""; + else { + currentStepIdx = getNextStepIndex(currentStepIdx); + if (rdef != null) + if (!rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) + if (getCurrentStep().equals(AppConstants.WS_TABLES) + && (rdef.getDataSourceList().getDataSource().size() == 0)) + currentSubStep = AppConstants.WSS_ADD; + else if (getCurrentStep().equals(AppConstants.WS_COLUMNS) + && (rdef.getAllColumns().size() == 0)) + currentSubStep = (rdef.getReportType().equals( + AppConstants.RT_CROSSTAB) ? AppConstants.WSS_ADD + : AppConstants.WSS_ADD_MULTI); + } + } else if (action.equals(AppConstants.WA_EDIT) || action.equals(AppConstants.WA_ADD) + || action.equals(AppConstants.WA_ADD_MULTI) + || action.equals(AppConstants.WA_ORDER_ALL)|| action.equals(AppConstants.WSS_ADD_BLANK) || action.equals(AppConstants.WA_MODIFY)) { + currentSubStep = action; + } + else if (currentSubStep.equals(AppConstants.WSS_ADD) + || currentSubStep.equals(AppConstants.WSS_EDIT)) + currentSubStep = AppConstants.WSS_EDIT; + else + currentSubStep = ""; + } // performAction + + public void performGoToStep(String step) { + int stepIdx = getStepIndex(step); + + if (stepIdx >= 0 && stepIdx < getStepCount()) { + currentStepIdx = stepIdx; + currentSubStep = ""; + } + } // performGoToStep + +} // WizardSequence diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceCrossTab.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceCrossTab.java new file mode 100644 index 00000000..686c8b7b --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceCrossTab.java @@ -0,0 +1,45 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class WizardSequenceCrossTab extends WizardSequence { + + public WizardSequenceCrossTab(boolean userIsAuthorizedToSeeLog) { + super(); + + add(AppConstants.WS_TABLES); + add(AppConstants.WS_COLUMNS); + add(AppConstants.WS_FORM_FIELDS); + add(AppConstants.WS_FILTERS); + add(AppConstants.WS_JAVASCRIPT); + add(AppConstants.WS_USER_ACCESS); + //add(AppConstants.WS_SCHEDULE); + if (userIsAuthorizedToSeeLog) + if (Globals.getEnableReportLog()) + add(AppConstants.WS_REPORT_LOG); + add(AppConstants.WS_RUN); + } // WizardSequenceCrossTab + +} // WizardSequenceCrossTab diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceDashboard.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceDashboard.java new file mode 100644 index 00000000..d8424f2c --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceDashboard.java @@ -0,0 +1,40 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class WizardSequenceDashboard extends WizardSequence { + + public WizardSequenceDashboard(boolean userIsAuthorizedToSeeLog) { + super(); + + add(AppConstants.WS_USER_ACCESS); + //add(AppConstants.WS_SCHEDULE); + if (userIsAuthorizedToSeeLog) + if (Globals.getEnableReportLog()) + add(AppConstants.WS_REPORT_LOG); + add(AppConstants.WS_RUN); + } // WizardSequenceDashboard + +} // WizardSequenceDashboard diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceLinear.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceLinear.java new file mode 100644 index 00000000..2015a7b9 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceLinear.java @@ -0,0 +1,47 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class WizardSequenceLinear extends WizardSequence { + + public WizardSequenceLinear(boolean userIsAuthorizedToSeeLog) { + super(); + + add(AppConstants.WS_TABLES); + add(AppConstants.WS_COLUMNS); + add(AppConstants.WS_FORM_FIELDS); + add(AppConstants.WS_FILTERS); + add(AppConstants.WS_SORTING); + //add(AppConstants.WS_JAVASCRIPT); + //add(AppConstants.WS_CHART); + add(AppConstants.WS_USER_ACCESS); + //add(AppConstants.WS_SCHEDULE); + if (userIsAuthorizedToSeeLog) + if (Globals.getEnableReportLog()) + add(AppConstants.WS_REPORT_LOG); + add(AppConstants.WS_RUN); + } // WizardSequenceLinear + +} // WizardSequenceLinear diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedCrossTab.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedCrossTab.java new file mode 100644 index 00000000..db2f8c6f --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedCrossTab.java @@ -0,0 +1,44 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class WizardSequenceSQLBasedCrossTab extends WizardSequence { + + public WizardSequenceSQLBasedCrossTab(boolean userIsAuthorizedToSeeLog) { + super(); + + add(AppConstants.WS_SQL); + add(AppConstants.WS_COLUMNS); + add(AppConstants.WS_FORM_FIELDS); + add(AppConstants.WS_JAVASCRIPT); + add(AppConstants.WS_USER_ACCESS); + //add(AppConstants.WS_SCHEDULE); + if (userIsAuthorizedToSeeLog) + if (Globals.getEnableReportLog()) + add(AppConstants.WS_REPORT_LOG); + add(AppConstants.WS_RUN); + } // WizardSequenceSQLBasedCrossTab + +} // WizardSequenceSQLBasedCrossTab diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedHive.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedHive.java new file mode 100644 index 00000000..7f64cb9a --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedHive.java @@ -0,0 +1,46 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class WizardSequenceSQLBasedHive extends WizardSequence { + + public WizardSequenceSQLBasedHive(boolean userIsAuthorizedToSeeLog) { + super(); + + add(AppConstants.WS_SQL); + add(AppConstants.WS_COLUMNS); + add(AppConstants.WS_FORM_FIELDS); + add(AppConstants.WS_JAVASCRIPT); + add(AppConstants.WS_CHART); + add(AppConstants.WS_USER_ACCESS); + //add(AppConstants.WS_MAP); + //add(AppConstants.WS_SCHEDULE); + if (userIsAuthorizedToSeeLog) + if (Globals.getEnableReportLog()) + add(AppConstants.WS_REPORT_LOG); + add(AppConstants.WS_RUN); + } // WizardSequenceSQLBasedHive + +} // WizardSequenceSQLBasedHive diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinear.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinear.java new file mode 100644 index 00000000..a19c66b4 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinear.java @@ -0,0 +1,47 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class WizardSequenceSQLBasedLinear extends WizardSequence { + + public WizardSequenceSQLBasedLinear(boolean userIsAuthorizedToSeeLog) { + super(); + + add(AppConstants.WS_SQL); + add(AppConstants.WS_COLUMNS); + add(AppConstants.WS_FORM_FIELDS); + //add(AppConstants.WS_JAVASCRIPT); + //if(!Globals.showAnimatedChartOnly()) + //add(AppConstants.WS_CHART); + add(AppConstants.WS_USER_ACCESS); + //add(AppConstants.WS_MAP); + //add(AppConstants.WS_SCHEDULE); + if (userIsAuthorizedToSeeLog) + if (Globals.getEnableReportLog()) + add(AppConstants.WS_REPORT_LOG); + add(AppConstants.WS_RUN); + } // WizardSequenceSQLBasedLinear + +} // WizardSequenceSQLBasedLinear diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinearDatamining.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinearDatamining.java new file mode 100644 index 00000000..5c8759d9 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinearDatamining.java @@ -0,0 +1,46 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.controller; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class WizardSequenceSQLBasedLinearDatamining extends WizardSequence { + + public WizardSequenceSQLBasedLinearDatamining(boolean userIsAuthorizedToSeeLog) { + super(); + + add(AppConstants.WS_SQL); + add(AppConstants.WS_COLUMNS); + add(AppConstants.WS_FORM_FIELDS); + add(AppConstants.WS_DATA_FORECASTING); + add(AppConstants.WS_JAVASCRIPT); + add(AppConstants.WS_CHART); + add(AppConstants.WS_USER_ACCESS); + //add(AppConstants.WS_SCHEDULE); + if (userIsAuthorizedToSeeLog) + if (Globals.getEnableReportLog()) + add(AppConstants.WS_REPORT_LOG); + add(AppConstants.WS_RUN); + } // WizardSequenceSQLBasedLinear + +} // WizardSequenceSQLBasedLinear diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorException.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorException.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorException.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorException.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorRuntimeException.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorRuntimeException.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorRuntimeException.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorRuntimeException.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorSchedularException.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorSchedularException.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorSchedularException.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/RaptorSchedularException.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/ReportSQLException.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/ReportSQLException.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/ReportSQLException.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/ReportSQLException.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserAccessException.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserAccessException.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserAccessException.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserAccessException.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserDefinedException.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserDefinedException.java new file mode 100644 index 00000000..0145ecfd --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserDefinedException.java @@ -0,0 +1,36 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.error; + +/** + * @author sundar + * This class is exclusively used to print error messages to user. + * + */ +public class UserDefinedException extends RaptorRuntimeException { + + public UserDefinedException(String message) { + super(message); + } + +} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/ValidationException.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/ValidationException.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/ValidationException.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/ValidationException.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/Line.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/Line.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/Line.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/Line.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineCollection.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineCollection.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineCollection.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineCollection.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineInfo.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineInfo.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineInfo.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/line/LineInfo.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/ColorProperties.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/ColorProperties.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/ColorProperties.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/ColorProperties.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GMapProperties.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GMapProperties.java new file mode 100644 index 00000000..036e83bf --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GMapProperties.java @@ -0,0 +1,49 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.gmap.map; + +import java.io.InputStream; +import java.util.Properties; + +import org.openecomp.portalsdk.analytics.system.Globals; + +public class GMapProperties { + + public static String getProjectFolder() { + return Globals.getProjectFolder(); + } + + public static String getMarketShapefileFolder() { + return Globals.getMarketShapefileFolder(); + } + + public static String getTileSize() { + return Globals.getTileSize(); + } + + public static String getOutputFolder() { + return Globals.getOutputFolder(); + } + + public static String getTempFolderURL() { + return Globals.getTempFolderURL(); + } + +} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GeoCoordinate.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GeoCoordinate.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GeoCoordinate.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GeoCoordinate.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/MapConstant.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/MapConstant.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/MapConstant.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/MapConstant.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/NovaMap.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/NovaMap.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/NovaMap.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/NovaMap.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/layer/SwingLayer.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/layer/SwingLayer.java new file mode 100644 index 00000000..9100637c --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/layer/SwingLayer.java @@ -0,0 +1,235 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.gmap.map.layer; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Stroke; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.analytics.gmap.map.ColorProperties; +import org.openecomp.portalsdk.analytics.gmap.map.MapConstant; +import org.openecomp.portalsdk.analytics.gmap.map.NovaMap; +import org.openecomp.portalsdk.analytics.gmap.node.Node; +import org.openecomp.portalsdk.analytics.gmap.node.NodeInfo; +import org.openecomp.portalsdk.analytics.system.Globals; + + +public class SwingLayer { + private Rectangle shape; + private NovaMap map; + + public SwingLayer(NovaMap map) { + this.map = map; + } + + public boolean paintLayer(HttpServletRequest request, Graphics2D g2d, Rectangle bounds, Rectangle2D mapArea, Graphics2D g2Legend) { + return paintNodes(request, g2d, bounds, mapArea, g2Legend); + } + + protected boolean paintNodes(HttpServletRequest request, Graphics2D g2d, Rectangle bounds, Rectangle2D mapArea, Graphics2D g2Legend) { + boolean painted = false; + Node node = map.getNode(); + ColorProperties colorProperties = map.getColorProperties(); + int legendSize = 0; + if(map.isShowLegend()) + legendSize = map.getShowListSize(); + Object showListArr[] = ((HashSet)map.getShowList()).toArray(); + HashMap hashMap = node.getNodeCollection().getNodeCollection(); + Set set = hashMap.entrySet(); + int width = map.getShapeWidth(); + ArrayList visibleLabel = new ArrayList(151); + Color oldColor = g2d.getColor(); + Stroke oldStroke = g2d.getStroke(); + int textWidth = 0; + int legendLength = 0; + for (int i = 0; i < showListArr.length; i++) { + legendLength = ((String)showListArr[i]).length(); + if(legendLength > textWidth) textWidth = legendLength; + } + Point2D point = null; + for (Iterator iterator = set.iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + NodeInfo nodeInfo = (NodeInfo) entry.getValue(); + + String id1 = (String) request.getAttribute("server_process_id"); + String id2 = (String) request.getSession().getAttribute("server_process_id"); + + if (!id1.equals(id2)) { + request.setAttribute("server_process_interrupted", true); + System.out.println("swing layer interrupted"); + return false; + } + //System.out.println("%%%%%%%getImage. no of T1%%%%%%" + nodeInfo.getAttribute("x_sequence")); + + + point = map.getPixelPos(nodeInfo.geoCoordinate.latitude, nodeInfo.geoCoordinate.longitude); + + if (!mapArea.contains(point.getX(), point.getY())) { + continue; + } + + painted = true; + + g2d.setColor(colorProperties.getColor(nodeInfo.getNodeType())); + + Point2D xyPoint = map.getScreenPointFromPixel(point.getX(), point.getY()); + int width2 = (colorProperties.getSize(nodeInfo.getNodeType()) * width) / 5; + + if (shape == null) { + shape = new Rectangle((int) xyPoint.getX(), (int) xyPoint.getY(), width2, width2); + } + else { + shape.setRect((int) xyPoint.getX(), (int) xyPoint.getY(), width2, width2); + } + + if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.FILLED_SQUARE)) { + g2d.fillRect((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); + } + else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.HOLLOW_SQUARE)) { + g2d.drawRect((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); + } + else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.FILLED_CIRCLE)) { + g2d.fillOval((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); + } + else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.HOLLOW_CIRCLE)) { + g2d.drawOval((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); + } + else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.FILLED_TRIANGLE)) { + int[] xPoints = {(int) shape.getX(), (int) shape.getX() - width2 / 2, (int) shape.getX() + width2 / 2}; + int[] yPoints = {(int) shape.getY() + width2 / 2, (int) shape.getY() - width2 / 2, (int) shape.getY() - width2 / 2}; + g2d.fillPolygon(xPoints, yPoints, xPoints.length); + } + else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.HOLLOW_TRIANGLE)) { + int[] xPoints = {(int) shape.getX(), (int) shape.getX() - width2 / 2, (int) shape.getX() + width2 / 2}; + int[] yPoints = {(int) shape.getY() + width2 / 2, (int) shape.getY() - width2 / 2, (int) shape.getY() - width2 / 2}; + g2d.drawPolygon(xPoints, yPoints, xPoints.length); + } + else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.FILLED_DIAMOND)) { + int[] xPoints = {(int) shape.getX() - width2 / 2, (int) shape.getX(), (int) shape.getX() + width2 / 2, (int) shape.getX()}; + int[] yPoints = {(int) shape.getY() , (int) shape.getY() - width2 / 2, (int) shape.getY(), (int) shape.getY() + width2 / 2}; + g2d.fillPolygon(xPoints, yPoints, xPoints.length); + } + else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.HOLLOW_DIAMOND)) { + int[] xPoints = {(int) shape.getX() - width2 / 2, (int) shape.getX(), (int) shape.getX() + width2 / 2, (int) shape.getX()}; + int[] yPoints = {(int) shape.getY() , (int) shape.getY() - width2 / 2, (int) shape.getY(), (int) shape.getY() + width2 / 2}; + g2d.drawPolygon(xPoints, yPoints, xPoints.length); + } else { + g2d.drawRect((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); + } + + if (nodeInfo.isMoveable()) { + int fontSize = width / 2; + fontSize = fontSize > 14 ? 14 : fontSize; + fontSize = (colorProperties.getSize(nodeInfo.getNodeType()) * fontSize) / 5; + Font font = new Font("sans-serif", Font.BOLD, fontSize); + g2d.setFont(font); + g2d.setColor(Color.BLACK); + g2d.drawString("M", shape.x + width2 / 2, shape.y); + } + +// if (map.containsShowLabelList(nodeInfo.getNodeType())) { +// g2d.setColor(Color.BLACK); +// FontMetrics metrics = g2d.getFontMetrics(); +// int x = shape.x - metrics.stringWidth(nodeInfo.getID()) / 2; +// int y = shape.y + width2 * 4 / 3; +// g2d.drawString(nodeInfo.getID(), x, y); +// } + } + String legendName = ""; + int baseY = 0; + baseY = (int)(20*showListArr.length) + 20;//+5; + int baseX = 0; + if(map.isShowLegend()) { + for (int i = showListArr.length-1; i>=0; i--) { + + legendName = (String)showListArr[i]; + //for(int i = 0; i < showListArr.length; i++ ) { + if(i == showListArr.length-1){ + textWidth = (textWidth<="Legend".length())?"Legend".length():textWidth; + g2Legend.setColor(Color.WHITE); + //g2d.draw(new Rectangle2D.Double((int) bounds.getMaxX()*0.1, (int) bounds.getMaxY()*0.75*showListArr.length, (int) bounds.getMaxX()*0.75, (int) bounds.getMaxY()*0.75)); + g2Legend.fill3DRect((int)(0), (int)(0), (int) bounds.getWidth() , (int)(baseY) , true); // (int)(bounds.getMaxX()*0.9)- (int)(bounds.getMaxX()*0.25) + //if(i == 0){ + g2Legend.setColor(Color.BLACK); + g2Legend.setFont(NovaMap.HEADER_FONT); + g2Legend.drawString("Legend", (int) (10), 10); + } + int[] xPointsL = {(int) (10 - width / 2), (int) (10), (int) (10 + width/2), (int) (10)}; + int[] yPointsL = {(int) (15*i+5+20), (int) (15*i+5+20 - width / 2), (int) (15*i+5+20), (int) (15*i+5+20 + width / 2)}; + g2Legend.setColor(colorProperties.getColor( ((String)showListArr[i]).toUpperCase())); + g2Legend.fillPolygon(xPointsL, yPointsL, xPointsL.length); + g2Legend.setFont(NovaMap.TEXT_FONT); + g2Legend.setColor(Color.BLACK); + + g2Legend.drawString(legendName.substring(0, legendName.indexOf("-")), (int) (10) + width+10, (int) (15*i)+10+20); + } + } + +/* g2d.drawString("0", (int) bounds.getMaxX()/2+20 + width+10, 0); + g2d.drawString("50", (int) bounds.getMaxX()/2+20 + width+10, 50); + g2d.drawString("100", (int) bounds.getMaxX()/2+20 + width+10, 100); + g2d.drawString("200", (int) bounds.getMaxX()/2+20 + width+10, 200); + g2d.drawString("400", (int) bounds.getMaxX()/2+20 + width+10, 400); + g2d.drawString("600", (int) bounds.getMaxX()/2+20 + width+10, 600); +*/ +// g2d.setFont(NovaMap.TEXT_FONT); +// g2d.setColor(Color.BLACK); + if(nvl(map.getDataLoaded()).trim().length() > 0) { + g2d.setColor(Color.WHITE); + g2d.fill3DRect(new Double(bounds.getMinX()).intValue(), new Double(bounds.getMaxY()).intValue()-30, (int) bounds.getWidth() , (int)(30) , true); // (int)(bounds.getMaxX()*0.9)- (int)(bounds.getMaxX()*0.25) + g2d.setColor(Color.RED); + g2d.setFont(NovaMap.HEADER_FONT); + g2d.drawString(Globals.getUserDefinedMessageForMemoryLimitReached() + " "+ map.getDataLoaded()+ " were downloaded to Map.", new Double(bounds.getMinX()).intValue()+80, new Double(bounds.getMaxY()).intValue()-15); + } + + //g2d.drawString("Hello", new Double(bounds.getMinX()).intValue()+20, new Double(bounds.getMaxY()).intValue()-50); + FontMetrics metrics = g2d.getFontMetrics(); + + for (int i = 0; i < visibleLabel.size(); i++) { + String[] properties = visibleLabel.get(i).split(">>>"); + int x = Integer.parseInt(properties[1]) - metrics.stringWidth(properties[0]) / 2; + int y = Integer.parseInt(properties[2]) + Integer.parseInt(properties[3]) * 4 / 3; + g2d.drawString(properties[0], x, y); + } + + g2d.setColor(oldColor); + g2d.setStroke(oldStroke); + + return painted; + } + + private String nvl(String s) { + return (s == null) ? "" : s; + } +} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/Node.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/Node.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/Node.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/Node.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeCollection.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeCollection.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeCollection.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeCollection.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeInfo.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeInfo.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeInfo.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/node/NodeInfo.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/MapUtils.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/MapUtils.java new file mode 100644 index 00000000..b281c230 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/MapUtils.java @@ -0,0 +1,70 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.gmap.utils; + +import java.io.ObjectOutputStream; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + + + +public class MapUtils { + public static final short PLATE_CARREE_PROJECTION = 0; + public static final short WEB_MERCATOR_PROJECTION = 1; + + + + private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new java.text.SimpleDateFormat("yyyy/MM"); + + + + public static String getModifiedMarketID(String marketID) { + String modifiedMarketID = marketID.replaceAll("/", "_"); + modifiedMarketID = modifiedMarketID.replaceAll(" ", "_"); + return modifiedMarketID; + } + + /** + * increment or decrement + * @param currentYearMonth + * @param value - positive value will increment, otherwise decrement + * @return null if not valid number (must be between 2008/01 to 2010/12) + */ + + +/* public static void saveColor(HttpServletRequest request, DomainService domainService, + String type, String colorValue) { +// String userID = Integer.toString(UserUtils.getUserId(request)); +// MapColorPK colorPK = new MapColorPK(); +// MapColorVO colorVO = new MapColorVO(); +// +// colorPK.setUserID(userID); +// colorPK.setPrefID(type); +// colorVO.setMapColorPK(colorPK); +// colorVO.setColorValue(colorValue); +// +// domainService.saveDomainObject(colorVO); + } */ +} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/SwingWorker.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/SwingWorker.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/SwingWorker.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/SwingWorker.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/DataCache.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/DataCache.java new file mode 100644 index 00000000..2757c595 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/DataCache.java @@ -0,0 +1,516 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model; + +import java.util.*; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.error.ReportSQLException; +import org.openecomp.portalsdk.analytics.model.base.*; +import org.openecomp.portalsdk.analytics.model.definition.*; +import org.openecomp.portalsdk.analytics.model.runtime.*; +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class DataCache extends org.openecomp.portalsdk.analytics.RaptorObject { + private static Vector dataViewActions = null; + + private static Vector publicReportIdNames = null; + + private static Vector privateReportIdNames = null; + + private static Vector groupReportIdNames = null; + + private static Vector reportTableSources = null; + + private static Vector reportTableJoins = null; + + private static HashMap reportTableDbColumns = new HashMap(); + + private static HashMap reportFieldDbLookups = null; + + public DataCache() { + } + + public static Vector getDataViewActions() throws RaptorException { + if (dataViewActions == null) + /* try */{ + dataViewActions = new Vector(); + + //DataSet ds = DbUtils + // .executeQuery("SELECT ts.web_view_action FROM cr_table_source ts WHERE ts.web_view_action IS NOT NULL"); + + String sql = Globals.getTheDataViewActions(); + DataSet ds = DbUtils + .executeQuery(sql); + + for (int i = 0; i < ds.getRowCount(); i++) + dataViewActions.add(ds.getString(i, 0)); + } // catch(Exception e) {} + + return dataViewActions; + } // getDataViewActions + + public static Vector getPublicReportIdNames() throws RaptorException { + // if(publicReportIdNames==null) => needs to be up-to-date at any time + /* try */{ + publicReportIdNames = new Vector(); + + //DataSet ds = DbUtils + // .executeQuery("SELECT rep_id, title FROM cr_report WHERE public_yn = 'Y' ORDER BY title"); + + String sql = Globals.getThePublicReportIdNames(); + DataSet ds = DbUtils + .executeQuery(sql); + for (int i = 0; i < ds.getRowCount(); i++) + publicReportIdNames + .add(new IdNameValue(ds.getString(i, 0), ds.getString(i, 1))); + } // catch(Exception e) {} + + return publicReportIdNames; + } // getPublicReportIdNames + + public static Vector getPrivateAccessibleReportIdNames(String user_id, Vector userRoles) throws RaptorException { + // if(publicReportIdNames==null) => needs to be up-to-date at any time + /* try */{ + privateReportIdNames = new Vector(); + + // StringBuffer query = new StringBuffer(" SELECT cr.rep_id, cr.title FROM cr_report cr "); + String sql = Globals.getThePrivateAccessibleNamesA(); + //query.append(" WHERE cr.rep_id not in (select rep_id from cr_report_access cra where user_id = '"+ user_id+"' "); + sql = sql.replace("[user_id]", user_id); + StringBuffer query = new StringBuffer(sql); + for (int i = 0; i < userRoles.size(); i++) { + if( i == 0){ + // query.append(" OR role_id in ("); + query.append(Globals.getThePrivateAccessibleNamesIf()); + } + if(i < (userRoles.size()-1)) + query.append((String)userRoles.get(i) + ","); + + else if(i == (userRoles.size()-1)) + query.append((String)userRoles.get(i)+")"); + + } + //query.append(" ) "); + //query.append(" AND public_yn = 'N' and cr.owner_id = '"+ user_id+"' order by 2 "); + sql = Globals.getThePrivateAccessibleNamesB(); + sql = sql.replace("[user_id]", user_id); + query.append(sql); + + DataSet ds = DbUtils + .executeQuery(query.toString() ); + + for (int i = 0; i < ds.getRowCount(); i++) + privateReportIdNames + .add(new IdNameValue(ds.getString(i, 0), ds.getString(i, 1))); + } // catch(Exception e) {} + + return privateReportIdNames; + } // getPrivateAccessibleReportIdNames + + + public static Vector getGroupAccessibleReportIdNames(String user_id, Vector userRoles) throws RaptorException { + // if(publicReportIdNames==null) => needs to be up-to-date at any time + /* try */{ + groupReportIdNames = new Vector(); + + //StringBuffer query = new StringBuffer(" SELECT cr.rep_id, cr.title FROM cr_report cr "); + //query.append(" WHERE cr.rep_id in (select rep_id from cr_report_access cra where user_id = '"+ user_id+"' "); + String sql = Globals.getTheGroupAccessibleNamesA(); + sql = sql.replace("[user_id]", user_id); + StringBuffer query = new StringBuffer(sql); + + for (int i = 0; i < userRoles.size(); i++) { + if( i == 0) + query.append(Globals.getThePrivateAccessibleNamesIf()); + if(i < (userRoles.size()-1)) + query.append((String)userRoles.get(i) + ","); + else if(i == (userRoles.size()-1)) + query.append((String)userRoles.get(i)+")"); + + } + //query.append(" ) "); + //query.append(" AND public_yn = 'N' order by 2 "); + + query.append(Globals.getTheGroupAccessibleNamesB()); + DataSet ds = DbUtils + .executeQuery(query.toString() ); + + for (int i = 0; i < ds.getRowCount(); i++) + groupReportIdNames + .add(new IdNameValue(ds.getString(i, 0), ds.getString(i, 1))); + } // catch(Exception e) {} + + return groupReportIdNames; + } // getGroupAccessibleReportIdNames + + + public static TableSource getTableSource(String tableName, String dBinfo, Vector userRoles, String userId, HttpServletRequest request) throws RaptorException { + try { + Vector tableSources = null; + if(Globals.getRestrictTablesByRole()) { + tableSources = getReportTableSources(userRoles, dBinfo, userId, request); + } else { + tableSources = getReportTableSources(dBinfo); + } + for (Iterator iter = getReportTableSources(dBinfo).iterator(); iter.hasNext();) { + TableSource tableSource = (TableSource) iter.next(); + if (tableSource.getTableName().equals(tableName)) + return tableSource; + } // for + } catch (RaptorException e) { + throw new RaptorException(e.getMessage(), e.getCause()); + } + + return null; + } + public static void refreshReportTableSources() { + reportTableSources = null; + } + + public static Vector getReportTableSources(String dBInfo) throws RaptorException { + if (reportTableSources == null) + /* try */{ + reportTableSources = new Vector(); + //String query = " SELECT table_name, display_name, pk_fields, web_view_action, large_data_source_yn, filter_sql FROM cr_table_source "; + String query = Globals.getTheReportTableSourcesA(); + if (dBInfo != null && !dBInfo.equals(AppConstants.DB_LOCAL)){ + //query += " where SOURCE_DB= '" + dBInfo + "'"; + query+=Globals.getTheReportTableSourcesWhere(); + query = query.replace("[dBInfo]", dBInfo); + } + else { + //query += " where SOURCE_DB is null or SOURCE_DB = '" + AppConstants.DB_LOCAL + // + "'"; + query+=Globals.getTheReportTableSourcesIf(); + query = query.replace("[AppConstants.DB_LOCAL]", AppConstants.DB_LOCAL); + } + //query += " ORDER BY table_name "; + query+=Globals.getTheReportTableSourcesElse(); + DataSet ds = DbUtils.executeQuery(query); + for (int i = 0; i < ds.getRowCount(); i++) + reportTableSources.add(new TableSource(ds.getString(i, 0), ds.getString(i, 1), + ds.getString(i, 2), ds.getString(i, 3), ds.getString(i, 4), ds + .getString(i, 5))); + } // catch(Exception e) {} + + return reportTableSources; + } // getReportTableSources + + public static Vector getReportTableSources(Vector userRoles, String dBInfo, String userId, HttpServletRequest request) + throws RaptorException { + if (!Globals.getRestrictTablesByRole()) + return getReportTableSources(dBInfo); + Vector userTableSources = new Vector(); + if (userRoles.size() > 0) + /* try */{ + StringBuffer sb = new StringBuffer(); + for (Iterator iter = userRoles.iterator(); iter.hasNext();) { + sb.append((sb.length() == 0) ? "(" : ", "); + sb.append(iter.next()); + } // for + sb.append(")"); + //StringBuffer query = new StringBuffer("SELECT ts.table_name, ts.display_name, ts.pk_fields, "); + // query.append(" ts.web_view_action, ts.large_data_source_yn, ts.filter_sql FROM cr_table_source ts "); + // query.append (" WHERE "); + StringBuffer query = new StringBuffer(Globals.grabTheReportTableA()); + //if(!(AppUtils.isAdminUser(userId) || AppUtils.isSuperUser(userId))) + // query.append (" (EXISTS (SELECT 1 FROM cr_table_role tr WHERE tr.table_name=ts.table_name AND tr.role_id IN "+sb.toString()+")) and "); + //+ " OR (NOT EXISTS (SELECT 1 FROM cr_table_role tr WHERE tr.table_name=ts.table_name)) "; + if (dBInfo != null && !dBInfo.equals(AppConstants.DB_LOCAL)){ + String d_sql = Globals.grabTheReportTableIf(); + d_sql = d_sql.replace("[dBInfo]", dBInfo); + //query.append( " ts.SOURCE_DB= '" + dBInfo + "'"); + query.append(d_sql); + } + else{ + //query.append(" (ts.SOURCE_DB is null or ts.SOURCE_DB = '"+ AppConstants.DB_LOCAL + "')"); + String d_sql = Globals.grabTheReportTableElse(); + d_sql = d_sql.replace("[AppConstants.DB_LOCAL]", AppConstants.DB_LOCAL); + query.append(d_sql); + } + if(!(AppUtils.isAdminUser(request) || AppUtils.isSuperUser(request))) { + //query.append(" minus "); + + // query.append(" SELECT ts.table_name, ts.display_name, ts.pk_fields, ts.web_view_action, "); + // query.append(" ts.large_data_source_yn, ts.filter_sql from cr_table_source ts where "); + // query.append(" table_name in (select table_name from cr_table_role where role_id not IN "+sb.toString()+") and "); + String e_sql = Globals.grabTheReportTableB(); + e_sql = e_sql.replace("[sb.toString()]", sb.toString()); + query.append(e_sql); + + if (dBInfo != null && !dBInfo.equals(AppConstants.DB_LOCAL)){ + + // query.append( " ts.SOURCE_DB= '" + dBInfo + "'"); + String d_sql = Globals.grabTheReportTableIf(); + d_sql = d_sql.replace("[dBInfo]", dBInfo); + query.append(d_sql); + } + else{ + //query.append(" (ts.SOURCE_DB is null or ts.SOURCE_DB = '"+ AppConstants.DB_LOCAL + "')"); + String d_sql = Globals.grabTheReportTableElse(); + d_sql = d_sql.replace("[AppConstants.DB_LOCAL]", AppConstants.DB_LOCAL); + query.append(d_sql); + } + } + //query.append(" ORDER BY 1 "); + query.append(Globals.grabTheReportTableC()); + DataSet ds = DbUtils.executeQuery(query.toString()); + for (int i = 0; i < ds.getRowCount(); i++) + userTableSources.add(new TableSource(ds.getString(i, 0), ds.getString(i, 1), + ds.getString(i, 2), ds.getString(i, 3), ds.getString(i, 4), ds + .getString(i, 5))); + } // catch(Exception e) {} + + return userTableSources; + } // getReportTableSources + + public static Vector getReportTableJoins() throws RaptorException { + if (reportTableJoins == null) + /* try */{ + reportTableJoins = new Vector(); + + //DataSet ds = DbUtils + // .executeQuery("SELECT src_table_name, dest_table_name, join_expr FROM cr_table_join"); + DataSet ds = DbUtils + .executeQuery(Globals.getTheReportTableCrJoin()); + for (int i = 0; i < ds.getRowCount(); i++) + reportTableJoins.add(new TableJoin(ds.getString(i, 0), ds.getString(i, 1), ds + .getString(i, 2))); + } // catch(Exception e) {} + + return reportTableJoins; + } // getReportTableJoins + + public static Vector getReportTableJoins(Vector userRoles) throws RaptorException { + if (!Globals.getRestrictTablesByRole()) + return getReportTableJoins(); + + Vector userTableJoins = new Vector(); + if (userRoles.size() > 0) + /* try */{ + StringBuffer sb = new StringBuffer(); + for (Iterator iter = userRoles.iterator(); iter.hasNext();) { + sb.append((sb.length() == 0) ? "(" : ", "); + sb.append(iter.next()); + } // for + sb.append(")"); + + /*DataSet ds = DbUtils + .executeQuery("SELECT tj.src_table_name, tj.dest_table_name, tj.join_expr FROM cr_table_join tj " + + "WHERE ((EXISTS (SELECT 1 FROM cr_table_role trs WHERE trs.table_name=tj.src_table_name AND trs.role_id IN " + + sb.toString() + + ")) " + + "OR (NOT EXISTS (SELECT 1 FROM cr_table_role trs WHERE trs.table_name=tj.src_table_name))) " + + "AND ((EXISTS (SELECT 1 FROM cr_table_role trd WHERE trd.table_name=tj.dest_table_name AND trd.role_id IN " + + sb.toString() + + ")) " + + "OR (NOT EXISTS (SELECT 1 FROM cr_table_role trd WHERE trd.table_name=tj.dest_table_name)))");*/ + + + String f_sql = Globals.getTheReportTableJoins(); + f_sql = f_sql.replace("[sb.toString()]", sb.toString()); + + DataSet ds = DbUtils + .executeQuery(f_sql); + + for (int i = 0; i < ds.getRowCount(); i++) + userTableJoins.add(new TableJoin(ds.getString(i, 0), ds.getString(i, 1), ds + .getString(i, 2))); + } // catch(Exception e) {} + + return userTableJoins; + } // getReportTableJoins + + private static void processDollarFields(Vector tableDbColumns) { + int i = 0; + while (i < tableDbColumns.size()) { + DBColumnInfo dbci = (DBColumnInfo) tableDbColumns.get(i); + if (dbci.getColName().equals("DL$MONTH")) { + tableDbColumns.remove(i); + dbci.setLabel("Data Month/Year"); + tableDbColumns.add(0, dbci); + i++; + } else if (dbci.getColName().indexOf('$') >= 0) + tableDbColumns.remove(i); + else + i++; + } // while + } // processDollarFields + + private static String generateReportTableDbUserColumnSQL(String tableName) { + StringBuffer sb = new StringBuffer(); + // sb.append("SELECT a.table_name, a.column_name, a.data_type, a.label "); + //sb.append(" FROM user_column_def a "); + // sb.append("WHERE a.table_name = '" + tableName.toUpperCase() + "' "); + // sb.append("ORDER BY a.column_id"); + + String sql = Globals.getGenerateReportTableCol(); + sql = sql.replace("[tableName.toUpperCase()]", tableName.toUpperCase()); + sb.append(sql); + + return sb.toString(); + }//generateReportTableDbUserColumnSQL + private static String generateReportTableDbColumnsSQL(String tableName, String maskSql) { + StringBuffer sb = new StringBuffer(); + //sb.append("SELECT utc.table_name, utc.column_name, utc.data_type, "); + sb.append(Globals.getGenerateDbUserSqlA()); + if (maskSql == null){ + //sb.append("utc.column_name label "); + sb.append(Globals.getGenerateDbUserSqlIf()); + } + else{ + //sb.append("nvl(x.label, utc.column_name) label "); + //sb.append("FROM user_tab_columns utc "); + sb.append(Globals.getGenerateDbUserSqlElse()); + } + if (maskSql != null) { + sb.append(", ("); + sb.append(maskSql); + sb.append(") AS x "); + } + //sb.append("WHERE utc.table_name = '" + tableName.toUpperCase() + "' "); + String g_sql = Globals.getGenerateDbUserSqlB(); + g_sql = g_sql.replace("[tableName.toUpperCase()]", tableName.toUpperCase()); + sb.append(g_sql); + if (maskSql != null){ + //sb.append(" AND utc.table_name = x.table_name AND utc.column_name = x.column_name "); + sb.append(Globals.getGenerateDbUserSqlC()); + } + //sb.append("ORDER BY utc.column_id"); + sb.append(Globals.getGenerateDbUserSqlD()); + //System.out.println(sb.toString()); + return sb.toString(); + } // generateReportTableDbColumnsSQL + + public static synchronized Vector getReportTableDbColumns(String tableName, + String remoteDbPrefix) throws RaptorException { + Vector tableDbColumns = null; + if(reportTableDbColumns!=null) + tableDbColumns = (Vector) reportTableDbColumns.get(tableName); + else + reportTableDbColumns = new HashMap(); + if (tableDbColumns == null) + /* try */{ + tableDbColumns = new Vector(); + + String maskSql = AppUtils.getReportDbColsMaskSQL(); + DataSet ds = null; + if(Globals.getUserColDef()) { + try { + ds = ConnectionUtils.getDataSet( + generateReportTableDbUserColumnSQL(tableName),AppConstants.DB_LOCAL); + } + catch (ReportSQLException ex) { + throw new ReportSQLException("No Such Table. Please create table or make user_column_def in raptor.properties as \"false\""); + } + + } + else if(maskSql!=null){ + try { + ds = ConnectionUtils.getDataSet( + generateReportTableDbColumnsSQL(tableName, maskSql), remoteDbPrefix); + } + catch(ReportSQLException ex){ + throw new ReportSQLException("Field related table is not present in the database. Please make \"use_field_table\"" + + " as \"no\" in the raptor_app_.properties");} + } + if (ds==null || ds.getRowCount() == 0) { + // In case there are no records in the FIELDS table + ds = ConnectionUtils.getDataSet(generateReportTableDbColumnsSQL(tableName, + null), remoteDbPrefix); + } + for (int i = 0; i < ds.getRowCount(); i++) + tableDbColumns.add(new DBColumnInfo(ds.getString(i, 0), ds.getString(i, 1), ds + .getString(i, 2), ds.getString(i, 3))); + + processDollarFields(tableDbColumns); + reportTableDbColumns.put(tableName, tableDbColumns); + } // catch(Exception e) {} + + return tableDbColumns; + } // getReportTableDbColumns + + public static synchronized String getReportTableDbColumnType(String tableName, + String columnName, String dbInfo) throws RaptorException { + for (Iterator iter = getReportTableDbColumns(tableName, dbInfo).iterator(); iter + .hasNext();) { + DBColumnInfo dbCol = (DBColumnInfo) iter.next(); + if (dbCol.getColName().equals(columnName)) + return dbCol.getColType(); + } // for + + return null; + } // getReportTableDbColumnType + + public static synchronized LookupDBInfo getLookupTable(String tableName, String fieldName) throws RaptorException { + if (reportFieldDbLookups == null) + try { + String sql = AppUtils.getReportDbLookupsSQL(); + + if (sql != null) { + DataSet ds = DbUtils.executeQuery(sql); + reportFieldDbLookups = new HashMap(); + for (int i = 0; i < ds.getRowCount(); i++) { + String tName = ds.getString(i, 0); + String fName = ds.getString(i, 1); + reportFieldDbLookups.put(tName + '|' + fName, new LookupDBInfo(tName, + fName, ds.getString(i, 2), ds.getString(i, 3), ds.getString(i, + 4))); + } // for + } // if + } catch (Exception e) { throw new RaptorException(e.getMessage(), e.getCause()); + } + + LookupDBInfo lookupDBInfo = null; + if (reportFieldDbLookups != null) + lookupDBInfo = (LookupDBInfo) reportFieldDbLookups + .get(tableName + '|' + fieldName); + + if (lookupDBInfo == null) + lookupDBInfo = new LookupDBInfo(tableName, fieldName, tableName, fieldName, + fieldName); + + return lookupDBInfo; + } // getLookupTable + + // public static void setRemoteDBPrefix (String remoteDBPrefix) { + // _remoteDBPrefix = remoteDBPrefix; + // } + // + // public static String getRemoteDBPrefix () { + // return _remoteDBPrefix; + // } + + public static void refreshAll() { + DataCache.dataViewActions = null; + DataCache.privateReportIdNames = null; + DataCache.publicReportIdNames = null; + DataCache.reportFieldDbLookups = null; + DataCache.reportTableDbColumns = null; + DataCache.reportTableJoins = null; + DataCache.reportTableSources = null; + AppUtils.resetUserCache(); + } +} // DataCache + diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportHandler.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportHandler.java new file mode 100644 index 00000000..be950b99 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportHandler.java @@ -0,0 +1,6638 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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. + * ================================================================================ + */ +/* =========================================================================================== + * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) + * Raptor : This tool is used to generate different kinds of reports with lot of utilities + * =========================================================================================== + * + * ------------------------------------------------------------------------------------------- + * ReportHandler.java - This class is used to generate reports in Excel using POI and also to + * create ReportRuntime and ReportDefinition object using report id. + * ------------------------------------------------------------------------------------------- + * + * + * Changes + * ------- + * 18-Aug-2009 : Version 8.5.1 (Sundar);
  • request Object is passed to prevent caching user/roles - Datamining/Hosting.
+ * 14-Jul-2009 : Version 8.4 (Sundar);
  • Signature for generating excel method has been changed to add the report name as sheet name.
  • + *
  • Dashboard reports can be downloaded with each report as a separate sheet.
  • + *
+ * 08-Jun-2009 : Version 8.3 (Sundar);
  • Short datatype is replaced with default integer datatype to create + * row as short is not expoting more than 32768 rows.
+ * + */ +package org.openecomp.portalsdk.analytics.model; + +import java.io.BufferedInputStream; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeMap; +import java.util.Vector; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFCellStyle; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.hssf.usermodel.HSSFFont; +import org.apache.poi.hssf.usermodel.HSSFFooter; +import org.apache.poi.hssf.usermodel.HSSFHeader; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.hssf.util.Region; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Header; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellReference; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; +import org.apache.poi.xssf.usermodel.XSSFDataFormat; +import org.apache.poi.xssf.usermodel.XSSFFont; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.openecomp.portalsdk.analytics.controller.ErrorHandler; +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.error.ReportSQLException; +import org.openecomp.portalsdk.analytics.model.base.IdNameValue; +import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; +import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.system.ConnectionUtils; +import org.openecomp.portalsdk.analytics.system.ExecuteQuery; +import org.openecomp.portalsdk.analytics.system.Globals; +import org.openecomp.portalsdk.analytics.util.AppConstants; +import org.openecomp.portalsdk.analytics.util.DataSet; +import org.openecomp.portalsdk.analytics.util.ExcelColorDef; +import org.openecomp.portalsdk.analytics.util.HtmlStripper; +import org.openecomp.portalsdk.analytics.util.Log; +import org.openecomp.portalsdk.analytics.util.Utils; +import org.openecomp.portalsdk.analytics.view.ColumnHeader; +import org.openecomp.portalsdk.analytics.view.ColumnHeaderRow; +import org.openecomp.portalsdk.analytics.view.DataRow; +import org.openecomp.portalsdk.analytics.view.DataValue; +import org.openecomp.portalsdk.analytics.view.HtmlFormatter; +import org.openecomp.portalsdk.analytics.view.ReportData; +import org.openecomp.portalsdk.analytics.view.RowHeader; +import org.openecomp.portalsdk.analytics.view.RowHeaderCol; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; +import org.openecomp.portalsdk.analytics.xmlobj.DataSourceType; +import org.openecomp.portalsdk.analytics.xmlobj.FormatList; +import org.openecomp.portalsdk.analytics.xmlobj.FormatType; +import org.openecomp.portalsdk.analytics.xmlobj.Reports; +import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreList; +import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreType; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +import com.lowagie.text.Document; +import com.lowagie.text.Paragraph; +import com.lowagie.text.html.simpleparser.HTMLWorker; +import com.lowagie.text.html.simpleparser.StyleSheet; +import com.lowagie.text.pdf.PdfPTable; +//import javax.servlet.RequestDispatcher; + +public class ReportHandler extends org.openecomp.portalsdk.analytics.RaptorObject { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ReportHandler.class); + + public ReportHandler() { + } + + private String SHEET_NAME = ""; + private static final String XML_ENCODING = "UTF-8"; + private static int font_size = 10; + private static int font_header_title_size = 12; + private static int font_header_descr_size = 9; + private static int font_footer_size = 9; + + + private HashMap loadStyles(ReportRuntime rr, HSSFWorkbook wb) { + HSSFCellStyle styleDefault = wb.createCellStyle(); + //System.out.println("Load Styles"); + // Style default will be normal with no background + HSSFFont fontDefault = wb.createFont(); + // The default will be plain . + fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); + fontDefault.setFontHeight((short) (font_size / 0.05)); + fontDefault.setFontName("Tahoma"); + + styleDefault.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleDefault.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleDefault.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleDefault.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleDefault.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleDefault.setFillPattern(HSSFCellStyle.NO_FILL); + styleDefault.setFont(fontDefault); + + HSSFCellStyle styleRed = wb.createCellStyle(); + styleRed.cloneStyleFrom(styleDefault); + styleRed.setFillForegroundColor((short)HSSFColor.RED.index); + styleRed.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + HSSFFont fontRed = wb.createFont(); + fontRed.setColor((short) HSSFColor.WHITE.index); + fontRed.setFontHeight((short) (font_size / 0.05)); + fontRed.setFontName("Tahoma"); + styleRed.setFont(fontRed); + + HSSFCellStyle styleYellow = wb.createCellStyle(); + styleYellow.cloneStyleFrom(styleDefault); + styleYellow.setFillForegroundColor((short)HSSFColor.YELLOW.index); + styleYellow.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + HSSFFont fontYellow = wb.createFont(); + fontYellow.setColor((short) HSSFColor.BLACK.index); + fontYellow.setFontHeight((short) (font_size / 0.05)); + fontYellow.setFontName("Tahoma"); + styleYellow.setFont(fontYellow); + + HSSFCellStyle styleGreen = wb.createCellStyle(); + styleGreen.cloneStyleFrom(styleDefault); + styleGreen.setFillForegroundColor((short)HSSFColor.GREEN.index); + styleGreen.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + HSSFFont fontGreen = wb.createFont(); + fontGreen.setColor((short) HSSFColor.WHITE.index); + fontGreen.setFontHeight((short) (font_size / 0.05)); + fontGreen.setFontName("Tahoma"); + styleGreen.setFont(fontGreen); + + + ArrayList semColumnList = new ArrayList(); + List dsList = rr.getDataSourceList().getDataSource(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType element = (DataSourceType) iter.next(); + List dcList = element.getDataColumnList().getDataColumn(); + for (Iterator iterator = dcList.iterator(); iterator.hasNext();) { + DataColumnType element1 = (DataColumnType) iterator.next(); + semColumnList.add(element1.getSemaphoreId()); + + } + } + SemaphoreList semList = rr.getSemaphoreList(); + HashMap hashMapStyles = new HashMap(); + HashMap hashMapFonts = new HashMap(); + hashMapFonts.put("default", fontDefault); + hashMapFonts.put("red", fontRed); + hashMapFonts.put("yellow", fontYellow); + hashMapFonts.put("green", fontGreen); + hashMapStyles.put("default", styleDefault); + hashMapStyles.put("red", styleRed); + hashMapStyles.put("yellow", styleYellow); + hashMapStyles.put("green", styleGreen); + HSSFCellStyle cellStyle = null; + if (semList == null || semList.getSemaphore() == null) { + return hashMapStyles; + } else { + for (Iterator iter = semList.getSemaphore().iterator(); iter.hasNext();) { + SemaphoreType sem = (SemaphoreType) iter.next(); + if(!semColumnList.contains(sem.getSemaphoreId())) continue; + //System.out.println("SemphoreId ----> " + sem.getSemaphoreId()); + FormatList fList = sem.getFormatList(); + List formatList = fList.getFormat(); + for (Iterator fIter = formatList.iterator(); fIter.hasNext();) { + FormatType fmt = (FormatType) fIter.next(); + if(fmt!=null){ + //if (fmt.getLessThanValue().length() > 0) { + cellStyle = wb.createCellStyle(); + HSSFFont cellFont = wb.createFont(); + //System.out.println("Format Id " + fmt.getFormatId()); + if (nvl(fmt.getBgColor()).length() > 0) { +// System.out.println("Load Styles " + +// fmt.getFormatId() +// + " " +fmt.getBgColor() + " " + +// ExcelColorDef.getExcelColor(fmt.getBgColor())); + cellStyle.setFillForegroundColor(ExcelColorDef.getExcelColor(fmt + .getBgColor())); + cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + } + if (nvl(fmt.getFontColor()).length() > 0) { + cellFont.setColor(ExcelColorDef.getExcelColor(fmt.getFontColor())); + } else + cellFont.setColor((short) HSSFFont.COLOR_NORMAL); + if (fmt.isBold()) + cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + if (fmt.isItalic()) + cellFont.setItalic(true); + if (fmt.isUnderline()) + cellFont.setUnderline(HSSFFont.U_SINGLE); + if(nvl(fmt.getFontFace()).length()>0) + cellFont.setFontName(fmt.getFontFace()); + else + cellFont.setFontName("Tahoma"); + //cellFont.setFontHeight((short) (10 / 0.05)); + + if(nvl(fmt.getFontSize()).length()>0) { + try { + //cellFont.setFontHeight((short) (Integer.parseInt(fmt.getFontSize()) / 0.05)); + cellFont.setFontHeight((short) (font_size/0.05)); + } catch(NumberFormatException e){ + cellFont.setFontHeight((short) (font_size / 0.05));//10 + } + } + else + cellFont.setFontHeight((short) (font_size / 0.05)); + cellStyle.setFont(cellFont); + cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); + cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); + cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); + cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); + cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); + hashMapStyles.put(fmt.getFormatId(), cellStyle); + } else { + hashMapStyles.put(fmt.getFormatId(), styleDefault); + hashMapStyles.put("default", styleDefault); + } + } + + } + } + return hashMapStyles; + } + + private void paintExcelParams(HSSFWorkbook wb,int rowNum,int col,ArrayList paramsList, String customizedParamInfo, HSSFSheet sheet, String reportTitle, String reportDescr) throws IOException { + //HSSFSheet sheet = wb.getSheet(getSheetName()); + int cellNum = 0; + HSSFRow row = null; + short s1 = 0, s2 = (short) 1; + HtmlStripper strip = new HtmlStripper(); + // Name Style + HSSFCellStyle styleName = wb.createCellStyle(); + //styleName.setFillBackgroundColor(HSSFColor.GREY_80_PERCENT.index); + styleName.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index); + //styleName.setFillPattern(HSSFCellStyle.SPARSE_DOTS); + styleName.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleName.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleName.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleName.setBorderRight(HSSFCellStyle.BORDER_THIN); + styleName.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleName.setDataFormat((short)0); + HSSFFont font = wb.createFont(); + font.setFontHeight((short) (font_size / 0.05)); + font.setFontName("Tahoma"); + font.setColor(HSSFColor.BLACK.index); + font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + styleName.setFont(font); + //Data Style + + // Create some fonts. + HSSFFont fontDefault = wb.createFont(); + // Initialize the styles & fonts. + // The default will be plain . + fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); + fontDefault.setFontHeight((short) (font_size / 0.05)); + fontDefault.setFontName("Tahoma"); + fontDefault.setItalic(true); + // Style default will be normal with no background + HSSFCellStyle styleValue = wb.createCellStyle(); + styleValue.setDataFormat((short)0); + styleValue.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleValue.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleValue.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleValue.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleValue.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleValue.setFillForegroundColor(HSSFColor.YELLOW.index); + styleValue.setFillPattern(HSSFCellStyle.NO_FILL); + styleValue.setFont(fontDefault); + HSSFCell cell = null; + HSSFCellStyle styleDescription = wb.createCellStyle(); + styleDescription.setAlignment(HSSFCellStyle.ALIGN_CENTER); +// styleDescription.setBorderBottom(HSSFCellStyle.BORDER_THIN); +// styleDescription.setBorderTop(HSSFCellStyle.BORDER_THIN); +// styleDescription.setBorderRight(HSSFCellStyle.BORDER_THIN); +// styleDescription.setBorderLeft(HSSFCellStyle.BORDER_THIN); + HSSFFont fontDescr = wb.createFont(); + fontDescr.setFontHeight((short) (font_size / 0.05)); //14 + fontDescr.setFontName("Tahoma"); + fontDescr.setColor(HSSFColor.BLACK.index); + fontDescr.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + styleDescription.setFont(font); + HSSFCell cellDescr = null; + int paramSeq = 0; + HSSFHeader header = sheet.getHeader(); + StringBuffer strBuf = new StringBuffer(); + if(!Globals.customizeFormFieldInfo() || customizedParamInfo.length()<=0) { + for (Iterator iter = paramsList.iterator(); iter.hasNext();) { + IdNameValue value = (IdNameValue) iter.next(); + //System.out.println("\"" + value.getId() + " = " + value.getName() + "\""); + if(nvl(value.getId()).trim().length()>0 && (!nvl(value.getId()).trim().equals("BLANK"))) { + paramSeq += 1; + if(paramSeq <= 1) { + row = sheet.createRow(++rowNum); + cell = row.createCell((short) 0); + sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); + cellDescr = row.createCell((short) 0); + cellDescr.setCellValue("Run-time Parameters"); + cellDescr.setCellStyle(styleDescription); + + + strBuf.append(reportTitle+"\n"); + //strBuf.append("Run-time Parameters\n"); + } + row = sheet.createRow(++rowNum); + cellNum = 0; + //System.out.println("RowNum " + rowNum + " " + value.getId() + " " +value.getName()); + cell = row.createCell((short) cellNum); + cell.setCellValue(value.getId()); + cell.setCellStyle(styleName); + cellNum += 1; + cell = row.createCell((short) cellNum); + cell.setCellValue(value.getName().replaceAll("~",",")); + cell.setCellStyle(styleValue); + + //strBuf.append(value.getId()+": "+ value.getName()+"\n"); + } + } //for + } else { + strBuf.append(reportTitle+"\n"); + Document document = new Document(); + document.open(); + HTMLWorker worker = new HTMLWorker(document); + StyleSheet style = new StyleSheet(); + style.loadTagStyle("body", "leading", "16,0"); + ArrayList p = HTMLWorker.parseToList(new StringReader(customizedParamInfo), style); + String name = ""; + String token = ""; + String value = ""; + String s = ""; + PdfPTable pdfTable = null; + for (int k = 0; k < p.size(); ++k){ + if(p.get(k) instanceof Paragraph) + s = ((Paragraph)p.get(k)).toString(); + else { /*if ((p.get(k) instanceof PdfPTable))*/ + pdfTable = ((PdfPTable)p.get(k)); + } + //todo: Logic for parsing pdfTable should be added after upgrading to iText 5.0.0 + //s = Utils.replaceInString(s, ",", "|"); + s = s.replaceAll(",", "|"); + s = s.replaceAll("~", ","); + if(s.indexOf(":")!= -1) { + //System.out.println("|"+s+"|"); + row = sheet.createRow(++rowNum); + cell = row.createCell((short) 0); + sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); + cellDescr = row.createCell((short) 0); + cellDescr.setCellValue("Run-time Parameters"); + cellDescr.setCellStyle(styleDescription); + + //strBuf.append("Run-time Parameters\n"); + StringTokenizer st = new StringTokenizer(s.trim(), "|"); + while(st.hasMoreTokens()) { + token = st.nextToken(); + token = token.trim(); + if (!(token.trim().equals("|") || token.trim().equals("]]") || token.trim().equals("]") || token.trim().equals("[") )) { + if(token.endsWith(":")) { + name = token; + name = name.substring(0, name.length()-1); + if(name.startsWith("[")) + name = name.substring(1); + value = st.nextToken(); + if(nvl(value).endsWith("]"))value = nvl(value).substring(0, nvl(value).length()-1); + } /*else if(name != null && name.length() > 0) { + value = st.nextToken(); + if(value.endsWith("]]"))value = value.substring(0, value.length()-1); + }*/ + if(name!=null && name.trim().length()>0) { + row = sheet.createRow((short) ++rowNum); + cellNum = 0; + cell = row.createCell((short) cellNum); + cell.setCellValue(name.trim()); + cell.setCellStyle(styleName); + cellNum += 1; + cell = row.createCell((short) cellNum); + cell.setCellValue(value.trim()); + cell.setCellStyle(styleValue); + //strBuf.append(name.trim()+": "+ value.trim()+"\n"); + } +/* if(token.endsWith(":") && (value!=null && value.trim().length()<=0) && (name!=null && name.trim().length()>0 && name.endsWith(":"))) { + name = name.substring(0, name.indexOf(":")+1); + //value = token.substring(token.indexOf(":")+1); + row = sheet.createRow((short) ++rowNum); + cellNum = 0; + cell = row.createCell((short) cellNum); + cell.setCellValue(name.trim()); + cell.setCellStyle(styleName); + cellNum += 1; + cell = row.createCell((short) cellNum); + cell.setCellValue(value.trim()); + cell.setCellStyle(styleValue); + + //strBuf.append(name.trim()+": "+ value.trim()+"\n"); + value = ""; + name = ""; + } +*/ } + int cw = 0; + cw = name.trim().length() + 12; + // if(i!=cellWidth.size()-1) + if(sheet.getColumnWidth((short)0)< (short) name.trim().length()) + sheet.setColumnWidth((short)0, (short) name.trim().length()); + if(sheet.getColumnWidth((short)1)< (short) value.trim().length()) + sheet.setColumnWidth((short)1, (short) value.trim().length()); + name = ""; + value = ""; + + } + + try { + SimpleDateFormat oracleDateFormat = new SimpleDateFormat("MM/dd/yyyy kk:mm:ss"); + Date sysdate = oracleDateFormat.parse(ReportLoader.getSystemDateTime()); + SimpleDateFormat dtimestamp = new SimpleDateFormat(Globals.getScheduleDatePattern()); + + row = sheet.createRow((short) ++rowNum); + cellNum = 0; + cell = row.createCell((short) cellNum); + cell.setCellValue("Report Date/Time"); + cell.setCellStyle(styleName); + cellNum += 1; + cell = row.createCell((short) cellNum); + + cell.setCellValue(dtimestamp.format(sysdate)+" "+Globals.getTimeZone()); + cell.setCellStyle(styleValue); + + } catch(Exception ex) { + //ex.printStackTrace(); + } + + + } + } + + +/* Iterator iter1 = paramsList.iterator(); + s1 = 0; s2 = (short)10; + if(iter1.hasNext()) { + row = sheet.createRow((short) ++rowNum); + cellNum = 0; + cell = row.createCell((short) cellNum); + sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); + cell.setCellValue(strip.stripHtml(customizedParamInfo)); + } +*/ +/* rowNum += 2; + row = sheet.createRow(rowNum);*/ + } // if + Iterator iterCheck = paramsList.iterator(); + if(iterCheck.hasNext()) { + rowNum += 2; + row = sheet.createRow(rowNum); + } + header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) 9)+" " + strBuf.toString()); + HSSFFooter footer = sheet.getFooter(); + footer.setLeft(HSSFFooter.font("Tahoma", "")+ HSSFFooter.fontSize((short) 9)+ "Page " + HSSFFooter.page() + + " of " + HSSFFooter.numPages() ); + footer.setCenter(HSSFFooter.font("Tahoma", "")+ HSSFFooter.fontSize((short) 9)+Globals.getFooterFirstLine()+"\n"+Globals.getFooterSecondLine()); + + } + + + + private int paintExcelData(HSSFWorkbook wb, int rowNum, int col, ReportData rd, + HashMap styles, ReportRuntime rr, HSSFSheet sheet, String sql_whole, OutputStream sos, HttpServletRequest request) throws RaptorException { + int mb = 1024*1024; + Runtime runtime = Runtime.getRuntime(); + int returnValue = 0; + // HSSFSheet sheet = wb.getSheetAt(0); + HSSFCellStyle styleDefault = wb.createCellStyle(); + HSSFCellStyle styleNumber = wb.createCellStyle(); + HSSFCellStyle styleDecimalNumber = wb.createCellStyle(); + HSSFCellStyle styleCurrencyNumber = wb.createCellStyle(); + HSSFCellStyle styleCurrencyDecimalNumber = wb.createCellStyle(); + HSSFCellStyle styleDate = wb.createCellStyle(); + HtmlStripper strip = new HtmlStripper(); + //HSSFSheet sheet = wb.getSheet(getSheetName()); + HSSFCellStyle styleDataHeader = wb.createCellStyle(); + // style.setFillBackgroundColor(HSSFColor.AQUA.index); + styleDataHeader.setFillForegroundColor(HSSFColor.GREY_40_PERCENT.index); + styleDataHeader.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + styleDataHeader.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleDataHeader.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleDataHeader.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleDataHeader.setBorderRight(HSSFCellStyle.BORDER_THIN); + styleDataHeader.setBorderLeft(HSSFCellStyle.BORDER_THIN); + HSSFFont font = wb.createFont(); + font.setFontHeight((short) (font_size / 0.05)); + font.setFontName("Tahoma"); + font.setColor(HSSFColor.BLACK.index); + styleDataHeader.setFont(font); + // Column Header + boolean firstPass = true; + ArrayList cellWidth = new ArrayList(); + java.util.HashMap dataTypeMap = new java.util.HashMap(); + int cellNum = 0; + rowNum += 0; + ColumnHeaderRow chr = null; + String title = ""; + +// System.out.println("***************** Size " + rd.reportColumnHeaderRows.size()); +// for (int i = 0; i < rd.reportColumnHeaderRows.size(); i++) { +// for (int j = 0; j < rd.reportColumnHeaderRows.getColumnHeaderRow(i).size(); j++) { +// System.out.println("Column Title " + rd.reportColumnHeaderRows.getColumnHeaderRow(i).getColumnHeader(j).getColumnTitle() +// + " " + rd.reportColumnHeaderRows.getColumnHeaderRow(i).getColumnHeader(j).isVisible()); +// } +// } +/* List dsList = rr.getDataSourceList().getDataSource(); + HashMap dataColumnTypeHashMap = new HashMap(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType element = (DataSourceType) iter.next(); + List dcList = element.getDataColumnList().getDataColumn(); + for (Iterator iterator = dcList.iterator(); iterator.hasNext();) { + DataColumnType element1 = (DataColumnType) iterator.next(); + dataTypeMap.put(element1.getColId(), element1.getColType()); + dataColumnTypeHashMap.put(element1.getColName(), element1); + } + } +*/ + int columnRows = rr.getVisibleColumnCount() - 1; + + HttpSession session = request.getSession(); + String drilldown_index = (String) session.getAttribute("drilldown_index"); + int index = 0; + try { + index = Integer.parseInt(drilldown_index); + } catch (NumberFormatException ex) { + index = 0; + } + String header = (String) session.getAttribute("TITLE_"+index); + String subtitle = (String) session.getAttribute("SUBTITLE_"+index); + if(nvl(header).length()>0) { + header = Utils.replaceInString(header, "
", " "); + header = Utils.replaceInString(header, "
", " "); + header = Utils.replaceInString(header, "
", " "); + header = strip.stripHtml(nvl(header).trim()); + subtitle = Utils.replaceInString(subtitle, "
", " "); + subtitle = Utils.replaceInString(subtitle, "
", " "); + subtitle = Utils.replaceInString(subtitle, "
", " "); + subtitle = strip.stripHtml(nvl(subtitle).trim()); + HSSFRow row = sheet.createRow(rowNum); + cellNum = 0; + row.createCell((short) cellNum).setCellValue(header); + sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); + rowNum += 1; + row = sheet.createRow(rowNum); + cellNum = 0; + row.createCell((short) cellNum).setCellValue(subtitle); + sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); + rowNum += 1; + } + + for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { + HSSFRow row = sheet.createRow(rowNum); + cellNum = -1; + /*if(rd.reportTotalRowHeaderCols!=null) { + cellNum +=1; + row.createCell((short) cellNum).setCellValue("Total"); + row.createCell((short) cellNum).setCellStyle(styleDataHeader); + //row.getCell((short) cellNum).setCellStyle(styleDataHeader); + }*/ + chr = rd.reportColumnHeaderRows.getNext(); + + if(nvl(sql_whole).length() <= 0 || (!rr.getReportType().equals(AppConstants.RT_LINEAR))) { + if(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) + rd.reportRowHeaderCols.resetNext(0); + else + rd.reportRowHeaderCols.resetNext(1); + + for (; rd.reportRowHeaderCols.hasNext();) { + cellNum += 1; + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + + if (firstPass) { + title = rhc.getColumnTitle(); + title = Utils.replaceInString(title,"_nl_", " \n"); + row.createCell((short) cellNum).setCellValue(title); + //commented after bug reported by EPAT 01/17/2015 + //sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum+columnRows, (short) (cellNum))); + //System.out.println(" **************** Row Header Title " + rhc.getColumnTitle() + " " + cellNum + " " ); + //System.out.println(cellNum + " " + cellWidth.size()); + if (cellWidth.size() > 0 && cellWidth.size() > cellNum) { + if (((Integer) cellWidth.get(cellNum)).intValue() < rhc + .getColumnTitle().length()) + cellWidth.set(cellNum, new Integer(title.length())); + } else + cellWidth.add(cellNum, new Integer(title.length())); + row.getCell((short) cellNum).setCellStyle(styleDataHeader); + } + + + } // for + + } + + firstPass = false; + +/* for(chr.resetNext(); chr.hasNext(); ) { + ColumnHeader ch = chr.getNext(); + if(ch.isVisible()) { + cellNum += 1; + row.createCell((short) cellNum).setCellValue(ch.getColumnTitle()); +// <%= ch.getColSpanHtml() %><%= ch.getRowSpanHtml() %>> +// <%= ch.getColumnTitleHtml() %> +// + } // if + } // for +*/ + + //cellNum = -1; + + +// Set mapSet = dataTypeMap.entrySet(); +// Map.Entry me; +// String element, value ; +// for (Iterator iter = mapSet.iterator(); iter.hasNext();) { +// me=(Map.Entry)iter.next(); +// element = (String) me.getKey(); +// value = (String) me.getValue(); +// System.out.println("DataTypeMap " + element + " " + value); +// } + + for (chr.resetNext(); chr.hasNext();) { + ColumnHeader ch = chr.getNext(); + if(ch.isVisible()) { + cellNum += 1; + + int colSpan = ch.getColSpan()-1; + title = ch.getColumnTitle(); + title = Utils.replaceInString(title,"_nl_", " \n"); + row.createCell((short) cellNum).setCellValue(title); + if(colSpan > 0) { + for ( int k = 1; k <= colSpan; k++ ) { + row.createCell((short) cellNum+k); + } + sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (cellNum+colSpan))); + } + + + +/* if (cellWidth.size() > cellNum) { + if (((Integer) cellWidth.get(cellNum)).intValue() < ch + .getColumnTitle().length()) + cellWidth + .set((cellNum), new Integer(ch.getColumnTitle().length())); + } else + cellWidth.add((cellNum), new Integer(ch.getColumnTitle().length())); +*/ row.getCell((short) (cellNum)).setCellStyle(styleDataHeader); + for ( int k = 1; k <= colSpan; k++ ) { + row.getCell((short) (cellNum+k)).setCellStyle(styleDataHeader); + } + + if(colSpan > 0) + cellNum += colSpan; + } + } // for + +/* int cw = 0; + for (int i = 0; i < cellWidth.size(); i++) { + cw = ((Integer) cellWidth.get(i)).intValue() + 6; + sheet.setColumnWidth((short) (i), (short) ((cw * 8) / ((double) 1 / 20))); + } +*/ + rowNum += 1; + } // for + + + // Data + // Create some cell styles. + //HSSFCellStyle styleDefault = wb.createCellStyle(); + HSSFCellStyle styleCell = null; + + HSSFCellStyle styleTotal = wb.createCellStyle(); + HSSFCellStyle styleCurrencyTotal = wb.createCellStyle(); + HSSFCellStyle styleDefaultTotal = wb.createCellStyle(); + HSSFCellStyle styleCurrencyDecimalNumberTotal = wb.createCellStyle(); + HSSFCellStyle styleDecimalNumberTotal = wb.createCellStyle(); + HSSFCellStyle styleCurrencyNumberTotal = wb.createCellStyle(); + + + // Create some fonts. + HSSFFont fontDefault = wb.createFont(); + HSSFFont fontBold = wb.createFont(); + // Initialize the styles & fonts. + // The default will be plain . + fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); + fontDefault.setFontHeight((short) (font_size / 0.05)); + fontDefault.setFontName("Tahoma"); + + // The default will be bold black tachoma 10pt text. + fontBold.setColor((short) HSSFFont.COLOR_NORMAL); + fontBold.setFontHeight((short) (font_size / 0.05)); + fontBold.setFontName("Tahoma"); + fontBold.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + // Style default will be normal with no background + styleDefault.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleDefault.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleDefault.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleDefault.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleDefault.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleDefault.setFillPattern(HSSFCellStyle.NO_FILL); + styleDefault.setFont(fontDefault); + styleDefault.setWrapText(true); + //Number + styleNumber.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleNumber.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleNumber.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleNumber.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleNumber.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleNumber.setFillPattern(HSSFCellStyle.NO_FILL); + styleNumber.setFont(fontDefault); + try { + styleNumber.setDataFormat((short)0x26);//HSSFDataFormat.getBuiltinFormat("(#,##0_);[Red](#,##0)")); + } catch (Exception e) { + + } + //Decimal Number + styleDecimalNumber.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleDecimalNumber.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleDecimalNumber.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleDecimalNumber.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleDecimalNumber.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleDecimalNumber.setFillPattern(HSSFCellStyle.NO_FILL); + styleDecimalNumber.setFont(fontDefault); + styleDecimalNumber.setDataFormat((short)0x27);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); + + //Decimal Number + styleDecimalNumberTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleDecimalNumberTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleDecimalNumberTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleDecimalNumberTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleDecimalNumberTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleDecimalNumberTotal.setFillPattern(HSSFCellStyle.NO_FILL); + styleDecimalNumberTotal.setFont(fontBold); + styleDecimalNumberTotal.setDataFormat((short)0x27);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); + + //CurrencyNumber + styleCurrencyDecimalNumber.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleCurrencyDecimalNumber.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleCurrencyDecimalNumber.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleCurrencyDecimalNumber.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleCurrencyDecimalNumber.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleCurrencyDecimalNumber.setFillPattern(HSSFCellStyle.NO_FILL); + styleCurrencyDecimalNumber.setFont(fontDefault); + styleCurrencyDecimalNumber.setDataFormat((short)8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); + + //currency number bold + styleCurrencyDecimalNumberTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleCurrencyDecimalNumberTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleCurrencyDecimalNumberTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleCurrencyDecimalNumberTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleCurrencyDecimalNumberTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleCurrencyDecimalNumberTotal.setFillPattern(HSSFCellStyle.NO_FILL); + styleCurrencyDecimalNumberTotal.setFont(fontBold); + styleCurrencyDecimalNumberTotal.setDataFormat((short)8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); + + + //CurrencyNumber + styleCurrencyNumber.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleCurrencyNumber.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleCurrencyNumber.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleCurrencyNumber.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleCurrencyNumber.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleCurrencyNumber.setFillPattern(HSSFCellStyle.NO_FILL); + styleCurrencyNumber.setFont(fontDefault); + styleCurrencyNumber.setDataFormat((short) 6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); + + + //CurrencyNumber + styleCurrencyNumberTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleCurrencyNumberTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleCurrencyNumberTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleCurrencyNumberTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleCurrencyNumberTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleCurrencyNumberTotal.setFillPattern(HSSFCellStyle.NO_FILL); + styleCurrencyNumberTotal.setFont(fontBold); + styleCurrencyNumberTotal.setDataFormat((short) 6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); + + //Date + styleDate.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleDate.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleDate.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleDate.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleDate.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleDate.setFillPattern(HSSFCellStyle.NO_FILL); + styleDate.setFont(fontDefault); + styleDate.setDataFormat((short)0xe);//HSSFDataFormat.getBuiltinFormat("m/d/yy")); + + // Style for Total will be Bold with normal font with no background + styleTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleTotal.setFillPattern(HSSFCellStyle.NO_FILL); + styleTotal.setDataFormat((short)0x28);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); + styleTotal.setFont(fontBold); + + styleCurrencyTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleCurrencyTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleCurrencyTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleCurrencyTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleCurrencyTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleCurrencyTotal.setFillPattern(HSSFCellStyle.NO_FILL); + styleCurrencyTotal.setDataFormat((short)8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); + styleCurrencyTotal.setFont(fontBold); + + styleDefaultTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleDefaultTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleDefaultTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleDefaultTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleDefaultTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleDefaultTotal.setFillPattern(HSSFCellStyle.NO_FILL); + styleDefaultTotal.setDataFormat((short)0x28); + ////styleDefaultTotal.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); + styleDefaultTotal.setFont(fontBold); + + firstPass = true; + // Declare a row object reference. + HSSFRow row = null; + // Declare a cell object reference. + HSSFCell cell = null; + //HSSFCell cellNumber = null; + //HSSFCell cellCurrencyNumber = null; + //HSSFCell cellDate = null; + + //All the possible combinations of date format + SimpleDateFormat MMDDYYYYFormat = new SimpleDateFormat("MM/dd/yyyy"); + SimpleDateFormat YYYYMMDDFormat = new SimpleDateFormat("yyyy/MM/dd"); + SimpleDateFormat MONYYYYFormat = new SimpleDateFormat("MMM yyyy"); + SimpleDateFormat MMYYYYFormat = new SimpleDateFormat("MM/yyyy"); + SimpleDateFormat MMMMMDDYYYYFormat = new SimpleDateFormat("MMMMM dd, yyyy"); + SimpleDateFormat YYYYMMDDDASHFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat DDMONYYYYFormat = new SimpleDateFormat("dd-MMM-yyyy"); + SimpleDateFormat MONTHYYYYFormat = new SimpleDateFormat("MMMMM, yyyy"); + SimpleDateFormat MMDDYYYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + SimpleDateFormat MMDDYYYYHHMMFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm"); + SimpleDateFormat YYYYMMDDHHMMSSFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + SimpleDateFormat YYYYMMDDHHMMFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); + SimpleDateFormat DDMONYYYYHHMMSSFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); + SimpleDateFormat DDMONYYYYHHMMFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); + SimpleDateFormat DDMONYYHHMMFormat = new SimpleDateFormat("dd-MMM-yy HH:mm"); + SimpleDateFormat MMDDYYFormat = new SimpleDateFormat("MM/dd/yy"); + SimpleDateFormat MMDDYYHHMMFormat = new SimpleDateFormat("MM/dd/yy HH:mm"); + SimpleDateFormat MMDDYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); + SimpleDateFormat MMDDYYYYHHMMZFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm z"); + SimpleDateFormat MMMMMDDYYYYHHMMSS = new SimpleDateFormat("MMMMM-dd-yyyy HH:mm:ss"); + + + + + ResultSet rs = null; + Connection conn = null; + Statement st = null; + ResultSetMetaData rsmd = null; + CreationHelper createHelper = wb.getCreationHelper(); + + if(nvl(sql_whole).length() >0 && rr.getReportType().equals(AppConstants.RT_LINEAR)) { + try { + conn = ConnectionUtils.getConnection(rr.getDbInfo()); + st = conn.createStatement(); + System.out.println("************* Map Whole SQL *************"); + System.out.println(sql_whole); + System.out.println("*****************************************"); + rs = st.executeQuery(sql_whole); + rsmd = rs.getMetaData(); + int numberOfColumns = rsmd.getColumnCount(); + HashMap colHash = new HashMap(); + DataRow dr = null; + int j = 0; + int rowCount = 0; + while(rs.next()) { + rowCount++; + row = sheet.createRow(rowNum); + cellNum = -1; + colHash = new HashMap(); + for (int i = 1; i <= numberOfColumns; i++) { + colHash.put(rsmd.getColumnLabel(i).toUpperCase(), strip.stripHtml(rs.getString(i))); + } + rd.reportDataRows.resetNext(); + dr = rd.reportDataRows.getNext(); + j = 0; + //if(rowCount%1000 == 0) wb.write(sos); + + /*if(rd.reportTotalRowHeaderCols!=null) { + //cellNum = -1; + //for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { + cellNum += 1; + //RowHeaderCol rhc = rd.reportRowHeaderCols.getRowHeaderCol(0); + //if (firstPass) + // rhc.resetNext(); + //RowHeader rh = rhc.getRowHeader(rowCount-1); + row.createCell((short) cellNum).setCellValue(rowCount); + row.getCell((short) cellNum).setCellStyle(styleDefault); + if (firstPass) + cellWidth.add(cellNum, new Integer((rowCount+"").length())); + else + cellWidth.set(cellNum, new Integer((rowCount+"").length())); + + //} // for + }*/ + firstPass = false; + //cellNum = -1; + for (dr.resetNext(); dr.hasNext();j++) { + //for (chr.resetNext(); chr.hasNext();) { + //ColumnHeader ch = chr.getNext(); + styleCell = null; + DataValue dv = dr.getNext(); + HtmlFormatter htmlFormat = dv.getCellFormatter(); + if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) + styleCell = (HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default")); + if (htmlFormat != null && dv.getFormatId() != null && styles != null) + styleCell = (HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default")); + String value = nvl((String)colHash.get(dv.getColId().toUpperCase())); + + boolean bold = false; + + if(dv.isVisible()) { + cellNum += 1; + cell = row.createCell((short) cellNum); + //System.out.println("Stripping HTML 1"); + //cell.setCellValue(strip.stripHtml(dv.getDisplayValue())); + String dataType = (String) (dataTypeMap.get(dv.getColId())); + //System.out.println("Value " + value + " " + (( dataType !=null && dataType.equals("DATE")) || (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date"))) ); + if (dataType!=null && dataType.equals("NUMBER")){ + //cellNumber = row.createCell((short) cellNum); + //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + //cellNumber.setCellValue(dv.getDisplayValue()); + //cellCurrencyNumber = row.createCell((short) cellNum); + int zInt = 0; + if (value.equals("null")){ + cell.setCellValue(zInt); + }else{ + + if ((value.indexOf("."))!= -1){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + + //if (dv.getDisplayValue().startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempDollar = dv.getDisplayValue().trim(); + tempDollar = tempDollar.replaceAll(" ", "").substring(0); + tempDollar = tempDollar.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempDollar); + //System.out.println("Before copy Value |" + tempDollar); + //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); + //System.out.println("After copy Value |" + tempDollar); + if ((tempDollar.indexOf(","))!= -1){ + tempDollar = tempDollar.replaceAll(",", ""); + } + //System.out.println("The final string 1 is "+tempDollar); + double tempDoubleDollar = 0.0; + try { + tempDoubleDollar = Double.parseDouble(tempDollar); + if(styleCell!=null) { + styleCell.setDataFormat((short) 8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleCurrencyDecimalNumber); + cell.setCellValue(tempDoubleDollar); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + //cell.setCellStyle(styleDefault); + cell.setCellValue(tempDollar); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + double tempDouble = 0.0; + try { + tempDouble = Double.parseDouble(value); + if(styleCell!=null) { + styleCell.setDataFormat((short)0x28);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDecimalNumber); + cell.setCellValue(tempDouble); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(value); + } + + } + }else { + if (!(value.equals(""))){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //if (dv.getDisplayValue().startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempInt = value.trim(); + tempInt = tempInt.replaceAll(" ", "").substring(0); + tempInt = tempInt.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempInt); + //System.out.println("Before copy Value |" + tempInt); + //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); + //System.out.println("After copy Value |" + tempInt); + if ((tempInt.indexOf(","))!= -1){ + tempInt = tempInt.replaceAll(",", ""); + } + //System.out.println("The final string INT is "+tempInt); + Long tempIntDollar = 0L; + try { + tempIntDollar = Long.parseLong(tempInt); + if(styleCell!=null) { + styleCell.setDataFormat((short) 6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleCurrencyNumber); + cell.setCellValue(tempIntDollar); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempInt); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempStr = value.trim(); + if ((tempStr.indexOf(","))!= -1){ + tempStr = tempStr.replaceAll(",", ""); + } + Long temp = 0L; + + try { + temp = Long.parseLong(tempStr); + if(styleCell!=null) { + styleCell.setDataFormat((short) 0x26);//HSSFDataFormat.getBuiltinFormat("(#,##0_);[Red](#,##0)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleNumber); + cell.setCellValue(temp); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempStr); + } + + + } + //int temp = Integer.parseInt(value.trim()); + // cell.setCellValue(temp); + //}else{ + // cell.setCellValue(strip.stripHtml(value)); + //} + } + } + } + + }else if ( ( dataType !=null && dataType.equals("DATE")) || (dv.getDisplayName()!=null && dv.getDisplayName().toLowerCase().endsWith("date")) || + (dv.getColId()!=null && dv.getColId().toLowerCase().endsWith("date")) || + (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date")) ) { + //cellDate = row.createCell((short) cellNum); + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("mm/dd/yy")); + + if(styleCell!=null) { + styleCell.setDataFormat((short) 0xe);//HSSFDataFormat.getBuiltinFormat("m/d/yy")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDate); + //String MY_DATE_FORMAT = "yyyy-MM-dd"; + //value = nvl(value).length()<=0?nvl(dv.getDisplayValue()):value; + Date date = null; + int flag = 0; + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm")); + flag = 1; + } + if(date==null) + date = MMDDYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy")); + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy h:mm:ss")); + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); + flag = 1; + } + if(date==null) + date = MMDDYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy")); + flag = 1; + } + if(date==null) + date = YYYYMMDDFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy/m/d")); + flag = 1; + } + if(date==null) + date = timestampFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy-m-d h:mm:ss")); //yyyy-MM-dd HH:mm:ss + flag = 1; + } + if(date==null) + date = MONYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("mmm yyyy")); + flag = 1; + } + if(date==null) + date = MMYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/yyyy")); + flag = 1; + } + if(date==null) + date = MMMMMDDYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("mmm/d/yyyy")); + flag = 1; + } + if(date==null) + date = MONTHYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("mmm/yyyy")); + flag = 1; + } + if(date==null) + date = YYYYMMDDHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy/m/d h:mm:ss")); + flag = 1; + } + if(date==null) + date = YYYYMMDDDASHFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy-m-d")); + flag = 1; + } + if(date==null) + date = YYYYMMDDHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy/m/d h:mm")); + flag = 1; + } + if(date==null) + date = DDMONYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("d-mmm-yyyy h:mm:ss")); + flag = 1; + } + if(date==null) + date = DDMONYYYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("d-mmm-yyyy h:mm")); + flag = 1; + } + if(date==null) + date = DDMONYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("d-mmm-yy h:mm")); + flag = 1; + } + if(date==null) + date = DDMONYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("d-mmm-yyyy")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm")); + flag = 1; + } + if(date==null) + date = MMDDYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMZFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); + flag = 1; + } + if(date==null) + date = MMMMMDDYYYYHHMMSS.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); + flag = 1; + } + + if(date!=null) { + //System.out.println("ExcelDate " + HSSFDateUtil.getExcelDate(date)); + cell.setCellValue(HSSFDateUtil.getExcelDate(date)); + try { + String str = cell.getStringCellValue(); + } catch (IllegalStateException ex) { /*cell.getCellStyle().setDataFormat((short)0);*/cell.setCellValue(value);} + } else { + /*cell.getCellStyle().setDataFormat((short)0);*/ + cell.setCellValue(value); + } + //cellDate.setCellValue(date); + //cellDate.setCellValue(value); //cellDate.setCellValue(date); + //cellDate.setCellValue(dv.getDisplayValue()); + + }else if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + //cellNumber = row.createCell((short) cellNum); + //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + //cellNumber.setCellValue(dv.getDisplayValue()); + cell = row.createCell((short) cellNum); + int zInt = 0; + if (value.equals("null")){ + cell.setCellValue(zInt); + }else{ + + if ((value.indexOf("."))!= -1){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempDollar = value.trim(); + tempDollar = tempDollar.replaceAll(" ", "").substring(0); + tempDollar = tempDollar.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempDollar); + //System.out.println("Before copy Value |" + tempDollar); + //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); + //System.out.println("After copy Value |" + tempDollar); + if ((tempDollar.indexOf(","))!= -1){ + tempDollar = tempDollar.replaceAll(",", ""); + } + //System.out.println("The final string 2IF is "+tempDollar); + double tempDoubleDollar = 0.0; + try { + tempDoubleDollar = Double.parseDouble(tempDollar); + if(styleCell!=null) { + styleCell.setDataFormat((short) 8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleCurrencyDecimalNumber); + cell.setCellValue(tempDoubleDollar); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempDollar); + } + + + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempDoubleStr = value.trim(); + tempDoubleStr = tempDoubleStr.replaceAll(" ", "").substring(0); + if ((tempDoubleStr.indexOf(","))!= -1){ + tempDoubleStr = tempDoubleStr.replaceAll(",", ""); + } + double tempDouble = 0.0; + try { + tempDouble = Double.parseDouble(tempDoubleStr); + if(styleCell!=null) { + styleCell.setDataFormat((short)0x28 );//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDecimalNumber); + cell.setCellValue(tempDouble); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempDoubleStr); + } + } + + }else { + if (!(value.equals(""))){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempInt = value.trim(); + tempInt = tempInt.replaceAll(" ", "").substring(0); + tempInt = tempInt.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempInt); + //System.out.println("Before copy Value |" + tempInt); + //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); + //System.out.println("After copy Value |" + tempInt); + if ((tempInt.indexOf(","))!= -1){ + tempInt = tempInt.replaceAll(",", ""); + } + //System.out.println("The final string INT 2 is "+tempInt); + + Long tempIntDollar = 0L; + + try { + tempIntDollar = Long.parseLong(tempInt); + if(styleCell!=null) { + styleCell.setDataFormat((short) 6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleCurrencyNumber); + cell.setCellValue(tempIntDollar); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempInt); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempStr = value.trim(); + if ((tempStr.indexOf(","))!= -1){ + tempStr = tempStr.replaceAll(",", ""); + } + Long temp = 0L; + + try { + temp = Long.parseLong(tempStr); + if(styleCell!=null) { + styleCell.setDataFormat((short) 0x26);//HSSFDataFormat.getBuiltinFormat("(#,##0_);[Red](#,##0)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleNumber); + cell.setCellValue(temp); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempStr); + } + } + //int temp = Integer.parseInt(dv.getDisplayValue().trim()); + // cell.setCellValue(temp); + //}else{ + // cell.setCellValue(strip.stripHtml(dv.getDisplayValue())); + //} + } else { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + } + } + } + + + } + else { + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("General")); + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(strip.stripHtml(value)); + } + + //if (!(value.equals(""))){ + //int temp = Integer.parseInt(value.trim()); + //cell.setCellValue(temp); + //}else{ + // cell.setCellValue(strip.stripHtml(value)); + //} + //HSSFCellStyle styleFormat = null; + //HSSFCellStyle numberStyle = null; + //HSSFFont formatFont = null; + //short fgcolor = 0; + //short fillpattern = 0; + if (cellWidth.size() > cellNum) { + if (((Integer) cellWidth.get(cellNum)).intValue() < dv + .getDisplayValue().length()) + cellWidth.set((cellNum), + (value.length()<=Globals.getMaxCellWidthInExcel())?new Integer(value.length()):new Integer(Globals.getMaxCellWidthInExcel())); + } else + cellWidth.add((cellNum), (value.length()<=Globals.getMaxCellWidthInExcel())?new Integer(value.length()):new Integer(Globals.getMaxCellWidthInExcel())); + //System.out.println("1IF "+ (dv.isBold()) + " "+ value + " " + dv.getDisplayTotal() + " " + dv.getColName() ); + if (dv.isBold()) { + if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + cell.setCellStyle(styleCurrencyTotal); + } + else { + cell.setCellStyle(styleTotal); + } + } else { + cell.setCellStyle(styleDefaultTotal); + } + bold = true; + } + //System.out.println("2IF "+ (dr.isRowFormat()) + " " + (dv.isCellFormat()) + " " + (styles!=null)); + if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) { + //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); + continue; + } + //System.out.println("3IF "+ (htmlFormat != null) + " " + (dv.getFormatId() != null) + " " + (bold == false) + " "+ (styles != null)); + if (htmlFormat != null && dv.getFormatId() != null && bold == false + && styles != null) { + //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default"))); + } //else if (bold == false) + //cell.setCellStyle(styleDefault); + } // dv.isVisible + } + rowNum += 1; + + } + + int cw = 0; + for (int i = 0; i < cellWidth.size(); i++) { + cw = ((Integer) cellWidth.get(i)).intValue() + 12; + // if(i!=cellWidth.size()-1) + sheet.setColumnWidth((short) (i), (short) ((cw * 8) / ((double) 1 / 20))); + // else + // sheet.setColumnWidth((short) (i + 1), (short) ((cw * 10) / + // ((double) 1 / 20))); + } + + // To Display Total Values for Linear report + if(rd.reportDataTotalRow!=null) { + row = sheet.createRow(rowNum); + cellNum = -1; + rd.reportTotalRowHeaderCols.resetNext(); + //for (rd.reportTotalRowHeaderCols.resetNext(); rd.reportTotalRowHeaderCols.hasNext();) { + cellNum += 1; + RowHeaderCol rhc = rd.reportTotalRowHeaderCols.getNext(); + RowHeader rh = rhc.getRowHeader(0); + row.createCell((short) cellNum).setCellValue(strip.stripHtml(rh.getRowTitle())); + row.getCell((short) cellNum).setCellStyle(styleDefaultTotal); + //} + + rd.reportDataTotalRow.resetNext(); + DataRow drTotal = rd.reportDataTotalRow.getNext(); + //cellNum = -1; + + drTotal.resetNext(); + drTotal.getNext(); + for (; drTotal.hasNext();) { + cellNum += 1; + cell = row.createCell((short) cellNum); + DataValue dv = drTotal.getNext(); + String value = dv.getDisplayValue(); + cell.setCellValue(value); + boolean bold = false; + if (dv.isBold()) { + if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + cell.setCellStyle(styleCurrencyTotal); + } else { + cell.setCellStyle(styleTotal); + } + } else { + cell.setCellStyle(styleDefaultTotal); + } + bold = true; + } + } + } + + } catch (SQLException ex) { + ex.printStackTrace(); + throw new RaptorException(ex); + } catch (ReportSQLException ex) { + throw new RaptorException(ex); + } catch (Exception ex) { + if(!(ex.getCause() instanceof java.net.SocketException) ) + throw new RaptorException (ex); + } finally { + try { + if(conn!=null) + conn.close(); + if(st!=null) + st.close(); + if(rs!=null) + rs.close(); + } catch (SQLException ex) { + throw new RaptorException(ex); + } + } + + /*if(Globals.getShowDisclaimer() && !Globals.disclaimerPositionedTopInCSVExcel()) { + rowNum += 1; + row = sheet.createRow(rowNum); + cellNum = 0; + String disclaimer = Globals.getFooterFirstLine() + " " + Globals.getFooterSecondLine(); + row.createCell((short) cellNum).setCellValue(disclaimer); + sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); + rowNum += 1; + }*/ + } else { + if(rr.getReportType().equals(AppConstants.RT_LINEAR)) { + int rowCount = 0; + for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { + DataRow dr = rd.reportDataRows.getNext(); + //List l = rd.getReportDataList(); + //for (int dataRow = 0; dataRow < l.size(); dataRow++) { + rowCount++; + + + //DataRow dr = (DataRow) l.get(dataRow); + row = sheet.createRow(rowNum); + + cellNum = -1; + + if (rr.getReportType().equals(AppConstants.RT_LINEAR) && rd.reportTotalRowHeaderCols!=null) { + rd.reportRowHeaderCols.resetNext(0); + if(rd.reportTotalRowHeaderCols!=null) { + //cellNum = -1; + //for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { + //cellNum += 1; + //RowHeaderCol rhc = rd.reportRowHeaderCols.getRowHeaderCol(0); + //if (firstPass) + // rhc.resetNext(); + //RowHeader rh = rhc.getRowHeader(rowCount-1); + //row.createCell((short) cellNum).setCellValue(rowCount); + //row.getCell((short) cellNum).setCellStyle(styleDefault); + //if (firstPass) + //cellWidth.add(cellNum, new Integer((rowCount+"").length())); + //else + //cellWidth.set(cellNum, new Integer((rowCount+"").length())); + + //} // for + } + + } else { + rd.reportRowHeaderCols.resetNext(0); + } + for (; rd.reportRowHeaderCols.hasNext();) { + cellNum += 1; + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + if (firstPass) + rhc.resetNext(); + RowHeader rh = rhc.getNext(); + row.createCell((short) cellNum).setCellValue(strip.stripHtml(rh.getRowTitle())); + row.getCell((short) cellNum).setCellStyle(styleDefault); + if (cellWidth.size() > 0) { + if (((Integer) cellWidth.get(cellNum)).intValue() < rh.getRowTitle() + .length()) + cellWidth.set(cellNum, new Integer(rh.getRowTitle().length())); + } else + cellWidth.add(cellNum, new Integer(rh.getRowTitle().length())); + + } // for + firstPass = false; + //cellNum = -1; + int j = 0; + + for (dr.resetNext(); dr.hasNext();j++) { + DataValue dv = dr.getNext(); + styleCell = null; + boolean bold = false; + String value = nvl(dv.getDisplayValue()); + value = strip.stripHtml(value); + HtmlFormatter htmlFormat = dv.getCellFormatter(); + if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) + styleCell = (HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default")); + if (htmlFormat != null && dv.getFormatId() != null && styles != null) + styleCell = (HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default")); + + if(dv.isVisible()) { + cellNum += 1; + cell = row.createCell((short) cellNum); + //System.out.println("Stripping HTML 1"); + //cell.setCellValue(strip.stripHtml(value)); + String dataType = (String) (dataTypeMap.get(dv.getColId())); + //System.out.println(" The Display Value is ********"+value + " " + dv.getDisplayTotal() + " " + dv.getColName()); + + if (dataType!=null && dataType.equals("NUMBER")){ + //cellNumber = row.createCell((short) cellNum); + //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + //cellNumber.setCellValue(value); + //cellCurrencyNumber = row.createCell((short) cellNum); + int zInt = 0; + if (value.equals("null")){ + cell.setCellValue(zInt); + }else{ + + if ((value.indexOf("."))!= -1){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempDollar = value.trim(); + tempDollar = tempDollar.replaceAll(" ", "").substring(0); + tempDollar = tempDollar.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempDollar); + //System.out.println("Before copy Value |" + tempDollar); + //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); + //System.out.println("After copy Value |" + tempDollar); + if ((tempDollar.indexOf(","))!= -1){ + tempDollar = tempDollar.replaceAll(",", ""); + } + //System.out.println("The final string 1 is "+tempDollar); + double tempDoubleDollar = 0.0; + try { + tempDoubleDollar = Double.parseDouble(tempDollar); + if(styleCell!=null) { + styleCell.setDataFormat((short) 8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleCurrencyDecimalNumber); + cell.setCellValue(tempDoubleDollar); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempDollar); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + double tempDouble = 0.0; + try { + tempDouble = Double.parseDouble(value); + if(styleCell!=null) { + styleCell.setDataFormat((short) 0x28);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDecimalNumber); + cell.setCellValue(tempDouble); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(value); + } + + } + }else { + if (!(value.equals(""))){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempInt = value.trim(); + tempInt = tempInt.replaceAll(" ", "").substring(0); + tempInt = tempInt.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempInt); + //System.out.println("Before copy Value |" + tempInt); + //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); + //System.out.println("After copy Value |" + tempInt); + if ((tempInt.indexOf(","))!= -1){ + tempInt = tempInt.replaceAll(",", ""); + } + //System.out.println("The final string INT is "+tempInt); + Long tempIntDollar = 0L; + try { + tempIntDollar = Long.parseLong(tempInt); + if(styleCell!=null) { + styleCell.setDataFormat((short)6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleCurrencyNumber); + cell.setCellValue(tempIntDollar); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempInt); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempStr = value.trim(); + if ((tempStr.indexOf(","))!= -1){ + tempStr = tempStr.replaceAll(",", ""); + } + Long temp = 0L; + + try { + temp = Long.parseLong(tempStr); + if(styleCell!=null) { + styleCell.setDataFormat((short)0x26);//HSSFDataFormat.getBuiltinFormat("(#,##0_);[Red](#,##0)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleNumber); + cell.setCellValue(temp); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempStr); + } + + + } + //int temp = Integer.parseInt(value.trim()); + // cell.setCellValue(temp); + //}else{ + // cell.setCellValue(strip.stripHtml(value)); + //} + } + } + } + + }else if ( ( dataType !=null && dataType.equals("DATE")) || (dv.getDisplayName()!=null && dv.getDisplayName().toLowerCase().endsWith("date")) || + (dv.getColId()!=null && dv.getColId().toLowerCase().endsWith("date")) || + (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date")) ) { + //cellDate = row.createCell((short) cellNum); + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("mm/dd/yy")); + + if(styleCell!=null) { + styleCell.setDataFormat((short)0xe); //HSSFDataFormat.getBuiltinFormat("m/d/yy")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDate); + //String MY_DATE_FORMAT = "yyyy-MM-dd"; + Date date = null; + int flag = 0; + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm")); + flag = 1; + } + if(date==null) + date = MMDDYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy")); + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy h:mm:ss")); + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); + flag = 1; + } + if(date==null) + date = MMDDYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy")); + flag = 1; + } + if(date==null) + date = YYYYMMDDFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy/m/d")); + flag = 1; + } + if(date==null) + date = timestampFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy-m-d h:mm:ss")); //yyyy-MM-dd HH:mm:ss + flag = 1; + } + if(date==null) + date = MONYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("mmm yyyy")); + flag = 1; + } + if(date==null) + date = MMYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/yyyy")); + flag = 1; + } + if(date==null) + date = MMMMMDDYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("mmm/d/yyyy")); + flag = 1; + } + if(date==null) + date = MONTHYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("mmm/yyyy")); + flag = 1; + } + if(date==null) + date = YYYYMMDDHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy/m/d h:mm:ss")); + flag = 1; + } + if(date==null) + date = YYYYMMDDDASHFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy-m-d")); + flag = 1; + } + if(date==null) + date = YYYYMMDDHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("yyyy/m/d h:mm")); + flag = 1; + } + if(date==null) + date = DDMONYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("d-mmm-yyyy h:mm:ss")); + flag = 1; + } + if(date==null) + date = DDMONYYYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("d-mmm-yyyy h:mm")); + flag = 1; + } + if(date==null) + date = DDMONYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("d-mmm-yy h:mm")); + flag = 1; + } + if(date==null) + date = DDMONYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("d-mmm-yyyy")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm")); + flag = 1; + } + if(date==null) + date = MMDDYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMZFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); + flag = 1; + } + if(date==null) + date = MMMMMDDYYYYHHMMSS.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cell.getCellStyle().setDataFormat( + createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); + flag = 1; + } + + if(date!=null) { + //System.out.println("ExcelDate " + HSSFDateUtil.getExcelDate(date)); + cell.setCellValue(HSSFDateUtil.getExcelDate(date)); + try { + String str = cell.getStringCellValue(); + } catch (IllegalStateException ex) { /*cell.getCellStyle().setDataFormat((short)0);*/cell.setCellValue(value);} + } else { + /*cell.getCellStyle().setDataFormat((short)0);*/ + cell.setCellValue(value); + } + //cellDate.setCellValue(date); + //cellDate.setCellValue(value); + + }else if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + //cellNumber = row.createCell((short) cellNum); + //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + //cellNumber.setCellValue(value); + cell = row.createCell((short) cellNum); + int zInt = 0; + if (value.equals("null")){ + cell.setCellValue(zInt); + }else{ + + if ((value.indexOf("."))!= -1){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempDollar = value.trim(); + tempDollar = tempDollar.replaceAll(" ", "").substring(0); + tempDollar = tempDollar.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempDollar); + //System.out.println("Before copy Value |" + tempDollar); + //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); + //System.out.println("After copy Value |" + tempDollar); + if ((tempDollar.indexOf(","))!= -1){ + tempDollar = tempDollar.replaceAll(",", ""); + } + //System.out.println("The final string 2IF is "+tempDollar); + double tempDoubleDollar = 0.0; + try { + tempDoubleDollar = Double.parseDouble(tempDollar); + if(styleCell!=null) { + styleCell.setDataFormat((short)8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleCurrencyDecimalNumber); + cell.setCellValue(tempDoubleDollar); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempDollar); + } + + + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempDoubleStr = value.trim(); + tempDoubleStr = tempDoubleStr.replaceAll(" ", "").substring(0); + if ((tempDoubleStr.indexOf(","))!= -1){ + tempDoubleStr = tempDoubleStr.replaceAll(",", ""); + } + double tempDouble = 0.0; + try { + tempDouble = Double.parseDouble(tempDoubleStr); + if(styleCell!=null) { + styleCell.setDataFormat((short) 0x28); // for decimal + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDecimalNumber); + cell.setCellValue(tempDouble); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempDoubleStr); + } + } + + }else { + if (!(value.equals(""))){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempInt = value.trim(); + tempInt = tempInt.replaceAll(" ", "").substring(0); + tempInt = tempInt.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempInt); + //System.out.println("Before copy Value |" + tempInt); + //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); + //System.out.println("After copy Value |" + tempInt); + if ((tempInt.indexOf(","))!= -1){ + tempInt = tempInt.replaceAll(",", ""); + } + //System.out.println("The final string INT 2 is "+tempInt); + + Long tempIntDollar = 0L; + + try { + tempIntDollar = Long.parseLong(tempInt); + if(styleCell!=null) { + styleCell.setDataFormat((short) 6); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleCurrencyNumber); + cell.setCellValue(tempIntDollar); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempInt); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempStr = value.trim(); + if ((tempStr.indexOf(","))!= -1){ + tempStr = tempStr.replaceAll(",", ""); + } + Long temp = 0L; + + try { + temp = Long.parseLong(tempStr); + if(styleCell!=null) { + styleCell.setDataFormat((short) 0x26); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleNumber); + cell.setCellValue(temp); + } catch (NumberFormatException ne) { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(tempStr); + } + } + //int temp = Integer.parseInt(value.trim()); + // cell.setCellValue(temp); + //}else{ + // cell.setCellValue(strip.stripHtml(value)); + //} + } else { + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + } + } + } + + + } + else { + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("General")); + if(styleCell!=null) { + styleCell.setWrapText(true); + cell.setCellStyle(styleCell); + } else + cell.setCellStyle(styleDefault); + cell.setCellValue(strip.stripHtml(value)); + } + + //if (!(value.equals(""))){ + //int temp = Integer.parseInt(value.trim()); + //cell.setCellValue(temp); + //}else{ + // cell.setCellValue(strip.stripHtml(value)); + //} + //HSSFCellStyle styleFormat = null; + //HSSFCellStyle numberStyle = null; + //HSSFFont formatFont = null; + //short fgcolor = 0; + //short fillpattern = 0; + if (cellWidth.size() > cellNum) { + if (((Integer) cellWidth.get(cellNum)).intValue() < dv + .getDisplayValue().length()) + cellWidth.set((cellNum), + (value.length()<=Globals.getMaxCellWidthInExcel())?new Integer(value.length()):new Integer(Globals.getMaxCellWidthInExcel())); + } else + cellWidth.add((cellNum), (value.length()<=Globals.getMaxCellWidthInExcel())?new Integer(value.length()):new Integer(Globals.getMaxCellWidthInExcel())); + //System.out.println("1IF "+ (dv.isBold()) + " "+ value + " " + dv.getDisplayTotal() + " " + dv.getColName() ); + if (dv.isBold()) { + if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + cell.setCellStyle(styleCurrencyTotal); + } + else { + cell.setCellStyle(styleTotal); + } + } else { + cell.setCellStyle(styleDefaultTotal); + } + bold = true; + } + //System.out.println("2IF "+ (dr.isRowFormat()) + " " + (dv.isCellFormat()) + " " + (styles!=null)); + if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) { + //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); + continue; + } + //System.out.println("3IF "+ (htmlFormat != null) + " " + (dv.getFormatId() != null) + " " + (bold == false) + " "+ (styles != null)); + if (htmlFormat != null && dv.getFormatId() != null && bold == false + && styles != null) { + // cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default"))); + } //else if (bold == false) + //cell.setCellStyle(styleDefault); + } // if (dv.isVisible) + } // for + + /*for (int tmp=0; tmp rowNames = dr.getRowValues(); + for(dr.resetNext(); dr.hasNext(); rowCount++ ) { + if(first) { + if(rowNames!=null) { + for(int i=0; i0) { + cellNum += 1; + row.createCell((short) cellNum).setCellValue(strip.stripHtml(dv.getDisplayValue())); + //row.getCell((short) cellNum).setCellStyle(styleDefault); + if(nvl(dv.getFormatId()).length()>0) + row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default"))); + else + row.setRowStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); + } else { + cellNum += 1; + row.createCell((short) cellNum).setCellValue(strip.stripHtml(value)); + row.getCell((short) cellNum).setCellStyle(styleDefault); + } // end + value = dv.getDisplayValue(); + if(value.indexOf("|#")!=-1) { + String color = value.substring(value.indexOf("|")+1); + if(color.equals("#FF0000")) + row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get("red")); + else if (color.equals("#008000")) + row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get("green")); + else if (color.equals("#FFFF00")) + row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get("yellow")); + else { + row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get("default")); + } + + } + } + } + rowNum += 1; + int cw = 0; + for (int i = 0; i < cellWidth.size(); i++) { + cw = ((Integer) cellWidth.get(i)).intValue() + 12; + // if(i!=cellWidth.size()-1) + sheet.setColumnWidth((short) (i), (short) ((cw * 8) / ((double) 1 / 20))); + // else + // sheet.setColumnWidth((short) (i + 1), (short) ((cw * 10) / + // ((double) 1 / 20))); + } + + + } // for + + } + + + } + + String footer = (String) session.getAttribute("FOOTER_"+index); + if(nvl(footer).length()>0) { + footer = Utils.replaceInString(footer, "
", " "); + footer = Utils.replaceInString(footer, "
", " "); + footer = Utils.replaceInString(footer, "
", " "); + footer = strip.stripHtml(nvl(footer).trim()); + row = sheet.createRow(rowNum); + cellNum = 0; + row.createCell((short) cellNum).setCellValue(footer); + sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); + //sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum+columnRows, (short) (cellNum))); + rowNum += 1; + } + + if(Globals.getShowDisclaimer() && !Globals.disclaimerPositionedTopInCSVExcel()) { + + rowNum += 1; + row = sheet.createRow(rowNum); + cellNum = 0; + String disclaimer = Globals.getFooterFirstLine() + " " + Globals.getFooterSecondLine(); + row.createCell((short) cellNum).setCellValue(disclaimer); + sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); + rowNum += 1; + } + + logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); + logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" + + (runtime.maxMemory() - runtime.freeMemory()) / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" + + runtime.freeMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); + return returnValue; + + } + + private void paintExcelHeader(HSSFWorkbook wb, int rowNum, int col, String reportTitle, + String reportDescr, HSSFSheet sheet) { + short s1 = 0, s2 = (short) (col-1); + rowNum += 1; + sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); + HSSFRow row = null, row1 = null; + + row = sheet.createRow(rowNum); + // Header Style + HSSFCellStyle styleHeader = wb.createCellStyle(); + styleHeader.setAlignment(HSSFCellStyle.ALIGN_CENTER); + HSSFFont font = wb.createFont(); + font.setFontHeight((short) (font_header_title_size / 0.05)); //14 + font.setFontName("Tahoma"); + font.setColor(HSSFColor.BLACK.index); + styleHeader.setFont(font); + + HSSFCell cell = row.createCell((short) 0); + cell.setCellValue(reportTitle); + cell.setCellStyle(styleHeader); + HSSFHeader header = sheet.getHeader(); + header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) 9)+" " + reportTitle); + + //header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) 9)+reportTitle+"\n"+((Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0)?reportDescr:"")); + + // Report Description + if (Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0) { + rowNum += 1; + sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); + HSSFCellStyle styleDescription = wb.createCellStyle(); + styleDescription.setAlignment(HSSFCellStyle.ALIGN_CENTER); + HSSFFont fontDescr = wb.createFont(); + fontDescr.setFontHeight((short) font_header_descr_size); + fontDescr.setFontName("Tahoma"); + fontDescr.setColor(HSSFColor.BLACK.index); + styleDescription.setFont(fontDescr); + HSSFCell cellDescr = row.createCell((short) 0); + cellDescr.setCellValue(reportDescr); + cellDescr.setCellStyle(styleHeader); + } + + if(Globals.disclaimerPositionedTopInCSVExcel()) { + rowNum += 1; + row = sheet.createRow(rowNum); + sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); + HSSFCellStyle styleDescription = wb.createCellStyle(); + styleDescription.setAlignment(HSSFCellStyle.ALIGN_CENTER); + HSSFFont fontDescr = wb.createFont(); + fontDescr.setFontHeight((short) (font_size / 0.05)); //14 + fontDescr.setFontName("Tahoma"); + fontDescr.setColor(HSSFColor.BLACK.index); + fontDescr.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + styleDescription.setFont(fontDescr); + HSSFCell cellDescr = row.createCell((short) 0); + String disclaimer = Globals.getFooterFirstLine() + " " + Globals.getFooterSecondLine(); + cellDescr.setCellValue(disclaimer); + cellDescr.setCellStyle(styleDescription); + } + + rowNum += 1; + row = sheet.createRow(rowNum); + // System.out.println(" Last Row " + wb.getSheetAt(0).getLastRowNum()); + } + + private void paintExcelFooter(HSSFWorkbook wb, int rowNum, int col, HSSFSheet sheet) { + logger.debug(EELFLoggerDelegate.debugLogger, ("excel footer")); + //HSSFSheet sheet = wb.getSheet(getSheetName()); + HSSFFooter footer = sheet.getFooter(); + footer.setLeft(HSSFFooter.font("Tahoma", "")+ HSSFFooter.fontSize((short) font_footer_size)+ "Page " + HSSFFooter.page() + + " of " + HSSFFooter.numPages() ); + footer.setCenter(HSSFFooter.font("Tahoma", "")+ HSSFFooter.fontSize((short) font_footer_size)+Globals.getFooterFirstLine()+"\n"+Globals.getFooterSecondLine()); + //footer.setCenter(HSSFFooter.font("Tahoma", "Italic")+ HSSFFooter.fontSize((short) 16))+Globals.getFooterSecondLine()); +/* footer.font("Tahoma"); + short s1 = 0, s2 = (short) (col-1); + rowNum += 1; + sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); + HSSFRow row = null, row1 = null; + + row = sheet.createRow(rowNum); + // Header Style + HSSFCellStyle styleFooter = wb.createCellStyle(); + styleFooter.setAlignment(HSSFCellStyle.ALIGN_CENTER); + HSSFFont font = wb.createFont(); + font.setFontHeight((short) (10 / 0.05)); + font.setFontName("Tahoma"); + font.setColor(HSSFColor.BLACK.index); + font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + styleFooter.setFont(font); + + HSSFCell cell = row.createCell((short) 0); + debugLogger.debug(Globals.getFooterFirstLine()); + cell.setCellValue(Globals.getFooterFirstLine()); + cell.setCellStyle(styleFooter); + + rowNum += 1; + sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); + row = sheet.createRow(rowNum); + cell = row.createCell((short) 0); + debugLogger.debug(Globals.getFooterSecondLine()); + cell.setCellValue(Globals.getFooterSecondLine()); + cell.setCellStyle(styleFooter); +*/ + logger.debug(EELFLoggerDelegate.debugLogger, ("Done")); + } + + public String saveAsExcelFile(HttpServletRequest request, ReportData rd, + ArrayList reportParamNameValues, String reportTitle, String reportDescr) { + return saveAsExcelFile(request, rd, reportParamNameValues, reportTitle, reportDescr, 2); //2 denotes ReportRuntime object should be taken from session. + } + public String saveAsExcelFile(HttpServletRequest request, ReportData rd, + ArrayList reportParamNameValues, String reportTitle, String reportDescr, int requestFlag) { + setSheetName(Globals.getSheetName()); + try { + ReportRuntime rr; + if(requestFlag == 2) + rr = (ReportRuntime) request.getSession().getAttribute( + AppConstants.SI_REPORT_RUNTIME); + else + rr = (ReportRuntime) request.getAttribute( + AppConstants.SI_REPORT_RUNTIME); + HSSFWorkbook wb = new HSSFWorkbook(); + HashMap styles = new HashMap(); + if (rr != null) + styles = loadStyles(rr, wb); + String xlsFName = AppUtils.generateUniqueFileName(request, rr.getReportName(), AppConstants.FT_XLS); + logger.debug(EELFLoggerDelegate.debugLogger, ("Xls File name " + + AppUtils.getTempFolderPath() + + xlsFName)); + FileOutputStream xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() + + xlsFName); + // BufferedWriter xlsOut = new BufferedWriter(new + // FileWriter(AppUtils + // .getTempFolderPath() + // + xlsFName)); + + int col = 0; + //System.out.println("Row Header Count " + rd.reportRowHeaderCols.getRowCount()); + //System.out.println("Total Count " + rd.getTotalColumnCount()); + + if (!rd.reportRowHeaderCols.hasNext()) + col = rd.getTotalColumnCount(); + else + col = rd.getTotalColumnCount(); + int rowNum = 0; + HSSFSheet sheet = wb.createSheet(getSheetName()); + + if (Globals.getPrintTitleInDownload()&& reportTitle != null ) { + paintExcelHeader(wb, rowNum, col, reportTitle, reportDescr, sheet); + rowNum = sheet.getLastRowNum(); + } else + rowNum = 0; + if (Globals.getPrintParamsInDownload() && rr.getParamNameValuePairsforPDFExcel(request, 1) != null) { + paintExcelParams(wb,rowNum,col,rr.getParamNameValuePairsforPDFExcel(request, 1), rr.getFormFieldComments(request), sheet, reportTitle, reportDescr); + } // if + rowNum = sheet.getLastRowNum(); + //System.out.println(" rowNum after Params " + rowNum); + paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, "", xlsOut, request); + if (Globals.getPrintFooterInDownload() ) { + rowNum = sheet.getLastRowNum(); + rowNum += 2; + paintExcelFooter(wb, rowNum, col, sheet); + } + //response.setContentType("application/vnd.ms-excel"); + //response.setHeader("Content-disposition", "attachment;filename=download_all_" + // + user_id + ".xls"); + wb.write(xlsOut); + xlsOut.flush(); + xlsOut.close(); + return xlsFName; + } catch (Exception e) { + e.printStackTrace(); + (new ErrorHandler()).processError(request, "Exception saving data to EXCEL file: " + + e.getMessage()); + return null; + } + } // saveAsExcelFile + + public void createExcelFileContent(Writer out, ReportData rd, ReportRuntime rr, HttpServletRequest request, + HttpServletResponse response, String user_id, int type) throws IOException, RaptorException { + // Adding utility for downloading Dashboard reports. + + HashMap styles = new HashMap(); + HttpSession session = request.getSession(); + ServletOutputStream sos = null; + BufferedInputStream buf = null; + HSSFWorkbook wb = null; +// if(session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) +// ReportRuntime rrDashboard = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); + String formattedDate = ""; + String xlsFName = ""; + int returnValue = 0; + boolean isDashboard = false; + if ((session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) && ( ((String) session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)).equals(rr.getReportID())) ) { + isDashboard = true; + } + if(isDashboard) { + try { + formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); + xlsFName = "dashboard"+formattedDate+user_id+".xls"; + + FileInputStream xlsIn = null; + POIFSFileSystem fileSystem = null; + buf = null; + FileOutputStream xlsOut = null; + + +/* try { + xlsIn = new FileInputStream (AppUtils.getTempFolderPath() + + xlsFName); + } + catch (FileNotFoundException e) { + System.out.println ("File not found in the specified path."); + e.printStackTrace (); + } + if(xlsIn != null) { + fileSystem = new POIFSFileSystem (xlsIn); + wb = new HSSFWorkbook(fileSystem); + } else { + xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() + + xlsFName); + wb = new HSSFWorkbook(); + } +*/ + + Map reportRuntimeMap = null; + Map reportDataMap = null; + //Map reportDisplayTypeMap = null; + reportRuntimeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); + reportDataMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); + //reportDisplayTypeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI); + HSSFSheet sheet = null; + if(reportRuntimeMap!=null) { + //ServletOutputStream sos = response.getOutputStream(); + Set setReportRuntime = reportRuntimeMap.entrySet(); + Set setReportDataMap = reportDataMap.entrySet(); + Iterator iter2 = setReportDataMap.iterator(); + int count = 0; + + for(Iterator iter = setReportRuntime.iterator(); iter.hasNext(); ) { + count++; + try { + xlsIn = new FileInputStream (AppUtils.getTempFolderPath() + + xlsFName); + } + catch (FileNotFoundException e) { + System.out.println ("File not found in the specified path."); + //e.printStackTrace (); + } + if(xlsIn != null) { + fileSystem = new POIFSFileSystem (xlsIn); + wb = new HSSFWorkbook(fileSystem); + xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() + + xlsFName); + } else { + xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() + + xlsFName); + wb = new HSSFWorkbook(); + } + + Map.Entry entryData = (Entry) iter2.next(); + Map.Entry entry = (Entry) iter.next(); + //String rep_id = (String) entry.getKey(); + ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); + ReportData rdDashRep = (ReportData) entryData.getValue(); + //styles = loadStyles(rrDashRep, wb); + int col = 0; + String reportTitle = (nvl(rrDashRep.getReportTitle()).length()>0?rrDashRep.getReportTitle():rrDashRep.getReportName()); + String reportDescr = rrDashRep.getReportDescr(); + if (!rdDashRep.reportRowHeaderCols.hasNext()) + col = rdDashRep.getTotalColumnCount(); + else + col = rdDashRep.getTotalColumnCount(); + if(col==0) col=10; + int rowNum = 0; + String formattedReportName = new HtmlStripper().stripSpecialCharacters(rrDashRep.getReportName()); + + try { + sheet = wb.createSheet(formattedReportName); + sheet.getPrintSetup().setLandscape(true); + styles = loadStyles(rrDashRep, wb); + } catch (IllegalArgumentException ex) { wb.write(xlsOut);xlsOut.flush();xlsOut.close();continue;} + + if (Globals.getPrintTitleInDownload()&& reportTitle != null ) { + paintExcelHeader(wb, rowNum, col, reportTitle, reportDescr, sheet); + rowNum = sheet.getLastRowNum(); + } else + rowNum = 0; + //getting ReportRuntime object from session + if (Globals.getPrintParamsInDownload() && rrDashRep.getParamNameValuePairsforPDFExcel(request, 1) != null) { + if(count > 1 && Globals.showParamsInAllDashboardReports()) + paintExcelParams(wb,rowNum,col,rrDashRep.getParamNameValuePairsforPDFExcel(request, 1), rrDashRep.getFormFieldComments(request), sheet, reportTitle, reportDescr); + else if (count == 1) + paintExcelParams(wb,rowNum,col,rrDashRep.getParamNameValuePairsforPDFExcel(request, 1), rrDashRep.getFormFieldComments(request), sheet, reportTitle, reportDescr); + } // if + rowNum = sheet.getLastRowNum(); + String sql_whole = rrDashRep.getWholeSQL(); + returnValue = paintExcelData(wb, rowNum, col, rdDashRep, styles,rrDashRep, sheet, sql_whole, xlsOut, request); + if( returnValue == 0 ) { + if (Globals.getPrintFooterInDownload()) { + rowNum = sheet.getLastRowNum(); + rowNum += 2; + paintExcelFooter(wb, rowNum, col, sheet); + } + //wb.write(sos); + wb.write(xlsOut); + //TODO Remove comment + xlsOut.flush(); + xlsOut.close(); + wb = null; + } else { + //xlsOut.flush(); + //xlsOut.close(); + //response.reset(); + //response.setContentType("application/vnd.ms-excel"); +// RequestDispatcher dispatcher = request.getRequestDispatcher("raptor.htm?r_action=report.message"); +// request.setAttribute("message", Globals.getUserDefinedMessageForMemoryLimitReached()); +// try { +// dispatcher.forward(request, response); +// } catch (ServletException ex) {} + } + } + + response.reset(); + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Content-disposition", "attachment;filename="+"dashboard"+formattedDate+user_id+".xls"); + sos = response.getOutputStream(); + xlsIn = new FileInputStream (AppUtils.getTempFolderPath() + + xlsFName); + buf = new BufferedInputStream(xlsIn); + int readBytes = 0; + byte [] bOut = new byte [4096]; + //read from the file; write to the ServletOutputStream + //while ((readBytes = buf.read()) != -1) + while ((readBytes = buf.read (bOut, 0, 4096))> 0) { + buf.available(); + sos.write (bOut, 0, readBytes); + } + + //sos.write(readBytes); + } + } catch (IOException ex) { ex.printStackTrace(); throw ex;} + + finally { + if (sos != null) + sos.close(); + if (buf != null) + buf.close(); + } + + File f = new File (AppUtils.getTempFolderPath() + + xlsFName); + if(f.exists()) f.delete(); + + } else { + wb = new HSSFWorkbook(); + // PrintWriter xlsOut = new PrintWriter(out).; + setSheetName(Globals.getSheetName()); + //ServletOutputStream sos = response.getOutputStream(); + //PrintWriter outWriter = response.getWriter(); + if (rr != null) + styles = loadStyles(rr, wb); + /* int col = 0; + if (!rd.reportRowHeaderCols.hasNext()) + col = rd.getTotalColumnCount(); + else + col = rd.getTotalColumnCount() + 1; + int rowNum = 0; + String reportTitle = rr.getReportName(); + String reportDescr = rr.getReportDescr(); + // if (Globals.getPrintTitleInDownload() && reportTitle != null) { + HSSFSheet sheet = wb.createSheet(getSheetName()); + System.out.println(" Title " + Globals.getPrintTitleInDownload()); + + if (Globals.getPrintTitleInDownload()&& reportTitle != null ) { + paintExcelHeader(wb, rowNum, col, reportTitle, reportDescr); + rowNum = wb.getSheetAt(0).getLastRowNum(); + } else + rowNum = 0; + System.out.println(" Params " + Globals.getPrintParamsInDownload()); + if (Globals.getPrintParamsInDownload() && rr.getParamNameValuePairs() != null) { + paintExcelParams(wb,rowNum,col,rr.getParamNameValuePairs()); + } // if + paintExcelData(wb, rowNum, col, rd, styles); + rowNum = wb.getSheetAt(0).getLastRowNum(); + */ + int col = 0; + //System.out.println("Row Header Count " + rd.reportRowHeaderCols.getRowCount()); + //System.out.println("Total Count " + rd.getTotalColumnCount()); + String reportTitle = (nvl(rr.getReportTitle()).length()>0?rr.getReportTitle():rr.getReportName()); + String reportDescr = rr.getReportDescr(); + + col = getColumnCountForDownloadFile(rr,rd); + /*if (!rd.reportRowHeaderCols.hasNext()) + col = rd.getTotalColumnCount(); + else + col = rd.getTotalColumnCount(); + */ + int rowNum = 0; + HSSFSheet sheet = wb.createSheet(getSheetName()); + sheet.getPrintSetup().setLandscape(true); + + if (Globals.getPrintTitleInDownload()&& reportTitle != null ) { + paintExcelHeader(wb, rowNum, col, reportTitle, reportDescr, sheet); + rowNum = sheet.getLastRowNum(); + } else + rowNum = 0; + if (Globals.getPrintParamsInDownload() && rr.getParamNameValuePairsforPDFExcel(request, 1) != null) { + ArrayList paramsList = rr.getParamNameValuePairsforPDFExcel(request, 1); + if(paramsList.size()<=0) { + paramsList = (ArrayList) request.getSession().getAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); + } + + paintExcelParams(wb,rowNum,col,paramsList, rr.getFormFieldComments(request), sheet, reportTitle, reportDescr); + } // if + rowNum = sheet.getLastRowNum(); + + String formattedReportName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); + formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); + response.reset(); + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Content-disposition", "attachment;filename="+formattedReportName+formattedDate+user_id+".xls"); + sos = response.getOutputStream(); + + if(type == 3 && rr.getSemaphoreList()==null && !(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) ) { //type = 3 is whole + //String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + //String sql_whole = rr.getWholeSQL(); + String sql_whole = ""; + sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + + if(sql_whole==null) { + if (!rr.getReportType().equals(AppConstants.RT_HIVE)) + sql_whole = rr.getWholeSQL(); + else + sql_whole = rr.getReportSQL(); + } + + returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, sql_whole, sos, request); + } else if(type == 2) { + returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, "", sos, request); + } else { + //String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + int downloadLimit = (rr.getMaxRowsInExcelDownload()>0)?rr.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); + String action = request.getParameter(AppConstants.RI_ACTION); + if(!(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) && !action.endsWith("session")) { + rd = rr.loadReportData(-1, AppUtils.getUserID(request), downloadLimit,request, false /*download*/); + } + if(rr.getSemaphoreList()!=null) { + if(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { + returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, "", sos, request); + } else { + rd = rr.loadReportData(-1, AppUtils.getUserID(request), downloadLimit,request, true); + returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, "", sos, request); + } + } else { + String sql_whole = ""; + sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + + if(sql_whole==null) { + if (!rr.getReportType().equals(AppConstants.RT_HIVE)) + sql_whole = rr.getWholeSQL(); + else + sql_whole = rr.getReportSQL(); + } + + returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, sql_whole, sos, request); + } + } + if( returnValue == 0 ) { + if (Globals.getPrintFooterInDownload()) { + rowNum = sheet.getLastRowNum(); + rowNum += 2; + paintExcelFooter(wb, rowNum, col, sheet); + } + //Alternatively: + wb.setPrintArea( + 0, //sheet index + 0, //start column + col, //end column + 0, //start row + rowNum //end row + ); + //TODO Remove comment + wb.write(sos); + sos.flush(); + sos.close(); + wb = null; + } else { + //sos.flush(); + //sos.close(); +/* response.reset(); + + RequestDispatcher dispatcher = request.getRequestDispatcher("/raptor.htm?action=raptor&r_action=report.message"); + request.setAttribute("message", Globals.getUserDefinedMessageForMemoryLimitReached()); + try { + dispatcher.forward(request, response); + } catch (ServletException ex) {} +*/ + } + } + } + + + public void createFlatFileContent(Writer out, ReportData rd, ReportRuntime rr, + HttpServletRequest request, HttpServletResponse response, String user_id) + throws IOException, Exception { + ReportHandler rephandler = new ReportHandler(); + String reportID = rr.getReportID(); + rr = rephandler.loadReportRuntime(request, reportID); + String query = rr.getWholeSQL(); + String dbInfo = rr.getDbInfo(); + //File f = new File(request.(arg0)("/")); + DataSet ds = ConnectionUtils.getDataSet(query, dbInfo); + + //Writing Column names to the file + List l = rr.getAllColumns(); + StringBuffer allColumnsBuffer = new StringBuffer(); + DataColumnType dct = null; + + for (Iterator iter = l.iterator(); iter.hasNext();) { + dct = (DataColumnType) iter.next(); + allColumnsBuffer.append(dct.getDisplayName()); + if(iter.hasNext()) + allColumnsBuffer.append("|"); + } + rd = rr.loadReportData(-1, user_id, -1,request, true); + //PrintWriter txtOut = new PrintWriter(out); + //response.setContentType("application/notepad"); + //response.setHeader("Content-disposition", "attachment;filename=download_all_"+AppUtils.getUserID(request)+".txt"); + ServletOutputStream sos = response.getOutputStream(); + + //No Report Title for flat file. +// if (Globals.getPrintTitleInDownload() && reportTitle != null) { +// txtOut.println(); +// txtOut.println("\"" + reportTitle + "\""); +// txtOut.println(); +// if (Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0) { +// txtOut.println("\"" + reportDescr + "\""); +// txtOut.println(); +// } +// } // if + // No Params either +// int count = 0; +// if (Globals.getPrintParamsInDownload() && reportParamNameValues != null) { +// for (Iterator iter = reportParamNameValues.iterator(); iter.hasNext();) { +// count += 1; +// if(count == 1) txtOut.println(); +// IdNameValue value = (IdNameValue) iter.next(); +// txtOut.println(value.getId() + " = " + value.getName()); +// if(!iter.hasNext()) txtOut.println(); +// } // for +// } // if + + + + boolean firstPass = true; + for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { + DataRow dr = rd.reportDataRows.getNext(); + for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + if (firstPass) + rhc.resetNext(); + RowHeader rh = rhc.getNext(); + + sos.print(rh.getRowTitle()); + if(rhc.hasNext()) sos.print("|"); + } // for + firstPass = false; + + for (dr.resetNext(); dr.hasNext();) { + DataValue dv = dr.getNext(); + + sos.print( dv.getDisplayValue()); + if(dr.hasNext()) sos.print("|"); + } // for + + sos.println(); + } // for + //sos.flush(); + sos.close(); + } // createFlatFileContent + + + public void createExcel2007FileContent(Writer out, ReportData rd, ReportRuntime rr, HttpServletRequest request, + HttpServletResponse response, String user_id, int type) + throws Exception { + + // to check performance + int mb = 1024*1024; + Runtime runtime = Runtime.getRuntime(); + + logger.debug(EELFLoggerDelegate.debugLogger, ("STARTING.EXCELX DOWNLOAD....")); + logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); + logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" + + (runtime.totalMemory() - runtime.freeMemory()) / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" + + runtime.freeMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("##### END #####")); + + // Adding utility for downloading Dashboard reports. + + Map styles = new HashMap(); + HttpSession session = request.getSession(); + ServletOutputStream sos = null; + BufferedInputStream buf = null; + XSSFWorkbook wb = null; + String formattedReportName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); + String formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); + //Sheet name to be filled is taken from property. How would this be called if it is Dashboard? + //commented out since application will create and leave it blank. + //setSheetName(Globals.getSheetName()); + boolean isDashboard = false; + if ((session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) && ( ((String) session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)).equals(rr.getReportID())) ) { + isDashboard = true; + } + //boolean isDashboard = (session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null); + ArrayList sheetArrayList = new ArrayList(); + + Map reportRuntimeMap = null; + Map reportDataMap = null; + + ArrayList reportIDList = new ArrayList(); + + //Map reportDisplayTypeMap = null; + if(isDashboard) { + reportRuntimeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); + reportDataMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); + + if(reportRuntimeMap!=null) { + Set setReportRuntime = reportRuntimeMap.entrySet(); + for(Iterator iter = setReportRuntime.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); + reportIDList.add(rrDashRep.getReportID()); + } + } + } + + + + + int col = 0; + String reportTitle = (nvl(rr.getReportTitle()).length()>0?rr.getReportTitle():rr.getReportName()); + String reportDescr = rr.getReportDescr(); + + // Total Columns visible in excel + //col = getColumnCountForDownloadFile(rr, rd); + + int rowNum = 0; + + + XSSFSheet sheet = null; + //save the template + String filename = ""; + String extension = ""; + + String sheetRef = null; + + FileOutputStream os = null; //template file + File templateFile = null; + + if(isDashboard) { + if(reportRuntimeMap!=null) { + + FileInputStream readTemplate = null; + //Load customized styles + int count = 0; + + //If template supplied by Application + String templateFilename = rr.getTemplateFile(); + extension = templateFilename.substring(templateFilename.lastIndexOf(".")+1); + filename = formattedReportName+formattedDate+user_id; + + Set setReportRuntimeWB = reportRuntimeMap.entrySet(); + for(Iterator iter = setReportRuntimeWB.iterator(); iter.hasNext(); ) { + count++; + Map.Entry entry = (Entry) iter.next(); + ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); + os = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); + + if(count==1) { + if(nvl(rr.getTemplateFile()).length()>0) { + readTemplate = new FileInputStream(org.openecomp.portalsdk.analytics.system.AppUtils.getExcelTemplatePath()+rr.getTemplateFile()); + wb=new XSSFWorkbook(readTemplate); + } else { + //copy the os file to new file and open new file in below line + wb=new XSSFWorkbook(); + } + } else { + readTemplate = new FileInputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); + wb=new XSSFWorkbook(readTemplate); + } + if(rrDashRep!=null) + styles = loadXSSFStyles(rrDashRep, wb, styles); + String reportSheetName = new HtmlStripper().stripSpecialCharacters(rrDashRep.getReportName()); + if(nvl(reportSheetName).length()>28) + reportSheetName = reportSheetName.substring(0, 28); + sheet = wb.createSheet(count+"-"+reportSheetName); + if(!Globals.printExcelInLandscapeMode()) + sheet.getPrintSetup().setLandscape(false); + else + sheet.getPrintSetup().setLandscape(true); + wb.write(os); + os.flush(); + if(nvl(rr.getTemplateFile()).length()>0) { + readTemplate.close(); + } + os.close(); + + FileInputStream inF = new FileInputStream(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); + FileOutputStream outStream = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); + copyStream(inF, outStream); + outStream.flush(); + outStream.close(); + inF.close(); + + } + + FileInputStream xlsIn = null; + POIFSFileSystem fileSystem = null; + buf = null; + FileOutputStream xlsOut = null; + formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); + String xlsFName = "dashboard"+formattedDate+user_id+".xls"; + + Set setReportRuntime = reportRuntimeMap.entrySet(); + Set setReportDataMap = reportDataMap.entrySet(); + Iterator iter2 = setReportDataMap.iterator(); + + + //filename = templateFilename.substring(0, templateFilename.lastIndexOf("."))+"_"+formattedDate+user_id; + + count = 0; + for(Iterator iter = setReportRuntime.iterator(); iter.hasNext(); ) { + count++; + + Map.Entry entry = (Entry) iter.next(); + Map.Entry entryData = (Entry) iter2.next(); + ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); + ReportData rdDashRep = (ReportData) entryData.getValue(); + + String reportSheetName = new HtmlStripper().stripSpecialCharacters(rrDashRep.getReportName()); + if(nvl(reportSheetName).length()>28) + reportSheetName = reportSheetName.substring(0, 28); + sheet = wb.getSheet(count+"-"+reportSheetName); + sheetRef = sheet.getPackagePart().getPartName().getName(); + + //Step 2. Generate XML file. + File tmp = File.createTempFile("sheet", ".xml"); + FileOutputStream fileOutTemp = new FileOutputStream(tmp); + Writer fw = new OutputStreamWriter(fileOutTemp, XML_ENCODING); + String sql_whole = rrDashRep.getWholeSQL(); + + SpreadsheetWriter sw = new SpreadsheetWriter(fw); + sw.beginSheet(); + + + generate(wb, sw, styles, rdDashRep, sql_whole, rrDashRep, request, sheet); + + + sw.endSheet(); + + fw.flush(); + fw.close(); + fileOutTemp.flush(); + fileOutTemp.close(); + + + //Step 3. Substitute the template entry with the generated data + + FileOutputStream outF = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); + templateFile = new File(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); + substitute(templateFile, tmp, sheetRef.substring(1), outF); + outF.flush(); + outF.close(); + + FileInputStream inF = new FileInputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); + FileOutputStream outStream = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); + copyStream(inF, outStream); + outStream.flush(); + outStream.close(); + inF.close(); + } + } + } else { + //If template supplied by Application + if(nvl(rr.getTemplateFile()).length()>0) { + String templateFilename = rr.getTemplateFile(); + extension = templateFilename.substring(templateFilename.lastIndexOf(".")+1); + filename = formattedReportName+formattedDate+user_id; + //filename = templateFilename.substring(0, templateFilename.lastIndexOf("."))+"_"+formattedDate+user_id; + } else + filename = formattedReportName+formattedDate+user_id; + + + if(nvl(rr.getTemplateFile()).length()<=0) { + os = new FileOutputStream(AppUtils.getTempFolderPath()+"template"+formattedDate+user_id+".xlsx"); + wb=new XSSFWorkbook(); + //Load customized styles + if (rr != null) + styles = loadXSSFStyles(rr, wb, styles); + //create data sheet + if(isDashboard) { + + } else { + + } + String reportSheetName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); + if(nvl(reportSheetName).length()>28) + reportSheetName = reportSheetName.substring(0, 28); + sheet = wb.createSheet(reportSheetName); + + //customized mode + if(!Globals.printExcelInLandscapeMode()) + sheet.getPrintSetup().setLandscape(false); + else + sheet.getPrintSetup().setLandscape(true); + //get data sheet name + sheetRef = sheet.getPackagePart().getPartName().getName(); + wb.write(os); + os.flush(); + //wb = null; + os.close(); + + } else { + os = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); + FileInputStream readTemplate = new FileInputStream(org.openecomp.portalsdk.analytics.system.AppUtils.getExcelTemplatePath()+rr.getTemplateFile()); + wb=new XSSFWorkbook(readTemplate); + if (rr != null) + styles = loadXSSFStyles(rr, wb, styles); + sheet = wb.getSheetAt(0); + if(!Globals.printExcelInLandscapeMode()) + sheet.getPrintSetup().setLandscape(false); + else + sheet.getPrintSetup().setLandscape(true); + //sheet = wb.getSheet(getSheetName()); + sheetRef = sheet.getPackagePart().getPartName().getName(); + wb.write(os); + os.flush(); + readTemplate.close(); + //wb = null; + os.close(); + } + + //Step 2. Generate XML file. + File tmp = File.createTempFile("sheet", ".xml"); + FileOutputStream fileOutTemp = new FileOutputStream(tmp); + Writer fw = new OutputStreamWriter(fileOutTemp, XML_ENCODING); + + //String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + String sql_whole = ""; + sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + + if(sql_whole==null) { + if (!rr.getReportType().equals(AppConstants.RT_HIVE)) + sql_whole = rr.getWholeSQL(); + else + sql_whole = rr.getReportSQL(); + } + + SpreadsheetWriter sw = new SpreadsheetWriter(fw); + + sw.beginSheet(); + + if((rd.getDataRowCount() >= rr.getReportDataSize()) && !rr.getReportType().equals(AppConstants.RT_HIVE)) { + sql_whole=""; + } + + generate(wb, sw, styles, rd, sql_whole, rr, request, sheet); + + sw.endSheet(); + + fw.flush(); + fw.close(); + fileOutTemp.flush(); + fileOutTemp.close(); + + + //Step 3. Substitute the template entry with the generated data + + FileOutputStream outF = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); + + if(nvl(rr.getTemplateFile()).length()>0) { + templateFile = new File(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); + } else + templateFile = new File(AppUtils.getTempFolderPath()+"template"+formattedDate+user_id+".xlsx"); + + substitute(templateFile, tmp, sheetRef.substring(1), outF); + outF.flush(); + outF.close(); + + } + //get servlet output stream + + + response.reset(); + sos = response.getOutputStream(); + String mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + if(extension.equals("xlsm")) + mime_type = "application/vnd.ms-excel.sheet.macroEnabled.12"; + response.setContentType(mime_type); + + response.setHeader("Content-disposition", "attachment;filename="+filename+"."+ nvls(extension, "xlsx")); + + buf = new BufferedInputStream(new FileInputStream(AppUtils.getTempFolderPath()+filename + "."+ nvls(extension, "xlsx"))); + int readBytes = 0; + + //read from the file; write to the ServletOutputStream + while ((readBytes = buf.read()) != -1) + sos.write(readBytes); + + buf.close(); + sos.flush(); + sos.close(); + logger.debug(EELFLoggerDelegate.debugLogger, ("ENDING..DOWNLOADING XLSX...")); + logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); + logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" + + (runtime.totalMemory() - runtime.freeMemory()) / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" + + runtime.freeMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("##### END #####")); + } + + /** + * + * @param zipfile the template file + * @param tmpfile the XML file with the sheet data + * @param entry the name of the sheet entry to substitute, e.g. xl/worksheets/sheet1.xml + * @param out the stream to write the result to + */ + private static void substitute(File zipfile, File tmpfile, String entry, OutputStream out) throws IOException { + ZipFile zip = new ZipFile(zipfile); + + ZipOutputStream zos = new ZipOutputStream(out); + + @SuppressWarnings("unchecked") + Enumeration en = (Enumeration) zip.entries(); + while (en.hasMoreElements()) { + ZipEntry ze = en.nextElement(); + if(!ze.getName().equals(entry)){ + zos.putNextEntry(new ZipEntry(ze.getName())); + InputStream is = zip.getInputStream(ze); + copyStream(is, zos); + is.close(); + } + } + zos.putNextEntry(new ZipEntry(entry)); + InputStream is = new FileInputStream(tmpfile); + copyStream(is, zos); + zos.flush(); + zos.close(); + is.close(); + zip.close(); + } + + private static void copyStream(InputStream in, OutputStream out) throws IOException { + byte[] chunk = new byte[1024]; + int count; + while ((count = in.read(chunk)) >=0 ) { + out.write(chunk,0,count); + } + } + + + public void createCSVFileContent(Writer out, ReportData rd, + ReportRuntime rr, HttpServletRequest request, HttpServletResponse response) + throws RaptorException { + //ArrayList reportParamNameValues = rr.getParamNameValuePairs(); + //String reportTitle = rr.getReportName(); + //String reportDescr = rr.getReportDescr(); + PrintWriter csvOut = new PrintWriter(out); + ServletOutputStream sos = null; + BufferedInputStream buf = null; + String fileName = ""; + String formattedReportName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); + String formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); + String fName = formattedReportName+formattedDate+AppUtils.getUserID(request); + boolean raw = AppUtils.getRequestFlag(request, "raw"); + String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + + + String csvFName = fName+".csv"; + String zipFName = fName+".zip"; + if(true) { + try { + fileName = AppUtils.getTempFolderPath()+""+csvFName; + csvOut = new PrintWriter(new BufferedWriter( + new OutputStreamWriter( + new FileOutputStream(fileName), "UTF-8")), false); + } catch (FileNotFoundException fex) { + fex.printStackTrace(); + } + catch (UnsupportedEncodingException fex1) { + fex1.printStackTrace(); + } + } + HtmlStripper strip = new HtmlStripper(); + ResultSet rs = null; + //OracleConnection conn = null; + //OracleStatement st = null; + //Connection conO = null; + //Statement stO = null; + Connection conn = null; + Statement st = null; + ResultSetMetaData rsmd = null; + ColumnHeaderRow chr = null; + int mb = 1024*1024; + Runtime runtime = Runtime.getRuntime(); + String valueName = ""; + if(!raw) { + String reportTitle = (nvl(rr.getReportTitle()).length()>0?rr.getReportTitle():rr.getReportName()); + csvOut.println(); + csvOut.print("\"" + reportTitle + "\","); + csvOut.println(); + + if(Globals.disclaimerPositionedTopInCSVExcel()) { + if(Globals.getShowDisclaimer()) { + csvOut.println(); + csvOut.print("\"" + Globals.getFooterFirstLine() + "\","); + csvOut.println(); + csvOut.print("\"" + Globals.getFooterSecondLine() + "\","); + csvOut.println(); + csvOut.println(); + } + } + } + if (Globals.getPrintParamsInCSVDownload() && !raw) { + ArrayList paramsList = rr.getParamNameValuePairsforPDFExcel(request, 1); + if(paramsList.size()<=0) { + paramsList = (ArrayList) request.getSession().getAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); + } + int paramSeq = 0; + for (Iterator iter = paramsList.iterator(); iter.hasNext();) { + IdNameValue value = (IdNameValue) iter.next(); + //System.out.println("\"" + value.getId() + " = " + value.getName() + "\""); + if(nvl(value.getId()).trim().length()>0 && (!nvl(value.getId()).trim().equals("BLANK"))) { + paramSeq += 1; + if(paramSeq <= 1) { + csvOut.print("\"" + "Run-time Parameters" + "\""); + csvOut.println(); + //strBuf.append("Run-time Parameters\n"); + } + csvOut.print("\"" + value.getId() +":" + "\","); + valueName = nvl(value.getName()); + if(valueName.indexOf("~")!= -1 && valueName.startsWith("(")) { + csvOut.print("\"'" + valueName.replaceAll("~",",")+ "'\","); + } else { + if(valueName.startsWith("(") && valueName.endsWith(")")) { + csvOut.print("\"" + valueName.replaceAll("~",",").substring(1, valueName.length()-1)+ "\","); + } else + csvOut.print("\"" + valueName.replaceAll("~",",")+ "\","); + } + csvOut.println(); + + //strBuf.append(value.getId()+": "+ value.getName()+"\n"); + } + } //for + csvOut.println(); + csvOut.println(); + } + + System.out.println("##### Heap utilization statistics [MB] #####"); + System.out.println("Used Memory:" + + (runtime.maxMemory() - runtime.freeMemory()) / mb); + System.out.println("Free Memory:" + + runtime.freeMemory() / mb); + System.out.println("Total Memory:" + runtime.totalMemory() / mb); + System.out.println("Max Memory:" + runtime.maxMemory() / mb); + + sql_whole = ""; + sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + + if(sql_whole==null) { + if (!rr.getReportType().equals(AppConstants.RT_HIVE)) + sql_whole = rr.getWholeSQL(); + else + sql_whole = rr.getReportSQL(); + } + + + if(nvl(sql_whole).length()>0) { + try { + conn = ConnectionUtils.getConnection(rr.getDbInfo()); + st = conn.createStatement(); + //conn.setDefaultRowPrefetch(1000); + //st.setFetchDirection(ResultSet.TYPE_FORWARD_ONLY); + //st.setFetchSize(1000); + System.out.println("************* Map Whole SQL *************"); + System.out.println(sql_whole); + System.out.println("*****************************************"); + rs = st.executeQuery(sql_whole); + //st.setFetchSize(1000); + rsmd = rs.getMetaData(); + int numberOfColumns = rsmd.getColumnCount(); + HashMap colHash = new HashMap(); + String title = ""; + + if(rd!=null) { + + /*if(rd.reportTotalRowHeaderCols!=null) { + csvOut.print("\"" + "#" + "\","); + }*/ + + for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { + chr = rd.reportColumnHeaderRows.getNext(); + for (chr.resetNext(); chr.hasNext();) { + ColumnHeader ch = chr.getNext(); + title = ch.getColumnTitle(); + title = Utils.replaceInString(title,"_nl_", " \n"); + if(ch.isVisible() && nvl(title).length()>0) { + csvOut.print("\"" + title + "\","); + for (int i = 1; i < ch.getColSpan(); i++) + csvOut.print(","); + } + } // for + + csvOut.println(); + } // for + int rowCount = 0; + while(rs.next()) { +/* if(runtime.freeMemory()/mb <= ((runtime.maxMemory()/mb)*Globals.getMemoryThreshold()/100) ) { + csvOut.print(Globals.getUserDefinedMessageForMemoryLimitReached() + " " + rowCount +"records out of " + rr.getReportDataSize() + " were downloaded to CSV."); + break; + } +*/ rowCount++; + //if(!raw) { + colHash = new HashMap(); + for (int i = 1; i <= numberOfColumns; i++) { + colHash.put(rsmd.getColumnLabel(i).toUpperCase(), rs.getString(i)); + } + /*if(rd.reportDataTotalRow!=null) { + csvOut.print("\"" + rowCount + "\","); + }*/ + for (chr.resetNext(); chr.hasNext();) { + ColumnHeader ch = chr.getNext(); + title = ch.getColumnTitle(); + title = Utils.replaceInString(title,"_nl_", " \n"); + + if(ch.isVisible() && nvl(title).length()>0) { + csvOut.print("\"" + strip.stripCSVHtml(nvl((String)colHash.get(ch.getColId().toUpperCase()))) + "\","); + } + + } + csvOut.println(); + /*} else { + for (int i = 1; i <= numberOfColumns; i++) { + csvOut.print("\"" + strip.stripCSVHtml( rs.getString(i)) + "\","); + } + csvOut.println(); + }*/ + + } + + if(rd.reportDataTotalRow!=null) { + for (rd.reportDataTotalRow.resetNext(); rd.reportDataTotalRow.hasNext();) { + DataRow dr = rd.reportDataTotalRow.getNext(); + csvOut.print("\"" + "Total" + "\","); + dr.resetNext();dr.getNext(); + for (; dr.hasNext();) { + DataValue dv = dr.getNext(); + if(dv.isVisible()) { + csvOut.print("\"" + strip.stripCSVHtml(dv.getDisplayValue()) + "\","); + } + } // for + + csvOut.println(); + } + } + + if(rowCount == 0) { + csvOut.print("\"No Data Found \""); + } + } else { + csvOut.print("\"No Data Found \""); + } + + } catch (SQLException ex) { + throw new RaptorException(ex); + } catch (ReportSQLException ex) { + throw new RaptorException(ex); + } catch (Exception ex) { + throw new RaptorException (ex); + } finally { + try { + if(conn!=null) + conn.close(); + if(st!=null) + st.close(); + if(rs!=null) + rs.close(); + } catch (SQLException ex) { + throw new RaptorException(ex); + } + } + + if(!raw) { + if(!Globals.disclaimerPositionedTopInCSVExcel()) { + if(Globals.getShowDisclaimer()) { + csvOut.print("\"" + Globals.getFooterFirstLine() + "\","); + csvOut.println(); + csvOut.print("\"" + Globals.getFooterSecondLine() + "\","); + csvOut.println(); + } + } + } + + // csvOut.flush(); + } else { + boolean firstPass = true; + if(rd!=null) { + if(rd.reportTotalRowHeaderCols!=null) { + csvOut.print("\"" + "#" + "\","); + } + + for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { + chr = rd.reportColumnHeaderRows.getNext(); + for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + + if (firstPass) + csvOut.print("\"" + rhc.getColumnTitle() + "\""); + csvOut.print(","); + } // for + firstPass = false; + + for (chr.resetNext(); chr.hasNext();) { + ColumnHeader ch = chr.getNext(); + if(ch.isVisible()) { + csvOut.print("\"" + ch.getColumnTitle() + "\","); + for (int i = 1; i < ch.getColSpan(); i++) + csvOut.print(","); + } + } // for + + csvOut.println(); + } // for + + firstPass = true; + int rowCount = 0; + for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { + if(rd.reportDataTotalRow!=null) { + rowCount++; + csvOut.print("\"" + rowCount + "\","); + } + + DataRow dr = rd.reportDataRows.getNext(); + + for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + if (firstPass) + rhc.resetNext(); + RowHeader rh = rhc.getNext(); + + csvOut.print("\"" + strip.stripCSVHtml(rh.getRowTitle()) + "\","); + } // for + firstPass = false; + + for (dr.resetNext(); dr.hasNext();) { + DataValue dv = dr.getNext(); + if(dv.isVisible()) + csvOut.print("\"" + strip.stripCSVHtml(dv.getDisplayValue()) + "\","); + } // for + + csvOut.println(); + } // for + if(rd.reportDataTotalRow!=null) { + for (rd.reportDataTotalRow.resetNext(); rd.reportDataTotalRow.hasNext();) { + DataRow dr = rd.reportDataTotalRow.getNext(); + csvOut.print("\"" + "Total" + "\","); + firstPass = false; + + for (dr.resetNext(); dr.hasNext();) { + DataValue dv = dr.getNext(); + if(dv.isVisible()) + csvOut.print("\"" + strip.stripCSVHtml(dv.getDisplayValue()) + "\","); + } // for + + csvOut.println(); + } + } + + if(!raw) { + if(!Globals.disclaimerPositionedTopInCSVExcel()) { + if(Globals.getShowDisclaimer()) { + csvOut.print("\"" + Globals.getFooterFirstLine() + "\","); + csvOut.println(); + csvOut.print("\"" + Globals.getFooterSecondLine() + "\","); + csvOut.println(); + } + } + } + + //csvOut.flush(); + } else { + csvOut.print("\"No Data Found \""); + } + } + csvOut.flush(); + csvOut.close(); + +/* + if (Globals.getPrintTitleInDownload() && reportTitle != null) { + csvOut.println(); + csvOut.println("\"" + reportTitle + "\""); + csvOut.println(); + if (Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0) { + csvOut.println("\"" + reportDescr + "\""); + csvOut.println(); + } + } // if + + if (Globals.getPrintParamsInDownload() && reportParamNameValues != null) { + csvOut.println(); + for (Iterator iter = reportParamNameValues.iterator(); iter.hasNext();) { + IdNameValue value = (IdNameValue) iter.next(); + csvOut.println("\"" + value.getId() + " = " + value.getName() + "\""); + } // for + csvOut.println(); + } // if +*/ + if(true && !raw) { + try { + + //final int BUFFER = 2048; + + //fis.read(buf,0,buf.length); + int size = 0; + byte[] buffer = new byte[1024]; + + //CRC32 crc = new CRC32(); + //PrintStream fos = new PrintStream(new WriterOutputStream(out)); + //BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); + //ZipOutputStream s = new ZipOutputStream(dest); + ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(AppUtils.getTempFolderPath()+""+zipFName)); + FileInputStream fis = new FileInputStream(fileName); + + //s.setLevel(6); + + ZipEntry entry = new ZipEntry(csvFName); + //crc.reset(); + zos.putNextEntry(entry); + + // read data to the end of the source file and write it to the zip + // output stream. + while ((size = fis.read(buffer, 0, buffer.length)) > 0) { + zos.write(buffer, 0, size); + } + + zos.closeEntry(); + fis.close(); + + // Finish zip process + zos.close(); + + } catch(Exception e) { + e.printStackTrace(); + } + } + + response.reset(); + java.io.File file = null; + + if(true && !raw) { + response.setContentType("application/octet-stream"); + response.setHeader("Content-disposition","attachment;filename="+fName+".zip"); + file = new java.io.File(AppUtils.getTempFolderPath()+""+fName+".zip"); + } else { + response.setContentType("application/csv"); + response.setHeader("Content-disposition","attachment;filename="+fName+".csv"); + file = new java.io.File(AppUtils.getTempFolderPath()+""+fName+".csv"); + } + + + FileInputStream fileIn = null; + int c; + try { + sos = response.getOutputStream(); + fileIn = new FileInputStream(file); + buf = new BufferedInputStream(fileIn); + byte [] bOut = new byte [4096]; + //read from the file; write to the ServletOutputStream + //while ((readBytes = buf.read()) != -1) + int readBytes = 0; + while ((readBytes = buf.read (bOut, 0, 4096))> 0) { + buf.available(); + sos.write (bOut, 0, readBytes); + } + + } catch (IOException ex) { + ex.printStackTrace(); + } + catch(Exception e) { + e.printStackTrace(); + } finally { + try { + if (sos != null) + sos.close(); + if (buf != null) + buf.close(); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + + File f = new File (AppUtils.getTempFolderPath() + + fName); + if(f.exists()) f.delete(); + System.out.println("##### Heap utilization statistics [MB] #####"); + System.out.println("Used Memory:" + + (runtime.maxMemory() - runtime.freeMemory()) / mb); + logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" + + runtime.freeMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); + + } // createCSVFileContent + +/* public String saveCSVPageFile(HttpServletRequest request, ReportData rd, + ArrayList reportParamNameValues, String reportTitle, String reportDescr) { + try { + String formattedReportName = new HtmlStripper().stripSpecialCharacters(reportTitle); + String formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); + + String csvFName = formattedReportName+formattedDate+AppUtils.getUserID(request)+".csv"; + //String csvFName = AppUtils.generateFileName(request, AppConstants.FT_CSV); + + BufferedWriter csvOut = new BufferedWriter(new FileWriter(AppUtils + .getTempFolderPath() + + csvFName)); + createCSVFileContent(csvOut, rd, reportParamNameValues, reportTitle, reportDescr); + csvOut.close(); + + return csvFName; + } catch (Exception e) { + (new ErrorHandler()).processError(request, "Exception saving data to CSV file: " + + e.getMessage()); + return null; + } + } // saveCSVPageFile +*/ + +// public String saveAsFlatFile(HttpServletRequest request, ReportData rd, +// ReportRuntime rr, String reportTitle, String reportDescr) { +// try { +// String csvFName = AppUtils.generateFileName(request, AppConstants.FT_TXT); +// +// BufferedWriter txtOut = new BufferedWriter(new FileWriter(AppUtils +// .getTempFolderPath() +// + csvFName)); +// createFlatFileContent(txtOut, rd, rr, reportTitle, reportDescr); +// txtOut.close(); +// +// return csvFName; +// } catch (Exception e) { +// (new ErrorHandler()).processError(request, "Exception saving data to CSV file: " +// + e.getMessage()); +// return null; +// } +// } // saveCSVPageFile + + public String saveXMLFile(HttpServletRequest request, String reportName, String reportXML) { + try { + String xmlFName = AppUtils.generateUniqueFileName(request, reportName, AppConstants.FT_XML); + + PrintWriter xmlOut = new PrintWriter(new BufferedWriter(new FileWriter(new File( + AppUtils.getTempFolderPath() + xmlFName)))); + xmlOut.println(reportXML); + xmlOut.close(); + + //return AppUtils.getTempFolderURL() + // + java.net.URLEncoder.encode(java.net.URLDecoder.decode(xmlFName)); + return java.net.URLEncoder.encode(java.net.URLDecoder.decode(xmlFName)); + + } catch (Exception e) { + (new ErrorHandler()).processError(request, + "Exception saving XML source to file system: " + e.getMessage()); + return null; + } + } // saveXMLFile + + public ReportRuntime loadReportRuntime(HttpServletRequest request, String reportID) + throws RaptorException { + return loadReportRuntime(request, reportID, true); + } // loadReportRuntime + + public ReportRuntime loadReportRuntime(HttpServletRequest request, String reportID, + boolean prepareForExecution) throws RaptorException { + return loadReportRuntime(request, reportID, true, 2); // where 2 is adding to session + } + public ReportRuntime loadReportRuntime(HttpServletRequest request, String reportID, + boolean prepareForExecution, int requestFlag) throws RaptorException { + boolean refresh = nvl(request.getParameter(AppConstants.RI_REFRESH)).toUpperCase().startsWith("Y"); + boolean rDisplayContent = AppUtils.getRequestFlag(request, + AppConstants.RI_DISPLAY_CONTENT) + || AppUtils.getRequestFlag(request, "noFormFields"); + + ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( + AppConstants.SI_REPORT_RUNTIME); + boolean inSchedule = AppUtils.getRequestFlag(request, AppConstants.SCHEDULE_ACTION); + if (rr != null ) { + if(requestFlag == 7) { // DASH + String reportXML = ReportLoader.loadCustomReportXML(reportID); + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Report [" + reportID + "]: XML loaded")); + rr = ReportRuntime.unmarshal(reportXML, reportID, request); + rr.setParamValues(request, false,refresh); + rr.setDisplayFlags(true, true); // show content even at the first time + return rr; + } else { + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Load Report Runtime "+ reportID + " " +rr.getReportID() + " " + request.getParameter("refresh") )); + if (reportID.equals(rr.getReportID()) && (request.getParameter("refresh")==null || !request.getParameter("refresh").equals("Y"))) { + // The report runtime is already in the session + if (prepareForExecution) { + boolean resetParams = AppUtils.getRequestFlag(request, + AppConstants.RI_RESET_PARAMS); + rr.setParamValues(request, resetParams,refresh); + + if (resetParams) + rr.resetVisualSettings(); + rr.setDisplayFlags(nvl(request.getParameter(AppConstants.RI_SOURCE_PAGE)) + .length() == 0, rDisplayContent || rr.isDisplayOptionHideForm()); + } // if + + return rr; + } // if + } + } + + /* + * Cannot convert the definition => XML file not saved for preview also, + * commented code not maintained up to date ReportDefinition rdef = + * (ReportDefinition) + * request.getSession().getAttribute(AppConstants.SI_REPORT_DEFINITION); + * if(rdef!=null) if(reportID.equals(rdef.getReportID())) { // The + * report definition is in the session => create report runtime from it + * rr = new ReportRuntime(rdef, request); if(prepareForExecution) { + * request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, + * rr); + * rr.setDisplayFlags(request.getParameter(AppConstants.RI_SOURCE_PAGE)==null); } // + * if return rr; } // if + */ + + // Report is NOT in the session => load from the database + String reportXML = ReportLoader.loadCustomReportXML(reportID); + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Report [" + reportID + "]: XML loaded")); + + rr = ReportRuntime.unmarshal(reportXML, reportID, request); + if (prepareForExecution) { + String userID ; + int flag = 0; + if(request.getAttribute("schedule_email_userId") != null) { + userID = (String)request.getAttribute("schedule_email_userId"); + flag = 1; + } + else + userID = AppUtils.getUserID(request); + // If it is dashboard type then report can be viewed without specific privilege to report + String dashboardId = AppUtils.getRequestValue(request, AppConstants.RI_DASHBOARD_ID); + //System.out.println("USSSSSSSSSSSSERID " + userID); + //System.out.println("PDF " + AppUtils.getRequestNvlValue(request, "pdfAttachmentKey") ); + if(!rr.isDashboardType() && !(isReportAddedAsDashboard(request, dashboardId, rr.getReportID()))) { + if ( AppUtils.getRequestNvlValue(request, "pdfAttachmentKey").length()<=0 ) + if(flag == 1 )rr.checkUserReadAccess(request, userID); + else rr.checkUserReadAccess(request); + } + // TODO ON Demand + //rr.setXmlFileName(saveXMLFile(request, rr.getReportName(), reportXML)); + if (rDisplayContent) { + //System.out.println("In rDisplayContent "); + rr.setParamValues(request, false,true); + //if (requestFlag==2) + request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); + } + if(inSchedule) { + //System.out.println("In inSchedule "); + rr.setParamValues(request, false,false); + } + if( requestFlag == 7 ) { // DASH + rr.setDisplayFlags(true, true); + } else { + rr.setDisplayFlags(request.getParameter(AppConstants.RI_SOURCE_PAGE) == null, + rDisplayContent || rr.isDisplayOptionHideForm()); + } +// System.out.println("Report ID B4 Id in reportHandler " +// + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); +// System.out.println("requestFlag " + requestFlag); + if(requestFlag==2 && !rDisplayContent) { + //System.out.println("In Request Flag "); + request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); + rr.setParamValues(request, false, false); + } + else if(requestFlag==1) { + rr.setParamValues(request, false,refresh); + request.setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); + + } +// System.out.println("Report ID B4 Id in reportHandler " +// + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); + //request.setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); + } // if + + return rr; + } // loadReportRuntime + + private boolean isReportAddedAsDashboard(HttpServletRequest request, String dashboardId, String reportId)throws RaptorException { + if(nvl(dashboardId).length() <= 0) + return false; + String reportXML = ReportLoader.loadCustomReportXML(dashboardId); + ReportDefinition rdef = createReportDefinition(request, dashboardId, reportXML); + List l = rdef.getDashBoardReports().getReportsList(); + for (Iterator iterator = l.iterator(); iterator.hasNext();) { + Reports reports = (Reports) iterator.next(); + if(reports.getReportId().equals(reportId)) return true; + + } + return false; + } + + public ReportDefinition createReportDefinition(HttpServletRequest request, + String reportID, String reportXML) throws RaptorException { + ReportDefinition rdef = ReportDefinition.unmarshal(reportXML, reportID, request); + rdef.generateWizardSequence(request); + return rdef; + } // createReportDefinition + + public ReportDefinition loadReportDefinition(HttpServletRequest request, String reportID) + throws RaptorException { + //System.out.println("********* ReportID " + reportID); + boolean isReportIDBlank = (reportID.length() == 0 || reportID.equals("-1")); + String actionKey = nvl(request.getParameter(AppConstants.RI_ACTION), ""); + String wizardActionKey = nvl(request.getParameter(AppConstants.RI_WIZARD_ACTION), ""); + ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( + AppConstants.SI_REPORT_DEFINITION); + if(nvl(actionKey).equals("report.edit")) + rdef = null; + //ReportDefinition rdef = null; + if (rdef != null) + if (isReportIDBlank || reportID.equals(rdef.getReportID())) { + // The report definition is already in the session + return rdef; + } + + ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( + AppConstants.SI_REPORT_RUNTIME); + if (rr != null) + if (isReportIDBlank || reportID.equals(rr.getReportID())) { + // The report runtime is in the session => create report + // definition from it + rdef = new ReportDefinition(rr, request); + String userID = AppUtils.getUserID(request); + rdef.generateWizardSequence(request); + // rdef.checkUserWriteAccess(userID); + + request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); + return rdef; + } // if + + // Report is NOT in the session => load from the database + if (isReportIDBlank) + rdef = ReportDefinition.createBlank(request); + else { + String reportXML = ReportLoader.loadCustomReportXML(reportID); + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Report [" + reportID + "]: XML loaded")); + rdef = createReportDefinition(request, reportID, reportXML); + } // else + + request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); + return rdef; + } // loadReportDefinition + + public void setSheetName( String sheet_name ) { + SHEET_NAME = sheet_name; + } + + public String getSheetName() { + return SHEET_NAME; + } + + /** + * Writes spreadsheet data in a Writer. + * (YK: in future it may evolve in a full-featured API for streaming data in Excel) + */ + public static class SpreadsheetWriter { + private final Writer _out; + private int _rownum; + + public SpreadsheetWriter(Writer out){ + _out = out; + } + + public void beginSheet() throws IOException { + _out.write("" + + "" ); + _out.write("\n"); + } + + public void endSheet() throws IOException { + _out.write(""); + _out.write(""); + } + + /** + * Insert a new row + * + * @param rownum 0-based row number + */ + public void insertRow(int rownum) throws IOException { + _out.write("\n"); + this._rownum = rownum; + } + + /** + * Insert row end marker + */ + public void endRow() throws IOException { + _out.write("\n"); + } + + public void createCell(int columnIndex, String value, int styleIndex) throws IOException { + String ref = new CellReference(_rownum, columnIndex).formatAsString(); + _out.write(""); + _out.write(""+value+""); + _out.write(""); + } + + public void createCell(int columnIndex, String value) throws IOException { + createCell(columnIndex, value, -1); + } + + public void createCell(int columnIndex, double value, int styleIndex) throws IOException { + String ref = new CellReference(_rownum, columnIndex).formatAsString(); + _out.write(""); + _out.write(""+value+""); + _out.write(""); + } + + public void createCell(int columnIndex, double value) throws IOException { + createCell(columnIndex, value, -1); + } + + public void createCell(int columnIndex, Calendar value, int styleIndex) throws IOException { + createCell(columnIndex, DateUtil.getExcelDate(value, false), styleIndex); + } + } + + public int getColumnCountForDownloadFile(ReportRuntime rr, ReportData rd) { + int columnCount = 0; + for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { + ColumnHeaderRow chr = rd.reportColumnHeaderRows.getNext(); + for(chr.resetNext(); chr.hasNext(); ) { + ColumnHeader ch = chr.getNext(); + if(ch.isVisible()) { + columnCount++; + } + } + } + if(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { + for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + if(rhc.isVisible()) { + columnCount++; + } + } + } + return columnCount; + } + + + private Map loadXSSFStyles(ReportRuntime rr, XSSFWorkbook wb, Map loadedStyles) { + XSSFCellStyle styleDefault = wb.createCellStyle(); + //System.out.println("Load Styles"); + // Style default will be normal with no background + XSSFFont fontDefault = wb.createFont(); + + XSSFDataFormat xssffmt = wb.createDataFormat(); + // The default will be plain . + fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); + fontDefault.setFontHeight((short) (font_size / 0.05)); + fontDefault.setFontName("Tahoma"); + + styleDefault.setAlignment(XSSFCellStyle.ALIGN_CENTER); + styleDefault.setBorderBottom(XSSFCellStyle.BORDER_THIN); + styleDefault.setBorderTop(XSSFCellStyle.BORDER_THIN); + styleDefault.setBorderLeft(XSSFCellStyle.BORDER_THIN); + styleDefault.setBorderRight(XSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleDefault.setFillPattern(XSSFCellStyle.NO_FILL); + styleDefault.setFont(fontDefault); + ArrayList semColumnList = new ArrayList(); + List dsList = rr.getDataSourceList().getDataSource(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType element = (DataSourceType) iter.next(); + List dcList = element.getDataColumnList().getDataColumn(); + for (Iterator iterator = dcList.iterator(); iterator.hasNext();) { + DataColumnType element1 = (DataColumnType) iterator.next(); + semColumnList.add(element1.getSemaphoreId()); + + } + } + SemaphoreList semList = rr.getSemaphoreList(); + Map hashMapStyles = new HashMap();; + Map hashMapFonts = new HashMap(); + hashMapFonts.put("default", fontDefault); + hashMapStyles.put("default", styleDefault); + XSSFCellStyle styleLeftDefault = wb.createCellStyle(); + styleLeftDefault.setAlignment(XSSFCellStyle.ALIGN_LEFT); + styleLeftDefault.setBorderBottom(XSSFCellStyle.BORDER_THIN); + styleLeftDefault.setBorderTop(XSSFCellStyle.BORDER_THIN); + styleLeftDefault.setBorderLeft(XSSFCellStyle.BORDER_THIN); + styleLeftDefault.setBorderRight(XSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleLeftDefault.setFillPattern(XSSFCellStyle.NO_FILL); + styleLeftDefault.setFont(fontDefault); + hashMapStyles.put("defaultLeft", styleLeftDefault); + + + XSSFCellStyle styleDate = wb.createCellStyle(); + styleDate.setAlignment(XSSFCellStyle.ALIGN_RIGHT); + styleDate.setDataFormat(xssffmt.getFormat("d-mmm-yy")); + styleDate.setAlignment(XSSFCellStyle.ALIGN_CENTER); + styleDate.setBorderBottom(XSSFCellStyle.BORDER_THIN); + styleDate.setBorderTop(XSSFCellStyle.BORDER_THIN); + styleDate.setBorderLeft(XSSFCellStyle.BORDER_THIN); + styleDate.setBorderRight(XSSFCellStyle.BORDER_THIN); + // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); + styleDate.setFillPattern(XSSFCellStyle.NO_FILL); + styleDate.setFont(fontDefault); + hashMapStyles.put("date", styleDate); + + XSSFCellStyle rowHeaderStyle = wb.createCellStyle(); + XSSFFont headerFont = wb.createFont(); + headerFont.setBold(true); + rowHeaderStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + rowHeaderStyle.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND); + rowHeaderStyle.setFont(headerFont); + rowHeaderStyle.setBorderTop(XSSFCellStyle.BORDER_THIN); + rowHeaderStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN); + rowHeaderStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN); + rowHeaderStyle.setBorderRight(XSSFCellStyle.BORDER_THIN); + hashMapStyles.put("header", rowHeaderStyle); + + + XSSFCellStyle boldStyle = wb.createCellStyle(); + //headerFont = wb.createFont(); + //headerFont.setBold(true); + boldStyle.setFont(headerFont); + boldStyle.setBorderTop(XSSFCellStyle.BORDER_THIN); + boldStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN); + boldStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN); + boldStyle.setBorderRight(XSSFCellStyle.BORDER_THIN); + boldStyle.setAlignment(HorizontalAlignment.CENTER); + hashMapStyles.put("title", boldStyle); + + XSSFCellStyle cellStyle = null; + if (semList == null || semList.getSemaphore() == null) { + hashMapStyles.put("default", styleDefault); + } /*else { + for (Iterator iter = semList.getSemaphore().iterator(); iter.hasNext();) { + SemaphoreType sem = (SemaphoreType) iter.next(); + if(!semColumnList.contains(sem.getSemaphoreId())) continue; + //System.out.println("SemphoreId ----> " + sem.getSemaphoreId()); + FormatList fList = sem.getFormatList(); + List formatList = fList.getFormat(); + for (Iterator fIter = formatList.iterator(); fIter.hasNext();) { + FormatType fmt = (FormatType) fIter.next(); + if(fmt!=null){ + //if (fmt.getLessThanValue().length() > 0) { + cellStyle = wb.createCellStyle(); + XSSFFont cellFont = wb.createFont(); + //System.out.println("Format Id " + fmt.getFormatId()); + if (nvl(fmt.getBgColor()).length() > 0) { +// System.out.println("Load Styles " + +// fmt.getFormatId() +// + " " +fmt.getBgColor() + " " + +// ExcelColorDef.getExcelColor(fmt.getBgColor())); + cellStyle.setFillForegroundColor(ExcelColorDef.getExcelColor(fmt + .getBgColor())); + cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); + } + if (nvl(fmt.getFontColor()).length() > 0) { + cellFont.setColor(ExcelColorDef.getExcelColor(fmt.getFontColor())); + } else + cellFont.setColor((short) HSSFFont.COLOR_NORMAL); + if (fmt.isBold()) + cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + if (fmt.isItalic()) + cellFont.setItalic(true); + if (fmt.isUnderline()) + cellFont.setUnderline(HSSFFont.U_SINGLE); + if(nvl(fmt.getFontFace()).length()>0) + cellFont.setFontName(fmt.getFontFace()); + else + cellFont.setFontName("Tahoma"); + //cellFont.setFontHeight((short) (10 / 0.05)); + + if(nvl(fmt.getFontSize()).length()>0) { + try { + cellFont.setFontHeight((short) (Integer.parseInt(fmt.getFontSize()) / 0.05)); + } catch(NumberFormatException e){ + cellFont.setFontHeight((short) (font_size / 0.05)); + } + } + else + cellFont.setFontHeight((short) (font_size / 0.05)); + cellStyle.setFont(cellFont); + cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); + cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); + cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); + cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); + cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); + hashMapStyles.put(fmt.getFormatId(), cellStyle); + } else { + //hashMapStyles.put(fmt.getFormatId(), styleDefault); + hashMapStyles.put("default", styleDefault); + } + } + + } + }*/ + loadedStyles.putAll(hashMapStyles); + return loadedStyles; + } + + private void generate(XSSFWorkbook wb, SpreadsheetWriter sw, Map styles, ReportData rd, String sql_whole, ReportRuntime rr, HttpServletRequest request, XSSFSheet sheet) throws Exception { + HtmlStripper strip = new HtmlStripper(); + XSSFCellStyle styleCell = null; + XSSFCellStyle styleRowCell = null; + XSSFCellStyle styleDefaultCell = null; + + styleDefaultCell = (XSSFCellStyle) styles.get("default"); + + + // to check performance + int mb = 1024*1024; + Runtime runtime = Runtime.getRuntime(); + + int rowNum = 0; + /*short s1 = 0, s2 = (short) (col-1); + rowNum += 1; + sw.insertRow(rowNum); + int styleIndex = styles.get("header").getIndex(); + sw.createCell(rowNum, reportTitle, styleIndex); + + //header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) 9)+reportTitle+"\n"+((Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0)?reportDescr:"")); + + // Report Description + if (Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0) { + sw.createCell(rowNum, reportDescr, styleIndex); + } + rowNum += 2; + sw.insertRow(rowNum);*/ + int cellNum = 0; + + + ColumnHeaderRow chr = null; + java.util.HashMap dataTypeMap = new java.util.HashMap(); + boolean firstPass = true; + int columnRows = rr.getVisibleColumnCount() ; + + HttpSession session = request.getSession(); + String drilldown_index = (String) session.getAttribute("drilldown_index"); + int index = 0; + try { + index = Integer.parseInt(drilldown_index); + } catch (NumberFormatException ex) { + index = 0; + } + String header = (String) session.getAttribute("TITLE_"+index); + String subtitle = (String) session.getAttribute("SUBTITLE_"+index); + if(nvl(header).length()>0) { + header = Utils.replaceInString(header, "
", " "); + header = Utils.replaceInString(header, "
", " "); + header = Utils.replaceInString(header, "
", " "); + header = strip.stripHtml(nvl(header).trim()); + subtitle = Utils.replaceInString(subtitle, "
", " "); + subtitle = Utils.replaceInString(subtitle, "
", " "); + subtitle = Utils.replaceInString(subtitle, "
", " "); + subtitle = strip.stripHtml(nvl(subtitle).trim()); + //XSSFRow row = sheet.createRow(rowNum); + sw.insertRow(rowNum); + cellNum = 0; + //XSSFCell cell = row.createCell(cellNum); + sw.createCell(cellNum, Utils.excelEncode(header)); + for (int i = 1; i <= columnRows; i++) { + sw.createCell(cellNum+i, ""); + } + sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); + sw.endRow(); +/* cell.setCellValue(Utils.excelEncode(header)); + cell.setCellStyle(styles.get("title")); +*/ //sw.createCell(cellNum,Utils.excelEncode(header), styles.get("title").getIndex()); +// sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); + rowNum += 1; +// row = sheet.createRow(rowNum); + sw.insertRow(rowNum); + cellNum = 0; +/* cell = row.createCell(cellNum); + cell.setCellValue(Utils.excelEncode(subtitle)); + cell.setCellStyle(styles.get("title")); +*/ //sw.createCell(cellNum,Utils.excelEncode(header), styles.get("title").getIndex()); + + sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); + sw.createCell(cellNum, Utils.excelEncode(subtitle)); + sw.endRow(); + //sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); +/* sw.insertRow(rowNum); + cellNum = 0; + sw.createCell(cellNum,Utils.excelEncode(subtitle), styles.get("title").getIndex()); + sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); + +*/ rowNum += 1; + } + cellNum = 0; + String title = ""; + for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { + sw.insertRow(rowNum); + cellNum = -1; + /*if(rd.reportTotalRowHeaderCols!=null) { + cellNum +=1; + sw.createCell(cellNum, "No.", styles.get("header").getIndex()); + + //row.getCell((short) cellNum).setCellStyle(styleDataHeader); + }*/ + chr = rd.reportColumnHeaderRows.getNext(); + + if(nvl(sql_whole).length() <= 0 || (!rr.getReportType().equals(AppConstants.RT_LINEAR))) { + + for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { + cellNum += 1; + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + title = rhc.getColumnTitle(); + title = Utils.replaceInString(title,"_nl_", " \n"); + + sw.createCell(cellNum,Utils.excelEncode(title), styles.get("header").getIndex()); + //sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum+columnRows, (short) (cellNum))); + //System.out.println(" **************** Row Header Title " + rhc.getColumnTitle() + " " + cellNum + " " ); + //System.out.println(cellNum + " " + cellWidth.size()); + } // for + + } + + firstPass = false; + for (chr.resetNext(); chr.hasNext();) { + ColumnHeader ch = chr.getNext(); + if(ch.isVisible()) { + cellNum += 1; + int colSpan = ch.getColSpan()-1; + title = ch.getColumnTitle(); + title = Utils.replaceInString(title,"_nl_", " \n"); + sw.createCell(cellNum, Utils.excelEncode(title), styles.get("header").getIndex()); + if(colSpan > 0) { + for ( int k = 1; k <= colSpan; k++ ) { + sw.createCell(cellNum+k, "", styles.get("header").getIndex()); + } + //sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (cellNum+colSpan))); + } + if(colSpan > 0) + cellNum += colSpan; + } + } // for + rowNum += 1; + } // for + + sw.endRow(); + //All the possible combinations of date format + CreationHelper createHelper = wb.getCreationHelper(); + HashMap dateFormatMap = new HashMap(); + + SimpleDateFormat MMDDYYYYFormat = new SimpleDateFormat("MM/dd/yyyy"); + SimpleDateFormat YYYYMMDDFormat = new SimpleDateFormat("yyyy/MM/dd"); + SimpleDateFormat MONYYYYFormat = new SimpleDateFormat("MMM yyyy"); + SimpleDateFormat MMYYYYFormat = new SimpleDateFormat("MM/yyyy"); + SimpleDateFormat MMMMMDDYYYYFormat = new SimpleDateFormat("MMMMM dd, yyyy"); + SimpleDateFormat YYYYMMDDDASHFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat DDMONYYYYFormat = new SimpleDateFormat("dd-MMM-yyyy"); + SimpleDateFormat MONTHYYYYFormat = new SimpleDateFormat("MMMMM, yyyy"); + SimpleDateFormat MMDDYYYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + SimpleDateFormat MMDDYYYYHHMMFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm"); + SimpleDateFormat YYYYMMDDHHMMSSFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + SimpleDateFormat YYYYMMDDHHMMFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); + SimpleDateFormat DDMONYYYYHHMMSSFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); + SimpleDateFormat DDMONYYYYHHMMFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); + SimpleDateFormat DDMONYYHHMMFormat = new SimpleDateFormat("dd-MMM-yy HH:mm"); + SimpleDateFormat MMDDYYFormat = new SimpleDateFormat("MM/dd/yy"); + SimpleDateFormat MMDDYYHHMMFormat = new SimpleDateFormat("MM/dd/yy HH:mm"); + SimpleDateFormat MMDDYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); + SimpleDateFormat MMDDYYYYHHMMZFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm z"); + SimpleDateFormat MMMMMDDYYYYHHMMSS = new SimpleDateFormat("MMMMM-dd-yyyy HH:mm:ss"); + + short dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yyyy"); + dateFormatMap.put("MMDDYYYY", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("yyyy/MM/dd"); + dateFormatMap.put("YYYYMMDD", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MMM yyyy"); + dateFormatMap.put("MONYYYY", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MM/yyyy"); + dateFormatMap.put("MMYYYY", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MMMMM dd, yyyy"); + dateFormatMap.put("MMMMMDDYYYY", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("yyyy-MM-dd"); + dateFormatMap.put("YYYYMMDDDASH", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"); + dateFormatMap.put("timestamp", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yyyy"); + dateFormatMap.put("MONTHYYYY", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MMMMM, yyyy"); + dateFormatMap.put("MMDDYYYY", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yyyy HH:mm:ss"); + dateFormatMap.put("MMDDYYYYHHMM", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yyyy HH:mm"); + dateFormatMap.put("MMDDYYYY", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("yyyy/MM/dd HH:mm:ss"); + dateFormatMap.put("YYYYMMDDHHMMSS", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("yyyy/MM/dd HH:mm"); + dateFormatMap.put("YYYYMMDDHHMM", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yyyy HH:mm:ss"); + dateFormatMap.put("DDMONYYYYHHMMSS", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yyyy HH:mm"); + dateFormatMap.put("DDMONYYYYHHMM", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yy HH:mm"); + dateFormatMap.put("DDMONYYHHMM", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yyyy"); + dateFormatMap.put("DDMONYYYY", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yy"); + dateFormatMap.put("MMDDYY", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yy HH:mm"); + dateFormatMap.put("MMDDYYHHMM", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yy HH:mm:ss"); + dateFormatMap.put("MMDDYYHHMMSS", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yyyy HH:mm z"); + dateFormatMap.put("MMDDYYYYHHMMZ", new Short(dateFormat)); + dateFormat = createHelper.createDataFormat().getFormat("MMMMM-dd-yyyy HH:mm:ss"); + dateFormatMap.put("MMMMMDDYYYYHHMMSS", new Short(dateFormat)); + + ResultSet rs = null; + Connection conn = null; + Statement st = null; + ResultSetMetaData rsmd = null; + + + if(nvl(sql_whole).length() >0 && (rr.getReportType().equals(AppConstants.RT_LINEAR) || rr.getReportType().equals(AppConstants.RT_HIVE) )) { + try { + conn = ConnectionUtils.getConnection(rr.getDbInfo()); + st = conn.createStatement(); + logger.debug(EELFLoggerDelegate.debugLogger, ("************* Map Whole SQL *************")); + logger.debug(EELFLoggerDelegate.debugLogger, (sql_whole)); + logger.debug(EELFLoggerDelegate.debugLogger, ("*****************************************")); + rs = st.executeQuery(sql_whole); + rsmd = rs.getMetaData(); + int numberOfColumns = rsmd.getColumnCount(); + HashMap colHash = new HashMap(); + DataRow dr = null; + int j = 0; + int rowCount = 0; + while(rs.next()) { + + rowCount++; + + if(rowCount%10000 == 0) { + // to check performance + logger.debug(EELFLoggerDelegate.debugLogger, ("Performance check for "+rowCount+" starting**************")); + logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); + logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" + + (runtime.totalMemory() - runtime.freeMemory()) / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" + + runtime.freeMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); + System.out.println(rowCount+"TH ROW****##### END #####"); + + // + } + sw.insertRow(rowNum); + cellNum = -1; + colHash = new HashMap(); + for (int i = 1; i <= numberOfColumns; i++) { + colHash.put(rsmd.getColumnLabel(i).toUpperCase(), strip.stripHtml(rs.getString(i))); + } + rd.reportDataRows.resetNext(); + dr = rd.reportDataRows.getNext(); + styleRowCell = null; + if (dr.isRowFormat() && styles != null) + styleRowCell = (XSSFCellStyle) styles.get(nvl(/*dr.getFormatId(),*/"","default")); + j = 0; + //if(rowCount%1000 == 0) wb.write(sos); + + /*if(rd.reportTotalRowHeaderCols!=null) { + //cellNum = -1; + //for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { + cellNum += 1; + //RowHeaderCol rhc = rd.reportRowHeaderCols.getRowHeaderCol(0); + //if (firstPass) + // rhc.resetNext(); + //RowHeader rh = rhc.getRowHeader(rowCount-1); + sw.createCell(cellNum, rowCount, styleDefaultCell.getIndex()); + + //} // for + }*/ + firstPass = false; + //cellNum = -1; + for (dr.resetNext(); dr.hasNext();j++) { + styleCell = null; + //for (chr.resetNext(); chr.hasNext();) { + //ColumnHeader ch = chr.getNext(); + DataValue dv = dr.getNext(); + HtmlFormatter htmlFormat = dv.getCellFormatter(); + + if (htmlFormat != null && dv.getFormatId() != null && styles != null) + styleCell = (XSSFCellStyle) styles.get(nvl(/*dv.getFormatId()*/"","default")); + String value = nvl((String)colHash.get(dv.getColId().toUpperCase())); + + boolean bold = false; + + if(dv.isVisible()) { + cellNum += 1; + //System.out.println("Stripping HTML 1"); + //cell.setCellValue(strip.stripHtml(dv.getDisplayValue())); + String dataType = (String) (dataTypeMap.get(dv.getColId())); + //System.out.println("Value " + value + " " + (( dataType !=null && dataType.equals("DATE")) || (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date"))) ); + if (dataType!=null && dataType.equals("NUMBER")){ + //cellNumber = row.createCell((short) cellNum); + //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + //cellNumber.setCellValue(dv.getDisplayValue()); + //cellCurrencyNumber = row.createCell((short) cellNum); + int zInt = 0; + if (value.equals("null")){ + sw.createCell(cellNum,zInt,styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + }else{ + + if ((value.indexOf("."))!= -1){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + + //if (dv.getDisplayValue().startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempDollar = dv.getDisplayValue().trim(); + tempDollar = tempDollar.replaceAll(" ", "").substring(0); + tempDollar = tempDollar.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempDollar); + //System.out.println("Before copy Value |" + tempDollar); + //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); + //System.out.println("After copy Value |" + tempDollar); + if ((tempDollar.indexOf(","))!= -1){ + tempDollar = tempDollar.replaceAll(",", ""); + } + //System.out.println("The final string 1 is "+tempDollar); + double tempDoubleDollar = 0.0; + try { + tempDoubleDollar = Double.parseDouble(tempDollar); + if(styleRowCell!=null) + sw.createCell(cellNum, tempDoubleDollar, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempDoubleDollar, styleCell.getIndex()); + else + sw.createCell(cellNum, tempDoubleDollar, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + double tempDouble = 0.0; + try { + tempDouble = Double.parseDouble(value); + if(styleRowCell!=null) + sw.createCell(cellNum, tempDouble, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempDouble, styleCell.getIndex()); + else + sw.createCell(cellNum, tempDouble, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(value),styleRowCell.getIndex() ); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(value), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(value), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } + + } + }else { + if (!(value.equals(""))){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //if (dv.getDisplayValue().startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempInt = value.trim(); + tempInt = tempInt.replaceAll(" ", "").substring(0); + tempInt = tempInt.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempInt); + //System.out.println("Before copy Value |" + tempInt); + //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); + //System.out.println("After copy Value |" + tempInt); + if ((tempInt.indexOf(","))!= -1){ + tempInt = tempInt.replaceAll(",", ""); + } + //System.out.println("The final string INT is "+tempInt); + Long tempIntDollar = 0L; + try { + tempIntDollar = Long.parseLong(tempInt); + if(styleRowCell!=null) + sw.createCell(cellNum, tempIntDollar, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempIntDollar, styleCell.getIndex()); + else + sw.createCell(cellNum, tempIntDollar, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, tempInt, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempInt, styleCell.getIndex()); + else + sw.createCell(cellNum, tempInt, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempStr = value.trim(); + if ((tempStr.indexOf(","))!= -1){ + tempStr = tempStr.replaceAll(",", ""); + } + Long temp = 0L; + + try { + temp = Long.parseLong(tempStr); + if(styleRowCell!=null) + sw.createCell(cellNum, temp, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, temp, styleCell.getIndex()); + else + sw.createCell(cellNum, temp, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempStr), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempStr), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempStr), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } + } + } + } + } + + } else if ( ( dataType !=null && dataType.equals("DATE")) || (dv.getDisplayName()!=null && dv.getDisplayName().toLowerCase().endsWith("date")) || + (dv.getColId()!=null && dv.getColId().toLowerCase().endsWith("date")) || + (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date")) ) { + XSSFCellStyle cellStyle = null; + if(styleRowCell!=null) { + cellStyle = styleRowCell; + } else if (styleCell!=null) { + cellStyle = styleCell; + } else { + cellStyle = styles.get(nvl(/*dv.getFormatId()*/"","date")); + } + + + Date date = null; + int flag = 0; + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMMSS")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMM")); + flag = 1; + } + if(date==null) + date = MMDDYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYY")); + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYYYHHMMSS")); + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYYYHHMM")); + flag = 1; + } + if(date==null) + date = MMDDYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYYY")); + flag = 1; + } + if(date==null) + date = YYYYMMDDFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("YYYYMMDD")); + flag = 1; + } + if(date==null) + date = timestampFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("timestamp")); + flag = 1; + } + if(date==null) + date = MONYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MONYYYY")); + flag = 1; + } + if(date==null) + date = MMYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMYYYY")); + flag = 1; + } + if(date==null) + date = MMMMMDDYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMMMMDDYYYY")); + flag = 1; + } + if(date==null) + date = MONTHYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MONTHYYYY")); + flag = 1; + } + if(date==null) + date = YYYYMMDDHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("YYYYMMDDHHMMSS")); + flag = 1; + } + if(date==null) + date = YYYYMMDDDASHFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("YYYYMMDDDASH")); + flag = 1; + } + if(date==null) + date = YYYYMMDDHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("YYYYMMDDHHMM")); + flag = 1; + } + if(date==null) + date = DDMONYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("DDMONYYYYHHMMSS")); + flag = 1; + } + if(date==null) + date = DDMONYYYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("DDMONYYYYHHMM")); + flag = 1; + } + if(date==null) + date = DDMONYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("DDMONYYHHMM")); + flag = 1; + } + if(date==null) + date = DDMONYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("DDMONYYYY")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMMSS")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMM")); + flag = 1; + } + if(date==null) + date = MMDDYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYY")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMM")); + flag = 1; + } + if(date==null) + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMMSS")); + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMZFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMDDYYYYHHMMZ")); + flag = 1; + } + if(date==null) + date = MMMMMDDYYYYHHMMSS.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + cellStyle.setDataFormat(dateFormatMap.get("MMMMMDDYYYYHHMMSS")); + flag = 1; + } + + if(date!=null) { + //System.out.println("ExcelDate " + HSSFDateUtil.getExcelDate(date)); + Calendar cal=Calendar.getInstance(); + cal.setTime(date); + //sw.createCell(cellNum, cal,styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + //if(styleRowCell!=null) + sw.createCell(cellNum, cal, cellStyle.getIndex()); + //else if (styleCell!=null) + //sw.createCell(cellNum, cal, cellStyle.getIndex()); + //else + //sw.createCell(cellNum, cal, cellStyle.getIndex()); + } else { + //cell.getCellStyle().setDataFormat((short)0); + //if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(value), cellStyle.getIndex()); + //else if (styleCell!=null) + //sw.createCell(cellNum, Utils.excelEncode(value), cellStyle.getIndex()); + //else + //sw.createCell(cellNum, Utils.excelEncode(value), cellStyle.getIndex()); + + } + //cellDate.setCellValue(date); + //cellDate.setCellValue(value); //cellDate.setCellValue(date); + //cellDate.setCellValue(dv.getDisplayValue()); + + } else if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + //cellNumber = row.createCell((short) cellNum); + //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + //cellNumber.setCellValue(dv.getDisplayValue()); + int zInt = 0; + if (value.equals("null")){ + if(styleRowCell!=null) + sw.createCell(cellNum, zInt, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, zInt, styleCell.getIndex()); + else + sw.createCell(cellNum, zInt, styleDefaultCell.getIndex()); + + } else { + + if ((value.indexOf("."))!= -1){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempDollar = value.trim(); + tempDollar = tempDollar.replaceAll(" ", "").substring(0); + tempDollar = tempDollar.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempDollar); + //System.out.println("Before copy Value |" + tempDollar); + //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); + //System.out.println("After copy Value |" + tempDollar); + if ((tempDollar.indexOf(","))!= -1){ + tempDollar = tempDollar.replaceAll(",", ""); + } + //System.out.println("The final string 2IF is "+tempDollar); + double tempDoubleDollar = 0.0; + try { + tempDoubleDollar = Double.parseDouble(tempDollar); + if(styleRowCell!=null) + sw.createCell(cellNum, tempDoubleDollar,styleRowCell.getIndex() ); + else if (styleCell!=null) + sw.createCell(cellNum, tempDoubleDollar, styleCell.getIndex()); + else + sw.createCell(cellNum, tempDoubleDollar, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } + + + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempDoubleStr = value.trim(); + tempDoubleStr = tempDoubleStr.replaceAll(" ", "").substring(0); + if ((tempDoubleStr.indexOf(","))!= -1){ + tempDoubleStr = tempDoubleStr.replaceAll(",", ""); + } + double tempDouble = 0.0; + try { + tempDouble = Double.parseDouble(tempDoubleStr); + if(styleRowCell!=null) + sw.createCell(cellNum, tempDouble, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempDouble, styleCell.getIndex()); + else + sw.createCell(cellNum, tempDouble, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } + } + + }else { + if (!(value.equals(""))){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempInt = value.trim(); + tempInt = tempInt.replaceAll(" ", "").substring(0); + tempInt = tempInt.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempInt); + //System.out.println("Before copy Value |" + tempInt); + //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); + //System.out.println("After copy Value |" + tempInt); + if ((tempInt.indexOf(","))!= -1){ + tempInt = tempInt.replaceAll(",", ""); + } + //System.out.println("The final string INT 2 is "+tempInt); + + Long tempIntDollar = 0L; + + try { + tempIntDollar = Long.parseLong(tempInt); + if(styleRowCell!=null) + sw.createCell(cellNum, tempIntDollar,styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempIntDollar,styleCell.getIndex()); + else + sw.createCell(cellNum, tempIntDollar,styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempInt), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempInt),styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempInt), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempStr = value.trim(); + if ((tempStr.indexOf(","))!= -1){ + tempStr = tempStr.replaceAll(",", ""); + } + Long temp = 0L; + + try { + temp = Long.parseLong(tempStr); + if(styleRowCell!=null) + sw.createCell(cellNum, temp, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, temp, styleCell.getIndex()); + else + sw.createCell(cellNum, temp, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempStr), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempStr), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempStr), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + + } + } + } else { + sw.createCell(cellNum, "", styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + } + } + } + + + } + else { + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("General")); + if(styleRowCell!=null) + sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styleCell.getIndex()); + else { + if(nvl(value).startsWith(" ")) + sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styles.get(nvl(/*dv.getFormatId(),*/"","defaultLeft")).getIndex()); + else + sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + + } + + } + + if (dv.isBold()) { + if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //cell.setCellStyle(styleCurrencyTotal); + } + else { + //cell.setCellStyle(styleTotal); + } + } else { + //cell.setCellStyle(styleDefaultTotal); + } + bold = true; + } + //System.out.println("2IF "+ (dr.isRowFormat()) + " " + (dv.isCellFormat()) + " " + (styles!=null)); + if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) { + //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); + continue; + } + //System.out.println("3IF "+ (htmlFormat != null) + " " + (dv.getFormatId() != null) + " " + (bold == false) + " "+ (styles != null)); + if (htmlFormat != null && dv.getFormatId() != null && bold == false + && styles != null) { + //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(/*dv.getFormatId()*/"","default"))); + } //else if (bold == false) + //cell.setCellStyle(styleDefault); + } // dv.isVisible + + } + rowNum += 1; + sw.endRow(); + + } + if(rd.reportTotalRowHeaderCols!=null) { + rowCount++; + sw.insertRow(rowNum); + cellNum = -1; + rd.reportTotalRowHeaderCols.resetNext(); + cellNum += 1; + RowHeaderCol rhc = rd.reportTotalRowHeaderCols.getNext(); + RowHeader rh = rhc.getRowHeader(0); + if (dr.isRowFormat() && styles != null) + styleRowCell = (XSSFCellStyle) styles.get(nvl(/*dr.getFormatId(),*/"","default")); + + if(styleRowCell!=null) + sw.createCell(cellNum, strip.stripHtml(rh.getRowTitle()), styleRowCell.getIndex()); + else + sw.createCell(cellNum, strip.stripHtml(rh.getRowTitle()), styleDefaultCell.getIndex()); + rd.reportDataTotalRow.resetNext(); + //rd.reportDataTotalRow.getNext(); + DataRow drTotal = rd.reportDataTotalRow.getNext(); + if(drTotal!=null) { + drTotal.resetNext(); drTotal.getNext(); + for (; drTotal.hasNext();) { + DataValue dv = drTotal.getNext(); + if(dv.isVisible()) { + cellNum += 1; + styleCell = null; + String value = dv.getDisplayValue(); + sw.createCell(cellNum,value,styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + } + } + rowNum += 1; + sw.endRow(); + } + + + + + +/* // To Display Total Values for Linear report + if(rd.reportDataTotalRow!=null) { + row = sheet.createRow(rowNum); + cellNum = -1; + rd.reportTotalRowHeaderCols.resetNext(); + //for (rd.reportTotalRowHeaderCols.resetNext(); rd.reportTotalRowHeaderCols.hasNext();) { + cellNum += 1; + RowHeaderCol rhc = rd.reportTotalRowHeaderCols.getNext(); + RowHeader rh = rhc.getRowHeader(0); + row.createCell((short) cellNum).setCellValue(strip.stripHtml(rh.getRowTitle())); + row.getCell((short) cellNum).setCellStyle(styleDefaultTotal); + //} + + DataRow drTotal = rd.reportDataTotalRow.getNext(); + //cellNum = -1; + for (drTotal.resetNext(); drTotal.hasNext();j++) { + cellNum += 1; + cell = row.createCell((short) cellNum); + DataValue dv = drTotal.getNext(); + String value = dv.getDisplayValue(); + cell.setCellValue(value); + boolean bold = false; + if (dv.isBold()) { + if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + cell.setCellStyle(styleCurrencyTotal); + } else { + cell.setCellStyle(styleTotal); + } + } else { + cell.setCellStyle(styleDefaultTotal); + } + bold = true; + } + } + }*/ + + } catch (SQLException ex) { + throw new RaptorException(ex); + } catch (ReportSQLException ex) { + throw new RaptorException(ex); + } catch (Exception ex) { + if(!(ex.getCause() instanceof java.net.SocketException) ) + throw new RaptorException (ex); + } finally { + try { + if(conn!=null) + conn.close(); + if(st!=null) + st.close(); + if(rs!=null) + rs.close(); + } catch (SQLException ex) { + throw new RaptorException(ex); + } + } + + String footer = (String) session.getAttribute("FOOTER_"+index); + if(nvl(footer).length()>0) { + footer = Utils.replaceInString(footer, "
", " "); + footer = Utils.replaceInString(footer, "
", " "); + footer = Utils.replaceInString(footer, "
", " "); + footer = strip.stripHtml(nvl(footer).trim()); + rowNum += 1; + sw.insertRow(rowNum); + cellNum = 0; + sw.createCell(cellNum, footer.replaceAll("&", "&"), styleDefaultCell.getIndex()); + sw.endRow(); + rowNum += 1; + } + + if(Globals.getShowDisclaimer()) { + rowNum += 1; + sw.insertRow(rowNum); + cellNum = 0; + + sw.createCell(cellNum, org.openecomp.portalsdk.analytics.system.Globals.getFooterFirstLine().replaceAll("&", "&"), styleDefaultCell.getIndex()); + sw.endRow(); + rowNum += 1; + sw.insertRow(rowNum); + cellNum = 0; + sw.createCell(cellNum, org.openecomp.portalsdk.analytics.system.Globals.getFooterSecondLine().replaceAll("&", "&"), styleDefaultCell.getIndex()); + sw.endRow(); + } + + } else { + //start data from rd + + int rowCount = 0; + DataRow dr = null; + for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { + rowCount++; + + + dr = rd.reportDataRows.getNext(); + sw.insertRow(rowNum); + + cellNum = -1; + + if (rr.getReportType().equals(AppConstants.RT_LINEAR) && rd.reportTotalRowHeaderCols!=null) { + rd.reportRowHeaderCols.resetNext(0); + if(rd.reportTotalRowHeaderCols!=null) { + //cellNum = -1; + //for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { + //a commented to suppress rownum + //a cellNum += 1; + //RowHeaderCol rhc = rd.reportRowHeaderCols.getRowHeaderCol(0); + //if (firstPass) + // rhc.resetNext(); + //RowHeader rh = rhc.getRowHeader(rowCount-1); + //a sw.createCell(cellNum, rowCount, styleDefaultCell.getIndex()); + //} // for + } + + } + firstPass = false; + //cellNum = -1; + int j = 0; + + for (dr.resetNext(); dr.hasNext();j++) { + DataValue dv = dr.getNext(); + styleCell = null; + boolean bold = false; + String value = nvl(dv.getDisplayValue()); + value = strip.stripHtml(value); + HtmlFormatter htmlFormat = dv.getCellFormatter(); + if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) + styleCell = (XSSFCellStyle) styles.get(nvl(/*dr.getFormatId(),*/"","default")); + if (htmlFormat != null && dv.getFormatId() != null && styles != null) + styleCell = (XSSFCellStyle) styles.get(nvl(/*dv.getFormatId(),*/"","default")); + + if(dv.isVisible()) { + cellNum += 1; + //cell = row.createCell((short) cellNum); + //System.out.println("Stripping HTML 1"); + //cell.setCellValue(strip.stripHtml(value)); + String dataType = (String) (dataTypeMap.get(dv.getColId())); + //System.out.println(" The Display Value is ********"+value + " " + dv.getDisplayTotal() + " " + dv.getColName()); + + if (dataType!=null && dataType.equals("NUMBER")){ + //cellNumber = row.createCell((short) cellNum); + //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + //cellNumber.setCellValue(value); + //cellCurrencyNumber = row.createCell((short) cellNum); + int zInt = 0; + if (value.equals("null")){ + sw.createCell(cellNum,zInt,styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + }else{ + + if ((value.indexOf("."))!= -1){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempDollar = value.trim(); + tempDollar = tempDollar.replaceAll(" ", "").substring(0); + tempDollar = tempDollar.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempDollar); + //System.out.println("Before copy Value |" + tempDollar); + //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); + //System.out.println("After copy Value |" + tempDollar); + if ((tempDollar.indexOf(","))!= -1){ + tempDollar = tempDollar.replaceAll(",", ""); + } + //System.out.println("The final string 1 is "+tempDollar); + double tempDoubleDollar = 0.0; + try { + tempDoubleDollar = Double.parseDouble(tempDollar); + if(styleRowCell!=null) + sw.createCell(cellNum, tempDoubleDollar, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempDoubleDollar, styleCell.getIndex()); + else + sw.createCell(cellNum, tempDoubleDollar, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + double tempDouble = 0.0; + try { + tempDouble = Double.parseDouble(value); + if(styleRowCell!=null) + sw.createCell(cellNum, tempDouble, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempDouble, styleCell.getIndex()); + else + sw.createCell(cellNum, tempDouble, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(value),styleRowCell.getIndex() ); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(value), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(value), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + + } + }else { + if (!(value.equals(""))){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempInt = value.trim(); + tempInt = tempInt.replaceAll(" ", "").substring(0); + tempInt = tempInt.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempInt); + //System.out.println("Before copy Value |" + tempInt); + //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); + //System.out.println("After copy Value |" + tempInt); + if ((tempInt.indexOf(","))!= -1){ + tempInt = tempInt.replaceAll(",", ""); + } + //System.out.println("The final string INT is "+tempInt); + Long tempIntDollar = 0L; + try { + tempIntDollar = Long.parseLong(tempInt); + if(styleRowCell!=null) + sw.createCell(cellNum, tempIntDollar, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempIntDollar, styleCell.getIndex()); + else + sw.createCell(cellNum, tempIntDollar, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, tempInt, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempInt, styleCell.getIndex()); + else + sw.createCell(cellNum, tempInt, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempStr = value.trim(); + if ((tempStr.indexOf(","))!= -1){ + tempStr = tempStr.replaceAll(",", ""); + } + Long temp = 0L; + + try { + temp = Long.parseLong(tempStr); + if(styleRowCell!=null) + sw.createCell(cellNum, temp, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, temp, styleCell.getIndex()); + else + sw.createCell(cellNum, temp, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempStr), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempStr), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempStr), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + + + } + //int temp = Integer.parseInt(value.trim()); + // cell.setCellValue(temp); + //}else{ + // cell.setCellValue(strip.stripHtml(value)); + //} + } + } + } + + }else if ( ( dataType !=null && dataType.equals("DATE")) || (dv.getDisplayName()!=null && dv.getDisplayName().toLowerCase().endsWith("date")) || + (dv.getColId()!=null && dv.getColId().toLowerCase().endsWith("date")) || + (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date")) ) { + Date date = null; + int flag = 0; + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = YYYYMMDDFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = timestampFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MONYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMMMMDDYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MONTHYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = YYYYMMDDHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = YYYYMMDDDASHFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = YYYYMMDDHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = DDMONYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = DDMONYYYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = DDMONYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = DDMONYYYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMDDYYYYHHMMZFormat.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + if(date==null) + date = MMMMMDDYYYYHHMMSS.parse(value, new ParsePosition(0)); + if(date != null && flag == 0) { + flag = 1; + } + + + if(date!=null) { + Calendar cal=Calendar.getInstance(); + cal.setTime(date); + //sw.createCell(cellNum, cal,styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); + if(styleRowCell!=null) + sw.createCell(cellNum, cal, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, cal, styleCell.getIndex()); + else + sw.createCell(cellNum, cal, styles.get(nvl(/*dv.getFormatId()*/"","date")).getIndex()); + + } else { + /*cell.getCellStyle().setDataFormat((short)0);*/ + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(value), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(value), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(value), styles.get(nvl(/*dv.getFormatId(),*/"","date")).getIndex()); + + } + //cellDate.setCellValue(date); + //cellDate.setCellValue(value); + + }else if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + //cellNumber = row.createCell((short) cellNum); + //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + //cellNumber.setCellValue(value); + int zInt = 0; + if (value.equals("null")){ + if(styleRowCell!=null) + sw.createCell(cellNum, zInt, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, zInt, styleCell.getIndex()); + else + sw.createCell(cellNum, zInt, styleDefaultCell.getIndex()); + } else { + + if ((value.indexOf("."))!= -1){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempDollar = value.trim(); + tempDollar = tempDollar.replaceAll(" ", "").substring(0); + tempDollar = tempDollar.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempDollar); + //System.out.println("Before copy Value |" + tempDollar); + //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); + //System.out.println("After copy Value |" + tempDollar); + if ((tempDollar.indexOf(","))!= -1){ + tempDollar = tempDollar.replaceAll(",", ""); + } + //System.out.println("The final string 2IF is "+tempDollar); + double tempDoubleDollar = 0.0; + try { + tempDoubleDollar = Double.parseDouble(tempDollar); + if(styleRowCell!=null) + sw.createCell(cellNum, tempDoubleDollar,styleRowCell.getIndex() ); + else if (styleCell!=null) + sw.createCell(cellNum, tempDoubleDollar, styleCell.getIndex()); + else + sw.createCell(cellNum, tempDoubleDollar, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempDollar), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + + + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempDoubleStr = value.trim(); + tempDoubleStr = tempDoubleStr.replaceAll(" ", "").substring(0); + if ((tempDoubleStr.indexOf(","))!= -1){ + tempDoubleStr = tempDoubleStr.replaceAll(",", ""); + } + double tempDouble = 0.0; + try { + tempDouble = Double.parseDouble(tempDoubleStr); + if(styleRowCell!=null) + sw.createCell(cellNum, tempDouble, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempDouble, styleCell.getIndex()); + else + sw.createCell(cellNum, tempDouble, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + } + + }else { + if (!(value.equals(""))){ + if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //if (value.startsWith("$")){ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); + String tempInt = value.trim(); + tempInt = tempInt.replaceAll(" ", "").substring(0); + tempInt = tempInt.replaceAll("\\$", "").substring(0); + //System.out.println("SUBSTRING |" + tempInt); + //System.out.println("Before copy Value |" + tempInt); + //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); + //System.out.println("After copy Value |" + tempInt); + if ((tempInt.indexOf(","))!= -1){ + tempInt = tempInt.replaceAll(",", ""); + } + //System.out.println("The final string INT 2 is "+tempInt); + + Long tempIntDollar = 0L; + + try { + tempIntDollar = Long.parseLong(tempInt); + if(styleRowCell!=null) + sw.createCell(cellNum, tempIntDollar,styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, tempIntDollar,styleCell.getIndex()); + else + sw.createCell(cellNum, tempIntDollar,styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempInt), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempInt),styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempInt), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + }else{ + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); + String tempStr = value.trim(); + if ((tempStr.indexOf(","))!= -1){ + tempStr = tempStr.replaceAll(",", ""); + } + Long temp = 0L; + + try { + temp = Long.parseLong(tempStr); + if(styleRowCell!=null) + sw.createCell(cellNum, temp, styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, temp, styleCell.getIndex()); + else + sw.createCell(cellNum, temp, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } catch (NumberFormatException ne) { + if(styleRowCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempStr), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, Utils.excelEncode(tempStr), styleCell.getIndex()); + else + sw.createCell(cellNum, Utils.excelEncode(tempStr), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + } + //int temp = Integer.parseInt(value.trim()); + // cell.setCellValue(temp); + //}else{ + // cell.setCellValue(strip.stripHtml(value)); + //} + } else { + sw.createCell(cellNum, "", styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + } + } + + + } + else { + //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("General")); + if(styleRowCell!=null) + sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styleRowCell.getIndex()); + else if (styleCell!=null) + sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styleCell.getIndex()); + else + sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); + } + + //if (!(value.equals(""))){ + //int temp = Integer.parseInt(value.trim()); + //cell.setCellValue(temp); + //}else{ + // cell.setCellValue(strip.stripHtml(value)); + //} + //HSSFCellStyle styleFormat = null; + //HSSFCellStyle numberStyle = null; + //HSSFFont formatFont = null; + //short fgcolor = 0; + //short fillpattern = 0; + //System.out.println("1IF "+ (dv.isBold()) + " "+ value + " " + dv.getDisplayTotal() + " " + dv.getColName() ); + if (dv.isBold()) { + if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ + if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { + //cell.setCellStyle(styleCurrencyTotal); + } + else { + //cell.setCellStyle(styleTotal); + } + } else { + //cell.setCellStyle(styleDefaultTotal); + } + bold = true; + } + //System.out.println("2IF "+ (dr.isRowFormat()) + " " + (dv.isCellFormat()) + " " + (styles!=null)); + if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) { + //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); + continue; + } + //System.out.println("3IF "+ (htmlFormat != null) + " " + (dv.getFormatId() != null) + " " + (bold == false) + " "+ (styles != null)); + if (htmlFormat != null && dv.getFormatId() != null && bold == false + && styles != null) { + // cell.setCellStyle((HSSFCellStyle) styles.get(nvl(/*dv.getFormatId()*/"","default"))); + } //else if (bold == false) + //cell.setCellStyle(styleDefault); + } // if (dv.isVisible) + } // for + + /*for (int tmp=0; tmp0) { + footer = Utils.replaceInString(footer, "
", " "); + footer = Utils.replaceInString(footer, "
", " "); + footer = Utils.replaceInString(footer, "
", " "); + footer = strip.stripHtml(nvl(footer).trim()); + rowNum += 1; + sw.insertRow(rowNum); + cellNum = 0; + sw.createCell(cellNum, footer.replaceAll("&", "&"), styleDefaultCell.getIndex()); + sw.endRow(); + rowNum += 1; + } + + + if(Globals.getShowDisclaimer()) { + rowNum += 1; + sw.insertRow(rowNum); + cellNum = 0; + + sw.createCell(cellNum, org.openecomp.portalsdk.analytics.system.Globals.getFooterFirstLine().replaceAll("&", "&"), styleDefaultCell.getIndex()); + sw.endRow(); + rowNum += 1; + sw.insertRow(rowNum); + cellNum = 0; + sw.createCell(cellNum, org.openecomp.portalsdk.analytics.system.Globals.getFooterSecondLine().replaceAll("&", "&"), styleDefaultCell.getIndex()); + sw.endRow(); + } + + + } + // end data from rd + } + + // System.out.println(" Last Row " + wb.getSheetAt(0).getLastRowNum()); + } + + private void paintXSSFExcelParams(XSSFWorkbook wb,int rowNum,int col,ArrayList paramsList, String customizedParamInfo, XSSFSheet sheet, String reportTitle, String reportDescr) throws IOException { + //HSSFSheet sheet = wb.getSheet(getSheetName()); + int cellNum = 0; + XSSFRow row = null; + short s1 = 0, s2 = (short) 1; + HtmlStripper strip = new HtmlStripper(); + // Name Style + XSSFCellStyle styleName = wb.createCellStyle(); + //styleName.setFillBackgroundColor(HSSFColor.GREY_80_PERCENT.index); + styleName.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index); + //styleName.setFillPattern(HSSFCellStyle.SPARSE_DOTS); + styleName.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleName.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleName.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleName.setBorderRight(HSSFCellStyle.BORDER_THIN); + styleName.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleName.setDataFormat((short)0); + XSSFFont font = wb.createFont(); + font.setFontHeight((short) (font_size / 0.05)); + font.setFontName("Tahoma"); + font.setColor(HSSFColor.BLACK.index); + font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + styleName.setFont(font); + //Data Style + + // Create some fonts. + XSSFFont fontDefault = wb.createFont(); + // Initialize the styles & fonts. + // The default will be plain . + fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); + fontDefault.setFontHeight((short) (font_size / 0.05)); + fontDefault.setFontName("Tahoma"); + fontDefault.setItalic(true); + // Style default will be normal with no background + XSSFCellStyle styleValue = wb.createCellStyle(); + styleValue.setDataFormat((short)0); + styleValue.setAlignment(HSSFCellStyle.ALIGN_CENTER); + styleValue.setBorderBottom(HSSFCellStyle.BORDER_THIN); + styleValue.setBorderTop(HSSFCellStyle.BORDER_THIN); + styleValue.setBorderLeft(HSSFCellStyle.BORDER_THIN); + styleValue.setBorderRight(HSSFCellStyle.BORDER_THIN); + // styleValue.setFillForegroundColor(HSSFColor.YELLOW.index); + styleValue.setFillPattern(HSSFCellStyle.NO_FILL); + styleValue.setFont(fontDefault); + XSSFCell cell = null; + XSSFCellStyle styleDescription = wb.createCellStyle(); + styleDescription.setAlignment(HSSFCellStyle.ALIGN_CENTER); +// styleDescription.setBorderBottom(HSSFCellStyle.BORDER_THIN); +// styleDescription.setBorderTop(HSSFCellStyle.BORDER_THIN); +// styleDescription.setBorderRight(HSSFCellStyle.BORDER_THIN); +// styleDescription.setBorderLeft(HSSFCellStyle.BORDER_THIN); + XSSFFont fontDescr = wb.createFont(); + fontDescr.setFontHeight((short) (font_header_descr_size / 0.05)); + fontDescr.setFontName("Tahoma"); + fontDescr.setColor(HSSFColor.BLACK.index); + fontDescr.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + styleDescription.setFont(font); + XSSFCell cellDescr = null; + int paramSeq = 0; + Header header = sheet.getHeader(); + StringBuffer strBuf = new StringBuffer(); + if(!Globals.customizeFormFieldInfo() || customizedParamInfo.length()<=0) { + for (Iterator iter = paramsList.iterator(); iter.hasNext();) { + IdNameValue value = (IdNameValue) iter.next(); + //System.out.println("\"" + value.getId() + " = " + value.getName() + "\""); + if(nvl(value.getId()).trim().length()>0 && (!nvl(value.getId()).trim().equals("BLANK"))) { + paramSeq += 1; + if(paramSeq <= 1) { + row = sheet.createRow(++rowNum); + cell = row.createCell((short) 0); + sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, s1, s2)); + cellDescr = row.createCell((short) 0); + cellDescr.setCellValue("Run-time Parameters"); + cellDescr.setCellStyle(styleDescription); + + + strBuf.append(reportTitle+"\n"); + //strBuf.append("Run-time Parameters\n"); + } + row = sheet.createRow(++rowNum); + cellNum = 0; + //System.out.println("RowNum " + rowNum + " " + value.getId() + " " +value.getName()); + cell = row.createCell((short) cellNum); + cell.setCellValue(value.getId()); + cell.setCellStyle(styleName); + cellNum += 1; + cell = row.createCell((short) cellNum); + cell.setCellValue(value.getName().replaceAll("~",",")); + cell.setCellStyle(styleValue); + + //strBuf.append(value.getId()+": "+ value.getName()+"\n"); + } + } //for + } else { + strBuf.append(reportTitle+"\n"); + Document document = new Document(); + document.open(); + HTMLWorker worker = new HTMLWorker(document); + StyleSheet style = new StyleSheet(); + style.loadTagStyle("body", "leading", "16,0"); + ArrayList p = HTMLWorker.parseToList(new StringReader(customizedParamInfo), style); + String name = ""; + String token = ""; + String value = ""; + String s = ""; + PdfPTable pdfTable = null; + for (int k = 0; k < p.size(); ++k){ + if(p.get(k) instanceof Paragraph) + s = ((Paragraph)p.get(k)).toString(); + else { /*if ((p.get(k) instanceof PdfPTable))*/ + pdfTable = ((PdfPTable)p.get(k)); + } + //todo: Logic for parsing pdfTable should be added after upgrading to iText 5.0.0 + //s = Utils.replaceInString(s, ",", "|"); + s = s.replaceAll(",", "|"); + s = s.replaceAll("~", ","); + if(s.indexOf(":")!= -1) { + //System.out.println("|"+s+"|"); + row = sheet.createRow(++rowNum); + cell = row.createCell((short) 0); + sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, s1, s2)); + cellDescr = row.createCell((short) 0); + cellDescr.setCellValue("Run-time Parameters"); + cellDescr.setCellStyle(styleDescription); + + //strBuf.append("Run-time Parameters\n"); + StringTokenizer st = new StringTokenizer(s.trim(), "|"); + while(st.hasMoreTokens()) { + token = st.nextToken(); + token = token.trim(); + if (!(token.trim().equals("|") || token.trim().equals("]]") || token.trim().equals("]") || token.trim().equals("[") )) { + if(token.endsWith(":")) { + name = token; + name = name.substring(0, name.length()-1); + if(name.startsWith("[")) + name = name.substring(1); + value = st.nextToken(); + if(nvl(value).endsWith("]"))value = nvl(value).substring(0, nvl(value).length()-1); + } /*else if(name != null && name.length() > 0) { + value = st.nextToken(); + if(value.endsWith("]]"))value = value.substring(0, value.length()-1); + }*/ + if(name!=null && name.trim().length()>0) { + row = sheet.createRow((short) ++rowNum); + cellNum = 0; + cell = row.createCell((short) cellNum); + cell.setCellValue(name.trim()); + cell.setCellStyle(styleName); + cellNum += 1; + cell = row.createCell((short) cellNum); + cell.setCellValue(value.trim()); + cell.setCellStyle(styleValue); + //strBuf.append(name.trim()+": "+ value.trim()+"\n"); + } +/* if(token.endsWith(":") && (value!=null && value.trim().length()<=0) && (name!=null && name.trim().length()>0 && name.endsWith(":"))) { + name = name.substring(0, name.indexOf(":")+1); + //value = token.substring(token.indexOf(":")+1); + row = sheet.createRow((short) ++rowNum); + cellNum = 0; + cell = row.createCell((short) cellNum); + cell.setCellValue(name.trim()); + cell.setCellStyle(styleName); + cellNum += 1; + cell = row.createCell((short) cellNum); + cell.setCellValue(value.trim()); + cell.setCellStyle(styleValue); + + //strBuf.append(name.trim()+": "+ value.trim()+"\n"); + value = ""; + name = ""; + } +*/ } + int cw = 0; + cw = name.trim().length() + 12; + // if(i!=cellWidth.size()-1) + if(sheet.getColumnWidth((short)0)< (short) name.trim().length()) + sheet.setColumnWidth((short)0, (short) name.trim().length()); + if(sheet.getColumnWidth((short)1)< (short) value.trim().length()) + sheet.setColumnWidth((short)1, (short) value.trim().length()); + name = ""; + value = ""; + + } + + try { + SimpleDateFormat oracleDateFormat = new SimpleDateFormat("MM/dd/yyyy kk:mm:ss"); + Date sysdate = oracleDateFormat.parse(ReportLoader.getSystemDateTime()); + SimpleDateFormat dtimestamp = new SimpleDateFormat(Globals.getScheduleDatePattern()); + + row = sheet.createRow((short) ++rowNum); + cellNum = 0; + cell = row.createCell((short) cellNum); + cell.setCellValue("Report Date/Time"); + cell.setCellStyle(styleName); + cellNum += 1; + cell = row.createCell((short) cellNum); + + cell.setCellValue(dtimestamp.format(sysdate)+" "+Globals.getTimeZone()); + cell.setCellStyle(styleValue); + + } catch(Exception ex) { + //ex.printStackTrace(); + } + + + } + } + + +/* Iterator iter1 = paramsList.iterator(); + s1 = 0; s2 = (short)10; + if(iter1.hasNext()) { + row = sheet.createRow((short) ++rowNum); + cellNum = 0; + cell = row.createCell((short) cellNum); + sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); + cell.setCellValue(strip.stripHtml(customizedParamInfo)); + } +*/ +/* rowNum += 2; + row = sheet.createRow(rowNum);*/ + } // if + Iterator iterCheck = paramsList.iterator(); + if(iterCheck.hasNext()) { + rowNum += 2; + row = sheet.createRow(rowNum); + } + header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) font_header_title_size)+strBuf.toString()); + } + + // Trying different --> + public void createHTMLFileContent(Writer out, ReportData rd, + ReportRuntime rr, String sql_whole, HttpServletRequest request, HttpServletResponse response) + throws RaptorException, IOException { + //response.setContentType("application/vnd.ms-excel"); + //response.setHeader("Content-disposition", + // "attachment; filename=" + + // "Example.xls" ); + PrintWriter csvOut = response.getWriter(); + HtmlStripper strip = new HtmlStripper(); + ResultSet rs = null; + Connection conn = null; + Statement st = null; + ResultSetMetaData rsmd = null; + ColumnHeaderRow chr = null; + int mb = 1024*1024; + Runtime runtime = Runtime.getRuntime(); + csvOut.println("\n" + + "" + rr.getReportName() + "\n" + + "\n" ); + System.out.println("HTML-Excel Generation Triggered: " + new java.util.Date()); + csvOut.print(""); + if (Globals.getPrintParamsInCSVDownload()) { + ArrayList paramsList = rr.getParamNameValuePairsforPDFExcel(request, 1); + int paramSeq = 0; + for (Iterator iter = paramsList.iterator(); iter.hasNext();) { + IdNameValue value = (IdNameValue) iter.next(); + //System.out.println("\"" + value.getId() + " = " + value.getName() + "\""); + if(nvl(value.getId()).trim().length()>0 && (!nvl(value.getId()).trim().equals("BLANK"))) { + paramSeq += 1; + if(paramSeq <= 1) { + csvOut.println(""); + //strBuf.append("Run-time Parameters\n"); + } + csvOut.println(""); + csvOut.println(""); + csvOut.println(""); + + //strBuf.append(value.getId()+": "+ value.getName()+"\n"); + } + } //for + csvOut.println(""); + csvOut.println(""); + System.out.println("HTML-Excel: Header Rendering complete " + new java.util.Date()); + } + int rowCount = 0; + if(nvl(sql_whole).length()>0) { + try { + conn = ConnectionUtils.getConnection(rr.getDbInfo()); + st = conn.createStatement(); + Log.write("[SQL] " + sql_whole, 4); + int downloadLimit = Globals.getDownloadLimit(); + Callable callable = new ExecuteQuery(st, sql_whole, downloadLimit); + ExecutorService executor = new ScheduledThreadPoolExecutor(5); + System.out.println("Time Started" + new java.util.Date()); + Future future = executor.submit(callable); + try { + rs = future.get(900, TimeUnit.SECONDS); + } catch (TimeoutException ex) { + System.out.println("Cancelling Query"); + st.cancel(); + System.out.println("Query Cancelled"); + throw new Exception("user requested"); + } + rsmd = rs.getMetaData(); + int numberOfColumns = rsmd.getColumnCount(); + HashMap colHash = new HashMap(); + + if(rd!=null) { + for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { + chr = rd.reportColumnHeaderRows.getNext(); + csvOut.println(""); + for (chr.resetNext(); chr.hasNext();) { + ColumnHeader ch = chr.getNext(); + if(ch.isVisible()) { + csvOut.print(""); + //for (int i = 1; i < ch.getColSpan(); i++) + // csvOut.print(","); + + } + } // for + csvOut.println(""); + } // for + + + while(rs.next()) { + csvOut.println(""); +/* if(runtime.freeMemory()/mb <= ((runtime.maxMemory()/mb)*Globals.getMemoryThreshold()/100) ) { + csvOut.print(Globals.getUserDefinedMessageForMemoryLimitReached() + " " + rowCount +"records out of " + rr.getReportDataSize() + " were downloaded to CSV."); + break; + } +*/ rowCount++; + colHash = new HashMap(); + for (int i = 1; i <= numberOfColumns; i++) { + colHash.put(rsmd.getColumnName(i), rs.getString(i)); + } + for (chr.resetNext(); chr.hasNext();) { + ColumnHeader ch = chr.getNext(); + if(ch.isVisible()) { + csvOut.println(""); + } + + } + csvOut.println(""); + } + System.out.println("Downloaded Rows in HTML-Excel " + rowCount + " : "+ new java.util.Date()); + if(rowCount == 0) { + csvOut.print(""); + } else { + } + } else { + csvOut.println(""); + } + csvOut.println("
" + "Run-time Parameters" + "
" + value.getId() +"" + value.getName().replaceAll("~",",")+ "
 
 
" + ch.getColumnTitle() + "
" + strip.stripCSVHtml(nvl((String)colHash.get(ch.getLinkColId().toUpperCase()))) + "
No Data Found
No Data Found
\n"); + + } catch (SQLException ex) { + throw new RaptorException(ex); + } catch (ReportSQLException ex) { + throw new RaptorException(ex); + } catch (Exception ex) { + throw new RaptorException (ex); + } finally { + try { + if(conn!=null) + conn.close(); + if(st!=null) + st.close(); + if(rs!=null) + rs.close(); + } catch (SQLException ex) { + throw new RaptorException(ex); + } + } + //csvOut.flush(); + } else { + boolean firstPass = true; + int numberOfColumns = 0; + if(rd!=null) { + for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { + chr = rd.reportColumnHeaderRows.getNext(); + csvOut.println(""); + for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + + if (firstPass) { + numberOfColumns++; + csvOut.print("" + rhc.getColumnTitle() + ""); + } + //csvOut.print(","); + } // for + + + for (chr.resetNext(); chr.hasNext();) { + ColumnHeader ch = chr.getNext(); + if(ch.isVisible()) { + if(firstPass) numberOfColumns++; + csvOut.print("" + ch.getColumnTitle() + ""); + //for (int i = 1; i < ch.getColSpan(); i++) + //csvOut.print(","); + } + } // for + firstPass = false; + csvOut.println(""); + } // for + + firstPass = true; + for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { + DataRow dr = rd.reportDataRows.getNext(); + csvOut.println(""); + for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + if (firstPass) + rhc.resetNext(); + RowHeader rh = rhc.getNext(); + + csvOut.print("" + strip.stripCSVHtml(rh.getRowTitle()) + ""); + } // for + firstPass = false; + + for (dr.resetNext(); dr.hasNext();) { + DataValue dv = dr.getNext(); + if(dv.isVisible()) + csvOut.print("" + strip.stripCSVHtml(dv.getDisplayValue()) + ""); + } // for + + csvOut.println(""); + + } // for + //csvOut.flush(); + } else { + csvOut.println("No Data Found"); + } + } + csvOut.println("\n"); + System.out.println("HTML-Excel Generation: Data Rendering complete " + new java.util.Date()); + System.out.println("##### Heap utilization statistics [MB] #####"); + System.out.println("Used Memory:" + + (runtime.maxMemory() - runtime.freeMemory()) / mb); + System.out.println("Free Memory:" + + runtime.freeMemory() / mb); + System.out.println("Total Memory:" + runtime.totalMemory() / mb); + System.out.println("Max Memory:" + runtime.maxMemory() / mb); + + } // createCSVFileContent + + /** + * Checking if every row and cell in merging region exists, and create those which are not + * @param sheet in which check is performed + * @param region to check + * @param cellStyle cell style to apply for whole region + */ + private void cleanBeforeMergeOnValidCells(XSSFSheet sheet,CellRangeAddress region, XSSFCellStyle cellStyle ) + { + for(int rowNum =region.getFirstRow();rowNum<=region.getLastRow();rowNum++){ + XSSFRow row= sheet.getRow(rowNum); + if(row==null){ + sheet.createRow(rowNum); + } + for(int colNum=region.getFirstColumn();colNum<=region.getLastColumn();colNum++){ + XSSFCell currentCell = row.getCell(colNum); + if(currentCell==null){ + currentCell = row.createCell(colNum); + } + + currentCell.setCellStyle(cellStyle); + + } + } + + + } +} // ReportHandler + + +/** + * Adapter for a Writer to behave like an OutputStream. + * + * Bytes are converted to chars using the platform default encoding. + * If this encoding is not a single-byte encoding, some data may be lost. + */ + class WriterOutputStream extends OutputStream { + + private final Writer writer; + + public WriterOutputStream(Writer writer) { + this.writer = writer; + } + + public void write(int b) throws IOException { + // It's tempting to use writer.write((char) b), but that may get the encoding wrong + // This is inefficient, but it works + write(new byte[] {(byte) b}, 0, 1); + } + + public void write(byte b[], int off, int len) throws IOException { + writer.write(new String(b, off, len)); + } + + public void flush() throws IOException { + writer.flush(); + } + + public void close() throws IOException { + writer.close(); + } +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportLoader.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportLoader.java new file mode 100644 index 00000000..ddbf442c --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportLoader.java @@ -0,0 +1,1079 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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. + * ================================================================================ + */ +/* =========================================================================================== + * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) + * Raptor : This tool is used to generate different kinds of reports with lot of utilities + * =========================================================================================== + * + * ------------------------------------------------------------------------------------------- + * ReportLoader.java - This class is used to call database interaction related to reports. + * ------------------------------------------------------------------------------------------- + * + * + * + * Changes + * ------- + * 28-Aug-2009 : Version 8.5.1 (Sundar);
  • isDashboardType is made to return false, as any report can be added to Dashboard.
+ * 18-Aug-2009 : Version 8.5.1 (Sundar);
  • request Object is passed to prevent caching user/roles - Datamining/Hosting.
+ * 27-Jul-2009 : Version 8.4 (Sundar);
  • Admin User is given the same privilege as Super User when the property + * "admin_role_equiv_to_super_role" in raptor.properties is Y. A check is made in corresponding to that.
+ * + */ +package org.openecomp.portalsdk.analytics.model; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Vector; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.error.ReportSQLException; +import org.openecomp.portalsdk.analytics.model.base.IdNameValue; +import org.openecomp.portalsdk.analytics.model.base.ReportWrapper; +import org.openecomp.portalsdk.analytics.model.definition.ReportLogEntry; +import org.openecomp.portalsdk.analytics.model.search.ReportSearchResult; +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.system.DbUtils; +import org.openecomp.portalsdk.analytics.system.Globals; +import org.openecomp.portalsdk.analytics.system.fusion.domain.QuickLink; +import org.openecomp.portalsdk.analytics.util.AppConstants; +import org.openecomp.portalsdk.analytics.util.DataSet; +import org.openecomp.portalsdk.analytics.util.Utils; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +public class ReportLoader extends org.openecomp.portalsdk.analytics.RaptorObject { + + static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ReportLoader.class); + + + //private static Properties sqlProperty; + + public static String loadCustomReportXML(String reportID) throws RaptorException { + Connection connection = DbUtils.getConnection(); + try { + return loadCustomReportXML(connection, reportID); + } finally { + DbUtils.clearConnection(connection); + } + } // loadCustomReportXML + + public static String loadCustomReportXML(Connection connection, String reportID) + throws RaptorException { + + StringBuffer sb = new StringBuffer(); + + PreparedStatement stmt = null; + + ResultSet rs = null; + + try { + + String sql = Globals.getLoadCustomReportXml(); + stmt = connection.prepareStatement(sql); + stmt.setInt(1,Integer.parseInt(reportID)); + rs = stmt.executeQuery(); + if(Globals.isWeblogicServer()) { + java.sql.Clob clob= null; + Object obj = null; + if (rs.next()) { + clob = rs.getClob(1); + } + else + throw new RaptorException("Report " + reportID + " not found in the database"); + + int len = 0; + char[] buffer = new char[512]; + Reader in = null; + in = new InputStreamReader(clob.getAsciiStream()); + // if(obj instanceof oracle.sql.CLOB) { + // in = ((oracle.sql.CLOB) obj).getCharacterStream(); + // } else if (obj instanceof weblogic.jdbc.wrapper.Clob) { + // in = ((weblogic.jdbc.base.BaseClob) obj).getCharacterStream(); + // } + while ((len = in.read(buffer)) != -1) + sb.append(buffer, 0, len); + in.close(); + } else if (Globals.isPostgreSQL() || Globals.isMySQL()) { + String clob= null; + Object obj = null; + if (rs.next()) { + sb.append(rs.getString(1)); + } + else + throw new RaptorException("Report " + reportID + " not found in the database"); + } else { + /*oracle.sql.CLOB clob = null; + if (rs.next()) + clob = (oracle.sql.CLOB) rs.getObject(1); + else + throw new RaptorException("Report " + reportID + " not found in the database"); + int len = 0; + char[] buffer = new char[512]; + Reader in = clob.getCharacterStream(); + while ((len = in.read(buffer)) != -1) + sb.append(buffer, 0, len); + in.close();*/ + throw new RaptorException("only maria db support for this "); + } + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } catch (IOException ex) { + throw new RaptorException (ex.getMessage(), ex.getCause()); + } finally { + try { + if(rs!=null) + rs.close(); + if(stmt!=null) + stmt.close(); + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } + } + return sb.toString(); + } // loadCustomReportXML + + private static void dbUpdateReportXML(Connection connection, String reportID, + String reportXML) throws RaptorException { + PreparedStatement stmt = null; + ResultSet rs = null; + + try { + String sql = ""; + if(!Globals.isMySQL()) + sql = Globals.getDBUpdateReportXml(); + else + sql = Globals.getDBUpdateReportXmlMySqlSelect(); + stmt = connection.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE, + ResultSet.CONCUR_UPDATABLE); + stmt.setInt(1,Integer.parseInt(reportID)); + rs = stmt.executeQuery(); + Writer out = null; + /*if(Globals.isWeblogicServer()) { + java.sql.Clob clob = null; + if (rs.next()) + clob = rs.getClob(1); + else + throw new RaptorException("Report " + reportID + " not found in the database"); + + if (clob.length() > reportXML.length()) + clob.truncate(0); + //clob.trim(reportXML.length()); + out = ((weblogic.jdbc.vendor.oracle.OracleThinClob)clob).getCharacterOutputStream(); + } else*/ + if (Globals.isPostgreSQL()) { + if (rs.next()) { + rs.updateString("report_xml",reportXML); + rs.updateRow(); + connection.commit(); + //sb.append(rs.getString(1)); + } + else + throw new RaptorException("Report " + reportID + " not found in the database"); + } else if (Globals.isMySQL()) { + if(rs.next()) { + final InputStream stream = rs.getBinaryStream( "report_xml" ); + InputStream streamNew = new ByteArrayInputStream(reportXML.getBytes(StandardCharsets.UTF_8)); + final PreparedStatement update = connection.prepareStatement( Globals.getDBUpdateReportXmlMySql() ); + update.setBinaryStream( 1,streamNew ); + update.setInt( 2,Integer.parseInt(reportID) ); + update.execute(); + } else + throw new RaptorException("Report " + reportID + " not found in the database"); + + } else { + /*oracle.sql.CLOB clob = null; + if (rs.next()) + clob = (oracle.sql.CLOB) rs.getObject(2); + else + throw new RaptorException("Report " + reportID + " not found in the database"); + + if (clob.length() > reportXML.length()) + clob.trim(reportXML.length()); + out = clob.getCharacterOutputStream();*/ + throw new RaptorException("only maria db support for this "); + } + if(!(Globals.isPostgreSQL() || Globals.isMySQL())) { + out.write(reportXML); + out.flush(); + out.close(); + } + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } catch (IOException ex) { + throw new RaptorException (ex.getMessage(), ex.getCause()); + } finally { + try { + if(rs!=null) + rs.close(); + if(stmt!=null) + stmt.close(); + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } + } + } // dbUpdateReportXML + + public static void updateCustomReportRec(Connection connection, ReportWrapper rw, + String reportXML) throws RaptorException { + /* DbUtils.executeUpdate(connection,"UPDATE cr_report SET title='" + + Utils.oracleSafe(rw.getReportName()) + "', descr='" + + Utils.oracleSafe(rw.getReportDescr()) + "', public_yn='" + + (rw.isPublic() ? "Y" : "N") + "', menu_id='" + rw.getMenuID() + + "', menu_approved_yn='" + (rw.isMenuApproved() ? "Y" : "N") + "', owner_id=" + + rw.getOwnerID() + ", maint_id=" + rw.getUpdateID() + + ", maint_date=TO_DATE('" + rw.getUpdateDate() + "', '" + + Globals.getOracleTimeFormat() + "'), dashboard_type_yn='"+ (rw.isDashboardType()?"Y":"N")+"', dashboard_yn= '" + + (rw.getReportType().equals(AppConstants.RT_DASHBOARD)?"Y":"N") + "' WHERE rep_id = " + rw.getReportID());*/ + + String sql = Globals.getUpdateCustomReportRec(); + + sql = sql.replace("[Utils.oracleSafe(rw.getReportName())]", Utils.oracleSafe(rw.getReportName())); + sql = sql.replace("[Utils.oracleSafe(rw.getReportDescr())]", Utils.oracleSafe(rw.getReportDescr())); + sql = sql.replace("[(rw.isPublic()]",(rw.isPublic() ? "Y" : "N")); + sql = sql.replace("[rw.getMenuID()]", rw.getMenuID()); + sql = sql.replace("[(rw.isMenuApproved()]", (rw.isMenuApproved() ? "Y" : "N")); + sql = sql.replace("[rw.getOwnerID()]",rw.getOwnerID()); + sql = sql.replace("[rw.getUpdateID()]",rw.getUpdateID()); + sql = sql.replace("[rw.getUpdateDate()]",rw.getUpdateDate()); + sql = sql.replace("[Globals.getTimeFormat()]", Globals.getTimeFormat()); + sql = sql.replace("[(rw.isDashboardType()]", (rw.isDashboardType()?"Y":"N")); + sql = sql.replace("[(rw.getReportType().equals(AppConstants.RT_DASHBOARD)]", (rw.getReportType().equals(AppConstants.RT_DASHBOARD)?"Y":"N")); + sql = sql.replace("[rw.getReportID()]", rw.getReportID()); + + DbUtils.executeUpdate(connection, sql); + + dbUpdateReportXML(connection, rw.getReportID(), reportXML); + } // updateCustomReportRec + + public static boolean isDashboardType ( String reportID ) throws RaptorException { + return false; +/* String sql = "select dashboard_type_yn from cr_report where rep_id = ?"; + Connection connection = DbUtils.getConnection(); + PreparedStatement stmt = null; + ResultSet rs = null; + boolean dashboardType= false; + try { + stmt = connection.prepareStatement(sql); + stmt.setString(1, reportID); + rs = stmt.executeQuery(); + if(rs.next()) { + dashboardType = nvls(rs.getString(1),"N").trim().toUpperCase().startsWith("Y"); + } + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } finally { + try { + rs.close(); + stmt.close(); + DbUtils.clearConnection(connection); + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } + } + return dashboardType;*/ + } + + public static boolean isReportsAlreadyScheduled ( String reportID ) throws RaptorException { + //String sql = "select rep_id from cr_report_schedule where rep_id = ?"; + String sql = Globals.getIsReportAlreadyScheduled(); + + Connection connection = DbUtils.getConnection(); + PreparedStatement stmt = null; + ResultSet rs = null; + boolean isScheduled= false; + try { + stmt = connection.prepareStatement(sql); + stmt.setInt(1, Integer.parseInt(reportID)); + rs = stmt.executeQuery(); + if(rs.next()) { + isScheduled = true; + } + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } finally { + try { + if(rs!=null) + rs.close(); + if(stmt!=null) + stmt.close(); + DbUtils.clearConnection(connection); + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } + } + return isScheduled; +} + + public static void createCustomReportRec(Connection connection, ReportWrapper rw, + String reportXML) throws RaptorException { + + /*DbUtils + .executeUpdate( + connection, + "INSERT INTO cr_report(rep_id, title, descr, public_yn, menu_id, menu_approved_yn, report_xml, owner_id, create_id, create_date, maint_id, maint_date, dashboard_type_yn, dashboard_yn, folder_id) VALUES(" + + rw.getReportID() + + ", '" + + Utils.oracleSafe(rw.getReportName()) + + "', '" + + Utils.oracleSafe(rw.getReportDescr()) + + "', '" + + (rw.isPublic() ? "Y" : "N") + + "', '" + + rw.getMenuID() + + "', '" + + (rw.isMenuApproved() ? "Y" : "N") + + "', '', " + + rw.getOwnerID() + + ", " + + rw.getCreateID() + + ", TO_DATE('" + + rw.getCreateDate() + + "', '" + + Globals.getOracleTimeFormat() + + "'), " + + rw.getUpdateID() + + ", TO_DATE('" + + rw.getUpdateDate() + + "', '" + + Globals.getOracleTimeFormat() + + "'), '" + + (rw.isDashboardType()?"Y":"N") + + "', '" + + (rw.getReportType().equals(AppConstants.RT_DASHBOARD)?"Y":"N") + + "', " + + rw.getFolderId() + + ")");*/ + String sql = Globals.getCreateCustomReportRec(); + + sql = sql.replace("[rw.getReportID()]", rw.getReportID()); + sql = sql.replace("[Utils.oracleSafe(rw.getReportName())]", Utils.oracleSafe(rw.getReportName())); + sql = sql.replace("[Utils.oracleSafe(rw.getReportDescr())]", Utils.oracleSafe(rw.getReportDescr())); + sql = sql.replace("[rw.isPublic()]", (rw.isPublic() ? "Y" : "N")); + sql = sql.replace("[rw.getMenuID()]", rw.getMenuID()); + sql = sql.replace("[rw.isMenuApproved()]", (rw.isMenuApproved() ? "Y" : "N")); + sql = sql.replace("[rw.getOwnerID()]", rw.getOwnerID()); + sql = sql.replace("[rw.getCreateID()]", rw.getCreateID()); + sql = sql.replace("[rw.getCreateDate()]", rw.getCreateDate()); + sql = sql.replace("[Globals.getTimeFormat()]", Globals.getTimeFormat()); + sql = sql.replace("[rw.getUpdateID()]", rw.getUpdateID()); + sql = sql.replace("[rw.getUpdateDate()]", rw.getUpdateDate()); + sql = sql.replace("[rw.isDashboardType()]", (rw.isDashboardType()?"Y":"N")); + sql = sql.replace("[rw.getReportType().equals(AppConstants.RT_DASHBOARD)]", (rw.getReportType().equals(AppConstants.RT_DASHBOARD)?"Y":"N")); + sql = sql.replace("[rw.getFolderId()]", rw.getFolderId()); + + + DbUtils.executeUpdate(connection,sql); + + dbUpdateReportXML(connection, rw.getReportID(), reportXML); + } // createCustomReportRec + + public static Vector getUserReportNames(HttpServletRequest request) { + return getUserReportNames(AppUtils.getUserID(request)); + } // getUserReportNames + + public static Vector getUserReportNames(String userID) { + Vector reportIdNames = new Vector(); + + try { + + String sql = Globals.getTheUserReportNames(); + sql = sql.replace("[userID]", userID); + DataSet ds = DbUtils.executeQuery(sql); + + //DataSet ds = DbUtils + // .executeQuery("SELECT cr.rep_id, cr.title FROM cr_report cr WHERE nvl(cr.owner_id, cr.create_id) = " + // + userID); + + for (int i = 0; i < ds.getRowCount(); i++) + reportIdNames.add(new IdNameValue(ds.getString(i, 0), ds.getString(i, 1))); + } catch (Exception e) { + } + + return reportIdNames; + } // getUserReportNames + + public static String getReportOwnerID(String reportID) throws RaptorException { + + // String sql = "SELECT nvl(cr.owner_id, cr.create_id) owner FROM cr_report cr WHERE rep_id = ?"; + + String sql = Globals.getTheReportOwnerId(); + + Connection connection = DbUtils.getConnection(); + PreparedStatement stmt = null; + ResultSet rs = null; + String reportOwnerID = null; + try { + stmt = connection.prepareStatement(sql); + stmt.setInt(1, Integer.parseInt(reportID)); + rs = stmt.executeQuery(); + if(rs.next()) { + reportOwnerID = rs.getString(1); + } + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } finally { + try { + if(rs!=null) + rs.close(); + if(stmt!=null) + stmt.close(); + DbUtils.clearConnection(connection); + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } + } + + return reportOwnerID; + } // getReportOwnerID + + public static void deleteReportRecord(String reportID) throws RaptorException { + Connection con = DbUtils.startTransaction(); + + /*try { + DbUtils.executeUpdate(con, "DELETE cr_report_log WHERE rep_id = " + reportID); + DbUtils.executeUpdate(con, "DELETE cr_report_schedule_users WHERE rep_id = " + + reportID); + DbUtils.executeUpdate(con, "DELETE cr_report_schedule WHERE rep_id = " + reportID); + DbUtils.executeUpdate(con, "DELETE cr_report_access WHERE rep_id = " + reportID); + DbUtils.executeUpdate(con, "DELETE cr_report_email_sent_log WHERE rep_id = " + reportID); + DbUtils.executeUpdate(con, "DELETE cr_favorite_reports WHERE rep_id = " + reportID); + DbUtils.executeUpdate(con, "DELETE cr_report WHERE rep_id = " + reportID); + DbUtils.commitTransaction(con); + } */ + + try{ + String sql1= Globals.getDeleteReportRecordLog(); + sql1 = sql1.replace("[reportID]", reportID); + String sql2= Globals.getDeleteReportRecordUsers(); + sql2 = sql2.replace("[reportID]", reportID); + String sql3= Globals.getDeleteReportRecordSchedule(); + sql3 = sql3.replace("[reportID]", reportID); + String sql4= Globals.getDeleteReportRecordAccess(); + sql4 = sql4.replace("[reportID]", reportID); + String sql5= Globals.getDeleteReportRecordEmail(); + sql5 = sql5.replace("[reportID]", reportID); + String sql6= Globals.getDeleteReportRecordFavorite(); + sql6 = sql6.replace("[reportID]", reportID); + String sql7= Globals.getDeleteReportRecordReport(); + sql7 = sql7.replace("[reportID]", reportID); + + DbUtils.executeUpdate(con, sql1); + DbUtils.executeUpdate(con, sql2); + DbUtils.executeUpdate(con, sql3); + DbUtils.executeUpdate(con, sql4); + DbUtils.executeUpdate(con, sql5); + DbUtils.executeUpdate(con, sql6); + DbUtils.executeUpdate(con, sql7); + DbUtils.commitTransaction(con); + + } + + + catch (Exception e) { + DbUtils.rollbackTransaction(con); + } finally { + DbUtils.clearConnection(con); + } + } // deleteReportRecord + + public static ArrayList loadQuickLinks(HttpServletRequest request, String menuId, boolean b) throws RaptorException { + String userID = AppUtils.getUserID(request); + StringBuffer roleList = new StringBuffer(); + roleList.append("-1"); + for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) + roleList.append("," + ((String) iter.next())); + + // DataSet ds = DbUtils.executeQuery("SELECT cr.rep_id, cr.title FROM + // cr_report cr WHERE cr.public_yn = 'Y' AND cr.menu_id = + // '"+nvls(menuId)+"' AND cr.menu_approved_yn = 'Y' ORDER BY cr.title"); + // Copied from SearchHandler and simplified + /*String query = "SELECT cr.rep_id, " + + "cr.title, " + + "cr.descr " + + "FROM cr_report cr, " + + "(SELECT rep_id, " + + "MIN(read_only_yn) read_only_yn " + + "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " + + userID + + ") " + + "UNION ALL " + + "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN (" + + roleList.toString() + "))" + ") report_access " + + "GROUP BY rep_id) ra " + "WHERE INSTR('|'||cr.menu_id||'|', '|'||'" + + nvls(menuId) + "'||'|') > 0 AND " + "cr.menu_approved_yn = 'Y' AND " + + "cr.rep_id = ra.rep_id (+) AND " + + "(nvl(cr.owner_id, cr.create_id) = " + userID + + " OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL) " + + "ORDER BY cr.title";*/ + + String query = Globals.getLoadQuickLinks(); + query = query.replace("[userID]", userID); + query = query.replace("[roleList.toString()]", roleList.toString()); + query = query.replace("[nvls(menuId)]", nvls(menuId)); + + DataSet ds = DbUtils + .executeQuery(query); + + ArrayList quickLinks = new ArrayList(ds.getRowCount()); + StringBuffer link = new StringBuffer(""); + for (int i = 0; i < ds.getRowCount(); i++) { + link = new StringBuffer(""); + link.append("" +ds.getString(i, 1) + "" + (Globals.getShowDescrAtRuntime() ? " - " + ds.getString(i, 2) : "") ); + quickLinks.add(link.toString()); + } + + return quickLinks; + } // loadQuickLinks + + public static ArrayList getQuickLinksJSON(HttpServletRequest request, String menuId, boolean b) throws RaptorException { + String userID = AppUtils.getUserID(request); + StringBuffer roleList = new StringBuffer(); + roleList.append("-1"); + for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) + roleList.append("," + ((String) iter.next())); + + String query = Globals.getLoadQuickLinks(); + query = query.replace("[userID]", userID); + query = query.replace("[roleList.toString()]", roleList.toString()); + query = query.replace("[nvls(menuId)]", nvls(menuId)); + + DataSet ds = DbUtils + .executeQuery(query); + + ArrayList quickLinksArray = new ArrayList(ds.getRowCount()); + for (int i = 0; i < ds.getRowCount(); i++) { + QuickLink quickLink = new QuickLink(); + StringBuffer link = new StringBuffer(""); + link.append(AppUtils.getReportExecuteActionURLNG() +"c_master="+ ds.getString(i, 0)); + if(b) link.append("&PAGE_ID="+menuId+"&refresh=Y"); + quickLink.setReportURL(link.toString()); + quickLink.setReportName(ds.getString(i, 1)); + quickLink.setShowDescr(Globals.getShowDescrAtRuntime()); + quickLink.setReportDescr(ds.getString(i, 2)); + quickLinksArray.add(quickLink); + } + + return quickLinksArray; + } // loadQuickLinks + + //this will retrieve all the reports within the specified folder. + public static ReportSearchResult loadFolderReports(HttpServletRequest request, String menuId, boolean b, String folderId, boolean isUserReport, boolean isPublicReport) throws RaptorException { + String HTML_FORM = "forma"; + String userID = AppUtils.getUserID(request); + StringBuffer roleList = new StringBuffer(); + roleList.append("-1"); + String rep_title_sql = "''"; + String PRIVATE_ICON = "Private "; + + for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) + roleList.append("," + ((String) iter.next())); + + /*String sql= "SELECT cr.rep_id, " + + "cr.rep_id report_id, " + + rep_title_sql+ + "||DECODE(cr.public_yn, 'Y', '', '" + + PRIVATE_ICON + + "')||cr.title||'' title, " + + "cr.descr, " + + "au.first_name||' '||au.last_name owner_name, " + + "TO_CHAR(cr.create_date, 'MM/DD/YYYY') create_date, " + + "DECODE(NVL(cr.owner_id, cr.create_id), " + + userID + + ", 'N', NVL(ra.read_only_yn, 'Y')) read_only_yn, " + + "DECODE(NVL(cr.owner_id, cr.create_id), " + + userID + + ", 'Y', 'N') user_is_owner_yn " + + " FROM cr_report cr, " + + "app_user au, " + + "(SELECT rep_id, MIN(read_only_yn) read_only_yn " + + "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " + + userID + + ") " + + "UNION ALL " + + "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN " + + "(-1,1000,1))" + ") report_access GROUP BY rep_id) ra " + + "WHERE TO_CHAR(cr.rep_id) = nvl('', TO_CHAR(cr.rep_id)) AND UPPER(cr.title) LIKE UPPER('%%') " + + "AND nvl(cr.owner_id, cr.create_id) = au.user_id AND cr.rep_id = ra.rep_id (+) " + + " AND cr.folder_id= '" + folderId + "'" ;*/ + + /*String sql = "" + + "SELECT cr.rep_id, " + + "cr.rep_id report_id, " + + rep_title_sql + "||DECODE(cr.public_yn, 'Y', '', '" + PRIVATE_ICON + "')||cr.title||'' title, " + + "cr.descr, " + + "au.first_name||' '||au.last_name owner_name, " + + "TO_CHAR(cr.create_date, 'MM/DD/YYYY') create_date, " + + "DECODE(NVL(cr.owner_id, cr.create_id), " + userID + + ", 'N', NVL(ra.read_only_yn, 'Y')) read_only_yn, " + + "DECODE(NVL(cr.owner_id, cr.create_id), " + userID + + ", 'Y', 'N') user_is_owner_yn " + + "FROM cr_report cr, " + + "app_user au, " + + "(SELECT rep_id, " + + "MIN(read_only_yn) read_only_yn " + + "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " + + userID + + ") " + + "UNION ALL " + + "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN (" + + roleList.toString() + "))" + ") report_access " + "GROUP BY rep_id) ra " + + "WHERE " + "nvl(cr.owner_id, cr.create_id) = au.user_id " + + "AND cr.rep_id = ra.rep_id (+) AND cr.folder_id= '" + folderId + "'";*/ + + String sql = Globals.getLoadFolderReports(); + sql = sql.replace("[userID]", userID); + sql = sql.replace("[PRIVATE_ICON]", PRIVATE_ICON); + sql = sql.replace("[rep_title_sql]", rep_title_sql); + sql = sql.replace("[roleList.toString()]", roleList.toString()); + sql = sql.replace("[folderId]", folderId); + + + // String user_sql = " AND nvl(cr.owner_id, cr.create_id) = " + userID; + // String public_sql = " AND (nvl(cr.owner_id, cr.create_id) = " + userID + // + " OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL)"; + + String user_sql = Globals.getLoadFolderReportsUser(); + user_sql = user_sql.replace("[userID]", userID); + String public_sql = Globals.getLoadFolderReportsPublicSql(); + public_sql = public_sql.replace("[userID]", userID); + + if (isUserReport) + // My reports - user is owner + sql += user_sql; + else if (isPublicReport) + // Public reports - user has read or write access to the report + // (user is owner or report is public or user has explicit user or + // role access) + if (!AppUtils.isSuperUser(request)) + sql += public_sql; + else if (!AppUtils.isSuperUser(request)) + // All reports + // If user is super user - gets unrestricted access to all reports + // (read_only gets overriden later) + // else - not super user - doesn't get access to private reports of + // other users (= Public reports); Admin users get edit right + // override later + sql += public_sql; + logger.debug(EELFLoggerDelegate.debugLogger, ("query is for folder list is : " + sql)); + + DataSet ds = DbUtils.executeQuery(sql); + + /*Vector quickLinks = new Vector(ds.getRowCount()); + StringBuffer link = new StringBuffer(""); + for (int i = 0; i < ds.getRowCount(); i++) { + link = new StringBuffer(""); + link.append("" +ds.getString(i, 2) + "" + (Globals.getShowDescrAtRuntime() ? " - " + ds.getString(i, 2) : "") ); + quickLinks.add(link.toString()); + } + + return quickLinks;*/ + ReportSearchResult rsr = new ReportSearchResult(-1, ds.getRowCount(), 6, 7); + rsr.parseData(ds, request); + //rsr.truncateToPage(pageNo); + + return rsr; + } // loadFolderReports + + public static ArrayList loadQuickDownloadLinks(String userID, HttpServletRequest request) throws RaptorException { + /*String query = " SELECT a.file_name, b.title,to_char(a.dwnld_start_time, 'Dy DD-Mon-YYYY HH24:MI:SS') as time, "+ + " a.dwnld_start_time " + + " FROM cr_report_dwnld_log a, cr_report b where a.user_id = "+userID +" and "+ + " a.rep_id = b.rep_id " + + " and (a.dwnld_start_time) >= to_date(to_char(sysdate-24/24, 'mm/dd/yyyy'), 'mm/dd/yyyy') " + + " and a.record_ready_time is not null " + + " order by a.dwnld_start_time desc"; */ + + String query = Globals.getLoadQuickDownloadLinks(); + query = query.replace("[userID]", userID); + + + DataSet ds = DbUtils + .executeQuery(query); + ArrayList quickDownloadLinks = new ArrayList(ds.getRowCount()); + logger.debug(EELFLoggerDelegate.debugLogger, ("ROW SIZE " + ds.getRowCount())); + for (int i = 0; i < ds.getRowCount(); i++) { + quickDownloadLinks.add("" + ds.getString(i, 1)+ "" + " "+ ds.getString(i, 2)); + } + logger.debug(EELFLoggerDelegate.debugLogger, ("VECTOR SIZE " + quickDownloadLinks.size())); + + return quickDownloadLinks; + } // loadQuickLinks + + public static HashMap loadReportsToSchedule (HttpServletRequest request) throws RaptorException { + String userID = AppUtils.getUserID(request); + StringBuffer roleList = new StringBuffer(); + roleList.append("-1"); + for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) + roleList.append("," + ((String) iter.next())); + /*StringBuffer query = new StringBuffer(""); + query.append("SELECT cr.rep_id, "); + query.append("Initcap(cr.title), "); + query.append("cr.descr "); + query.append("FROM cr_report cr, "); + query.append("(SELECT rep_id, "); + query.append("MIN(read_only_yn) read_only_yn "); + query.append("FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = "); + query.append(userID); + query.append(") "); + query.append("UNION ALL "); + query.append("(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN ("); + query.append(roleList.toString() + "))" + ") report_access "); + query.append("GROUP BY rep_id) ra " + "WHERE "); + query.append("cr.rep_id = ra.rep_id (+) AND "); + query.append(" (cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL or cr.owner_id = " + userID +") "); + query.append("ORDER BY Initcap(cr.title)") ;*/ + + String sql = Globals.getLoadReportsToSchedule(); + sql = sql.replace("[userID]", userID); + sql = sql.replace("[roleList.toString()]", roleList.toString()); + + // DataSet ds = DbUtils + // .executeQuery(query.toString()); + + DataSet ds = DbUtils + .executeQuery(sql); + HashMap map = new HashMap(); + for (int i = 0; i < ds.getRowCount(); i++) { + map.put(ds.getItem(i,0), ds.getItem(i,1)); + } + + return map; + } + + public static HashMap loadReportsToAddInDashboard (HttpServletRequest request) throws RaptorException { + String userID = AppUtils.getUserID(request); + StringBuffer roleList = new StringBuffer(); + roleList.append("-1"); + for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) + roleList.append("," + ((String) iter.next())); + /*StringBuffer query = new StringBuffer(""); + query.append("SELECT cr.rep_id, "); + query.append("cr.title, "); + query.append("cr.descr "); + query.append("FROM cr_report cr, "); + query.append("(SELECT rep_id, "); + query.append("MIN(read_only_yn) read_only_yn "); + query.append("FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = "); + query.append(userID); + query.append(") "); + query.append("UNION ALL "); + query.append("(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN ("); + query.append(roleList.toString() + "))" + ") report_access "); + query.append("GROUP BY rep_id) ra " + "WHERE "); + query.append("cr.rep_id = ra.rep_id (+) AND "); + query.append("(nvl(cr.owner_id, cr.create_id) = " + userID); + query.append(" OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL) "); + query.append(" AND (cr.dashboard_yn = 'N' or cr.dashboard_yn is null) "); + query.append("ORDER BY cr.title") ;*/ + + String sql = Globals.getLoadReportsToAddInDashboard(); + sql = sql.replace("[userID]", userID); + sql = sql.replace("[roleList.toString()]", roleList.toString()); + + // DataSet ds = DbUtils + // .executeQuery(query.toString()); + + DataSet ds = DbUtils + .executeQuery(sql); + + HashMap map = new HashMap(); + for (int i = 0; i < ds.getRowCount(); i++) { + map.put(ds.getItem(i,0), ds.getItem(i,1)); + } + + return map; + } + + public static Vector loadMyRecentLinks(String userID, HttpServletRequest request) throws RaptorException { + /* StringBuffer query = new StringBuffer(""); + query.append("select rep_id, title, descr, form_fields from ( select rownum, rep_id, title, descr, form_fields from "); + query.append(" (select cr.rep_id, cr.title, a.form_fields, cr.descr, a.log_time, a.user_id, a.action, a.action_value " ); + query.append(" from cr_report_log a, cr_report cr where user_id = " + userID); + query.append(" and action = 'Report Execution Time' and a.rep_id = cr.rep_id order by log_time desc) x where rownum <= 6 ) y where rownum >= 1");*/ +// DataSet ds = DbUtils +// .executeQuery( +// " SELECT a.file_name, b.title,to_char(a.dwnld_start_time, 'Dy DD-Mon-YYYY HH24:MI:SS') as time, "+ +// " a.dwnld_start_time " + +// " FROM cr_report_dwnld_log a, cr_report b where a.user_id = "+userID +" and "+ +// " a.rep_id = b.rep_id and (a.dwnld_start_time) >= to_date(to_char(sysdate-24/24, 'mm/dd/yyyy'), 'mm/dd/yyyy') " + +// " and a.record_ready_time is not null " + +// " order by a.dwnld_start_time desc"); +// DataSet ds = DbUtils + // .executeQuery(query.toString()); + + + String sql = Globals.getLoadMyRecentLinks(); + sql = sql.replace("[userID]", userID); + + DataSet ds = DbUtils + .executeQuery(sql); + + Vector myRecentLinks = new Vector(ds.getRowCount()); + logger.debug(EELFLoggerDelegate.debugLogger, ("ROW SIZE " + ds.getRowCount())); + for (int i = 0; i < ds.getRowCount(); i++) { + myRecentLinks.add("" + ds.getString(i, 1)+ ""); + } + logger.debug(EELFLoggerDelegate.debugLogger, ("VECTOR SIZE " + myRecentLinks.size())); + + return myRecentLinks; + } // loadQuickLinks + + public static void createReportLogEntry(Connection connection, String reportID, + String userID, String action, String executionTime,String form_fields) throws RaptorException { + if(form_fields.length()>=4000) form_fields = ""; + //String stmt = "INSERT INTO cr_report_log (rep_id, log_time, user_id, action, action_value, form_fields) VALUES(" + // + reportID + ", SYSDATE, " + userID + ", '" + action + "' , '" + executionTime + "', '"+ form_fields +"')"; + + String stmt = Globals.getCreateReportLogEntry(); + stmt = stmt.replace("[reportID]", reportID); + stmt = stmt.replace("[userID]", userID); + stmt = stmt.replace("[action]", action); + stmt = stmt.replace("[executionTime]", executionTime); + stmt = stmt.replace("[form_fields]", form_fields); + + if (Globals.getEnableReportLog()) + if (connection == null) + DbUtils.executeUpdate(stmt); + else + DbUtils.executeUpdate(connection, stmt); + } // createReportLogEntry + + public static void createReportLogEntryForExecutionTime(Connection connection, String reportID, + String userID, String executionTime, String action, String formFields) throws RaptorException { + if(formFields.length()>=4000) formFields = ""; + //String stmt = "INSERT INTO cr_report_log (rep_id, log_time, user_id, action, action_value, form_fields) VALUES(" + // + reportID + ", sysdate+1/(24*60*60) , " + userID + ", '" + action + "' , '" + executionTime + "', '"+ formFields +"')"; + + String stmt = Globals.getCreateReportLogEntryExecTime(); + stmt = stmt.replace("[reportID]", reportID); + stmt = stmt.replace("[userID]", userID); + stmt = stmt.replace("[action]", action); + stmt = stmt.replace("[executionTime]", executionTime); + stmt = stmt.replace("[formFields]", formFields); + + if (Globals.getEnableReportLog()) + if (connection == null) + DbUtils.executeUpdate(stmt); + else + DbUtils.executeUpdate(connection, stmt); + } // createReportLogEntry + + public static void clearReportLogEntries(String reportId, String userId) throws RaptorException { + String sql = Globals.getClearReportLogEntries(); + Connection connection = DbUtils.getConnection(); + PreparedStatement stmt = null; + String reportOwnerID = null; + int rowsAffected = 0; + try { + stmt = connection.prepareStatement(sql); + stmt.setInt(1, Integer.parseInt(reportId)); + stmt.setInt(2, Integer.parseInt(userId)); + rowsAffected = stmt.executeUpdate(); + if(rowsAffected > 0) connection.commit(); + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } finally { + try { + stmt.close(); + connection.close(); + DbUtils.clearConnection(connection); + } catch (SQLException ex) { + throw new ReportSQLException (ex.getMessage(), ex.getCause()); + } + } + } // clearReportLogEntries + + public static Vector loadReportLogEntries(String reportId) throws RaptorException { + /* StringBuffer query = new StringBuffer("SELECT x.log_time, x.user_id,") ; + query.append(" (CASE WHEN x.action = 'Report Execution Time' THEN "); + query.append(" ''||x.action||''"); + query.append(" ELSE x.action END) action, " ); + query.append(" (CASE WHEN x.action = 'Report Execution Time' THEN "); + query.append(" action_value " ); + query.append(" ELSE 'N/A' END) time_taken, " ); + query.append( " (CASE WHEN x.action = 'Report Execution Time' THEN '\"Run' ELSE 'N/A' END) run_image, " ); + query.append(" x.name FROM "); + query.append(" (SELECT rl.rep_id, TO_CHAR(rl.log_time, 'Month DD, YYYY HH:MI:SS AM') log_time, rl.action_value, fuser.last_name ||', '||fuser.first_name name, "); + query.append(" rl.user_id, rl.action, rl.form_fields FROM cr_report_log rl, fn_user fuser WHERE rl.rep_id = "+ nvls(reportId)+ " and rl.action != 'Report Run' and fuser.user_id = rl.user_id" ); + query.append(" ORDER BY rl.log_time DESC) x WHERE ROWNUM <= 100");*/ +// DataSet ds = DbUtils +// .executeQuery("SELECT x.log_time, x.user_id, x.action FROM (SELECT TO_CHAR(rl.log_time, 'Month DD, YYYY HH:MI:SS AM') log_time, rl.user_id, rl.action FROM cr_report_log rl WHERE rl.rep_id = " +// + nvls(reportId) + " ORDER BY rl.log_time DESC) x WHERE ROWNUM <= 100"); + // DataSet ds = DbUtils.executeQuery(query.toString()); + + String sql = Globals.getLoadReportLogEntries(); + sql = sql.replace("[AppUtils.getRaptorActionURL()]", AppUtils.getRaptorActionURL()); + sql = sql.replace("[AppUtils.getImgFolderURL()]", AppUtils.getImgFolderURL()); + sql = sql.replace("[nvls(reportId)]", nvls(reportId)); + + + DataSet ds = DbUtils.executeQuery(sql); + + Vector logEntries = new Vector(ds.getRowCount()); + + for (int i = 0; i < ds.getRowCount(); i++) + logEntries.add(new ReportLogEntry(ds.getString(i, 0), ds + .getString(i, 5), ds.getString(i, 2), ds.getString(i, 3), ds.getString(i, 4))); + + return logEntries; + } // loadReportLogEntries + + public static boolean doesUserCanScheduleReport(HttpServletRequest request, String scheduleId) throws RaptorException { + boolean flagLimit = false; + boolean flagScheduleIdPresent = false; + String userId = AppUtils.getUserID(request); + if(AppUtils.isAdminUser(request))return true; + //String query = "select crs.sched_user_id, count(*) from cr_report_schedule crs where sched_user_id = " + userId + " group by crs.sched_user_id having count(*) >= " + Globals.getScheduleLimit(); + String query = Globals.getDoesUserCanScheduleReport(); + query = query.replace("[userId]", userId); + query = query.replace("[Globals.getScheduleLimit()]", String.valueOf(Globals.getScheduleLimit())); + + DataSet ds = DbUtils.executeQuery(query); + logger.debug(EELFLoggerDelegate.debugLogger, (" User Schedule ds.getRowCount() " + ds.getRowCount() + " " +(ds.getRowCount()>0))); + if(ds.getRowCount() > 0) flagLimit = true; + else flagLimit = false; + logger.debug(EELFLoggerDelegate.debugLogger, ("scheduleId " + scheduleId)); + if(scheduleId==null || scheduleId.trim().length()<=0) return !flagLimit; + //query = "select crs.schedule_id from cr_report_schedule crs where schedule_id = " + scheduleId; + query = Globals.getDoesUserCanSchedule(); + query = query.replace("[scheduleId]", scheduleId); + + if(ds.getRowCount() > 0) flagScheduleIdPresent = true; + else flagScheduleIdPresent = false; + if(!flagLimit) return true; + if(flagLimit && flagScheduleIdPresent) return true; + else return false; + } + + public static String getSystemDateTime() throws RaptorException { + //String query = "select to_char(sysdate,'MM/dd/yyyy HH24:mi:ss') from dual"; + String query = Globals.getTheSystemDateTime(); + + DataSet ds = DbUtils.executeQuery(query); + String timeStr = ""; + if(ds.getRowCount() > 0) { + timeStr = ds.getString(0,0); + } + return timeStr; + + } + + public static String getNextDaySystemDateTime() throws RaptorException { + //String query = "select to_char(sysdate+1,'MM/dd/yyyy HH24:mi:ss') from dual"; + String query = Globals.getTheNextDayDateTime(); + DataSet ds = DbUtils.executeQuery(query); + String timeStr = ""; + if(ds.getRowCount() > 0) { + timeStr = ds.getString(0,0); + } + return timeStr; + + } + + public static String getNext15MinutesOfSystemDateTime() throws RaptorException { + //String query = "select to_char(sysdate+15/(24*60),'MM/dd/yyyy HH24:mi:ss') from dual"; + String query = Globals.getTheNextFifteenMinDateTime(); + + DataSet ds = DbUtils.executeQuery(query); + String timeStr = ""; + if(ds.getRowCount() > 0) { + timeStr = ds.getString(0,0); + } + return timeStr; + + } + + public static String getNext30MinutesOfSystemDateTime() throws RaptorException { + //String query = "select to_char(sysdate+30/(24*60),'MM/dd/yyyy HH24:mi:ss') from dual"; + String query = Globals.getTheNextThirtyMinDateTime(); + DataSet ds = DbUtils.executeQuery(query); + String timeStr = ""; + if(ds.getRowCount() > 0) { + timeStr = ds.getString(0,0); + } + return timeStr; + + } + + public static String getTemplateFile(String reportId) throws RaptorException { + //String query = "select template_file from cr_report_template_map where report_id = " + reportId; + String query = Globals.getTheTemplateFile(); + query = query.replace("[reportId]", reportId); + String templateFile = ""; + try { + DataSet ds = DbUtils.executeQuery(query); + if(ds.getRowCount() > 0) { + templateFile = ds.getString(0,0); + } + }catch(RaptorException ex) { + logger.debug(EELFLoggerDelegate.debugLogger, ("SQL Exception while trying to access cr_report_template_map ")); + } + return templateFile; + + } + + + public static HashMap loadPDFImgLookUp() throws RaptorException { + StringBuffer query = new StringBuffer(""); + HashMap pdfImgMap = new HashMap(); + //query.append("select image_id, image_loc from cr_raptor_pdf_img"); + query.append(Globals.getLoadPdfImgLookup()); + DataSet ds = DbUtils.executeQuery(query.toString()); + for (int i = 0; i < ds.getRowCount(); i++) { + pdfImgMap.put(ds.getString(i, 0), ds.getString(i,1)); + } + return pdfImgMap; + } // loadQuickLinks + + public static HashMap loadActionImgLookUp() throws RaptorException { + StringBuffer query = new StringBuffer(""); + HashMap pdfImgMap = new HashMap(); + //query.append("select image_id, image_loc from cr_raptor_action_img"); + query.append(Globals.getLoadActionImgLookup()); + DataSet ds = DbUtils.executeQuery(query.toString()); + for (int i = 0; i < ds.getRowCount(); i++) { + pdfImgMap.put(ds.getString(i, 0), ds.getString(i,1)); + } + return pdfImgMap; + } // loadQuickLinks + +} // ReportLoader + diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/SearchHandler.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/SearchHandler.java new file mode 100644 index 00000000..1a15e938 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/SearchHandler.java @@ -0,0 +1,479 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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. + * ================================================================================ + */ +/* =========================================================================================== + * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) + * Raptor : This tool is used to generate different kinds of reports with lot of utilities + * =========================================================================================== + * + * ------------------------------------------------------------------------------------------- + * SearchHandler.java - This class is used to search reports and sort them in different order + * based on preference. It can also download the list in CSV format. + * ------------------------------------------------------------------------------------------- + * + * + * + * Changes + * ------- + * 18-Aug-2009 : Version 8.5.1 (Sundar);
  • request Object is passed to prevent caching user/roles - Datamining/Hosting.
+ * 13-Aug-2009 : Version 8.5 (Sundar);
  • Refresh is added while running report.
  • + *
+ * 27-Jul-2009 : Version 8.4 (Sundar);
  • A new sort order PUBLIC is added.
  • + *
  • In Public reports option it brings all the reports + * including the one which logged in user didn't create + * and which is not public. This is available for Super users and "Admin equivalent Super Users".
  • + *
+ * + */ +package org.openecomp.portalsdk.analytics.model; + +import java.io.*; +import java.sql.*; +import java.util.*; +import javax.servlet.http.*; + +import org.openecomp.portalsdk.analytics.controller.*; +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.model.search.*; +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class SearchHandler extends org.openecomp.portalsdk.analytics.RaptorObject { + private static final String HTML_FORM = "forma"; + private final static String PRIVATE_ICON = "Private "; + + public SearchHandler() { + } + + public void createCSVFileContent(Writer out, ReportSearchResult sr) throws IOException { + PrintWriter csvOut = new PrintWriter(out); + HtmlStripper strip = new HtmlStripper(); + + for (int c = 1; c < sr.getNumColumns(); c++) { + SearchResultColumn column = sr.getColumn(c); + if (column.getLinkURL() == null) + csvOut.print("\"" + column.getColumnTitle() + "\","); + } // for + csvOut.println(); + + for (int r = 0; r < sr.getNumRows(); r++) { + SearchResultRow row = sr.getRow(r); + + int c = 1; + for (row.resetNext(1); row.hasNext();) { + SearchResultField field = row.getNext(); + if (sr.getColumn(c++).getLinkURL() == null) + if (field.getDisplayValue().startsWith(PRIVATE_ICON)) + csvOut.print("\"" + + strip.stripHtml(field.getDisplayValue().substring(PRIVATE_ICON.length())) + + "\","); + else + csvOut.print("\"" + strip.stripHtml(field.getDisplayValue()) + "\","); + } // for + + csvOut.println(); + } // for + } // createCSVFileContent + + public String saveCSVPageFile(HttpServletRequest request, ReportSearchResult sr) { + try { + String csvFName = AppUtils.generateFileName(request, + (sr.getPageNo() < 0) ? AppConstants.FT_CSV_ALL : AppConstants.FT_CSV); + + BufferedWriter csvOut = new BufferedWriter(new FileWriter(AppUtils + .getTempFolderPath() + + csvFName)); + createCSVFileContent(csvOut, sr); + csvOut.close(); + + if (sr.getPageNo() < 0) + sr.setCsvAllRowsFileName(csvFName); + else + sr.setCsvPageFileName(csvFName); + + return csvFName; + } catch (Exception e) { + (new ErrorHandler()).processError(request, "Exception saving data to CSV file: " + + e.getMessage()); + return null; + } + } // saveCSVPageFile + + public ReportSearchResultJSON loadReportSearchResult(HttpServletRequest request) + throws RaptorException { + String userID = AppUtils.getUserID(request); + String fReportID = nvl(AppUtils.getRequestValue(request, AppConstants.RI_F_REPORT_ID)); + String fReportName = nvl(AppUtils.getRequestValue(request, + AppConstants.RI_F_REPORT_NAME)); + String sortOrder = nvl(AppUtils.getRequestValue(request, AppConstants.RI_SORT_ORDER), + AppConstants.RI_F_REPORT_NAME); + + String menuId = nvl(AppUtils.getRequestValue(request, AppConstants.RI_LIST_CATEGORY)); + + boolean userOnly = AppUtils.getRequestFlag(request, AppConstants.RI_USER_REPORTS); + boolean publicOnly = AppUtils.getRequestFlag(request, AppConstants.RI_PUBLIC_REPORTS); + boolean favoriteOnly = AppUtils.getRequestFlag(request, AppConstants.RI_FAVORITE_REPORTS); + + int pageNo = 0; + try { + pageNo = Integer.parseInt(request.getParameter(AppConstants.RI_NEXT_PAGE)); + } catch (Exception e) { + } + + StringBuffer roleList = new StringBuffer(); + roleList.append("-1"); + String rep_title_sql = "''"; + for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) + roleList.append("," + ((String) iter.next())); + // + /*String sql = "SELECT cr.rep_id, " + + "cr.rep_id report_id, " + + rep_title_sql+ + "||DECODE(cr.public_yn, 'Y', '', '" + + PRIVATE_ICON + + "')||cr.title||'' title, " + + "cr.descr, " + + "au.first_name||' '||au.last_name owner_name, " + + "TO_CHAR(cr.create_date, 'MM/DD/YYYY') create_date, " + + "DECODE(NVL(cr.owner_id, cr.create_id), " + + userID + + ", 'N', NVL(ra.read_only_yn, 'Y')) read_only_yn, " + + "DECODE(NVL(cr.owner_id, cr.create_id), " + + userID + + ", 'Y', 'N') user_is_owner_yn, " + + "case when report_xml like '%N%' " + + "then 'N' " + + "when report_xml like '%Y%' " + + "or 1 = (select distinct 1 from cr_report_schedule where rep_id = cr.rep_id) " + + "then 'Y' " + + "else 'N' end " + + "FROM cr_report cr, " + + "app_user au, " + + "(SELECT rep_id, " + + "MIN(read_only_yn) read_only_yn " + + "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " + + userID + + ") " + + "UNION ALL " + + "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN (" + + roleList.toString() + "))" + ") report_access " + "GROUP BY rep_id) ra " + + "WHERE TO_CHAR(cr.rep_id) = nvl('" + fReportID + + "', TO_CHAR(cr.rep_id)) AND " + "UPPER(cr.title) LIKE UPPER('%" + + fReportName + "%') AND " + "nvl(cr.owner_id, cr.create_id) = au.user_id " + + "AND cr.rep_id = ra.rep_id (+) ";*/ + + String sql = Globals.getLoadReportSearchResult(); + String rep_id = ""; + String rep_id_options = ""; + String rep_id_sql = Globals.getLoadReportSearchRepIdSql(); + //rep_id_sql = " AND ROUND(cr.rep_id, 0) like coalesce('%%', ROUND(cr.rep_id, 0)) "; + if(request.getParameter("rep_id")!=null) { + rep_id = request.getParameter("rep_id"); + } + if(request.getParameter("rep_id_options")!=null) { + rep_id_options = request.getParameter("rep_id_options"); + } + + /*Default: AND FORMAT(cr.rep_id, 0) like coalesce('%%', FORMAT(cr.rep_id, 0)) */ + + /*Equal to AND cr.rep_id = 1000 0 */ + /*Less than : AND cr.rep_id < 1000 1 */ + /*Greater than AND cr.rep_id > 1000 2 */ + + + if(AppUtils.nvl(rep_id).length()>0 ) { + if(AppUtils.nvl(rep_id_options).length()>0 ) { + switch (rep_id_options) { + case "0": + rep_id_sql = " AND cr.rep_id = "+ rep_id+" "; + break; + case "1": + rep_id_sql = " AND cr.rep_id < "+ rep_id+" "; + break; + case "2": + rep_id_sql = " AND cr.rep_id > "+ rep_id+" "; + break; + default: + rep_id_sql = Globals.getLoadReportSearchRepIdSql(); + break; + } + } else { + rep_id_sql = " AND cr.rep_id = "+ rep_id+" "; + } + } else { + rep_id_sql = Globals.getLoadReportSearchRepIdSql(); //equal is default + } + + sql = sql.replace("[fReportID]", rep_id_sql); + + String rep_name = ""; + String rep_name_options = ""; + String rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%%') "; + if(request.getParameter("rep_name")!=null) { + rep_name = request.getParameter("rep_name"); + } + if(request.getParameter("rep_name_options")!=null) { + rep_name_options = request.getParameter("rep_name_options"); + } + + /* Report name AND UPPER(cr.title) LIKE UPPER('Dash%') 0 */ + + /* Report name AND UPPER(cr.title) LIKE UPPER('%1') 1 */ + /* Report name AND UPPER(cr.title) LIKE UPPER('%1%') 2 */ + + if(AppUtils.nvl(rep_name).length()>0 ) { + if(AppUtils.nvl(rep_name_options).length()>0 ) { + switch (rep_name_options) { + case "0": + rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('"+rep_name+"%') "; + break; + case "1": + rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%"+rep_name+"') "; + break; + case "2": + rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%"+rep_name+"%') "; + break; + default: + rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%%') "; + break; + } + } else { + rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%"+rep_name+"%') "; //contains is default + } + } else { + rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%%') "; + } + sql = sql.replace("[fReportName]", rep_name_sql); + + if (menuId.length() > 0){ + /*sql += "AND INSTR('|'||cr.menu_id||'|', '|'||'" + menuId + "'||'|') > 0 " + * +"AND + * cr.menu_approved_yn = + * 'Y' " + ;*/ + String sql_add = Globals.getLoadReportSearchInstr(); + sql+= sql_add; + } + + //String user_sql = " AND nvl(cr.owner_id, cr.create_id) = " + userID; + String user_sql = Globals.getLoadReportSearchResultUser(); + + //String public_sql = " AND (nvl(cr.owner_id, cr.create_id) = " + userID + // + " OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL)"; + String public_sql = Globals.getLoadReportSearchResultPublic(); + + //String fav_sql = " AND cr.rep_id in (select rep_id from cr_favorite_reports where user_id = " + userID +" ) "; + String fav_sql = Globals.getLoadReportSearchResultFav(); + + if (userOnly) + // My reports - user is owner + sql += " " + user_sql; + else if (publicOnly) { + // Public reports - user has read or write access to the report + // (user is owner or report is public or user has explicit user or + // role access) + if (!AppUtils.isSuperUser(request)) + sql += " " + public_sql; + } else if (favoriteOnly) { + sql += " " + public_sql; + sql += " " + fav_sql; + } else if (!AppUtils.isSuperUser(request)) { + // All reports + // If user is super user - gets unrestricted access to all reports + // (read_only gets overriden later) + // else - not super user - doesn't get access to private reports of + // other users (= Public reports); Admin users get edit right + // override later + //sql += public_sql; + sql += " " + public_sql; + } + + + + if (sortOrder.equals(AppConstants.RI_F_OWNER_ID)){ + //sql += " ORDER BY DECODE(nvl(cr.owner_id, cr.create_id), " + userID + //+ ", ' ', upper(au.first_name||' '||au.last_name)), upper(cr.title)"; + String sql_sort = Globals.getLoadReportSearchResultSort(); + sql+=" " + sql_sort; + } + else if (sortOrder.equals(AppConstants.RI_F_REPORT_ID)) + sql += " ORDER BY cr.rep_id"; + else if(sortOrder.equals(AppConstants.RI_F_REPORT_CREATE_DATE)) + sql += " ORDER BY cr.create_date"; + else if(sortOrder.equals(AppConstants.RI_F_PUBLIC)) + sql += " ORDER BY cr.public_yn desc"; + + else + // if(sortOrder.equals(AppConstants.RI_F_REPORT_NAME)) + sql += " ORDER BY upper(cr.title)"; + + sql = sql.replace("[rep_title_sql]", "cr.title"); + sql = sql.replace("[PRIVATE_ICON]", PRIVATE_ICON); + sql = sql.replace("[userID]", userID); + sql = sql.replace("[roleList.toString()]", roleList.toString()); + + //System.out.println("query is for search list is : " + sql); + DataSet ds = DbUtils.executeQuery(sql); + + ReportSearchResultJSON rsr = new ReportSearchResultJSON(0, 6, 7); + rsr.parseData(ds, request, 0, 20, 6, 7); + //saveCSVPageFile(request, rsr); + //rsr.truncateToPage(pageNo); + //saveCSVPageFile(request, rsr); + + return rsr; + } // loadReportSearchResult + + public ReportSearchResult loadFolderReportResult(HttpServletRequest request) + throws Exception { + String userID = AppUtils.getUserID(request); + String fReportID = nvl(AppUtils.getRequestValue(request, AppConstants.RI_F_REPORT_ID)); + String fReportName = nvl(AppUtils.getRequestValue(request, + AppConstants.RI_F_REPORT_NAME)); + String sortOrder = nvl(AppUtils.getRequestValue(request, AppConstants.RI_SORT_ORDER), + AppConstants.RI_F_REPORT_NAME); + + String menuId = nvl(AppUtils.getRequestValue(request, AppConstants.RI_LIST_CATEGORY)); + + boolean userOnly = AppUtils.getRequestFlag(request, AppConstants.RI_USER_REPORTS); + boolean publicOnly = AppUtils.getRequestFlag(request, AppConstants.RI_PUBLIC_REPORTS); + + int pageNo = 0; + try { + pageNo = Integer.parseInt(request.getParameter(AppConstants.RI_NEXT_PAGE)); + } catch (Exception e) { + } + + StringBuffer roleList = new StringBuffer(); + roleList.append("-1"); + String rep_title_sql = "''"; + for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) + roleList.append("," + ((String) iter.next())); + // + /*String sql = "SELECT cr.rep_id, " + + "cr.rep_id report_id, " + + rep_title_sql+ + "||DECODE(cr.public_yn, 'Y', '', '" + + PRIVATE_ICON + + "')||cr.title||'' title, " + + "cr.descr, " + + "au.first_name||' '||au.last_name owner_name, " + + "TO_CHAR(cr.create_date, 'MM/DD/YYYY') create_date, " + + "DECODE(NVL(cr.owner_id, cr.create_id), " + + userID + + ", 'N', NVL(ra.read_only_yn, 'Y')) read_only_yn, " + + "DECODE(NVL(cr.owner_id, cr.create_id), " + + userID + + ", 'Y', 'N') user_is_owner_yn " + + "FROM cr_report cr, " + + "app_user au, " + + "(SELECT rep_id, " + + "MIN(read_only_yn) read_only_yn " + + "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " + + userID + + ") " + + "UNION ALL " + + "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN (" + + roleList.toString() + "))" + ") report_access " + "GROUP BY rep_id) ra " + + "WHERE TO_CHAR(cr.rep_id) = nvl('" + fReportID + + "', TO_CHAR(cr.rep_id)) AND " + "UPPER(cr.title) LIKE UPPER('%" + + fReportName + "%') AND " + "nvl(cr.owner_id, cr.create_id) = au.user_id " + + "AND cr.rep_id = ra.rep_id (+) ";*/ + + String sql = Globals.getLoadFolderReportResult(); + sql = sql.replace("[rep_title_sql]", rep_title_sql); + sql = sql.replace("[PRIVATE_ICON]", PRIVATE_ICON); + sql = sql.replace("[userID]", userID); + sql = sql.replace("[roleList.toString()]", roleList.toString()); + sql = sql.replace("[fReportID]", fReportID); + sql = sql.replace("[fReportName]", fReportName); + + if (menuId.length() > 0){ + /*sql += "AND INSTR('|'||cr.menu_id||'|', '|'||'" + menuId + "'||'|') > 0 " + * +"AND + * cr.menu_approved_yn = + * 'Y' " + ;*/ + String sql_add = Globals.getLoadReportSearchInstr(); + sql+= sql_add; + } + + //String user_sql = " AND nvl(cr.owner_id, cr.create_id) = " + userID; + String user_sql = Globals.getLoadReportSearchResultUser(); + + //String public_sql = " AND (nvl(cr.owner_id, cr.create_id) = " + userID + // + " OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL)"; + String public_sql = Globals.getLoadReportSearchResultPublic(); + + if (userOnly) + // My reports - user is owner + sql += user_sql; + else if (publicOnly) + // Public reports - user has read or write access to the report + // (user is owner or report is public or user has explicit user or + // role access) + if (!AppUtils.isSuperUser(request)) + sql += public_sql; + else if (!AppUtils.isSuperUser(request)) { + // All reports + // If user is super user - gets unrestricted access to all reports + // (read_only gets overriden later) + // else - not super user - doesn't get access to private reports of + // other users (= Public reports); Admin users get edit right + // override later + sql += public_sql; + } + + if (sortOrder.equals(AppConstants.RI_F_OWNER_ID)){ + + + //sql += " ORDER BY DECODE(nvl(cr.owner_id, cr.create_id), " + userID + // + ", ' ', au.first_name||' '||au.last_name), cr.title"; + + String sql_sort = Globals.getLoadFolderReportResultSort(); + sql+=sql_sort; + } + else if (sortOrder.equals(AppConstants.RI_F_REPORT_ID)) + sql += " ORDER BY cr.rep_id"; + else if(sortOrder.equals(AppConstants.RI_F_REPORT_CREATE_DATE)) + sql += " ORDER BY cr.create_date"; + else if(sortOrder.equals(AppConstants.RI_F_PUBLIC)) + sql += " ORDER BY cr.public_yn desc"; + else + // if(sortOrder.equals(AppConstants.RI_F_REPORT_NAME)) + sql += " ORDER BY cr.title"; + + //System.out.println("query is for search list is : " + sql); + DataSet ds = DbUtils.executeQuery(sql); + + ReportSearchResult rsr = new ReportSearchResult(-1, 6, 7); + rsr.parseData(ds, request); + saveCSVPageFile(request, rsr); + rsr.truncateToPage(pageNo); + saveCSVPageFile(request, rsr); + + return rsr; + } // loadFolderReportResult + + +} // SearchHandler diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ChartSeqComparator.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ChartSeqComparator.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ChartSeqComparator.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ChartSeqComparator.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameColLookup.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameColLookup.java new file mode 100644 index 00000000..96326639 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameColLookup.java @@ -0,0 +1,37 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.base; + +import java.util.*; + +public class IdNameColLookup extends IdNameLookup { + private String colId = null; + + public IdNameColLookup(String colId, String dbTableName, String dbIdField, + String dbNameField, String dbSortByField) { + super(dbTableName, dbIdField, dbNameField, dbSortByField, false); + this.colId = colId; + } // IdNameColLookup + + public String getColId() { + return colId; + } + +} // IdNameColLookup diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameList.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameList.java new file mode 100644 index 00000000..3e6d6f42 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameList.java @@ -0,0 +1,183 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.base; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.system.*; + +public class IdNameList extends Vector { + protected int pageNo = -1; + + protected int pageSize = 50; + + private int nextElemIdx = 0; + + private String oldSql = null; + + public IdNameList() { + super(); + pageSize = Globals.getFormFieldsListSize(); + } // IdNameList + + public int getPageNo() { + return pageNo; + } // getPageNo + + public int getPageSize() { + return pageSize; + } // getPageSize + + public int getDataSize() { + return size(); + } // getDataSize + + public void resetNext() { + resetNext(0); + } // resetNext + + public void resetNext(int toPos) { + nextElemIdx = toPos; + } // resetNext + + public boolean hasNext() { + return (nextElemIdx < size()); + } // hasNext + + public IdNameValue getNext() { + return hasNext() ? getValue(nextElemIdx++) : null; + } // getNext + + public int getCount() { + return size(); + } // getCount + + public IdNameValue getValue(int idx) { + return (IdNameValue) get(idx); + } // getValue + + public void addValue(IdNameValue value) { + add(value); + } // addValue + + public void addValue(String id, String name, boolean defaultValue) { + addValue(new IdNameValue(id, name, defaultValue)); + } // addValue + + public void addValue(String id, String name, boolean defaultValue, boolean readOnly) { + addValue(new IdNameValue(id, name, defaultValue, readOnly)); + } // addValue + + public void addValue(String id, String name) { + addValue(new IdNameValue(id, name)); + } // addValue + + public void addValue(int idx, IdNameValue value) { + add(idx, value); + } // addValue + + public void addValue(int idx, String id, String name) { + addValue(idx, new IdNameValue(id, name)); + } // addValue + + public String getNameById(String id) { + for (int i = 0; i < size(); i++) { + IdNameValue value = getValue(i); + if (value.getId().equals(id)) + return value.getName(); + } // for + + return null; + } // getNameById + + public String getIdByName(String name) { + for (int i = 0; i < size(); i++) { + IdNameValue value = getValue(i); + if (value.getName().equals(name)) + return value.getId(); + } // for + + return null; + } // getIdByName + + public boolean canUseSearchString() { + return true; + } + + public String getBaseSQL() { + return null; + } + + public String getOldSql() { + return oldSql; + } + + public void setOldSql(String oldSql) { + this.oldSql = oldSql; + } + public String getBaseWholeSQL() { + return null; + } + + public String getBaseWholeReadonlySQL() { + return null; + } + + public String getBaseSQLForPDFExcel(boolean multiParam) { + return null; + } + + public void clearData() { + } + + public void loadData(String pageNo, String searchString, String dbInfo,String userId) throws RaptorException {} + public void loadUserData(String pageNo, String searchString, String dbInfo,String userId) throws RaptorException {} + public void loadUserData(int pageNo, String searchString, String dbInfo, String userId) throws RaptorException {} + public void loadUserData(String searchString, int pageNo, String dbInfo) throws RaptorException {} + + public void loadData(String pageNo) throws RaptorException {} + public void loadData(int pageNo) throws RaptorException {} + public void loadData(String pageNo, String searchString, String dbInfo) throws RaptorException {} + private void loadData(int pageNo, String searchString, String dbInfo) throws RaptorException {} + +/* + public void loadData(int pageNo, String dbInfo) throws RaptorException { + } + + public void loadUserData(int pageNo, String dbInfo, String userId) throws RaptorException { + } + + + + + public void loadData(String pageNo, String searchString) throws RaptorException { + } + +*/ + protected static String nvl(String s) { + return (s == null) ? "" : s; + } + + protected static String nvl(String s, String sDefault) { + return nvl(s).equals("") ? sDefault : s; + } + +} // IdNameList diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameLookup.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameLookup.java new file mode 100644 index 00000000..73f65c89 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameLookup.java @@ -0,0 +1,204 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.base; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.model.*; +import org.openecomp.portalsdk.analytics.model.runtime.*; +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; + +public class IdNameLookup extends IdNameSql { + private String dbTableName = null; + + private String dbIdField = null; + + private String dbNameField = null; + + private String dbSortByField = null; + + private String searchString = ""; + + public IdNameLookup(int pageNo, String dbTableName, String dbIdField, String dbNameField) { + this(dbTableName, dbIdField, dbNameField); + + this.pageNo = pageNo; + } // IdNameLookup + + public IdNameLookup(String dbTableName, String dbIdField, String dbNameField) { + this(dbTableName, dbIdField, dbNameField, null, "", false); + } // IdNameLookup + +/* public IdNameLookup(String dbTableName, String dbIdField, String dbNameField, + String dbSortByField) { + super(); + + setDbTableName(dbTableName); + setDbIdField(dbIdField); + setDbNameField(dbNameField); + setDbSortByField(dbSortByField); + updateParentSQL(); + } // IdNameLookup + + public IdNameLookup(String dbTableName, String dbIdField, String dbNameField, + String dbSortByField, String defaultSQL) { + super(); + + setDbTableName(dbTableName); + setDbIdField(dbIdField); + setDbNameField(dbNameField); + setDbSortByField(dbSortByField); + setDefaultSQL(defaultSQL); + updateParentSQL(); + } // IdNameLookup +*/ + public IdNameLookup(String dbTableName, String dbIdField, String dbNameField, + String dbSortByField, boolean textField) { + super(); + setDbTableName(dbTableName); + setDbIdField(dbIdField); + setDbNameField(dbNameField); + setDbSortByField(dbSortByField); + if(!textField) + updateParentSQL(); + } // IdNameLookup + + public IdNameLookup(String dbTableName, String dbIdField, String dbNameField, + String dbSortByField, String defaultSQL, boolean textField) { + super(); + + setDbTableName(dbTableName); + setDbIdField(dbIdField); + setDbNameField(dbNameField); + setDbSortByField(dbSortByField); + setDefaultSQL(defaultSQL); + if(!textField) + updateParentSQL(); + } // IdNameLookup + + public String getDbTableName() { + return dbTableName; + } + + public String getDbIdField() { + return dbIdField; + } + + public String getDbNameField() { + return dbNameField; + } + + public String getDbSortByField() { + return dbSortByField; + } + + public void setDbTableName(String dbTableName) { + this.dbTableName = dbTableName; + } + + public void setDbIdField(String dbIdField) { + this.dbIdField = dbIdField; + } + + public void setDbNameField(String dbNameField) { + this.dbNameField = dbNameField; + } + + + public void setDbSortByField(String dbSortByField) { + this.dbSortByField = dbSortByField; + } + + private void updateParentSQL() { + String sql_start = "SELECT DISTINCT " + dbIdField + " id, " + dbNameField + " name"; + String sql_end = " FROM " + dbTableName + " WHERE " + dbIdField + " IS NOT NULL"; + if (searchString.length() > 0) + sql_end += " AND UPPER(" + dbNameField + ") LIKE UPPER('" + searchString + "')"; + + String sql_middle = ""; + if (dbSortByField != null && (!dbSortByField.equals(dbNameField)) && (!dbSortByField.trim().startsWith("TO_DATE"))) + sql_middle = ", " + + ((dbSortByField.indexOf(' ') > 0) ? dbSortByField.substring(0, + dbSortByField.indexOf(' ')) : dbSortByField) + " sort"; + + setSqlNoOrderBy(sql_start + sql_middle + sql_end); +// System.out.println("SQL Start " + sql_start); +// System.out.println("SQL Middle " + sql_middle); +// System.out.println("SQL End " + sql_end); +// System.out.println("DbSortByField " + dbSortByField); + + setSql(sql_start + sql_middle + sql_end + " ORDER BY " + nvl(dbSortByField, "2")); + } // updateParentSQL + + public boolean canUseSearchString() { + return true; + } + + public String getBaseSQL() { + return "SELECT " + dbIdField + " FROM " + dbTableName; + } // getBaseSQL + + public String getBaseWholeSQL() { + return "SELECT " + dbIdField + " FROM " + dbTableName; + } // getBaseSQL + + /* + public void loadData(int pageNo) throws RaptorException { + loadData(pageNo, ""); + } // loadData + + public void loadData(String pageNo) throws RaptorException { + loadData(pageNo, ""); + } // loadData +*/ + + public void loadData(String pageNo, String searchString, String dbInfo) throws RaptorException { + int iPageNo = 0; + + if (pageNo != null) + try { + iPageNo = Integer.parseInt(pageNo); + } catch (NumberFormatException e) { + } + + loadData(iPageNo, searchString, dbInfo); + } // loadData + + private void loadData(int pageNo, String searchString, String dbInfo) throws RaptorException { + boolean dataAlreadyLoaded = (this.pageNo == pageNo) + && (this.searchString.equals(searchString)); + + if (dataAlreadyLoaded) + return; + + if (!this.searchString.equals(searchString)) { + dataSize = -1; + pageNo = 0; + } // if + + this.pageNo = pageNo; + this.searchString = searchString; + updateParentSQL(); + performLoadData(searchString,dbInfo); + } // loadData + +} // IdNameLookup diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameSql.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameSql.java new file mode 100644 index 00000000..602025fe --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameSql.java @@ -0,0 +1,400 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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. + * ================================================================================ + */ +/* =========================================================================================== + * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) + * Raptor : This tool is used to generate different kinds of reports with lot of utilities + * =========================================================================================== + * + * ------------------------------------------------------------------------------------------- + * IdNameSql.java - This class is used to generate form field items when sql is provided. + * ------------------------------------------------------------------------------------------- + * + * Created By : Stan Pishamanov + * Modified By: Sundar Ramalingam + * + * Changes + * ------- + * 08-Jun-2009 : Version 8.3 (RS); Rownum references is avoided for reports connnecting to Daytona + * Database. + * + */ +package org.openecomp.portalsdk.analytics.model.base; + +import java.util.*; + +import org.openecomp.portalsdk.analytics.controller.ActionHandler; +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.model.*; +import org.openecomp.portalsdk.analytics.model.runtime.*; +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +public class IdNameSql extends IdNameList { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(IdNameSql.class); + + + protected int dataSize = -1; + + protected int dataSizeUsedInPopup = -1; + + private String sql = null; + + private String oldSql = null; + + private String defaultSQL = null; + + private String sqlNoOrderBy = null; + + public IdNameSql(int pageNo, String sql, String defaultSQL) { + this(sql,defaultSQL); + this.pageNo = pageNo; + } // IdNameSql + + public IdNameSql(String sql) { + this(); + setSql(sql); + } // IdNameSql + + public IdNameSql(String sql, String defaultSQL) { + this(); + setDefaultSQL(defaultSQL); + setSql(sql); + } // IdNameSql + + protected IdNameSql() { + super(); + } // IdNameSql + + public boolean canUseSearchString() { + return true; + } + + public String getSql() { + return sql; + } + + public String getOldSql() { + return oldSql; + } + + public String getBaseSQL() { + return "SELECT id FROM (" + sql + ") xid"; + } + + public String getBaseWholeSQL() { + return "SELECT id, name FROM (" + sql + ") xid"; + } + + public String getBaseWholeReadonlySQL() { + return "SELECT id, name, ff_readonly FROM (" + sql + ") xid"; + } + + public String getBaseSQLForPDFExcel(boolean multiParam) { + if(!multiParam) + return "SELECT id, name FROM (" + sql + ") xid where id = '[VALUE]'"; + else + return "SELECT id, name FROM (" + sql + ") xid where id in [VALUE]"; + + } + + // public String getSqlNoOrderBy() { return sqlNoOrderBy; } + + protected void setSql(String sql) { + this.sql = sql; + } + + public void setOldSql(String oldSql) { + this.oldSql = oldSql; + } + + protected void setSqlNoOrderBy(String sql) { + this.sqlNoOrderBy = sql; + } + + public int getDataSize() { + return dataSize; + } // getDataSize + + public int getDataSizeUsedinPopup() { + return dataSizeUsedInPopup; + } // getDataSizeUsedinPopup + + public void setDataSizeUsedinPopup(int dataSizePop) { + this.dataSizeUsedInPopup = dataSizePop; + } // getDataSizeUsedinPopup + + public void clearData() { + removeAllElements(); + } // clearData + +/* public void loadData(String pageNo, String searchString, String dbInfo, String userId) throws RaptorException { + // setSql(searchString); + loadUserData(pageNo, searchString, dbInfo,userId); + } // loadData +*/ + + public void loadUserData(String pageNo, String searchString, String dbInfo,String userId) throws RaptorException { + int iPageNo = 0; + + if (pageNo != null) + try { + iPageNo = Integer.parseInt(pageNo); + } catch (NumberFormatException e) { + } + + loadUserData(iPageNo, searchString, dbInfo,userId); + } // loadData + + public void loadUserData(int pageNo, String searchString, String dbInfo, String userId) throws RaptorException { + if(userId!=null) { + String sql = Utils.replaceInString(getSql(), "[LOGGED_USERID]", userId); + //String defaultSQL = ""; + if(defaultSQL!=null && (defaultSQL.trim().toLowerCase().startsWith("select")) ) { + defaultSQL = Utils.replaceInString(getDefaultSQL(), "[LOGGED_USERID]", userId); + setDefaultSQL(defaultSQL); + } + setSql(sql); + + } + loadData(searchString,pageNo, dbInfo); + } + + public void loadData(String searchString, int pageNo, String dbInfo) throws RaptorException { + + //boolean dataAlreadyLoaded = (this.pageNo == pageNo); + + //if (dataAlreadyLoaded) + // return; + + this.pageNo = pageNo; + + performLoadData(searchString, dbInfo); + } // loadData + + protected void performLoadData(String searchString, String dbInfo) throws RaptorException { + long currentTime = System.currentTimeMillis(); + int startRow = 0; + int endRow = dataSize; + String readOnlyInSql = "ff_readonly"; + String dbType = Globals.getDBType(); + if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { + try { + org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); + dbType = remDbInfo.getDBType(dbInfo); + } catch (Exception ex) { + throw new RaptorException(ex); + } + } + if (pageNo >= 0) { + startRow = pageNo * pageSize; + endRow = startRow + pageSize; + } // if + DataSet ds = null; + DataSet dsDefault = null; + StringBuffer query = new StringBuffer(""); + StringBuffer queryPop = new StringBuffer(""); + String sql = getSql(); + boolean avail_ReadOnly = (sql.toLowerCase().indexOf(readOnlyInSql)!=-1); + + if (dbType.equals("DAYTONA") && getSql().trim().toUpperCase().startsWith("SELECT")) { + query.append(getSql()); + } else { + if(avail_ReadOnly) // need to add readonlyinsql + if(!(Globals.isMySQL() && dbType.equals(AppConstants.MYSQL))) + query.append("SELECT rownum, id, name, " + readOnlyInSql +" FROM ("+ Globals.getReportSqlForFormfield() +", " + readOnlyInSql + " FROM (" + sql + + ") x "+ Globals.getReportSqlForFormfieldSuffix()); + else + query.append("SELECT id, name, " + readOnlyInSql +" FROM ("+ Globals.getReportSqlForFormfield() +", " + readOnlyInSql + " FROM (" + sql + + ") x "+ Globals.getReportSqlForFormfieldSuffix()); + else + query.append(Globals.getReportSqlForFormfieldPrefix()+ Globals.getReportSqlForFormfield() +" FROM (" + sql + + ") x " + Globals.getReportSqlForFormfieldSuffix()); + if(pageNo!= -2 && (dbType.equals(AppConstants.ORACLE)) ) { + query.append(" WHERE rownum <= " + ((dataSize < 0) ? (endRow + 1) : endRow)); + } else if(pageNo!=2 && (dbType.equals(AppConstants.POSTGRESQL))) { + query.append(" LIMIT " + ((dataSize < 0) ? (endRow + 1) : endRow)); + + } else if(pageNo!=2 && (dbType.equals(AppConstants.MYSQL))) { + query.append(" LIMIT " + startRow); //((dataSize < 0) ? (endRow + 1) : endRow) + + } + if(searchString!=null && searchString.length()>0 && !searchString.equals("%")) { + if(pageNo == -2) query.append(" WHERE "); + else query.append(" and "); + query.append("name like '"+ searchString +"'"); + } + if(dbType.equals(AppConstants.POSTGRESQL)) { + query.append(") xx OFFSET " + startRow); + } else if(dbType.equals(AppConstants.MYSQL)) { + query.append(" ," + ((dataSize < 0) ? (endRow + 1) : endRow) +") xx"); + } else if(dbType.equals(AppConstants.ORACLE)) + query.append(") xx WHERE rownum>" + startRow); + } + String defaultQuery =""; + boolean readOnly = true; + ds = ConnectionUtils.getDataSet(query.toString(), dbInfo); + + // if ( (dbInfo!=null) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { + // Globals.getRDbUtils().setDBPrefix(dbInfo); + // ds = RemDbUtils.executeQuery(query); + // } + // else + // ds = DbUtils.executeQuery(query); + clearData(); + if (dbType.equals("DAYTONA") && (getDefaultSQL()!=null && getDefaultSQL().trim().toUpperCase().startsWith("SELECT"))) { + defaultQuery = getDefaultSQL(); + } else if (getDefaultSQL()!=null && getDefaultSQL().length()>10 && getDefaultSQL().substring(0,10).toLowerCase().startsWith("select")) { + defaultQuery = Globals.getReportSqlForFormfieldPrefix()+ Globals.getReportSqlForFormfield() +" FROM (" + getDefaultSQL() + + ") x " + + ") xx "; + logger.debug(EELFLoggerDelegate.debugLogger, ("Default Query " +defaultQuery)); + } + HashMap defaultMap = new HashMap(); + if(!isNull(defaultQuery)) { + dsDefault = ConnectionUtils.getDataSet(defaultQuery, dbInfo); + if(dsDefault!=null && dsDefault.getRowCount()>0) { + for (int i = 0; i < dsDefault.getRowCount(); i++) { + //addValue(dsDefault.getString(i, 0), dsDefault.getString(i, 1), true); + defaultMap.put(dsDefault.getString(i, "id"), dsDefault.getString(i, "name")); + } + } + } + + for (int i = 0; i < ((pageNo!=-2)?Math.min(ds.getRowCount(), pageSize):ds.getRowCount()); i++) { + //if(getCount()==0) + // addValue(ds.getString(i, 0), ds.getString(i, 1)); + if(i==0 && avail_ReadOnly) + readOnly = ds.getString(i, "ff_readonly").toUpperCase().startsWith("Y")||ds.getString(i, "ff_readonly").toUpperCase().startsWith("T"); + if(getCount()>=0) {//&& !((IdNameValue)getValue(0)).getId().equals(ds.getString(i, 0))) + if(defaultMap.get(ds.getString(i, "id")) == null) + if(avail_ReadOnly) + addValue(ds.getString(i, "id"), ds.getString(i, "name"), false, readOnly); + else + addValue(ds.getString(i, "id"), ds.getString(i, "name"), false); + else + if(avail_ReadOnly) + addValue(ds.getString(i, "id"), ds.getString(i, "name"), true, readOnly); + else + addValue(ds.getString(i, "id"), ds.getString(i, "name"), true); + } + } + + if (!(dbType.equals("DAYTONA"))) { + if (ds.getRowCount() <= pageSize) { + if(dsDefault!=null && dsDefault.getRowCount()>0) + dataSize = ds.getRowCount()+1; + else + dataSize = ds.getRowCount(); + + //System.out.println("IDNAME SQL COUNT");*/ + if(searchString!=null && searchString.length()>0 && !searchString.equals("%")) { + queryPop = new StringBuffer(""); + queryPop.append("SELECT count(*) num_rows FROM ("+ Globals.getReportSqlForFormfield() +", name FROM (" + sql + + ") x "); + if(searchString!=null && searchString.length()>0 && !searchString.equals("%")) + queryPop.append(" where name like '"+ searchString +"'"); + queryPop.append(") xx "); + + ds = ConnectionUtils.getDataSet(queryPop.toString(), dbInfo); + try { + dataSizeUsedInPopup = Integer.parseInt(ds.getString(0, 0)); + } catch (NumberFormatException e) { + } + } else if(dataSizeUsedInPopup == -3) { + queryPop = new StringBuffer(""); + //System.out.println("IDNAME SQL COUNT"); + //queryPop.append("SELECT count(*) num_rows FROM ("+query.toString()+") x"); + queryPop.append("SELECT count(*) num_rows FROM ("+ Globals.getReportSqlForFormfield() +", name FROM (" + sql + + ") x "); + queryPop.append(") xx "); + + ds = ConnectionUtils.getDataSet(queryPop.toString(), dbInfo); + // if ( (dbInfo!=null) && + // (!dbInfo.equals(AppConstants.DB_LOCAL))) { + // Globals.getRDbUtils().setDBPrefix(dbInfo); + // ds = RemDbUtils.executeQuery(query); + // } + // else + // ds = DbUtils.executeQuery(query); + // + try { + dataSizeUsedInPopup = Integer.parseInt(ds.getString(0, 0)); + } catch (NumberFormatException e) { + } + + } + + } else { + //pageNo = 0; + if(pageNo!= -2) { + queryPop = new StringBuffer(""); + //System.out.println("IDNAME SQL COUNT"); + //queryPop.append("SELECT count(*) num_rows FROM ("+query.toString()+") x"); + queryPop.append("SELECT count(*) num_rows FROM ("+ Globals.getReportSqlForFormfield() +" FROM (" + sql + + ") x "); + queryPop.append(") xx "); + + ds = ConnectionUtils.getDataSet(queryPop.toString(), dbInfo); + // if ( (dbInfo!=null) && + // (!dbInfo.equals(AppConstants.DB_LOCAL))) { + // Globals.getRDbUtils().setDBPrefix(dbInfo); + // ds = RemDbUtils.executeQuery(query); + // } + // else + // ds = DbUtils.executeQuery(query); + // + try { + dataSize = Integer.parseInt(ds.getString(0, 0)); + dataSizeUsedInPopup = Integer.parseInt(ds.getString(0, 0)); + } catch (NumberFormatException e) { + } + } + } // else + } // dataSize < 0 + long totalTime = System.currentTimeMillis() - currentTime; + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] ------->Time Taken to the above formfield Query (+ count Query if any) --- " + totalTime)); + } // performLoadData + + + public String getDefaultSQL() { + + return defaultSQL; + } + + + public void setDefaultSQL(String defaultSQL) { + + this.defaultSQL = defaultSQL; + } + + public void setSQL(String sql_) + { + this.sql = sql_; + } + + public static boolean isNull(String a) { + if ((a == null) || (a.length() == 0) || a.equalsIgnoreCase("null")) + return true; + else + return false; + } +} // IdNameSql diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameValue.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameValue.java new file mode 100644 index 00000000..763a44c0 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameValue.java @@ -0,0 +1,100 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.base; + +public class IdNameValue { + private String id = null; + + private String name = null; + + private boolean defaultValue = false; + + private boolean readOnly = false; + + public IdNameValue() { + super(); + } + + public IdNameValue(String id, String name) { + this(); + + setId(id); + setName(name); + setDefaultValue(false); + + } // IdNameValue + + public IdNameValue(String id, String name, boolean defaultValue) { + this(); + + setId(id); + setName(name); + setDefaultValue(defaultValue); + } // IdNameValue + + public IdNameValue(String id, String name, boolean defaultValue, boolean readOnly) { + this(); + + setId(id); + setName(name); + setDefaultValue(defaultValue); + setReadOnly(readOnly); + } // IdNameValue + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(boolean defaultValue) { + this.defaultValue = defaultValue; + } + + /** + * @return the visibility + */ + public boolean isReadOnly() { + return readOnly; + } + + /** + * @param readOnly the value to set + */ + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + + +} // IdNameValue diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/NameComparator.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/NameComparator.java new file mode 100644 index 00000000..4ccff331 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/NameComparator.java @@ -0,0 +1,34 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.base; + +import java.util.Comparator; + +import org.openecomp.portalsdk.analytics.model.base.IdNameValue; + +public class NameComparator implements Comparator { + + public int compare(Object o1, Object o2) { + return ((IdNameValue) o1).getName() + .compareToIgnoreCase((((IdNameValue) o2).getName())); + } // compare + +} // NameComparator + diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderBySeqComparator.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderBySeqComparator.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderBySeqComparator.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderBySeqComparator.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderSeqComparator.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderSeqComparator.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderSeqComparator.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/OrderSeqComparator.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportSecurity.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportSecurity.java new file mode 100644 index 00000000..40a3f266 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportSecurity.java @@ -0,0 +1,404 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.base; + +import java.io.*; +import java.sql.*; +import java.util.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.openecomp.portalsdk.analytics.controller.ActionHandler; +import org.openecomp.portalsdk.analytics.error.*; +import org.openecomp.portalsdk.analytics.model.base.*; +import org.openecomp.portalsdk.analytics.model.definition.*; +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +public class ReportSecurity extends org.openecomp.portalsdk.analytics.RaptorObject { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ReportSecurity.class); + + + private String reportID = null; + + private String ownerID = null; + + private String createID = null; + + private String createDate = null; + + private String updateID = null; + + private String updateDate = null; + + private boolean isPublic = false; + + private Hashtable reportRoles = new Hashtable(); + + private Hashtable reportUsers = new Hashtable(); + + public ReportSecurity(String reportID) { + this(reportID, null, null, null, null, null, false); + } // ReportSecurity + + public ReportSecurity(String reportID, String ownerID, String createID, String createDate, + String updateID, String updateDate, boolean isPublic) { + super(); + + if (ownerID == null) + // Need to load the report record from the database + if (!reportID.equals("-1")) + try { + /*DataSet ds = DbUtils + .executeQuery("SELECT NVL(cr.owner_id, cr.create_id) owner_id, cr.create_id, TO_CHAR(cr.create_date, '" + + Globals.getOracleTimeFormat() + + "') create_date, maint_id, TO_CHAR(cr.maint_date, '" + + Globals.getOracleTimeFormat() + + "') update_date, cr.public_yn FROM cr_report cr WHERE cr.rep_id=" + + reportID);*/ + String sql = Globals.getReportSecurity(); + sql = sql.replace("[rw.getReportID()]", reportID); + DataSet ds = DbUtils.executeQuery(sql); + ownerID = ds.getString(0, 0); + createID = ds.getString(0, 1); + createDate = ds.getString(0, 2); + updateID = ds.getString(0, 3); + updateDate = ds.getString(0, 4); + isPublic = nvl(ds.getString(0, 5)).equals("Y"); + } catch (Exception e) { + String eMsg = "ReportSecurity.ReportSecurity: Unable to load report record details. Exception: " + + e.getMessage(); + //Log.write(eMsg); + logger.debug(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] "+eMsg)); + throw new RuntimeException(eMsg); + } + + this.reportID = reportID; + this.ownerID = ownerID; + this.createID = createID; + this.createDate = createDate; + this.updateID = updateID; + this.updateDate = updateDate; + this.isPublic = isPublic; + + /* + * reportUsers.put(ownerID, "N"); // Owner has full access + * reportRoles.put(AppUtils.getSuperRoleID(), "N"); // Super role has + * full access for(Iterator iter=AppUtils.getAdminRoleIDs().iterator(); + * iter.hasNext(); ) reportRoles.put((String) iter.next(), "Y"); // + * Admin role(s) have read-only access + */ + try { + String reportUserAccessSql= Globals.getReportUserAccess(); + reportUserAccessSql = reportUserAccessSql.replace("[reportID]", reportID); + + DataSet ds = DbUtils + .executeQuery(reportUserAccessSql); + for (int i = 0; i < ds.getRowCount(); i++) { + String roleID = nvl(ds.getString(i, 0)); + if (roleID.length() > 0) + reportRoles.put(roleID, ds.getString(i, 2)); + + String userID = nvl(ds.getString(i, 1)); + if (userID.length() > 0) + reportUsers.put(userID, ds.getString(i, 2)); + } // for + } catch (Exception e) { + String eMsg = "ReportSecurity.ReportSecurity: Unable to load access priviledges - error " + + e.getMessage(); + logger.error(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] " + eMsg)); + throw new RuntimeException(eMsg); + } + } // ReportSecurity + + public String getOwnerID() { + return ownerID; + } + + public String getCreateID() { + return createID; + } + + public String getCreateDate() { + return createDate; + } + + public String getUpdateID() { + return updateID; + } + + public String getUpdateDate() { + return updateDate; + } + + public void setOwnerID(String ownerID) { + this.ownerID = ownerID; + } + + public void setPublic(boolean isPublic) { + this.isPublic = isPublic; + } + + public void reportCreate(String reportID, String userID, boolean isPublic) { + this.reportID = reportID; + this.ownerID = userID; + this.createID = userID; + this.createDate = Utils.getCurrentDateTime(); + this.updateID = userID; + this.updateDate = this.createDate; + this.isPublic = isPublic; + } // reportCreate + + public void reportUpdate(HttpServletRequest request) throws RaptorException { + checkUserWriteAccess(request); + String userID = AppUtils.getUserID(request); + this.updateID = userID; + this.updateDate = Utils.getCurrentDateTime(); + } // reportUpdate + + /** ************************************************************* */ + + public Vector getReportUsers(HttpServletRequest request) throws RaptorException { + HttpSession session = request.getSession(); + String query = Globals.getCustomizedScheduleQueryForUsers(); + String[] sessionParameters = Globals.getSessionParams().split(","); + session.setAttribute("login_id", AppUtils.getUserBackdoorLoginId(request)); + String param = ""; + for (int i = 0; i < sessionParameters.length; i++) { + param = (String)session.getAttribute(sessionParameters[0]); + query = Utils.replaceInString(query, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); + } + boolean isAdmin = AppUtils.isAdminUser(request); + Vector allUsers = AppUtils.getAllUsers(query,param, isAdmin); + Vector rUsers = new Vector(allUsers.size()); + + for (Iterator iter = allUsers.iterator(); iter.hasNext();) { + IdNameValue user = (IdNameValue) iter.next(); + String readOnlyAccess = (String) reportUsers.get(user.getId()); + if (readOnlyAccess != null) + rUsers.add(new SecurityEntry(user.getId(), user.getName(), readOnlyAccess + .equals("Y"))); + } // for + + return rUsers; + } // getReportUsers + + public Vector getReportRoles(HttpServletRequest request) throws RaptorException { + HttpSession session = request.getSession(); + String query = Globals.getCustomizedScheduleQueryForRoles(); + String[] sessionParameters = Globals.getSessionParams().split(","); + String param = ""; + for (int i = 0; i < sessionParameters.length; i++) { + param = (String)session.getAttribute(sessionParameters[0]); + query = Utils.replaceInString(query, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); + + } + boolean isAdmin = AppUtils.isAdminUser(request); + Vector allRoles = AppUtils.getAllRoles(query, param, isAdmin); + Vector rRoles = new Vector(allRoles.size()); + + for (Iterator iter = allRoles.iterator(); iter.hasNext();) { + IdNameValue role = (IdNameValue) iter.next(); + String readOnlyAccess = (String) reportRoles.get(role.getId()); + if (readOnlyAccess != null) + rRoles.add(new SecurityEntry(role.getId(), role.getName(), readOnlyAccess + .equals("Y"))); + } // for + + return rRoles; + } // getReportRoles + + /** ************************************************************* */ + + private void validateReadOnlyAccess(String readOnlyAccess) throws Exception { + if (!(readOnlyAccess != null && (readOnlyAccess.equals("Y") || readOnlyAccess + .equals("N")))) + throw new RuntimeException( + "[ReportSecurity.validateReadOnlyAccess] Invalid parameter value"); + } // validateReadOnlyAccess + + public void addUserAccess(String userID, String readOnlyAccess) throws Exception { + validateReadOnlyAccess(readOnlyAccess); + reportUsers.put(userID, readOnlyAccess); + String addUserAccessSql= Globals.getAddUserAccess(); + addUserAccessSql = addUserAccessSql.replace("[reportID]", reportID); + addUserAccessSql = addUserAccessSql.replace("[userID]", userID); + addUserAccessSql = addUserAccessSql.replace("[readOnlyAccess]", readOnlyAccess); + DbUtils + .executeUpdate(addUserAccessSql); + } // addUserAccess + + public void updateUserAccess(String userID, String readOnlyAccess) throws Exception { + validateReadOnlyAccess(readOnlyAccess); + reportUsers.remove(userID); + reportUsers.put(userID, readOnlyAccess); + String updateUserAccessSql= Globals.getUpdateUserAccess(); + updateUserAccessSql = updateUserAccessSql.replace("[reportID]", reportID); + updateUserAccessSql = updateUserAccessSql.replace("[userID]", userID); + updateUserAccessSql = updateUserAccessSql.replace("[readOnlyAccess]", readOnlyAccess); + DbUtils.executeUpdate(updateUserAccessSql); + } // updateUserAccess + + public void removeUserAccess(String userID) throws Exception { + reportUsers.remove(userID); + + String removeUserAccessSql= Globals.getRemoveUserAccess(); + removeUserAccessSql = removeUserAccessSql.replace("[reportID]", reportID); + removeUserAccessSql = removeUserAccessSql.replace("[userID]", userID); + DbUtils.executeUpdate(removeUserAccessSql); + } // removeUserAccess + + public void addRoleAccess(String roleID, String readOnlyAccess) throws Exception { + validateReadOnlyAccess(readOnlyAccess); + reportRoles.put(roleID, readOnlyAccess); + String addRoleAccessSql= Globals.getAddRoleAccess(); + addRoleAccessSql = addRoleAccessSql.replace("[reportID]", reportID); + addRoleAccessSql = addRoleAccessSql.replace("[roleID]", roleID); + addRoleAccessSql = addRoleAccessSql.replace("[readOnlyAccess]", readOnlyAccess); + DbUtils + .executeUpdate(addRoleAccessSql); + } // addRoleAccess + + public void updateRoleAccess(String roleID, String readOnlyAccess) throws Exception { + validateReadOnlyAccess(readOnlyAccess); + reportRoles.remove(roleID); + reportRoles.put(roleID, readOnlyAccess); + String updateRoleAccessSql= Globals.getUpdateRoleAccess(); + updateRoleAccessSql = updateRoleAccessSql.replace("[reportID]", reportID); + updateRoleAccessSql = updateRoleAccessSql.replace("[roleID]", roleID); + updateRoleAccessSql = updateRoleAccessSql.replace("[readOnlyAccess]", readOnlyAccess); + DbUtils.executeUpdate(updateRoleAccessSql); + } // updateRoleAccess + + public void removeRoleAccess(String roleID) throws Exception { + reportRoles.remove(roleID); + String removeRoleAccessSql= Globals.getRemoveRoleAccess(); + removeRoleAccessSql = removeRoleAccessSql.replace("[reportID]", reportID); + removeRoleAccessSql = removeRoleAccessSql.replace("[roleID]", roleID); + DbUtils.executeUpdate(removeRoleAccessSql); + } // removeRoleAccess + + /** ************************************************************* */ + + public void checkUserReadAccess(HttpServletRequest request, String userID) throws RaptorException { + if(userID == null) + userID = AppUtils.getUserID(request); + if(userID != null) { + //userID = AppUtils.getUserID(request); + if (nvl(reportID).equals("-1")) + return; + + if (true) //todo: replace with proper check isPublic + return; + + if (userID.equals(ownerID)) + return; + + if (reportUsers.get(userID) != null) + return; + } + Vector userRoles = null; + String userName = null; + if(userID == null) { + userRoles = AppUtils.getUserRoles(request); + userName = AppUtils.getUserName(request); + userID = AppUtils.getUserID(request); + } else { + userRoles = AppUtils.getUserRoles(userID); + userName = AppUtils.getUserName(userID); + } + if (nvl(reportID).equals("-1")) + return; + + if (isPublic) + return; + + if (userID.equals(ownerID)) + return; + + if (reportUsers.get(userID) != null) + return; + + for (Iterator iter = userRoles.iterator(); iter.hasNext();) { + String userRole = (String) iter.next(); + if (nvl(userRole).equals(AppUtils.getSuperRoleID())) + return; + } + for (Iterator iter = userRoles.iterator(); iter.hasNext();) { + String userRole = (String) iter.next(); + + if (nvl(userRole).equals(AppUtils.getSuperRoleID())) + return; + + if (reportRoles.get(userRole) != null) + return; + + for (Iterator iterA = AppUtils.getAdminRoleIDs().iterator(); iterA.hasNext();) + if (nvl(userRole).equals((String) iterA.next())) + return; + } // for + + throw new UserAccessException(reportID, "[" + userID + "] " + + userName, AppConstants.UA_READ); + } // checkUserReadAccess + + public void checkUserWriteAccess(HttpServletRequest request) throws RaptorException { + String userID = AppUtils.getUserID(request); + if (nvl(reportID).equals("-1")) + return; + + if (userID.equals(ownerID)) + return; + + if (nvl((String) reportUsers.get(userID)).equals("N")) + return; + + for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) { + String userRole = (String) iter.next(); + + if (nvl(userRole).equals(AppUtils.getSuperRoleID())) + return; + + if (nvl((String) reportRoles.get(userRole)).equals("N")) + return; + + for (Iterator iterA = AppUtils.getAdminRoleIDs().iterator(); iterA.hasNext();) + if (nvl(userRole).equals((String) iterA.next())) + return; + } // for + + throw new UserAccessException(reportID, "[" + userID + "] " + + AppUtils.getUserName(request), AppConstants.UA_WRITE); + } // checkUserWriteAccess + + public void checkUserDeleteAccess(HttpServletRequest request) throws RaptorException { + String userID = AppUtils.getUserID(request); + if (Globals.getDeleteOnlyByOwner()) { + if (!userID.equals(ownerID)) + throw new UserAccessException(reportID, "[" + userID + "] " + + AppUtils.getUserName(request), AppConstants.UA_DELETE); + } else + checkUserWriteAccess(request); + } // checkUserDeleteAccess + +} // ReportSecurity diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportWrapper.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportWrapper.java new file mode 100644 index 00000000..1638a396 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportWrapper.java @@ -0,0 +1,5719 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.base; + +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeSet; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.transform.stream.StreamResult; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.error.RaptorRuntimeException; +import org.openecomp.portalsdk.analytics.error.UserDefinedException; +import org.openecomp.portalsdk.analytics.model.DataCache; +import org.openecomp.portalsdk.analytics.model.ReportLoader; +import org.openecomp.portalsdk.analytics.model.definition.TableSource; +import org.openecomp.portalsdk.analytics.model.runtime.FormField; +import org.openecomp.portalsdk.analytics.model.runtime.ReportParamValues; +import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.system.ConnectionUtils; +import org.openecomp.portalsdk.analytics.system.DbUtils; +import org.openecomp.portalsdk.analytics.system.Globals; +import org.openecomp.portalsdk.analytics.util.AppConstants; +import org.openecomp.portalsdk.analytics.util.DataSet; +import org.openecomp.portalsdk.analytics.util.SQLCorrector; +import org.openecomp.portalsdk.analytics.util.Utils; +import org.openecomp.portalsdk.analytics.xmlobj.ChartAdditionalOptions; +import org.openecomp.portalsdk.analytics.xmlobj.ChartDrillFormfield; +import org.openecomp.portalsdk.analytics.xmlobj.ChartDrillOptions; +import org.openecomp.portalsdk.analytics.xmlobj.ColFilterList; +import org.openecomp.portalsdk.analytics.xmlobj.ColFilterType; +import org.openecomp.portalsdk.analytics.xmlobj.CustomReportType; +import org.openecomp.portalsdk.analytics.xmlobj.DashboardEditorList; +import org.openecomp.portalsdk.analytics.xmlobj.DashboardReports; +import org.openecomp.portalsdk.analytics.xmlobj.DashboardReportsNew; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnList; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; +import org.openecomp.portalsdk.analytics.xmlobj.DataSourceList; +import org.openecomp.portalsdk.analytics.xmlobj.DataSourceType; +import org.openecomp.portalsdk.analytics.xmlobj.DataminingOptions; +import org.openecomp.portalsdk.analytics.xmlobj.FormFieldList; +import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; +import org.openecomp.portalsdk.analytics.xmlobj.FormatList; +import org.openecomp.portalsdk.analytics.xmlobj.FormatType; +import org.openecomp.portalsdk.analytics.xmlobj.JavascriptItemType; +import org.openecomp.portalsdk.analytics.xmlobj.JavascriptList; +import org.openecomp.portalsdk.analytics.xmlobj.Marker; +import org.openecomp.portalsdk.analytics.xmlobj.ObjectFactory; +import org.openecomp.portalsdk.analytics.xmlobj.PDFAdditionalOptions; +import org.openecomp.portalsdk.analytics.xmlobj.PredefinedValueList; +import org.openecomp.portalsdk.analytics.xmlobj.ReportMap; +import org.openecomp.portalsdk.analytics.xmlobj.Reports; +import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreList; +import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreType; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +/**
+ * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting)
+ *
+ * + * --------------------------------------------------------------------------------------------------
+ * ReportWrapper.java - This is the base class for the RAPTOR. This involves in creating,
+ * modifying, running RAPTOR reports.
+ * --------------------------------------------------------------------------------------------------
+ * + * + * Change Log

+ * + * 31-Aug-2009 : Version 8.5.1 (Sundar);
  • All the elements in the meta xml is copied to the target reports.
+ * 18-Aug-2009 : Version 8.5.1 (Sundar);
  • request Object is passed to prevent caching user/roles - Datamining/Hosting.
+ * 27-Jul-2009 : Version 8.4 (Sundar);
  • verifySQLBasedReportAccess method checks for Admin user instead of super user.
+ * 09-Jul-2009 : Version 8.4 (Sundar);
  • Bug due to parsing and removing formfields from "and" is bulletproofed to the right "and" to which the formfield is associated.
+ * 08-Jul-2009 : Version 8.4 (Sundar);
  • Bug due to parsing and removing formfields when there is no parameter for Daytona specific database is resolved.
+ * 29-Jun-2009 : Version 8.4 (Sundar);
  • isLastSeriesALineChart() and setLastSeriesALineChart(String value) method have been added for the Bar Chart enhancements.
+ * 23-Jun-2009 : Version 8.4 (Sundar);
  • check for cr.getChartAdditionalOptions() for null value is added.
+ * 22-Jun-2009 : Version 8.4 (Sundar);
  • Wrapper functions to call JAXB were added. These Wrapper + * functions are related to the Pareto chart, Time Difference Chart, Multiple Pie Chart and generic Chart Options.
+ * + */ + +public class ReportWrapper extends org.openecomp.portalsdk.analytics.RaptorObject { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ReportWrapper.class); + + + protected CustomReportType cr = null; + + protected Vector allColumns = null; + + protected Vector allVisibleColumns = null; + + protected Vector allFilters = null; + + protected String generatedSQL = null; + + protected String generatedChartSQL = null; + + protected String wholeSQL = null; // For display purposes only + + + protected String reportID = null; + + protected String menuID = ""; + + protected boolean menuApproved = false; + + protected String reportDefType = ""; + + protected ReportSecurity reportSecurity = null; + + protected String reportSQLWithRowNum = null; + + protected String reportSQLOnlyFirstPart = null; + + + private ReportWrapper(CustomReportType cr, String reportID, ReportSecurity reportSecurity) { + super(); + + if (reportID == null) + reportID = "-1"; + + this.cr = cr; + this.reportID = reportID; + + this.reportSecurity = reportSecurity; + } // ReportWrapper + + public ReportWrapper(ReportWrapper rw) { + this(rw.getCustomReport(), // .cloneCustomReport() + rw.getReportID(), rw.reportSecurity); + + this.menuID = rw.getMenuID(); + this.menuApproved = rw.isMenuApproved(); + + this.reportDefType = rw.getReportDefType(); + } // ReportWrapper + + public ReportWrapper(CustomReportType cr, String reportID, String ownerID, String createID, + String createDate, String updateID, String updateDate, String menuID, + boolean menuApproved) throws RaptorException { + this(cr, reportID, null); + + if (ownerID == null) + // Need to load the report record from the database + if (!reportID.equals("-1")) + try { + /*DataSet ds = DbUtils + .executeQuery("SELECT NVL(cr.owner_id, cr.create_id) owner_id, cr.create_id, TO_CHAR(cr.create_date, '" + + Globals.getOracleTimeFormat() + + "') create_date, maint_id, TO_CHAR(cr.maint_date, '" + + Globals.getOracleTimeFormat() + + "') update_date, cr.menu_id, cr.menu_approved_yn FROM cr_report cr WHERE cr.rep_id=" + + reportID);*/ + + String r_sql = Globals.getReportWrapperFormat(); + r_sql = r_sql.replace("[Globals.getTimeFormat()]", Globals.getTimeFormat()); + r_sql = r_sql.replace("[reportID]", reportID); + + DataSet ds = DbUtils + .executeQuery(r_sql); + + ownerID = ds.getString(0, 0); + createID = ds.getString(0, 1); + createDate = ds.getString(0, 2); + updateID = ds.getString(0, 3); + updateDate = ds.getString(0, 4); + menuID = nvl(ds.getString(0, 5)); + menuApproved = nvl(ds.getString(0, 6)).equals("Y"); + } catch (Exception e) { + String eMsg = "ReportWrapper.ReportWrapper: Unable to load report record details. Exception: " + + e.getMessage(); + //Log.write(eMsg); + logger.error(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] "+ eMsg)); + throw new RaptorRuntimeException(eMsg); + } + + this.menuID = nvl(menuID); + this.menuApproved = menuApproved; + + if (!reportID.equals("-1")) + updateReportDefType(); + + reportSecurity = new ReportSecurity(reportID, ownerID, createID, createDate, updateID, + updateDate, cr.isPublic()); + } // ReportWrapper + + public CustomReportType getCustomReport() { + return cr; + } + + public String getReportID() { + return reportID; + } + + public String getMenuID() { + return menuID; + } + + public boolean checkMenuIDSelected(String chkMenuID) { + return ("|" + menuID + "|").indexOf("|" + chkMenuID + "|") >= 0; + } + + public boolean isMenuApproved() { + return menuApproved; + } + + public String getReportDefType() { + return reportDefType; + } + + public void setMenuID(String menuID) { + this.menuID = menuID; + } + + public void setMenuApproved(boolean menuApproved) { + this.menuApproved = menuApproved; + } + + public void setReportDefType(String reportDefType) { + this.reportDefType = reportDefType; + } + + public void updateReportDefType() { + this.reportDefType = (nvl(cr.getReportSQL()).length() > 0) ? ((cr.getDataminingOptions()!=null && nvl(cr.getDataminingOptions().getClassifier()).length()>0) ? + AppConstants.RD_SQL_BASED_DATAMIN:AppConstants.RD_SQL_BASED) + : AppConstants.RD_VISUAL; + } + + public String getJavascriptElement() { + return cr.getJavascriptElement(); + } + + public int getPageSize() { + return cr.getPageSize()==null?50:cr.getPageSize(); + } + + public int getMaxRowsInExcelDownload() { + return cr.getMaxRowsInExcelDownload()==null?500:cr.getMaxRowsInExcelDownload(); + } + + public boolean isDisplayFolderTree() { + return cr.isDisplayFolderTree()!=null?cr.isDisplayFolderTree().booleanValue():false; + } + + public boolean isHideFormFieldAfterRun() { + return cr.isHideFormFieldAfterRun()!=null?cr.isHideFormFieldAfterRun().booleanValue():false; + } + + public void setHideFormFieldAfterRun(boolean hideFormFieldAfterRun) { + cr.setHideFormFieldAfterRun(hideFormFieldAfterRun); + } + + public boolean isReportInNewWindow() { + return cr.isReportInNewWindow()!=null?cr.isReportInNewWindow().booleanValue():false; + } + + public String getReportType() { + return cr.getReportType(); + } + + public String getReportName() { + return cr.getReportName(); + } + + public String getDBInfo() { + return cr.getDbInfo(); + } + + public String getDBType() { + return cr.getDbType(); + } + + public boolean isDrillDownURLInPopupPresent() { + return cr.isDrillURLInPoPUpPresent()!=null?cr.isDrillURLInPoPUpPresent().booleanValue():false; + } + + public void setDrillDownURLInPopupPresent(boolean value) { + cr.setDrillURLInPoPUpPresent(value); + } + + public String getReportDescr() { + return cr.getReportDescr(); + } + + public String getChartType() { + return cr.getChartType(); + } + + public boolean displayChartTitle() { + return cr.isShowChartTitle(); + } + + public void setShowChartTitle(boolean showTitle) { + cr.setShowChartTitle(showTitle); + } + + + public String getChartTypeFixed() { + return cr.getChartTypeFixed(); + } + + public boolean isChartTypeFixed() { + return nvl(cr.getChartTypeFixed()).length() > 0 ? cr.getChartTypeFixed().equals("Y") + : (!Globals.getAllowRuntimeChartSel()); + } + + public String getChartLeftAxisLabel() { + return cr.getChartLeftAxisLabel(); + } + + public String getChartRightAxisLabel() { + return cr.getChartRightAxisLabel(); + } + + public String getChartWidth() { + return cr.getChartWidth(); + } + + public int getChartWidthAsInt() { + return getIntValue(cr.getChartWidth(), Globals.getDefaultChartWidth()); + } + + public String getChartHeight() { + return cr.getChartHeight()==null?"500":cr.getChartHeight(); + } + + /*public boolean isChartMultiSeries() { + //String s = cr.getChartMultiSeries(); + return + return (nvl(s).length()>0)? (s.equals("Y")||s.equals("y")||s.equalsIgnoreCase("true")?true:false):true; + }*/ + + public boolean displayPieOrderinRunPage() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieOrder():""; + if(nvl(s).indexOf("|")!= -1) { + s = s.substring(s.indexOf("|")+1); + return getFlagInBoolean(s); + } else return false; + } + + public boolean isMultiplePieOrderByRow() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieOrder():""; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return (nvl(s).length()>0)? (s.equals("row")?true:false):true; + } + + public boolean isMultiplePieOrderByColumn() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieOrder():""; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return (nvl(s).length()>0)&&(s.equals("column"))?true:false; + } + + public boolean displayPieLabelDisplayinRunPage() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieLabelDisplay():""; + if(nvl(s).indexOf("|")!= -1) { + s = s.substring(s.indexOf("|")+1); + return getFlagInBoolean(s); + } else return false; + } + + public String getMultiplePieLabelDisplay() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieLabelDisplay():""; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return s; + } + + public boolean displayChartDisplayinRunPage() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartDisplay():""; + if(nvl(s).indexOf("|")!= -1) { + s = s.substring(s.indexOf("|")+1); + return getFlagInBoolean(s); + } else return false; + } + + public boolean isChartDisplayIn3D() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartDisplay():""; + if(nvl(s).length()<=0) return true; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return (nvl(s).length()>0)&&(s.equals("3D"))?true:false; + } + + public boolean displayChartOrientationInRunPage() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartOrientation():""; + if(nvl(s).indexOf("|")!= -1) { + s = s.substring(s.indexOf("|")+1); + return getFlagInBoolean(s); + } else return false; + + } + + public String getLinearRegression() { + String s = ""; + s = nvl((cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLinearRegression():"Y"); + return s; + } + + public void setLinearRegression(String linear) { + cr.getChartAdditionalOptions().setLinearRegression(linear); + } + + public String getLinearRegressionColor() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLinearRegressionColor():""; + } + + public String getCustomizedRegressionPoint() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getMaxRegression():""; + } + + public void setCustomizedRegressionPoint( String d) { + cr.getChartAdditionalOptions().setMaxRegression(d); + } + + public void setLinearRegressionColor(String color) { + cr.getChartAdditionalOptions().setLinearRegressionColor(color); + } + + public String getExponentialRegressionColor() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getExponentialRegressionColor():""; + } + + public void setExponentialRegressionColor(String color) { + cr.getChartAdditionalOptions().setExponentialRegressionColor(color); + } + + public void setRangeAxisUpperLimit(String d) { + if(cr.getChartAdditionalOptions()!=null) + cr.getChartAdditionalOptions().setRangeAxisUpperLimit(d); + } + + public void setRangeAxisLowerLimit(String d) { + if(cr.getChartAdditionalOptions()!=null) + cr.getChartAdditionalOptions().setRangeAxisLowerLimit(d); + } + + public String getRangeAxisUpperLimit() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getRangeAxisUpperLimit():""; + } + + public String getRangeAxisLowerLimit() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getRangeAxisLowerLimit():""; + } + + public boolean isChartAnimate() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isAnimate()!=null?cr.getChartAdditionalOptions().isAnimate():false):false; + } + + public boolean isAnimateAnimatedChart() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isAnimateAnimatedChart()!=null?cr.getChartAdditionalOptions().isAnimateAnimatedChart():false):true; + } + + public void setAnimateAnimatedChart(boolean animate) { + cr.getChartAdditionalOptions().setAnimateAnimatedChart(animate); + } + + public void setChartStacked(boolean stacked) { + cr.getChartAdditionalOptions().setStacked(stacked); + } + + public boolean isChartStacked() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isStacked()!=null?cr.getChartAdditionalOptions().isStacked():true):false; + } + + public void setBarControls(boolean barControls) { + cr.getChartAdditionalOptions().setBarControls(barControls); + } + + public boolean displayBarControls() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isBarControls()!=null?cr.getChartAdditionalOptions().isBarControls():false):false; + } + + public void setXAxisDateType(boolean dateType) { + cr.getChartAdditionalOptions().setXAxisDateType(dateType); + } + + public boolean isXAxisDateType() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isXAxisDateType()!=null?cr.getChartAdditionalOptions().isXAxisDateType():false):false; + } + + public void setLessXaxisTickers(boolean lessTickers) { + cr.getChartAdditionalOptions().setLessXaxisTickers(lessTickers); + } + + public boolean isLessXaxisTickers() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isLessXaxisTickers()!=null?cr.getChartAdditionalOptions().isLessXaxisTickers():false):false; + } + + public void setTimeAxis(boolean timeAxis) { + cr.getChartAdditionalOptions().setTimeAxis(timeAxis); + } + + public boolean isTimeAxis() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isTimeAxis()!=null?cr.getChartAdditionalOptions().isTimeAxis():true):true; + } + + public void setLogScale(boolean logScale) { + cr.getChartAdditionalOptions().setLogScale(logScale); + } + + public boolean isLogScale() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isLogScale()!=null?cr.getChartAdditionalOptions().isLogScale():false):false; + } + + + public void setMultiSeries(boolean multiSeries) { + cr.getChartAdditionalOptions().setMultiSeries(multiSeries); + cr.setChartMultiSeries(multiSeries?"Y":"N"); + } + + public boolean isMultiSeries() { + if(AppUtils.nvl(cr.getChartMultiSeries()).equals("Y")) + cr.getChartAdditionalOptions().setMultiSeries(true); + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isMultiSeries()!=null?cr.getChartAdditionalOptions().isMultiSeries():false):false; + } + + public void setTimeSeriesRender(String timeSeriesRenderer) { + cr.getChartAdditionalOptions().setTimeSeriesRender(timeSeriesRenderer); + } + + public String getTimeSeriesRender() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getTimeSeriesRender():"line"; + } + + public void setShowXAxisLabel(boolean showXaxisLabel) { + cr.getChartAdditionalOptions().setShowXAxisLabel(showXaxisLabel); + } + + public boolean isShowXaxisLabel() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isShowXAxisLabel()!=null?cr.getChartAdditionalOptions().isShowXAxisLabel():false):false; + } + + public void setAddXAxisTickers(boolean addXAxisTickers) { + cr.getChartAdditionalOptions().setAddXAxisTickers(addXAxisTickers); + } + + public boolean isAddXAxisTickers() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isAddXAxisTickers()!=null?cr.getChartAdditionalOptions().isAddXAxisTickers():false):true; + } + + public void setZoomIn(Integer zoomIn) { + cr.getChartAdditionalOptions().setZoomIn(zoomIn); + } + + public Integer getZoomIn() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().getZoomIn()!=null?cr.getChartAdditionalOptions().getZoomIn():new Integer("25")): new Integer("25"); + } + + public void setTimeAxisType(String timeAxisType) { + cr.getChartAdditionalOptions().setTimeAxisType(timeAxisType); + } + + public String getTimeAxisType() { + return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().getTimeAxisType()!=null?cr.getChartAdditionalOptions().getTimeAxisType():"hourly"): "hourly"; + } + + public void setTopMargin(Integer topMargin) { + cr.getChartAdditionalOptions().setTopMargin(topMargin); + } + + public Integer getTopMargin() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getTopMargin(): new Integer("30"); + } + + public void setBottomMargin(Integer bottomMargin) { + cr.getChartAdditionalOptions().setBottomMargin(bottomMargin); + } + + public Integer getBottomMargin() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getBottomMargin(): new Integer("50"); + } + + public void setRightMargin(Integer rightMargin) { + cr.getChartAdditionalOptions().setRightMargin(rightMargin); + } + + public Integer getRightMargin() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getRightMargin(): new Integer("60"); + } + + public void setLeftMargin(Integer leftMargin) { + cr.getChartAdditionalOptions().setLeftMargin(leftMargin); + } + + public Integer getLeftMargin() { + return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLeftMargin(): new Integer("100"); + } + + + public boolean isVerticalOrientation() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartOrientation():""; + if(nvl(s).length()<=0) return true; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return (nvl(s).length()>0)&&(s.equals("vertical"))?true:false; + } + + public boolean isHorizontalOrientation() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartOrientation():""; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return (nvl(s).length()>0)&&(s.equals("horizontal"))?true:false; + } + + public boolean displaySecondaryChartRendererInRunPage() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getSecondaryChartRenderer():""; + if(nvl(s).indexOf("|")!= -1) { + s = s.substring(s.indexOf("|")+1); + return getFlagInBoolean(s); + } else return false; + + } + + public String getSecondaryChartRenderer() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getSecondaryChartRenderer():""; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return s; + } + + public String getOverlayItemValueOnStackBar() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getOverlayItemValueOnStackBar():"N"; + return s; + } + + public boolean displayIntervalInputInRunPage() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getIntervalFromdate():""; + if(nvl(s).indexOf("|")!= -1) { + s = s.substring(s.indexOf("|")+1); + return getFlagInBoolean(s); + } else return false; + } + + public boolean showLegendDisplayOptionsInRunPage() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getHidechartLegend():""; + if(nvl(s).indexOf("|")!= -1) { + s = s.substring(s.indexOf("|")+1); + return getFlagInBoolean(s); + } else return false; + } + + public String getIntervalFromdate() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getIntervalFromdate():""; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return nvl(s,""); + } + + public String getIntervalTodate() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getIntervalTodate():""; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return nvl(s,""); + } + + public String getIntervalLabel() { + return cr.getChartAdditionalOptions()!=null ? nvl(cr.getChartAdditionalOptions().getIntervalLabel()):""; + } + + public String getLegendPosition() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLegendPosition():""; + return nvl(s,"bottom"); + } + + public String getLegendLabelAngle() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLabelAngle():""; + return nvl(s,"UP90"); + } + + public String getMaxLabelsInDomainAxis() { + String s = ""; + s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getMaxLabelsInDomainAxis():""; + return nvl(s,"99"); + } + + public boolean isLastSeriesALineChart() { + String s = ""; + s = nvl((cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLastSeriesALineChart():""); + return s.equals("Y"); + } + + public boolean isLastSeriesABarChart() { + String s = ""; + s = nvl((cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLastSeriesABarChart():""); + return s.equals("Y"); + } + + public void setChartLegendDisplay(String value) { + cr.getChartAdditionalOptions().setHidechartLegend(value); + } + + public boolean hideChartLegend() { + String s = ""; + s = nvl((cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getHidechartLegend():"N"); + if(nvl(s).length()<=0) s = "N"; + if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); + return s.equals("Y"); + } + + public void setChartToolTips(String value) { + cr.getChartAdditionalOptions().setHideToolTips(value); + } + + public void setDomainAxisValuesAsString(String value) { + cr.getChartAdditionalOptions().setKeepDomainAxisValueAsString(value); + } + + public boolean hideChartToolTips() { + boolean s = true; + s = (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().getHideToolTips()!=null? + (cr.getChartAdditionalOptions().getHideToolTips().equals("Y")?true:false):(Globals.hideToolTipsGlobally()?true:false)):(Globals.hideToolTipsGlobally()?true:false); + return s; + } + + public boolean keepDomainAxisValueInChartAsString() { + boolean s = true; + s = (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().getKeepDomainAxisValueAsString()!=null? + (cr.getChartAdditionalOptions().getKeepDomainAxisValueAsString().equals("Y")?true:false):false):false; + return s; + } + + public int getChartHeightAsInt() { + return getIntValue(cr.getChartHeight(), Globals.getDefaultChartHeight()); + } + + public boolean isPublic() { + return cr.isPublic(); + } + + public boolean isDashboardType() throws RaptorException { + return cr.isDashboardType()!=null?cr.isDashboardType().booleanValue():false; + } + + // public String getCreateId() { return cr.getCreateId(); } + // public Calendar getCreateDate() { return cr.getCreateDate(); } + public String getReportSQL() { + return cr.getReportSQL(); + } + + public String getReportTitle() { + return cr.getReportTitle(); + } + + public String getReportSubTitle() { + return cr.getReportSubTitle(); + } + + public String getReportHeader() { + return cr.getReportHeader(); + } + + public String getReportFooter() { + return cr.getReportFooter(); + } + + public String getNumDashCols() { + return cr.getNumDashCols(); + } + + public int getNumDashColsAsInt() { + return getIntValue(cr.getNumDashCols(), 1); + } + + public String getNumFormCols() { + return cr.getNumFormCols(); + } + + public int getNumFormColsAsInt() { + return getIntValue(cr.getNumFormCols(), 5); + } + + public String getDisplayOptions() { + return cr.getDisplayOptions(); + } + + + +//Additional Methods + + public int getJumpTo() { + return cr.getJumpTo()==null?1:cr.getJumpTo(); + } + public void setJumpTo(int value){ + cr.setJumpTo(value); + } + + + public int getSearchPageSize(){ + return cr.getSearchPageSize()==null?20:cr.getSearchPageSize(); + } + public void setSearchPageSize(int value){ + cr.setSearchPageSize(value); + } + + + public boolean isToggleLayout(){ + if(cr.isToggleLayout()!=null) + return cr.isToggleLayout(); + + else + return Globals.displayRuntimeOptionsAsDefault(); + + } + public void setToggleLayout(boolean value){ + cr.setToggleLayout(value); + } + + public boolean isShowPageSize(){ + if(cr.isShowPageSize()!=null) + return cr.isShowPageSize(); + + else + return Globals.displayRuntimeOptionsAsDefault(); + + } + public void setShowPageSize(boolean value){ + cr.setShowPageSize(value); + } + + public boolean isShowNavPos(){ + if(cr.isShowNavPos()!=null) + return cr.isShowNavPos(); + + else + return Globals.displayRuntimeOptionsAsDefault(); + + } + public void setShowNavPos(boolean value){ + cr.setShowNavPos(value); + } + + public boolean isShowGotoOption(){ + if(cr.isShowGotoOption()!=null) + return cr.isShowGotoOption(); + + else + return Globals.displayRuntimeOptionsAsDefault(); + + } + public void setShowGotoOption(boolean value){ + cr.setShowGotoOption(value); + } + + public boolean isPageNav(){ + + if(cr.isPageNav()!=null) + return cr.isPageNav(); + + else + return Globals.displayRuntimeOptionsAsDefault(); + + } + + public void setPageNav(boolean value){ + cr.setPageNav(value); + } + + + public String getNavPosition(){ + if(cr.getNavPosition()!=null) + return cr.getNavPosition(); + + else + return "top"; + //return cr.getNavPosition(); + } + public void setNavPosition(String value){ + cr.setNavPosition(value); + } + + + public String getDashboardEditor(){ + return getDashBoardReportsNew().getDashboardEditor(); + } + + public void setDashboardEditor(String value){ + getDashBoardReportsNew().setDashboardEditor(value); + } + + + public DashboardEditorList getDashboardEditorList(){ + return getDashBoardReportsNew().getDashboardEditorList(); + } + + public void setDashboardEditorList(DashboardEditorList value){ + getDashBoardReportsNew().setDashboardEditorList(value); + } + + public PDFAdditionalOptions getPDFAdditionalOptions() { + try { + if(cr.getPdfAdditionalOptions()==null) + addPDFAdditionalOptions(new ObjectFactory()); + } catch(RaptorException ex) { + ex.printStackTrace(); + } + return cr.getPdfAdditionalOptions(); + } + + public String getPDFFont(){ + return getPDFAdditionalOptions().getPDFFont()!=null?getPDFAdditionalOptions().getPDFFont():Globals.getDataFontFamily(); + } + public void setPDFFont(String value){ + getPDFAdditionalOptions().setPDFFont(value); + } + + public int getPDFFontSize() { + return getPDFAdditionalOptions().getPDFFontSize()==null?9:getPDFAdditionalOptions().getPDFFontSize(); + } + public void setPDFFontSize(int value){ + getPDFAdditionalOptions().setPDFFontSize(value); + } + + public String getPDFOrientation(){ + return getPDFAdditionalOptions().getPDFOrientation()!=null?"portrait":"landscape"; + } + public void setPDFOrientation(String value){ + getPDFAdditionalOptions().setPDFOrientation(value); + } + + public String getPDFLogo1(){ + return getPDFAdditionalOptions().getPDFLogo1(); + } + public void setPDFLogo1(String value){ + getPDFAdditionalOptions().setPDFLogo1(value); + } + + public String getPDFLogo2(){ + return getPDFAdditionalOptions().getPDFLogo2(); + } + public void setPDFLogo2(String value){ + getPDFAdditionalOptions().setPDFLogo2(value); + } + + public int getPDFLogo1Size() { + return getPDFAdditionalOptions().getPDFLogo1Size()==null?0:getPDFAdditionalOptions().getPDFLogo1Size(); + } + public void setPDFLogo1Size(int value){ + getPDFAdditionalOptions().setPDFLogo1Size(value); + } + + public int getPDFLogo2Size() { + return getPDFAdditionalOptions().getPDFLogo2Size()==null?0:getPDFAdditionalOptions().getPDFLogo2Size(); + } + public void setPDFLogo2Size(int value){ + getPDFAdditionalOptions().setPDFLogo2Size(value); + } + + public boolean isPDFCoverPage(){ + + if(getPDFAdditionalOptions().isPDFCoverPage()!=null) + return getPDFAdditionalOptions().isPDFCoverPage(); + + else + return true; + + } + + public void setPDFCoverPage(boolean value){ + getPDFAdditionalOptions().setPDFCoverPage(value); + } + + public String getPDFFooter1(){ + return getPDFAdditionalOptions().getPDFFooter1(); + } + public void setPDFFooter1(String value){ + getPDFAdditionalOptions().setPDFFooter1(value); + } + + public String getPDFFooter2(){ + return getPDFAdditionalOptions().getPDFFooter2(); + } + public void setPDFFooter2(String value){ + getPDFAdditionalOptions().setPDFFooter2(value); + } + + + +//End of Additional Methods + + public String getDataContainerHeight() { + return cr.getDataContainerHeight(); + } + + public String getDataContainerWidth() { + return cr.getDataContainerWidth(); + } + + public boolean isAllowSchedule() { + String allowSchedule = getAllowSchedule(); + return (allowSchedule !=null )? allowSchedule.startsWith("Y"):false; + } + + public String getAllowSchedule() { + return cr.getAllowSchedule(); + } + + /* Multi Group */ + + public boolean isMultiGroupColumn() { + String multiGroupColumn = getMultiGroupColumn(); + return (multiGroupColumn !=null )? multiGroupColumn.startsWith("Y"):false; + } + + public String getMultiGroupColumn() { + return cr.getMultiGroupColumn(); + } + + public void setMultiGroupColumn(String value) { + cr.setMultiGroupColumn(value); + } + + private int getColumnGroupLevel(String colId) throws RaptorException { + DataColumnType dc = getColumnById(colId); + return (dc == null) ? 0 : dc.getLevel(); + } // getColumnGroupLevel + + public int getMaxGroupLevel() { + List reportCols = getAllColumns(); + int maxLevel = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (dc.getLevel()!=null) { + if(maxLevel < dc.getLevel()) + maxLevel = dc.getLevel(); + } + } // for + return maxLevel; + } // getMaxGroupLevel + + private int getColumnGroupStart(String colId) throws RaptorException { + DataColumnType dc = getColumnById(colId); + return (dc == null) ? 0 : dc.getStart(); + } // getColumnGroupStart + + private int getColumnGroupColSpan(String colId) throws RaptorException { + DataColumnType dc = getColumnById(colId); + return (dc == null) ? 0 : dc.getColspan(); + } // getColumnGroupColSpan + + public void setTopDown(String value) { + cr.setTopDown(value); + } + + public boolean isTopDown() { + String topDown = getTopDownOption(); + return (topDown !=null )? topDown.startsWith("Y"):false; + } + + public String getTopDownOption() { + return cr.getTopDown(); + } + + public void setSizedByContent(String value) { + cr.setSizedByContent(value); + } + + public boolean isSizedByContent() { + String sizedByContent = getSizedByContentOption(); + return (sizedByContent !=null )? sizedByContent.startsWith("Y"):false; + } + + public String getSizedByContentOption() { + return cr.getSizedByContent(); + } + + public String getDashboardOptions() { + return cr.getDashboardOptions(); + } + + public boolean isDashboardOptionHideChart() { + return nvl(getDashboardOptions()).length() > 0 && (getDashboardOptions().charAt(0) == 'Y'); + } + + public boolean isDashboardOptionHideData() { + return nvl(getDashboardOptions()).length() > 0 && (getDashboardOptions().charAt(1) == 'Y'); + } + + public boolean isDashboardOptionHideBtns() { + return nvl(getDashboardOptions()).length() > 0 && (getDashboardOptions().charAt(2) == 'Y'); + } + + public boolean isDisplayOptionHideForm() { + return nvl(getDisplayOptions()).length() > 0 && (getDisplayOptions().charAt(0) == 'Y'); + } + + public boolean isDisplayOptionHideChart() { + return nvl(getDisplayOptions()).length() > 1 && (getDisplayOptions().charAt(1) == 'Y'); + } + + public boolean isDisplayOptionHideData() { + return nvl(getDisplayOptions()).length() > 2 && (getDisplayOptions().charAt(2) == 'Y'); + } + + public boolean isDisplayOptionHideBtns() { + return nvl(getDisplayOptions()).length() > 3 && (getDisplayOptions().charAt(3) == 'Y'); + } + + public boolean isDisplayOptionHideMap() { + return nvl(getDisplayOptions()).length() > 4 && (getDisplayOptions().charAt(4) == 'Y'); + } + + public boolean isDisplayOptionHideExcelIcons() { + return nvl(getDisplayOptions()).length() > 5 && (getDisplayOptions().charAt(5) == 'Y'); + } + + public boolean isDisplayOptionHidePDFIcons() { + return nvl(getDisplayOptions()).length() > 6 && (getDisplayOptions().charAt(6) == 'Y'); + } + + public String getComment() { + return cr.getComment(); + } + + public DataSourceList getDataSourceList() { + return cr.getDataSourceList(); + } + + public ChartAdditionalOptions getChartAdditionalOptions() { + return cr.getChartAdditionalOptions(); + } + + public ChartDrillOptions getChartDrillOptions() { + return cr.getChartDrillOptions(); + } + + + public DataminingOptions getDataminingOptions() { + return cr.getDataminingOptions(); + } + + public DashboardReports getDashBoardReports() { + return cr.getDashBoardReports(); + } + + + public DashboardReportsNew getDashBoardReportsNew() { + try { + if(cr.getDashBoardReportsNew()==null) + addDashboardReportsNew(new ObjectFactory()); + } catch(RaptorException ex) { + ex.printStackTrace(); + } + return cr.getDashBoardReportsNew(); + } + + public String getDashboardLayoutHTML() { + return cr.getDashboardLayoutHTML(); + } + + public FormFieldList getFormFieldList() { + return cr.getFormFieldList(); + } + + public JavascriptList getJavascriptList() { + return cr.getJavascriptList(); + } + + public SemaphoreList getSemaphoreList() { + return cr.getSemaphoreList(); + } + + public void setPageSize(int value) { + cr.setPageSize(value); + } + + public void setAllowSchedule(String value) { + cr.setAllowSchedule(value); + } + + public void setMaxRowsInExcelDownload(int value) { + cr.setMaxRowsInExcelDownload(value); + } + + public void setReportInNewWindow (boolean value) { + cr.setReportInNewWindow(value); + } + + public void setDisplayFolderTree (boolean value) { + cr.setDisplayFolderTree(value); + } + + public void setReportType(String value) { + cr.setReportType(value); + } + + public void setReportName(String value) { + cr.setReportName(value); + } + + public void setDBInfo(String value) { + if (!(cr.getDbInfo() != null && cr.getDbInfo().length() > 0)) + cr.setDbInfo(value); + } + + public void setDBType(String value) { + if (!(cr.getDbType() != null && cr.getDbType().length() > 0)) + cr.setDbType(value); + } + + public void setReportDescr(String value) { + cr.setReportDescr(value); + } + + public void setChartType(String value) { + cr.setChartType(value); + } + + public void setChartMultiplePieOrder(String value) { + cr.getChartAdditionalOptions().setChartMultiplePieOrder(value); + } + + public void setChartMultiplePieLabelDisplay(String value) { + cr.getChartAdditionalOptions().setChartMultiplePieLabelDisplay(value); + } + + public void setChartOrientation(String value) { + cr.getChartAdditionalOptions().setChartOrientation(value); + } + + public void setSecondaryChartRenderer(String value) { + cr.getChartAdditionalOptions().setSecondaryChartRenderer(value); + } + + public void setOverlayItemValueOnStackBar(String value) { + cr.getChartAdditionalOptions().setOverlayItemValueOnStackBar(value); + } + + public void setIntervalFromdate(String value) { + cr.getChartAdditionalOptions().setIntervalFromdate(value); + } + + public void setIntervalLabel(String value) { + cr.getChartAdditionalOptions().setIntervalLabel(value); + } + + public void setIntervalTodate(String value) { + cr.getChartAdditionalOptions().setIntervalTodate(value); + } + + public void setLegendPosition(String value) { + cr.getChartAdditionalOptions().setLegendPosition(value); + } + + public void setLegendLabelAngle(String value) { + cr.getChartAdditionalOptions().setLabelAngle(value); + } + + public void setMaxLabelsInDomainAxis(String value) { + if(nvl(value).length()<=0) value = "99"; + cr.getChartAdditionalOptions().setMaxLabelsInDomainAxis(value); + } + + public void setLastSeriesALineChart(String value) { + cr.getChartAdditionalOptions().setLastSeriesALineChart(value); + } + + public void setLastSeriesABarChart(String value) { + cr.getChartAdditionalOptions().setLastSeriesABarChart(value); + } + + public void setChartDisplay(String value) { + cr.getChartAdditionalOptions().setChartDisplay(value); + } + + public void setChartAnimate(boolean animate) { + if(cr.getChartAdditionalOptions()!=null) + cr.getChartAdditionalOptions().setAnimate(animate); + else { + try { + if(getChartAdditionalOptions()==null) + addChartAdditionalOptions(new ObjectFactory()); + } catch(RaptorException ex) { + ex.printStackTrace(); + } + if(cr.getChartAdditionalOptions()!=null) + cr.getChartAdditionalOptions().setAnimate(animate); + + } + + } + + public void addChartAdditionalOptions(ObjectFactory objFactory) throws RaptorException { + ChartAdditionalOptions chartOptions = objFactory.createChartAdditionalOptions(); + cr.setChartAdditionalOptions(chartOptions); + } + + public void addDashboardReportsNew(ObjectFactory objFactory) throws RaptorException { + DashboardReportsNew dashboardReports = objFactory.createDashboardReportsNew(); + cr.setDashBoardReportsNew(dashboardReports); + } + + public void addPDFAdditionalOptions(ObjectFactory objFactory) throws RaptorException { + PDFAdditionalOptions pdfOptions = objFactory.createPDFAdditionalOptions(); + cr.setPdfAdditionalOptions(pdfOptions); + } + + public void setChartTypeFixed(String value) { + cr.setChartTypeFixed(value); + } + + public void setChartLeftAxisLabel(String value) { + cr.setChartLeftAxisLabel(value); + } + + public void setChartRightAxisLabel(String value) { + cr.setChartRightAxisLabel(value); + } + + public void setChartWidth(String value) { + cr.setChartWidth(value); + } + + public void setChartHeight(String value) { + cr.setChartHeight(value); + } + + public void setChartMultiSeries(String value) { + cr.setChartMultiSeries(value); + } + + public void setPublic(boolean value) { + cr.setPublic(value); + if (reportSecurity != null) + reportSecurity.setPublic(value); + } + + // public void setCreateId(String value) { cr.setCreateId(value); } + // public void setCreateDate(Calendar value) { cr.setCreateDate(value); } + public void setReportSQL(String value) { + cr.setReportSQL(value); + } + + public void setReportTitle(String value) { + cr.setReportTitle(value); + } + + public void setReportSubTitle(String value) { + cr.setReportSubTitle(value); + } + + public void setReportHeader(String value) { + cr.setReportHeader(value); + } + + public void setReportFooter(String value) { + cr.setReportFooter(value); + } + + public void setNumFormCols(String value) { + cr.setNumFormCols(value); + } + + public void setNumDashCols(String value) { + cr.setNumDashCols(value); + } + + public void setDisplayOptions(String value) { + cr.setDisplayOptions(value); + } + + public void setDataContainerHeight(String value) { + cr.setDataContainerHeight(value); + } + + public void setDataContainerWidth(String value) { + cr.setDataContainerWidth(value); + } + + public void setDashboardOptions(String value) { + cr.setDashboardOptions(value); + } + + public void setComment(String value) { + cr.setComment(value); + } + + public void setDashboardType(boolean dashboardType) { + cr.setDashboardType(dashboardType); + } + + public void setDashboardLayoutHTML(String html) { + cr.setDashboardLayoutHTML(html); + } + + public void setDataSourceList(DataSourceList value) { + cr.setDataSourceList(value); + } + + public void setFormFieldList(FormFieldList value) { + cr.setFormFieldList(value); + } + + public void setDashBoardReports(DashboardReports value) { + cr.setDashBoardReports(value); + } + + public void setSemaphoreList(SemaphoreList value) { + cr.setSemaphoreList(value); + } + + public void setJavascriptList(JavascriptList value) { + cr.setJavascriptList(value); + } + + public void setJavascriptElement(String javascriptElement) { + cr.setJavascriptElement(javascriptElement); + } + + public void checkUserReadAccess(HttpServletRequest request) throws RaptorException { + reportSecurity.checkUserReadAccess(request, null); + } + public void checkUserReadAccess(HttpServletRequest request, String userID) throws RaptorException { + reportSecurity.checkUserReadAccess(request, userID); + } + + public void checkUserWriteAccess(HttpServletRequest request) throws RaptorException { + reportSecurity.checkUserWriteAccess(request); + verifySQLBasedReportAccess(request); + } + + public String getOwnerID() { + return reportSecurity.getOwnerID(); + } + + public String getCreateID() { + return reportSecurity.getCreateID(); + } + + public String getCreateDate() { + return reportSecurity.getCreateDate(); + } + + public String getUpdateID() { + return reportSecurity.getUpdateID(); + } + + public String getUpdateDate() { + return reportSecurity.getUpdateDate(); + } + + public ReportSecurity getReportSecurity() { + return reportSecurity; + } + + /****Report Maps - Start****/ + public ReportMap getReportMap() { + return cr.getReportMap(); + } + + public void setReportMap(ReportMap reportMap) { + cr.setReportMap(reportMap); + } + /****Report Maps - End****/ + + /****Report Chart Drilldown - Start****/ + public ChartDrillOptions getReportChartDrillOptions() { + return cr.getChartDrillOptions(); + } + + public void setReportChartDrillOptions(ChartDrillOptions chartDrillOptions) { + cr.setChartDrillOptions(chartDrillOptions); + } + /****Report Maps - End****/ + + + /** ************************************************************************************************* */ + + public String getFormHelpText() { + String formHelpText = nvl(getComment()); + + if (formHelpText.indexOf('|') >= 0) + formHelpText = formHelpText.substring(formHelpText.lastIndexOf('|') + 1); + + return formHelpText; + } // getFormHelpText + + public void setFormHelpText(String formHelpText) { + String comment = nvl(getComment()); + + if (comment.indexOf('|') >= 0) + comment = comment.substring(0, comment.lastIndexOf('|')); + if (comment.length() > 0) + comment += '|'; + + setComment(comment + formHelpText); + } // setFormHelpText + + public boolean isRuntimeColSortDisabled() { + String comment = nvl(getComment()); + + if (comment.indexOf('|') < 0) + return false; + + return comment.substring(0, comment.indexOf('|')).equals("Y"); + } // isRuntimeColSortDisabled + + public void setRuntimeColSortDisabled(boolean value) { + String comment = nvl(getComment()); + + if (comment.indexOf('|') >= 0) + comment = comment.substring(comment.indexOf('|') + 1); + + setComment((value ? "Y" : "N") + "|" + comment); + } // setRuntimeColSortDisabled + + /** ************************************************************************************************* */ + + protected void verifySQLBasedReportAccess(HttpServletRequest request) throws RaptorException { + String userID = AppUtils.getUserID(request); + if (getReportDefType().equals(AppConstants.RD_SQL_BASED) + && (!Globals.getAllowSQLBasedReports()) && (!AppUtils.isAdminUser(request))) + throw new org.openecomp.portalsdk.analytics.error.UserAccessException(reportID, "[" + userID + "] " + + AppUtils.getUserName(request), AppConstants.UA_WRITE); + } // verifySQLBasedReportAccess + + /** ************************************************************************************************* */ + + private String getColumnNameById(String colId) throws RaptorException { + DataColumnType dc = getColumnById(colId); + return (dc == null) ? "NULL" : dc.getColName(); + } // getColumnNameById + + // Checks if drill-down URL points to individual record display (return + // true) or another report (return false) + private boolean isViewAction(String value) throws RaptorException { + try { + Vector viewActions = org.openecomp.portalsdk.analytics.model.DataCache.getDataViewActions(); + + for (int i = 0; i < viewActions.size(); i++) + if (value.equals(AppUtils.getBaseActionURL() + ((String) viewActions.get(i)))) + return true; + } catch (Exception e) { + throw new RaptorRuntimeException("ReportWrapper.isViewAction Exception: " + + e.getMessage()); + } + + return false; + } // isViewAction + + public String getSelectExpr(DataColumnType dct) { + // String colName = + // dct.isCalculated()?dct.getColName():((nvl(dct.getTableId()).length()>0)?(dct.getTableId()+"."+dct.getColName()):dct.getColName()); + return getSelectExpr(dct, dct.getColName() /* colName */); + } // getSelectExpr + + /*private String getSelectExpr(DataColumnType dct, String colName) { + String colType = dct.getColType(); + if (colType.equals(AppConstants.CT_CHAR) + || ((nvl(dct.getColFormat()).length() == 0) && (!colType + .equals(AppConstants.CT_DATE)))) + return colName; + else + return "TO_CHAR(" + colName + ", '" + + nvl(dct.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT) + "')"; + } // getSelectExpr + */ + + private String getSelectExpr(DataColumnType dct, String colName) { + String colType = dct.getColType(); + if(colType.equals(AppConstants.CT_NUMBER)) { + return colName; + } else + if (colType.equals(AppConstants.CT_CHAR) + || ((nvl(dct.getColFormat()).length() == 0) && (!colType + .equals(AppConstants.CT_DATE)))) + return colName; + + else + return "TO_CHAR(" + colName + ", '" + + nvl(dct.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT) + "')"; + } // getSelectExpr + + + /** ************************************************************************************************* */ + + public DataSourceType getTableById(String tableId) { + for (Iterator iter = getDataSourceList().getDataSource().iterator(); iter.hasNext();) { + DataSourceType ds = (DataSourceType) iter.next(); + if (ds.getTableId().equals(tableId)) + return ds; + } // for + + return null; + } // getTableById + + public DataSourceType getTableByDBName(String tableName) { + for (Iterator iter = getDataSourceList().getDataSource().iterator(); iter.hasNext();) { + DataSourceType ds = (DataSourceType) iter.next(); + if (ds.getTableName().equals(tableName)) + return ds; + } // for + + return null; + } // getTableByDBName + + public DataSourceType getColumnTableById(String colId) { + return getTableById(getColumnById(colId).getTableId()); + } // getColumnTableById + + public DataColumnType getColumnById(String colId) { + List reportCols = getAllColumns(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (dc.getColId().toLowerCase().equals(colId.toLowerCase())) + return dc; + } // for + + return null; + } // getColumnById + + public DataColumnType getChartLegendColumn() { + List reportCols = getAllColumns(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) + return dc; + } // for + return null; + } // getChartLegendColumn + + /* + * public DataColumnType getChartValueColumn() { List reportCols = + * getAllColumns(); for(Iterator iter=reportCols.iterator(); iter.hasNext(); ) { + * DataColumnType dc = (DataColumnType) iter.next(); if(dc.getChartSeq()>0) + * return dc; } // for + * + * return null; } // getChartValueColumn + */ + + public List getChartValueColumnsList( int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ + List reportCols = getAllColumns(); + + ArrayList chartValueCols = new ArrayList(); + int flag = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); +// if(filter == 2 || filter == 1) { + flag = getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 ) { + if(!AppUtils.nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) { + if(nvl(dc.getChartGroup()).length()<=0) { + if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue())) { + chartValueCols.add(dc); + } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { + chartValueCols.add(dc); + } + else if(filter == 0) chartValueCols.add(dc); + } else chartValueCols.add(dc); + } + } +// } else +// chartValueCols.add(dc); + } // for + Collections.sort(chartValueCols, new ChartSeqComparator()); + return chartValueCols; + } // getChartValueColumnsList + + + /* public ListModelList getChartValueColumnsListModelList( int filter, HashMap formValues) { / *filter; all=0;create without new chart =1; createNewChart=2 * / + List reportCols = getAllColumns(); + + ArrayList chartValueCols = new ArrayList(); + ListModelList chartValueListModelList = new ListModelList(); + int flag = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); +// if(filter == 2 || filter == 1) { + flag = getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 ) { + if(nvl(dc.getChartGroup()).length()<=0) { + if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue())) { + chartValueCols.add(dc); + } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { + chartValueCols.add(dc); + } + else if(filter == 0) chartValueCols.add(dc); + } else chartValueCols.add(dc); + } +// } else +// chartValueCols.add(dc); + chartValueListModelList.add(new Item(dc.getColId(), dc.getDisplayName())); + } // for + Collections.sort(chartValueCols, new ChartSeqComparator()); + return chartValueListModelList; + } // getChartValueColumnsList */ + + + /** Check whether chart has series (Category) columns **/ + public boolean hasSeriesColumn() { + List reportCols = getAllColumns(); + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (dc.isChartSeries()!=null && dc.isChartSeries().booleanValue()) + return true; + } // for + return false; + } // hasSeriesColumn + + + public List getChartDisplayNamesList( int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ + List reportCols = getAllColumns(); + ArrayList chartValueColNames = new ArrayList(); + int flag = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); +// if(filter == 2 || filter == 1) { + flag = getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { + if(nvl(dc.getChartGroup()).length()<=0) { + if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue()) ) { + chartValueColNames.add(dc.getDisplayName()); + } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { + chartValueColNames.add(dc.getDisplayName()); + } + else if(filter == 0) chartValueColNames.add(dc.getDisplayName()); + } else if(filter == 0) chartValueColNames.add(dc.getDisplayName()); + } + // } else + // chartValueColNames.add(dc.getDisplayName()); + + } + return chartValueColNames; + } // getChartDisplayNamesList + + + public List getChartColumnColorsList(int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ + List reportCols = getAllColumns(); + ArrayList chartValueColColors = new ArrayList(); + int flag = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); +// if(filter == 2 || filter == 1) { + flag = getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { + if(nvl(dc.getChartGroup()).length()<=0) { + if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue()) ) { + chartValueColColors.add(dc.getChartColor()); + } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { + chartValueColColors.add(dc.getChartColor()); + } + else if(filter == 0) chartValueColColors.add(dc.getChartColor()); + } else if(filter == 0) chartValueColColors.add(dc.getChartColor()); + } +// } else +// chartValueColColors.add(dc.getChartColor()); + } + return chartValueColColors; + } // getChartColumnColorsList + + public List getChartValueColumnAxisList( int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ + List reportCols = getAllColumns(); + ArrayList chartValueColAxis = new ArrayList(); + int flag = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); +// if(filter == 2 || filter == 1) { + flag = getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { + if(nvl(dc.getChartGroup()).length()<=0) { + if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue())) { + chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); + } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { + chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); + } + else if(filter == 0) chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); + } else if(filter == 0) chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); + } +// } else +// chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); + } + return chartValueColAxis; + } // getChartColumnAxisList + + + public List getChartValueNewChartList() { + ArrayList chartValueNewChartAxis = new ArrayList(); + for (Iterator iter = getChartValueColumnsList(2, null).iterator(); iter.hasNext();) + chartValueNewChartAxis.add(new Boolean(((DataColumnType) iter.next()).isCreateInNewChart())); + return chartValueNewChartAxis; + } // getChartValueNewChartList + + public List getAllChartGroups() { + ArrayList chartGroups = new ArrayList(); + String chartGroupName=""; + List reportCols = getAllColumns(); + Set groupSet = new TreeSet(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if(dc.getChartSeq()!=null && dc.getChartSeq()> 0) { + chartGroupName = dc.getChartGroup(); + if(nvl(chartGroupName).length()>0) + groupSet.add(chartGroupName); + } + } + List l = new ArrayList(groupSet); + return l; + } // getAllChartGroups + + public HashMap getAllChartYAxis(ReportParamValues reportParamValues) { + String chartYAxis=""; + List reportCols = getAllColumns(); + HashMap hashMap = new HashMap(); + FormFieldList formFieldList = getFormFieldList(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if(dc.getChartSeq()!=null && dc.getChartSeq()> 0) { + chartYAxis = dc.getYAxis(); + if(formFieldList!=null && reportParamValues!=null) { + for (Iterator iter1 = getFormFieldList().getFormField().iterator(); iter1.hasNext();) { + FormFieldType fft = (FormFieldType) iter1.next(); + String fieldDisplay = getFormFieldDisplayName(fft); + String fieldId = fft.getFieldId(); + if(!fft.getFieldType().equals(FormField.FFT_BLANK) && !fft.getFieldType().equals(FormField.FFT_LIST_MULTI) && !fft.getFieldType().equals(FormField.FFT_TEXTAREA)) { + String paramValue = Utils.oracleSafe(nvl(reportParamValues.getParamValue(fieldId))); + chartYAxis = Utils.replaceInString(chartYAxis, fieldDisplay, nvl( + paramValue, "")); + } + } + } + if(nvl(dc.getChartGroup()).length()>0) + hashMap.put(dc.getChartGroup(),chartYAxis); + } + } + return hashMap; + } // getAllChartGroups + + public List getChartGroupColumnAxisList( String chartGroupName, HashMap formValues ) { /*filter; all=0;create without new chart =1; createNewChart=2 */ + List reportCols = getAllColumns(); + ArrayList chartGroupColAxis = new ArrayList(); + String chartGroup = chartGroupName.substring(0,chartGroupName.lastIndexOf("|")); + int flag = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); +// if(filter == 2 || filter == 1) { + flag = getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { + if( nvl(dc.getChartGroup()).indexOf("|") > 0 && (nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup))) { + //if( nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup)) { + //System.out.println("$$$$$$$DC " + dc.getColId()+ " " + dc.getColOnChart()); + chartGroupColAxis.add(dc); + } + } +// } else +// chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); + } + Collections.sort(chartGroupColAxis, new ChartSeqComparator()); + return chartGroupColAxis; + } // getChartColumnAxisList + + public List getChartGroupValueColumnAxisList( String chartGroupName, HashMap formValues ) { + List reportCols = getAllColumns(); + String index = chartGroupName.substring(chartGroupName.lastIndexOf("|")+1); + String chartGroup = chartGroupName.substring(0,chartGroupName.lastIndexOf("|")); + //System.out.println("$$$$INDEX " + index); + ArrayList chartGroupValueColAxis = new ArrayList(); + int flag = 0; + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); + flag = getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { + //System.out.println(" Chartgroup " + dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))); + if( nvl(dc.getChartGroup()).indexOf("|") > 0 && (nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup))) { + //if( nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup)) { + //System.out.println(" Added Chartgroupname " + chartGroup + " " + dc.getChartGroup() + " " + index); + chartGroupValueColAxis.add(dc); + } + } + } + return chartGroupValueColAxis; + } // getChartColumnAxisList + + public List getChartGroupDisplayNamesList( String chartGroupName, HashMap formValues) { + List reportCols = getAllColumns(); + ArrayList chartGroupValueColNames = new ArrayList(); + String chartGroup = chartGroupName.substring(0,chartGroupName.lastIndexOf("|")); + int flag = 0; + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); + //System.out.println("$$$$$CHART " + dc.getChartSeq()+ " " + dc.getChartGroup()+ " " + chartGroup); + flag = getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 ) { + if( nvl(dc.getChartGroup()).indexOf("|") > 0 && (nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup))) { + chartGroupValueColNames.add(dc.getDisplayName()); + } + } + } + return chartGroupValueColNames; + } // getChartDisplayNamesList + + + public List getChartGroupColumnColorsList(String chartGroupName, HashMap formValues) { + List reportCols = getAllColumns(); + ArrayList chartValueColColors = new ArrayList(); + String chartGroup = chartGroupName.substring(0,chartGroupName.lastIndexOf("|")); + int flag = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); + flag = getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 ) { + if( nvl(dc.getChartGroup()).indexOf("|") > 0 && (nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup))) { + //if( nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup)) { + chartValueColColors.add(dc.getChartColor()); + } + } + } + return chartValueColColors; + } // getChartColumnColorsList + + + public List getCrossTabRowColumns() { + List reportCols = getAllColumns(); + Vector v = new Vector(reportCols.size()); + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (nvl(dc.getCrossTabValue()).equals(AppConstants.CV_ROW)) + v.add(dc); + } // for + + return v; + } // getCrossTabRowColumns + + public List getCrossTabColColumns() { + List reportCols = getAllColumns(); + Vector v = new Vector(reportCols.size()); + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (nvl(dc.getCrossTabValue()).equals(AppConstants.CV_COLUMN)) + v.add(dc); + } // for + + return v; + } // getCrossTabColColumns + + public String getCrossTabDisplayTotal(String rowColPos) { + DataColumnType dct = getCrossTabValueColumn(); + if (dct == null) + return ""; + + String displayTotal = nvl(dct.getDisplayTotal()); + if (displayTotal.indexOf('|') >= 0) { + String displayColTotal = displayTotal.substring(0, displayTotal.indexOf('|')); + String displayRowTotal = displayTotal.substring(displayTotal.indexOf('|') + 1); + + if (rowColPos.equals(AppConstants.CV_COLUMN)) + displayTotal = displayColTotal; + else if (rowColPos.equals(AppConstants.CV_ROW)) + displayTotal = displayRowTotal; + else if (displayColTotal.equals(displayRowTotal)) + displayTotal = displayColTotal; + } // if + + return displayTotal; + } // getCrossTabDisplayTotal + + public DataColumnType getCrossTabValueColumn() { + List reportCols = getAllColumns(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (nvl(dc.getCrossTabValue()).equals(AppConstants.CV_VALUE)) + return dc; + } // for + + return null; + } // getCrossTabValueColumn + + public int getCrossTabValueColumnIndex() { // Returns the index counting + // only visible columns + List reportCols = getAllColumns(); + + int idx = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (nvl(dc.getCrossTabValue()).equals(AppConstants.CV_VALUE)) + break; + if (dc.isVisible()) + idx++; + } // for + + return idx; + } // getCrossTabValueColumnIndex + + public ColFilterType getFilterById(String colId, int filterIndex) { + DataColumnType dc = getColumnById(colId); + try { + return (ColFilterType) dc.getColFilterList().getColFilter().get(filterIndex); + } catch (Exception e) { + return null; + } + } // getFilterById + + public boolean needFormInput() { + List reportCols = getAllColumns(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + + if (dct.getColFilterList() != null) { + List fList = dct.getColFilterList().getColFilter(); + for (Iterator iterF = fList.iterator(); iterF.hasNext();) { + ColFilterType cft = (ColFilterType) iterF.next(); + + if (nvl(cft.getArgType()).equals(AppConstants.AT_FORM)) + return true; + } // for + } // if + } // for + + return false; + } // needFormInput + + public int getNumSortColumns() { + int numSortCols = 0; + for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + if (dct.getOrderBySeq() != null && dct.getOrderBySeq() > 0) + numSortCols++; + } // for + + return numSortCols; + } // getNumSortColumns + + public SemaphoreType getSemaphoreById(String semaphoreId) { + if (getSemaphoreList() != null && semaphoreId != null) + for (Iterator iter = getSemaphoreList().getSemaphore().iterator(); iter.hasNext();) { + SemaphoreType sem = (SemaphoreType) iter.next(); + if (sem.getSemaphoreId().equals(semaphoreId)) + return sem; + } // for + + return null; + } // getSemaphoreById + + public void deleteSemaphore(SemaphoreType semaphore) { + if (getSemaphoreList() != null) { + if(getSemaphoreList().getSemaphore()!= null) + getSemaphoreList().getSemaphore().remove((SemaphoreType) semaphore); + } + } // deleteSemaphore + + + public void setSemaphore(SemaphoreType sem) { + if (getSemaphoreList() != null) { + getSemaphoreList().getSemaphore().add(sem); + } + + } // setSemaphore + + public static FormatType getSemaphoreFormatById(SemaphoreType semaphore, String formatId) { + if (semaphore != null) + for (Iterator iter = semaphore.getFormatList().getFormat().iterator(); iter + .hasNext();) { + FormatType fmt = (FormatType) iter.next(); + if (fmt.getFormatId().equals(formatId)) + return fmt; + } // for + + return null; + } // getSemaphoreFormatById + + public FormFieldType getFormFieldById(String fieldId) { + if (getFormFieldList() != null && fieldId != null) + for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { + FormFieldType fft = (FormFieldType) iter.next(); + if (fft.getFieldId().equals(fieldId)) + return fft; + } // for + + return null; + } // getFormFieldById + + public FormFieldType getFormFieldByDisplayValue(String fieldDisplay) { + // fieldDisplay expected to be [fieldName] + if (getFormFieldList() != null && fieldDisplay != null) + for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { + FormFieldType fft = (FormFieldType) iter.next(); + if (fieldDisplay.equals(getFormFieldDisplayName(fft))) + return fft; + } // for + + return null; + } // getFormFieldById + + public String getFormFieldDisplayName(FormFieldType fft) { + return "[" + fft.getFieldName() + "]"; + } // getFormFieldDisplayName + + /** ************************************************************************************************* */ + + public void resetCache(boolean sqlOnly) { + generatedSQL = null; + if (!sqlOnly) { + allColumns = null; + allFilters = null; + } + } // resetCache + + public String getOuterJoinType(DataSourceType curTable) { + String refDefinition = nvl(curTable.getRefDefinition()); + int outerJoinIdx = refDefinition.indexOf(" (+)"); + if (outerJoinIdx < 0) + // No outer join + return ""; + + int equalSignIdx = refDefinition.indexOf("="); + if (refDefinition.indexOf(curTable.getTableId()) < equalSignIdx) + // Cur. table is on the left side + return (outerJoinIdx < equalSignIdx) ? AppConstants.OJ_CURRENT + : AppConstants.OJ_JOINED; + else + // Joined table is on the left side + return (outerJoinIdx < equalSignIdx) ? AppConstants.OJ_JOINED + : AppConstants.OJ_CURRENT; + } // getOuterJoinType + + public String getFormFieldName(ColFilterType filter) { + FormFieldType fft = null; + if (filter.getArgType().equals(AppConstants.AT_FORM)) + fft = getFormFieldByDisplayValue(filter.getArgValue()); + + return (fft != null) ? fft.getFieldId() : filter.getColId() + "_f" + + filter.getFilterSeq(); + } // getFormFieldName + + public String getFormFieldDisplayName(DataColumnType column, ColFilterType filter) { + FormFieldType fft = null; + if (filter.getArgType().equals(AppConstants.AT_FORM)) + fft = getFormFieldByDisplayValue(filter.getArgValue()); + + return (fft != null) ? fft.getFieldName() : column.getDisplayName() + " " + + filter.getExpression(); + } // getFormFieldDisplayName + + public Calendar getFormFieldRangeStart(ColFilterType filter) { + FormFieldType fft = null; + if (filter.getArgType().equals(AppConstants.AT_FORM)) + fft = getFormFieldByDisplayValue(filter.getArgValue()); + + return (fft != null) ? fft.getRangeStartDate().toGregorianCalendar() : null; + } // getFormFieldRangeStart + + public Calendar getFormFieldRangeEnd(ColFilterType filter) { + FormFieldType fft = null; + if (filter.getArgType().equals(AppConstants.AT_FORM)) + fft = getFormFieldByDisplayValue(filter.getArgValue()); + + //System.out.println("as " + fft.getRangeEndDate()); + return (fft != null) ? fft.getRangeEndDate().toGregorianCalendar() : null; + } // getFormFieldRangeEnd + + public String getFormFieldRangeStartSQL(ColFilterType filter) { + FormFieldType fft = null; + if (filter.getArgType().equals(AppConstants.AT_FORM)) + fft = getFormFieldByDisplayValue(filter.getArgValue()); + + return (fft != null) ? fft.getRangeStartDateSQL() : null; + } // getFormFieldRangeStart + + public String getFormFieldRangeEndSQL(ColFilterType filter) { + FormFieldType fft = null; + if (filter.getArgType().equals(AppConstants.AT_FORM)) + fft = getFormFieldByDisplayValue(filter.getArgValue()); + + //System.out.println("as " + fft.getRangeEndDate()); + return (fft != null) ? fft.getRangeEndDateSQL() : null; + } // getFormFieldRangeEnd + + public String getUniqueTableId(String tableName) { + String tableIdPrefix = tableName.startsWith("MSA_") ? tableName.substring(4, 6) + : tableName.substring(0, 2); + String tableId = ""; + + int tableIdN = getDataSourceList().getDataSource().size() + 1; + do { + tableId = tableIdPrefix.toLowerCase() + (tableIdN++); + } while (getTableById(tableId) != null); + + return tableId; + } // getUniqueTableId + + /** ************************************************************************************************* */ + + protected void deleteDataSourceType(String tableId) { + List dsList = getDataSourceList().getDataSource(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType dst = (DataSourceType) iter.next(); + if (dst.getTableId().equals(tableId)) + iter.remove(); + else if (nvl(dst.getRefTableId()).equals(tableId)) { + dst.setRefTableId(null); + dst.setRefDefinition(null); + } + } // for + + resetCache(false); + } // deleteDataSourceType + + public static void adjustColumnType(DataColumnType dct) { + dct.setColType(dct.getDbColType()); + + if (dct.isCalculated()) + if (dct.getColName().startsWith("SUM(") || dct.getColName().startsWith("COUNT(") + || dct.getColName().startsWith("AVG(") + || dct.getColName().startsWith("STDDEV(") + || dct.getColName().startsWith("VARIANCE(")) + dct.setColType(AppConstants.CT_NUMBER); + else if (dct.getColName().startsWith("DECODE(") || dct.getColName().startsWith("coalesce(")) + dct.setColType(AppConstants.CT_CHAR); + } // adjustColumnType + + public static boolean getColumnNoParseDateFlag(DataColumnType dct) { + return (nvls(dct.getComment()).indexOf(AppConstants.CF_NO_PARSE_DATE) >= 0); + } // getColumnNoParseDateFlag + + public static void setColumnNoParseDateFlag(DataColumnType dct, boolean noParseDateFlag) { + dct.setComment(noParseDateFlag ? AppConstants.CF_NO_PARSE_DATE : null); + } // setColumnNoParseDateFlag + + /** ************************************************************************************************* */ + + public static String getSQLBasedFFTColTableName(String fftColId) { + return fftColId.substring(0, fftColId.indexOf('.')); + } // getSQLBasedFFTColTableName + + public static String getSQLBasedFFTColColumnName(String fftColId) { + fftColId = (fftColId.indexOf('|') < 0) ? fftColId : fftColId.substring(0, fftColId + .indexOf('|')); + return fftColId.substring(fftColId.indexOf('.') + 1); + } // getSQLBasedFFTColColumnName + + public static String getSQLBasedFFTColDisplayFormat(String fftColId) { + return (fftColId.indexOf('|') < 0) ? "" : fftColId + .substring(fftColId.indexOf('|') + 1); + } // getSQLBasedFFTColDisplayFormat + + /** ************************************************************************************************* */ + + public List getAllColumns() { + if (cr == null) + throw new NullPointerException("CustomReport not initialized"); + + if (allColumns == null) { + allColumns = new Vector(); + + List dsList = getDataSourceList().getDataSource(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType ds = (DataSourceType) iter.next(); + + // allColumns.addAll(ds.getDataColumnList().getDataColumn()); + List dcList = ds.getDataColumnList().getDataColumn(); + for (Iterator iterC = dcList.iterator(); iterC.hasNext();) { + DataColumnType dc = (DataColumnType) iterC.next(); + + allColumns.add(dc); + } // for + } // for + + Collections.sort(allColumns, new OrderSeqComparator()); + } // if + + return allColumns; + } // getAllColumns + + public List getOnlyVisibleColumns() { + if (cr == null) + throw new NullPointerException("CustomReport not initialized"); + + if (allVisibleColumns == null) { + allVisibleColumns = new Vector(); + + List dsList = getDataSourceList().getDataSource(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType ds = (DataSourceType) iter.next(); + + // allColumns.addAll(ds.getDataColumnList().getDataColumn()); + List dcList = ds.getDataColumnList().getDataColumn(); + for (Iterator iterC = dcList.iterator(); iterC.hasNext();) { + DataColumnType dc = (DataColumnType) iterC.next(); + if(dc.isVisible()) + allVisibleColumns.add(dc); + } // for + } // for + + Collections.sort(allVisibleColumns, new OrderSeqComparator()); + } // if + + return allVisibleColumns; + } // getOnlyVisibleColumns + public int getVisibleColumnCount() { + if (cr == null) + throw new NullPointerException("CustomReport not initialized"); + int colCount = 0; + List dsList = getDataSourceList().getDataSource(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType ds = (DataSourceType) iter.next(); + + // allColumns.addAll(ds.getDataColumnList().getDataColumn()); + List dcList = ds.getDataColumnList().getDataColumn(); + for (Iterator iterC = dcList.iterator(); iterC.hasNext();) { + DataColumnType dc = (DataColumnType) iterC.next(); + if(dc.isVisible()) colCount ++; + } // for + } // for + + return colCount; + } + + public List getAllFilters() { + if (cr == null) + throw new NullPointerException("CustomReport not initialized"); + + // if(allFilters==null) { + allFilters = new Vector(); + + List reportCols = getAllColumns(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + + if (dct.getColFilterList() != null) { + List colFilters = dct.getColFilterList().getColFilter(); + + for (Iterator iterF = colFilters.iterator(); iterF.hasNext();) { + ColFilterType cft = (ColFilterType) iterF.next(); + + allFilters.add(cft); + } // for + } // if + } // for + + // Collections.sort(allFilters, ??); + // } // if + + return allFilters; + } // getAllFilters + + private String formatValue(String value, DataColumnType dc, boolean useDefaultDateFormat) throws RaptorException { + return formatValue(value, dc, useDefaultDateFormat, getColumnTableById(dc.getColId()), null); + } // formatValue + + private String formatValue(String value, DataColumnType dc, boolean useDefaultDateFormat, + DataSourceType ds, FormFieldType fft) throws RaptorException { + String fmtValue = null; + + if (nvl(value).length() == 0) + fmtValue = ""; + else if (value.equals(AppConstants.FILTER_MAX_VALUE) + || value.equals(AppConstants.FILTER_MIN_VALUE)) + fmtValue = "(SELECT " + + (value.equals(AppConstants.FILTER_MAX_VALUE) ? "MAX" : "MIN") + "(" + + dc.getColName() + ") FROM " + ds.getTableName() + ")"; + else if (dc.getColType().equals(AppConstants.CT_NUMBER)) { + try { + double vD = Double.parseDouble(value); + fmtValue = value; + } catch(NumberFormatException ex) { + throw new UserDefinedException("Expected number, Given String for the form field \"" + fft.getFieldName()+"\""); + } + } + else if (dc.getColType().equals(AppConstants.CT_DATE)) { + if (fft!=null && (fft.getValidationType().equals(FormField.VT_TIMESTAMP_HR) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) ) { + fmtValue = "TO_DATE('" + + value + + "', '" + + (useDefaultDateFormat ? AppConstants.DEFAULT_DATE_FORMAT : nvl(dc + .getColFormat(), AppConstants.DEFAULT_DATE_FORMAT));//+" HH24:MI:SS')"; + fmtValue = fmtValue + " HH24"; + if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) + fmtValue = fmtValue + ":MI"; + if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) + fmtValue = fmtValue + " HH24:MI:SS"; + } else { + fmtValue = "TO_DATE('" + + value + + "', '" + + (useDefaultDateFormat ? AppConstants.DEFAULT_DATE_FORMAT : nvl(dc + .getColFormat(), AppConstants.DEFAULT_DATE_FORMAT)) + "')"; + if (Globals.getMonthFormatUseLastDay()) + if (!useDefaultDateFormat) + if (nvl(dc.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT).equals( + "MM/YYYY") + || nvl(dc.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT) + .equals("MONTH, YYYY")) + fmtValue = "ADD_MONTHS(" + fmtValue + ", 1)-1"; + } + }else { + fmtValue = value; + if (!fmtValue.startsWith("'")) + fmtValue = "'" + fmtValue + "'"; + } + + return fmtValue; + } // formatValue + + private String formatListValue(String listValue, DataColumnType dc, + boolean useDefaultDateFormat, boolean useOnlyPipeDelimiter) throws RaptorException { + return formatListValue("", listValue, dc, useDefaultDateFormat, useOnlyPipeDelimiter, + getColumnTableById(dc.getColId()), null); + } // formatListValue + + public String formatListValue(String fieldDisplay, String listValue, DataColumnType dc, + boolean useDefaultDateFormat, boolean useOnlyPipeDelimiter, DataSourceType ds, + String listBaseSQL) throws RaptorException { + StringBuffer fmtValue = new StringBuffer(""); + //if(nvl(listValue,"").trim().length()>0) { + // The below statement is commented so that pipe is taken out from parsing for text area form field +// StringTokenizer st = new StringTokenizer(listValue, useOnlyPipeDelimiter ? "|" + //: ",|\n\r\f"); + StringTokenizer st = new StringTokenizer(listValue, useOnlyPipeDelimiter ? "|" + : ",\n\r\f"); + + while (st.hasMoreTokens()) { + if (fmtValue.length() > 0) + fmtValue.append(", "); + + if (dc == null) { + // For SQL-based reports - value always string + String value = st.nextToken().trim(); + if (value.startsWith("'")) + fmtValue.append(value); + else + fmtValue.append("'" + value + "'"); + } else + fmtValue.append(formatValue(st.nextToken().trim(), dc, useDefaultDateFormat, + ds, null) ); + + } // while + + if (fmtValue.length() == 0) { + if(nvl(fieldDisplay).length() > 0) { + fmtValue.append(""); + } else { + fmtValue.append("("); + fmtValue.append(nvl(listBaseSQL, "NULL")); + fmtValue.append(")"); + } + } else if (fmtValue.charAt(0) != '(') { + fmtValue.insert(0, '('); + fmtValue.append(')'); + } + /* } else { + fmtValue = new StringBuffer("()"); + }*/ + return fmtValue.toString(); + } // formatListValue + + private String getColumnSelectStr(DataColumnType dc, ReportParamValues paramValues) { + String colName = dc.isCalculated() ? dc.getColName() + : ((nvl(dc.getTableId()).length() > 0) ? (dc.getTableId() + "." + dc + .getColName()) : dc.getColName()); + String paramValue = null; + if (dc.isCalculated()) + if (getFormFieldList() != null) + for (Iterator iter2 = getFormFieldList().getFormField().iterator(); iter2 + .hasNext();) { + FormFieldType fft = (FormFieldType) iter2.next(); + String fieldId = fft.getFieldId(); + String fieldDisplay = getFormFieldDisplayName(fft); + if (!paramValues.isParameterMultiValue(fieldId)) { + paramValue = paramValues.getParamValue(fieldId); + if(paramValue!=null && paramValue.length() > 0) { + colName = Utils.replaceInString(colName, fieldDisplay, Utils + .oracleSafe(nvl(paramValue, "NULL"))); + } else { + colName = Utils.replaceInString(colName, "'" + fieldDisplay + "'", nvl( + paramValue, "NULL")); + colName = Utils.replaceInString(colName, fieldDisplay, nvl( + paramValue, "NULL")); + } + } + } // for + + return colName; + } // getColumnSelectStr + + private void addExtraIdSelect(StringBuffer selectExtraIdCl, String drillDownParams, + boolean includeSelectExpr) { + // drillDownParams - example value "c_master=[bo1.RECID$]" + drillDownParams = drillDownParams.substring(10, drillDownParams.length() - 1); // i.e. + // "bo1.RECID$" + + selectExtraIdCl.append(", "); + if (includeSelectExpr) { + selectExtraIdCl.append(drillDownParams); + selectExtraIdCl.append(" "); + } // if + selectExtraIdCl.append(drillDownParams.replace('.', '_')); // i.e. + // "bo1_RECID$" + } // addExtraIdSelect + + private void addExtraDateSelect(StringBuffer selectExtraDateCl, String drillDownParams, + ReportParamValues paramValues, boolean includeSelectExpr) { + // drillDownParams - example value "ff1=[dl1]&fc2=[mo3]" + String colId = ""; + while (drillDownParams.indexOf('[') >= 0) { + int startIdx = drillDownParams.indexOf('['); + int endIdx = drillDownParams.indexOf(']'); + + if(startIdx<=endIdx) { + colId = drillDownParams.substring(startIdx + 1, endIdx); // i.e. + } else { + drillDownParams = drillDownParams.substring(endIdx + 1); + continue; + } + // "dl1" + + DataColumnType column = getColumnById(colId); + if (column != null) + if (column.getColType().equals(AppConstants.CT_DATE)) + if (!nvl(column.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT).equals( + AppConstants.DEFAULT_DATE_FORMAT)) + if (selectExtraDateCl.toString().indexOf( + " " + colId + AppConstants.DD_COL_EXTENSION) < 0) { + selectExtraDateCl.append(", "); + if (includeSelectExpr) { + selectExtraDateCl.append("TO_CHAR(" + + getColumnSelectStr(column, paramValues) + ", '" + + AppConstants.DEFAULT_DATE_FORMAT + "')"); + selectExtraDateCl.append(" "); + } // if + selectExtraDateCl.append(colId + AppConstants.DD_COL_EXTENSION); // i.e. + // "dl1_dde" + } // if + + drillDownParams = drillDownParams.substring(endIdx + 1); + } // while + } // addExtraDateSelect + + /* + * public String generateSQL() { return generateSQL(null); } // generateSQL + */ + public String generateSQL(String userId, HttpServletRequest request) throws RaptorException { + return generateSQL(new ReportParamValues(), userId, request); + } // generateSQL + + public String generateSQL(ReportParamValues paramValues, String userId, HttpServletRequest request) throws RaptorException { + return generateSQL(paramValues, null, AppConstants.SO_ASC, userId, request); + } // generateSQL + + public String generateSQL(ReportParamValues paramValues, String overrideSortByColId, + String overrideSortByAscDesc, String userId, HttpServletRequest request) throws RaptorException { + if (cr == null) + throw new NullPointerException("CustomReport not initialized"); + if(nvl(getWholeSQL()).length()>0) return getWholeSQL(); + if (paramValues.size() > 0) + resetCache(true); + //resetCache(true); + if (generatedSQL == null) { + if (getReportDefType().equals(AppConstants.RD_SQL_BASED) || getReportDefType().equals(AppConstants.RD_SQL_BASED_DATAMIN)) { + generatedSQL = generateSQLSQLBased(paramValues, overrideSortByColId, + overrideSortByAscDesc, userId, request ); + generatedChartSQL = generateSQLSQLBased(paramValues, null, + AppConstants.SO_ASC, userId, request ); + } else if (getReportDefType().equals(AppConstants.RD_VISUAL) && !getReportType().equals(AppConstants.RT_CROSSTAB)) { + generatedSQL = generateSQLVisual(paramValues, overrideSortByColId, + overrideSortByAscDesc, userId, request); + generatedChartSQL = generateSQLVisual(paramValues, null, + AppConstants.SO_ASC, userId, request); + } else { + generatedSQL = generateSQLCrossTabVisual(paramValues, overrideSortByColId, + overrideSortByAscDesc, userId, request); + } + + //debugLogger.debug("******************"); + //debugLogger.debug("SQL Before Changing new line \n" + generatedSQL); + //debugLogger.debug("******************"); + generatedSQL = replaceNewLine(generatedSQL, ""+ '\n', " "+'\n'+" " ); + //chart sql should not be null + if(nvl(generatedChartSQL).trim().length()>0) + generatedChartSQL = replaceNewLine(generatedChartSQL, ""+ '\n', " "+'\n'+" " ); + //(generatedSQL, "\n", " \n "); + //debugLogger.debug("******************"); + //debugLogger.debug("SQL After Changing new line \n" + generatedSQL); + //debugLogger.debug("******************"); + //generatedSQL = replaceNewLine(generatedSQL, "SELECT", "SELECT "); + //generatedSQL = replaceNewLine(generatedSQL, "select", "select "); + //debugLogger.debug("SQL After Changing new line \n" + generatedSQL); + //debugLogger.debug("[[[[[[[[[[[[[[[[[["); + //generatedSQL = Utils.replaceInString(generatedSQL, "\n", " "); + //generatedSQL = Utils.replaceInString(generatedSQL, "\t", " "); + } // if + + return generatedSQL; + } // generateSQL + + public String generateSQLSQLBased(ReportParamValues paramValues, + String overrideSortByColId, String overrideSortByAscDesc, String userId, HttpServletRequest request) throws RaptorException { + String sql = getReportSQL(); + DataSet ds = null; + //debugLogger.debug(" generateSQLSQLBased " + sql); + String[] reqParameters = Globals.getRequestParams().split(","); + String[] sessionParameters = Globals.getSessionParams().split(","); + String[] scheduleSessionParameters = Globals.getSessionParamsForScheduling().split(","); + javax.servlet.http.HttpSession session = request.getSession(); + String dbType = ""; + String dbInfo = getDBInfo(); + int fieldCount = 0; + // For Daytona removing all formfields which has null param value + Pattern re1 = null; + Matcher matcher = null; + int index = 0; + int posFormField = 0; + int posAnd = 0; + if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { + try { + org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); + dbType = remDbInfo.getDBType(dbInfo); + } catch (Exception ex) { + throw new RaptorException(ex); + } + } + + sql = sql + " "; + sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ss][Ee][Ll][Ee][Cc][Tt]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" SELECT "); + //sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ff][Rr][Oo][Mm]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" FROM "); + sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ww][Hh][Ee][Rr][Ee]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" WHERE "); + sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ww][Hh][Ee][Nn]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" WHEN "); + sql = Pattern.compile("(^[\r\n]*|([\\s]))[Aa][Nn][Dd]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" AND "); + + if (getFormFieldList() != null) { + for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { + + FormFieldType fft = (FormFieldType) iter.next(); + String fieldId = fft.getFieldId(); + String fieldDisplay = getFormFieldDisplayName(fft); + if(!fft.getFieldType().equals(FormField.FFT_BLANK)) { + if (paramValues.isParameterMultiValue(fieldId)) { + String replaceValue = formatListValue(fieldDisplay, Utils + .oracleSafe(nvl(paramValues.getParamValue(fieldId))), null, false, + true, null, paramValues.getParamBaseSQL(fieldId)); + if(replaceValue.length() > 0) { + sql = Utils.replaceInString(sql, fieldDisplay, replaceValue); + } else { + fieldCount++; + if(fieldCount == 1) { + //sql = sql + " "; + //sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ss][Ee][Ll][Ee][Cc][Tt]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" SELECT "); + //sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ww][Hh][Ee][Rr][Ee]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" WHERE "); + //sql = Pattern.compile("(^[\r\n]*|([\\s]))[Aa][Nn][Dd]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" AND "); + } + //sql = getReportSQL(); + while(sql.indexOf(fieldDisplay) > 0) { +/* sql = Utils.replaceInString(sql, "SELECT ", "select "); + sql = Utils.replaceInString(sql, "WHERE", "where"); + sql = Utils.replaceInString(sql, " AND ", " and "); +*/ + re1 = Pattern.compile("(^[\r\n]|[\\s])AND(.*?[^\r\n]*)"+ "\\["+fft.getFieldName()+ "\\](.*?)\\s", Pattern.DOTALL); + //re1 = Pattern.compile("(^[\r\n]|[\\s])AND(.*?[^\r\n]*)"+ "\\["+fft.getFieldName()+ "\\]", Pattern.DOTALL); +/* posFormField = sql.indexOf(fieldDisplay); + posAnd = sql.lastIndexOf("and", posFormField); + if(posAnd < 0) posAnd = 0; + else if (posAnd > 2) posAnd = posAnd - 2; + matcher = re1.matcher(sql); +*/ + posFormField = sql.indexOf(fieldDisplay); + int posSelectField = sql.lastIndexOf("SELECT ", posFormField); + int andField = 0; + int whereField = 0, whenField = 0; + andField = sql.lastIndexOf(" AND ", posFormField); + whereField = sql.indexOf(" WHERE" , posSelectField); + whenField = sql.indexOf(" WHEN" , posSelectField); + + if(posFormField > whereField) + andField = sql.lastIndexOf(" AND ", posFormField); + if (posFormField > andField && (andField > whereField || andField > whenField)) + posAnd = andField; + else + posAnd = 0; + matcher = re1.matcher(sql); + + + if (posAnd > 0 && matcher.find(posAnd-1)) { + //sql = Utils.replaceInString(sql, matcher.group(), " "); + matcher = re1.matcher(sql); + index = sql!=null?sql.lastIndexOf("["+fft.getFieldName()+"]"):-1; + + if(andField>0) + index = andField; + else + index = whereField; + if(index >= 0 && matcher.find(index-1)) { + sql = sql.replace(matcher.group(), " "); + } + } else { + + //sql = sql.replace + re1 = Pattern.compile("(^[\r\n]|[\\s])WHERE(.*?[^\r\n]*)\\["+fft.getFieldName()+ "\\](.*?)\\s", Pattern.DOTALL); + matcher = re1.matcher(sql); + if(whereField != -1) { + if(matcher.find(whereField-1)) { + matcher = re1.matcher(sql); + index = sql!=null?sql.lastIndexOf("["+fft.getFieldName()+"]"):-1; + if(index >= 0 && matcher.find(index-30)) { + sql = sql.replace(matcher.group(), " WHERE 1=1 "); + } + //sql = Utils.replaceInString(sql, matcher.group(), " where 1=1 "); + } /*else { + replaceValue = formatListValue("", Utils + .oracleSafe(nvl(paramValues.getParamValue(fieldId))), null, false, + true, null, paramValues.getParamBaseSQL(fieldId)); + sql = Utils.replaceInString(sql, fieldDisplay, replaceValue); + }*/ + } else { + sql = Utils.replaceInString(sql, fieldDisplay, replaceValue); + } + + } + } + } + + //sql = Utils.replaceInString(sql, " select ", " SELECT "); + //sql = Utils.replaceInString(sql, " where ", " WHERE "); + //sql = Utils.replaceInString(sql, " and ", " AND "); + + } else { + String paramValue = ""; + if(paramValues.isParameterTextAreaValueAndModified(fieldId)) { + String value = ""; + value = nvl(paramValues + .getParamValue(fieldId)); +// value = Utils.oracleSafe(nvl(value)); +// if (!(dbType.equals("DAYTONA") && sql.trim().toUpperCase().startsWith("SELECT"))) { +// value = "('" + Utils.replaceInString(value, ",", "'|'") + "')"; +// value = Utils.replaceInString(value, "|", ","); +// paramValue = XSSFilter.filterRequestOnlyScript(value); +// } else if (nvl(value.trim()).length()>0) { +// value = "('" + Utils.replaceInString(value, ",", "'|'") + "')"; +// value = Utils.replaceInString(value, "|", ","); +// paramValue = XSSFilter.filterRequestOnlyScript(value); +// } + paramValue = value; + } else + paramValue = Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId))); + + if (paramValue!=null && paramValue.length() > 0) { + if(paramValue.toLowerCase().trim().startsWith("select ")) { + paramValue = Utils.replaceInString(paramValue, "[LOGGED_USERID]", userId); + paramValue = Utils.replaceInString(paramValue, "[USERID]", userId); + paramValue = Utils.replaceInString(paramValue, "[USER_ID]", userId); + + paramValue = Utils.replaceInString(paramValue, "''", "'"); + ds = ConnectionUtils.getDataSet(paramValue, dbInfo); + if (ds.getRowCount() > 0) paramValue = ds.getString(0, 0); + } + //debugLogger.debug("SQLSQLBASED B4^^^^^^^^^ " + sql + " " + fft.getValidationType() + " " + fft.getFieldName() + " " + fft.getFieldId()); + if(fft!=null && (fft.getValidationType()!=null && (fft.getValidationType().equals(FormField.VT_TIMESTAMP_HR) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) ||fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC) ||fft.getValidationType().equals(FormField.VT_DATE) ))) { + //System.out.println("paramValues.getParamValue(fieldId_Hr) Inside if " + fft.getValidationType() + " " + fieldDisplay); + if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_HR)) { + sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue) +((nvl(paramValues + .getParamValue(fieldId+"_Hr") ).length()>0)?" "+addZero(Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId+"_Hr") ) ) ):"")); + } + else if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN)) { +/* System.out.println("paramValues.getParamValue(fieldId_Hr)" + paramValues + .getParamValue(fieldId+"_Hr") + " " + paramValues + .getParamValue(fieldId+"_Min")) ; +*/ sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue) + ((nvl(paramValues + .getParamValue(fieldId+"_Hr") ).length()>0)?" "+addZero(Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId+"_Hr") ) ) ):"") + ((nvl(paramValues + .getParamValue(fieldId+"_Min") ).length()>0)?":" + addZero(Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId+"_Min") ) ) ) : "") ) ; + } + else if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { + sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue) + ((nvl(paramValues + .getParamValue(fieldId+"_Hr") ).length()>0)?" "+addZero(Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId+"_Hr") ) ) ):"") + ((nvl(paramValues + .getParamValue(fieldId+"_Min") ).length()>0)?":" + addZero(Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId+"_Min") ) ) ) : "") + ((nvl(paramValues + .getParamValue(fieldId+"_Sec") ).length()>0)?":"+addZero(Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId+"_Sec") ) ) ) : "" ) ) ; + } else { + sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue, "NULL")); + } + + + } else { + if(paramValue!=null && paramValue.length() > 0) { + if(sql.indexOf("'"+fieldDisplay+"'")!=-1 || sql.indexOf("'"+fieldDisplay)!=-1 || sql.indexOf(fieldDisplay+"'")!=-1 + || sql.indexOf("'%"+fieldDisplay+"%'")!=-1 || sql.indexOf("'%"+fieldDisplay)!=-1 || sql.indexOf(fieldDisplay+"%'")!=-1 + || sql.indexOf("'_"+fieldDisplay+"_'")!=-1 || sql.indexOf("'_"+fieldDisplay)!=-1 || sql.indexOf(fieldDisplay+"_'")!=-1 + || sql.indexOf("'%_"+fieldDisplay+"_%'")!=-1 || sql.indexOf("^"+fieldDisplay+"^")!=-1 || sql.indexOf("'%_"+fieldDisplay)!=-1 || sql.indexOf(fieldDisplay+"_%'")!=-1) { + sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue, "NULL")); + } else { + if(sql.indexOf(fieldDisplay)!=-1) { + if(nvl(paramValue).length()>0) { + try { + double vD = Double.parseDouble(paramValue); + sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue, "NULL")); + + } catch (NumberFormatException ex) { + if (/*dbType.equals("DAYTONA") &&*/ sql.trim().toUpperCase().startsWith("SELECT")) { + sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue, "NULL")); + } else + throw new UserDefinedException("Expected number, Given String for the form field \"" + fieldDisplay+"\""); + } + /*sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue, "NULL"));*/ + } else + sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue, "NULL")); + + } + } + } + else { + if (dbType.equals("DAYTONA") && sql.trim().toUpperCase().startsWith("SELECT")) { + sql = sql + " "; + re1 = Pattern.compile("(^[\r\n]|[\\s]|[^0-9a-zA-Z])AND(.*?[^\r\n]*)"+ "\\["+fft.getFieldName()+ "\\](.*?)\\s", Pattern.DOTALL); + posFormField = sql.indexOf(fieldDisplay); + posAnd = sql.lastIndexOf(" AND ", posFormField); + if(posAnd < 0) posAnd = 0; + else if (posAnd > 2) posAnd = posAnd - 2; + matcher = re1.matcher(sql); + if (matcher.find(posAnd)) { + sql = sql.replace(matcher.group(), ""); + } + } else { + sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( + paramValue, "NULL")); + sql = Utils.replaceInString(sql, fieldDisplay, nvl( + paramValue, "NULL")); + } + } + } + + } + + if (dbType.equals("DAYTONA") && sql.trim().toUpperCase().startsWith("SELECT")) { + sql = sql + " "; + re1 = Pattern.compile("(^[\r\n]|[\\s]|[^0-9a-zA-Z])AND(.*?[^\r\n]*)"+ "\\["+fft.getFieldName()+ "\\](.*?)\\s", Pattern.DOTALL); //+[\'\\)|\'|\\s] + posFormField = sql.indexOf(fieldDisplay); + posAnd = sql.lastIndexOf(" AND ", posFormField); + if(posAnd < 0) posAnd = 0; + else if (posAnd > 2) posAnd = posAnd - 2; + matcher = re1.matcher(sql); + if (matcher.find(posAnd)) { + sql = sql.replace(matcher.group(), " "); + } + } else { + if( fft.isGroupFormField()!=null && fft.isGroupFormField().booleanValue()) { + sql = Pattern.compile("[[\\s*][,]]\\["+fft.getFieldName()+"\\](.*?)[,]",Pattern.MULTILINE).matcher(sql).replaceAll(" "); + //sql = Pattern.compile("[,][\\s*]\\["+fft.getFieldName()+"\\][\\s]",Pattern.MULTILINE).matcher(sql).replaceAll(" "); + sql = Pattern.compile("(,.+?)[\\s*]\\["+fft.getFieldName()+"\\][\\s]",Pattern.MULTILINE).matcher(sql).replaceAll(" "); + //sql = Pattern.compile("(?:,?)[\\s*]\\["+fft.getFieldName()+"\\]",Pattern.MULTILINE).matcher(sql).replaceAll(""); + //sql = Pattern.compile("[,][\\s*]\\["+fft.getFieldName()+"\\]",Pattern.MULTILINE).matcher(sql).replaceAll(" "); + //sql = Pattern.compile( "\\["+fft.getFieldName()+"\\](.*?[^\r\n]*)[,]",Pattern.DOTALL).matcher(sql).replaceAll(""); + + //sql = Pattern.compile("[,]|(.*?[^\r\n]*)"+fieldDisplay+"(.*?)\\s",Pattern.DOTALL).matcher(sql).replaceAll(""); + //sql = Pattern.compile("(.*?[^\r\n]*)"+fieldDisplay+"(.*?)\\s|[,]",Pattern.DOTALL).matcher(sql).replaceAll(""); +/* sql = Utils.replaceInString(sql, "," + fieldDisplay , nvl( + paramValue, "")); + sql = Utils.replaceInString(sql, fieldDisplay + "," , nvl( + paramValue, "")); +*/ } else { + //debugLogger.debug("ParamValue |" + paramValue + "| Sql |" + sql + "| Multi Value |" + paramValues.isParameterMultiValue(fieldId)); + sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( + paramValue, "NULL")); + sql = Utils.replaceInString(sql, fieldDisplay , nvl( + paramValue, "NULL")); + //debugLogger.debug("SQLSQLBASED AFTER^^^^^^^^^ " + sql); + } + } + + } // else + } // if BLANK + } // for + if(request != null ) { + for (int i = 0; i < reqParameters.length; i++) { + if(!reqParameters[i].startsWith("ff")) { + if (nvl(request.getParameter(reqParameters[i].toUpperCase())).length() > 0) + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); + } + else + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + } + + for (int i = 0; i < scheduleSessionParameters.length; i++) { + if(nvl(request.getParameter(scheduleSessionParameters[i])).trim().length()>0 ) + sql = Utils.replaceInString(sql, "[" + scheduleSessionParameters[i].toUpperCase()+"]", request.getParameter(scheduleSessionParameters[i]) ); + } + } + if(session != null ) { + for (int i = 0; i < sessionParameters.length; i++) { + //if(!sessionParameters[i].startsWith("ff")) + // paramValue = Utils.replaceInString(paramValue, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i].toUpperCase()) ); + // else { + //debugLogger.debug(" Session " + " sessionParameters[i] " + sessionParameters[i] + " " + (String)session.getAttribute(sessionParameters[i])); + sql = Utils.replaceInString(sql, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); + //} + } + } + } else { + //debugLogger.debug("BEFORE LOGGED USERID REPLACE " + sql); + //sql = Utils.replaceInString(sql, "'[logged_userId]'", "'"+userId+"'"); + //debugLogger.debug("Replacing string 2 " + sql); + sql = Utils.replaceInString(sql, "[LOGGED_USERID]", userId); + sql = Utils.replaceInString(sql, "[USERID]", userId); + sql = Utils.replaceInString(sql, "[USER_ID]", userId); + //debugLogger.debug("AFTER LOGGED USERID REPLACE " + sql); + // Added for Simon's GM Project where they need to get page_id in their query + //debugLogger.debug("SQLSQLBASED no formfields " + sql); + if(request != null ) { + for (int i = 0; i < reqParameters.length; i++) { + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + } + } + if(session != null ) { + for (int i = 0; i < sessionParameters.length; i++) { + //debugLogger.debug(" Session " + " sessionParameters[i] " + sessionParameters[i] + " " + (String)session.getAttribute(sessionParameters[i])); + sql = Utils.replaceInString(sql, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); + } + } + } + // if it is not multiple select and ParamValue is empty this is the place it can be replaced. + sql = Utils.replaceInString(sql, "[LOGGED_USERID]", userId); + sql = Utils.replaceInString(sql, "[USERID]", userId); + sql = Utils.replaceInString(sql, "[USER_ID]", userId); + //debugLogger.debug("SQLSQLBASED no formfields after" + sql); + //debugLogger.debug("Replacing String 2 "+ sql); + //debugLogger.debug("Replaced String " + sql); + + int closeBracketPos = 0; + if (nvl(overrideSortByColId).length() > 0) { + if(sql.lastIndexOf(")")!= -1) closeBracketPos = sql.lastIndexOf(")"); + int idxOrderBy = (closeBracketPos>0)?sql.toUpperCase().indexOf("ORDER BY", closeBracketPos):sql.toUpperCase().lastIndexOf("ORDER BY"); + DataColumnType dct = getColumnById(overrideSortByColId+"_sort"); + if(dct!=null && dct.getColName().length()>0) { + overrideSortByColId = overrideSortByColId+"_sort"; + } + if (idxOrderBy < 0) + sql += " ORDER BY " + overrideSortByColId + " " + overrideSortByAscDesc; + else { + int braketCount = 0; + int idxOrderByClauseEnd = 0; + for (idxOrderByClauseEnd = idxOrderBy; idxOrderByClauseEnd < sql.length(); idxOrderByClauseEnd++) { + char ch = sql.charAt(idxOrderByClauseEnd); + + if (ch == '(') + braketCount++; + else if (ch == ')') { + if (braketCount == 0) + break; + braketCount--; + } + } // for + + sql = sql.substring(0, idxOrderBy) + " ORDER BY " + overrideSortByColId + " " + + overrideSortByAscDesc + sql.substring(idxOrderByClauseEnd); + } // else + } // if + sql = Pattern.compile("([\n][\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" "); + return sql; + } // generateSQLSQLBased + + public String generateSQLVisual(ReportParamValues paramValues, String overrideSortByColId, + String overrideSortByAscDesc, String userId, HttpServletRequest request)throws RaptorException { + StringBuffer selectCl = new StringBuffer(); + StringBuffer fromCl = new StringBuffer(); + StringBuffer whereCl = new StringBuffer(); + StringBuffer groupByCl = new StringBuffer(); + StringBuffer havingCl = new StringBuffer(); + StringBuffer orderByCl = new StringBuffer(); + StringBuffer selectExtraIdCl = new StringBuffer(); + StringBuffer selectExtraDateCl = new StringBuffer(); + + int whereClBracketCount = 0; + int havingClBracketCount = 0; + int whereClCarryoverBrackets = 0; + int havingClCarryoverBrackets = 0; + + // Identifying FROM clause tables and WHERE clause joins + List dsList = getDataSourceList().getDataSource(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType ds = (DataSourceType) iter.next(); + + if (fromCl.length() > 0) + fromCl.append(", "); + fromCl.append(ds.getTableName()); + fromCl.append(" "); + fromCl.append(ds.getTableId()); + + if (nvl(ds.getRefTableId()).length() > 0) { + if (whereCl.length() > 0) + whereCl.append(" AND "); + whereCl.append(ds.getRefDefinition()); + } // if + // Add the condition. + TableSource tableSource = null; + String dBInfo = this.cr.getDbInfo(); + Vector userRoles = AppUtils.getUserRoles(request); + tableSource = DataCache.getTableSource(ds.getTableName(), dBInfo,userRoles,userId, request); + if (userId != null && (!AppUtils.isSuperUser(request)) + && (!AppUtils.isAdminUser(request)) && tableSource != null + && nvl(tableSource.getFilterSql()).length() > 0) { + if (whereCl.length() > 0) + whereCl.append(" AND "); + whereCl.append(Utils.replaceInString(Utils.replaceInString(tableSource + .getFilterSql(), "[" + ds.getTableName() + "]", ds.getTableId()), + "[USER_ID]", userId)); + } // if + } // for + + List reportCols = getAllColumns(); + + boolean isGroupStmt = false; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (dc.isGroupBreak()) { + isGroupStmt = true; + break; + } // if + } // for + + // Identifying SELECT and GROUP BY clause fields and WHERE and HAVING + // clause filters + // Collections.sort(reportCols, new OrderSeqComparator()); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, paramValues); + + // SELECT clause fields + //TODO: Uncomment if it's not working -- if (dc.isVisible()) { + if (selectCl.length() > 0) + selectCl.append(", "); + selectCl.append(getSelectExpr(dc, colName)); + selectCl.append(" "); + selectCl.append(dc.getColId()); + //TODO } // if + + // Checking for extra fields necessary for drill-down + if (nvl(dc.getDrillDownURL()).length() > 0) + if (isViewAction(dc.getDrillDownURL())) + addExtraIdSelect(selectExtraIdCl, nvl(dc.getDrillDownParams()), true); + else + addExtraDateSelect(selectExtraDateCl, nvl(dc.getDrillDownParams()), + paramValues, true); + + // GROUP BY clause fields + if (dc.isGroupBreak()) { + if (groupByCl.length() > 0) + groupByCl.append(", "); + groupByCl.append(colName); + } // if + + // WHERE/HAVING clause fields + //boolean isHavingCl = isGroupStmt && dc.isVisible() && (!dc.isGroupBreak()); + boolean isHavingCl = isGroupStmt && (!dc.isGroupBreak()); + StringBuffer filterCl = isHavingCl ? havingCl : whereCl; + // StringBuffer filterCl = + // isGroupStmt?(dc.isVisible()?(dc.isGroupBreak()?whereCl:havingCl):whereCl):whereCl; + if (dc.getColFilterList() != null) { + int fNo = 0; + List fList = dc.getColFilterList().getColFilter(); + for (Iterator iterF = fList.iterator(); iterF.hasNext(); fNo++) { + ColFilterType cf = (ColFilterType) iterF.next(); + + StringBuffer curFilter = new StringBuffer(); + if (filterCl.length() > 0) + curFilter.append(" " + cf.getJoinCondition() + " "); + if ((isHavingCl ? havingClCarryoverBrackets : whereClCarryoverBrackets) > 0) + for (int b = 0; b < (isHavingCl ? havingClCarryoverBrackets + : whereClCarryoverBrackets); b++) + filterCl.append('('); + curFilter.append(nvl(cf.getOpenBrackets())); + curFilter.append(colName + " "); + curFilter.append(cf.getExpression() + " "); + + boolean applyFilter = true; + if ((nvl(cf.getArgValue()).length() > 0) + || (nvl(cf.getArgType()).equals(AppConstants.AT_FORM))) + if (nvl(cf.getArgType()).equals(AppConstants.AT_FORMULA)) + curFilter.append(cf.getArgValue()); + else if (nvl(cf.getArgType()).equals(AppConstants.AT_VALUE)) + curFilter.append(formatValue(cf.getArgValue(), dc, false)); + else if (nvl(cf.getArgType()).equals(AppConstants.AT_LIST)) + curFilter.append(formatListValue(cf.getArgValue(), dc, false, + false)); + else if (nvl(cf.getArgType()).equals(AppConstants.AT_COLUMN)) + curFilter.append(getColumnNameById(cf.getArgValue())); + else if (nvl(cf.getArgType()).equals(AppConstants.AT_FORM)) { + String fieldName = getFormFieldName(cf); + String fieldValue = Utils.oracleSafe(paramValues + .getParamValue(fieldName)); + boolean isMultiValue = paramValues + .isParameterMultiValue(fieldName); + boolean usePipeDelimiterOnly = false; + + FormFieldType fft = getFormFieldByDisplayValue(cf.getArgValue()); + if (fft == null) + // If not FormField => applying default value + fieldValue = nvl(fieldValue, Utils + .oracleSafe(cf.getArgValue())); + else + usePipeDelimiterOnly = fft.getFieldType().equals( + FormField.FFT_CHECK_BOX) + || fft.getFieldType().equals(FormField.FFT_LIST_MULTI); + //Added for TimeStamp validation + String fieldId = fft.getFieldId(); + if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_HR)||fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN)||fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { + fieldValue = nvl( + fieldValue + " " + addZero(Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId+"_Hr") ) ) ) ) ; + if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { + fieldValue = fieldValue + (nvl(paramValues + .getParamValue(fieldId+"_Min")).length()>0 ? ":" + addZero(Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId+"_Min")))): "") ; + } + if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { + fieldValue = fieldValue + (nvl(paramValues + .getParamValue(fieldId+"_Sec")).length()>0 ? ":"+ addZero(Utils.oracleSafe(nvl(paramValues + .getParamValue(fieldId+"_Sec")))) : ""); + } + } + + // End + if (nvl(fieldValue).length() == 0) + // Does not append filter with missing form + // field argument + applyFilter = false; + else if (isMultiValue || nvl(cf.getExpression()).equals("IN") + || nvl(cf.getExpression()).equals("NOT IN")) + curFilter.append(formatListValue(fieldValue, dc, true, + usePipeDelimiterOnly)); + else + curFilter.append(formatValue(fieldValue, dc, true, null, fft)); + } // else + curFilter.append(nvl(cf.getCloseBrackets())); + + if (applyFilter) { + filterCl.append(curFilter.toString()); + + if (isHavingCl) { + havingClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + havingClCarryoverBrackets = 0; + } else { + whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + whereClCarryoverBrackets = 0; + } + } else if (nvl(cf.getOpenBrackets()).length() != nvl(cf.getCloseBrackets()) + .length()) + if (nvl(cf.getOpenBrackets()).length() > nvl(cf.getCloseBrackets()) + .length()) { + // Carry over opening brackets + if (isHavingCl) + havingClCarryoverBrackets += (nvl(cf.getOpenBrackets()) + .length() - nvl(cf.getCloseBrackets()).length()); + else + whereClCarryoverBrackets += (nvl(cf.getOpenBrackets()) + .length() - nvl(cf.getCloseBrackets()).length()); + + if (isHavingCl) + havingClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + else + whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + } else { + // Adding closing brackets + if (filterCl.length() > 0) { + for (int b = 0; b < nvl(cf.getCloseBrackets()).length() + - nvl(cf.getOpenBrackets()).length(); b++) + filterCl.append(')'); + + if (isHavingCl) + havingClBracketCount += (nvl(cf.getOpenBrackets()) + .length() - nvl(cf.getCloseBrackets()).length()); + else + whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + } // if + } // else + } // for + } // if + } // for + + // Identifying ORDER BY clause fields + DataColumnType overrideSortByCol = null; + if (overrideSortByColId != null) + overrideSortByCol = getColumnById(overrideSortByColId); + + if (overrideSortByCol != null) { + orderByCl.append(getColumnSelectStr(overrideSortByCol, paramValues)); + orderByCl.append(" "); + orderByCl.append(nvl(overrideSortByAscDesc, AppConstants.SO_ASC)); + } else if (getReportType().equals(AppConstants.RT_CROSSTAB)) { + /* + * for(Iterator iter=reportCols.iterator(); iter.hasNext(); ) { + * DataColumnType dc = (DataColumnType) iter.next(); + * + * if(nvl(dc.getCrossTabValue()).equals(AppConstants.CV_ROW)||nvl(dc.getCrossTabValue()).equals(AppConstants.CV_COLUMN)) { + * if(orderByCl.length()>0) orderByCl.append(", "); + * orderByCl.append(getColumnSelectStr(dc, paramValues)); + * orderByCl.append(" "); + * if(dc.getColType().equals(AppConstants.CT_DATE)) + * orderByCl.append(AppConstants.SO_DESC); else + * orderByCl.append(AppConstants.SO_ASC); } // if } // for + */ + } else { + Collections.sort(reportCols, new OrderBySeqComparator()); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + + if (dc.getOrderBySeq() > 0) { + if (orderByCl.length() > 0) + orderByCl.append(", "); + orderByCl.append(getColumnSelectStr(dc, paramValues)); + orderByCl.append(" "); + orderByCl.append(dc.getOrderByAscDesc()); + } // if + } // for + Collections.sort(reportCols, new OrderSeqComparator()); + } // else + + // Adding up the actual statement + StringBuffer sql = new StringBuffer(); + //sql.append("SELECT "); // Need to add PK for /*+ FIRST_ROWS */ "); + sql.append(Globals.getGenerateSqlVisualSelect()); + //sql.append((selectCl.length() == 0) ? "COUNT(*) cnt" : selectCl.toString()); + sql.append((selectCl.length() == 0) ? Globals.getGenerateSqlVisualCount() : selectCl.toString()); + if (groupByCl.length() == 0) + sql.append(selectExtraIdCl.toString()); + sql.append(selectExtraDateCl.toString()); + // sql.append(" FROM "); + sql.append((fromCl.length() == 0) ? Globals.getGenerateSqlVisualDual() : "FROM "+fromCl.toString()); + if (whereCl.length() > 0) { + if (whereClBracketCount > 0) { + for (int b = 0; b < whereClBracketCount; b++) + whereCl.append(')'); + } else if (whereClBracketCount < 0) { + for (int b = 0; b < Math.abs(whereClBracketCount); b++) + whereCl.insert(0, '('); + } // else + + sql.append(" WHERE "); + sql.append(whereCl.toString()); + } // if + if (groupByCl.length() > 0) { + sql.append(" GROUP BY "); + sql.append(groupByCl.toString()); + + if (havingCl.length() > 0) { + if (havingClBracketCount > 0) { + for (int b = 0; b < havingClBracketCount; b++) + havingCl.append(')'); + } else if (havingClBracketCount < 0) { + for (int b = 0; b < Math.abs(havingClBracketCount); b++) + havingCl.insert(0, '('); + } // else + + sql.append(" HAVING "); + sql.append(havingCl.toString()); + } + } + if (orderByCl.length() > 0) { + sql.append(" ORDER BY "); + sql.append(orderByCl.toString()); + } + //String sqlStr = Utils.replaceInString(sql.toString(), "[LOGGED_USERID]", userId); + //return sqlStr; + return sql.toString(); + } // generateSQLVisual + + public String generateSQLCrossTabVisual(ReportParamValues paramValues, String overrideSortByColId, + String overrideSortByAscDesc, String userId, HttpServletRequest request) throws RaptorException { + StringBuffer selectCl = new StringBuffer(); + StringBuffer fromCl = new StringBuffer(); + StringBuffer whereCl = new StringBuffer(); + StringBuffer groupByCl = new StringBuffer(); + StringBuffer havingCl = new StringBuffer(); + StringBuffer orderByCl = new StringBuffer(); + StringBuffer selectExtraIdCl = new StringBuffer(); + StringBuffer selectExtraDateCl = new StringBuffer(); + + int whereClBracketCount = 0; + int havingClBracketCount = 0; + int whereClCarryoverBrackets = 0; + int havingClCarryoverBrackets = 0; + + // Identifying FROM clause tables and WHERE clause joins + List dsList = getDataSourceList().getDataSource(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType ds = (DataSourceType) iter.next(); + + if (fromCl.length() > 0) + fromCl.append(", "); + fromCl.append(ds.getTableName()); + fromCl.append(" "); + fromCl.append(ds.getTableId()); + + if (nvl(ds.getRefTableId()).length() > 0) { + if (whereCl.length() > 0) + whereCl.append(" AND "); + whereCl.append(ds.getRefDefinition()); + } // if + // Add the condition. + TableSource tableSource = null; + String dBInfo = this.cr.getDbInfo(); + Vector userRoles = AppUtils.getUserRoles(request); + tableSource = DataCache.getTableSource(ds.getTableName(), dBInfo,userRoles,userId, request); + if (userId != null && (!AppUtils.isSuperUser(request)) + && (!AppUtils.isAdminUser(request)) && tableSource != null + && nvl(tableSource.getFilterSql()).length() > 0) { + if (whereCl.length() > 0) + whereCl.append(" AND "); + whereCl.append(Utils.replaceInString(Utils.replaceInString(tableSource + .getFilterSql(), "[" + ds.getTableName() + "]", ds.getTableId()), + "[USER_ID]", userId)); + } // if + } // for + + List reportCols = getAllColumns(); + + boolean isGroupStmt = false; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (dc.isGroupBreak()) { + isGroupStmt = true; + break; + } // if + } // for + + // Identifying SELECT and GROUP BY clause fields and WHERE and HAVING + // clause filters + // Collections.sort(reportCols, new OrderSeqComparator()); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, paramValues); + + // SELECT clause fields + if (dc.isVisible()) { + if (selectCl.length() > 0) + selectCl.append(", "); + selectCl.append(getSelectExpr(dc, colName)); + selectCl.append(" "); + selectCl.append(dc.getColId()); + } // if + + // Checking for extra fields necessary for drill-down + if (nvl(dc.getDrillDownURL()).length() > 0) + if (isViewAction(dc.getDrillDownURL())) + addExtraIdSelect(selectExtraIdCl, nvl(dc.getDrillDownParams()), true); + else + addExtraDateSelect(selectExtraDateCl, nvl(dc.getDrillDownParams()), + paramValues, true); + + // GROUP BY clause fields + if (dc.isGroupBreak()) { + if (groupByCl.length() > 0) + groupByCl.append(", "); + groupByCl.append(colName); + } // if + + // WHERE/HAVING clause fields + boolean isHavingCl = isGroupStmt && dc.isVisible() && (!dc.isGroupBreak()); + //boolean isHavingCl = isGroupStmt && (!dc.isGroupBreak()); + //StringBuffer filterCl = isHavingCl ? havingCl : whereCl; + StringBuffer filterCl = + isGroupStmt?(dc.isVisible()?(dc.isGroupBreak()?whereCl:havingCl):whereCl):whereCl; + if (dc.getColFilterList() != null) { + int fNo = 0; + List fList = dc.getColFilterList().getColFilter(); + for (Iterator iterF = fList.iterator(); iterF.hasNext(); fNo++) { + ColFilterType cf = (ColFilterType) iterF.next(); + + StringBuffer curFilter = new StringBuffer(); + if (filterCl.length() > 0) + curFilter.append(" " + cf.getJoinCondition() + " "); + if ((isHavingCl ? havingClCarryoverBrackets : whereClCarryoverBrackets) > 0) + for (int b = 0; b < (isHavingCl ? havingClCarryoverBrackets + : whereClCarryoverBrackets); b++) + filterCl.append('('); + curFilter.append(nvl(cf.getOpenBrackets())); + curFilter.append(colName + " "); + curFilter.append(cf.getExpression() + " "); + + boolean applyFilter = true; + if ((nvl(cf.getArgValue()).length() > 0) + || (nvl(cf.getArgType()).equals(AppConstants.AT_FORM))) + if (nvl(cf.getArgType()).equals(AppConstants.AT_FORMULA)) + curFilter.append(cf.getArgValue()); + else if (nvl(cf.getArgType()).equals(AppConstants.AT_VALUE)) + curFilter.append(formatValue(cf.getArgValue(), dc, false)); + else if (nvl(cf.getArgType()).equals(AppConstants.AT_LIST)) + curFilter.append(formatListValue(cf.getArgValue(), dc, false, + false)); + else if (nvl(cf.getArgType()).equals(AppConstants.AT_COLUMN)) + curFilter.append(getColumnNameById(cf.getArgValue())); + else if (nvl(cf.getArgType()).equals(AppConstants.AT_FORM)) { + String fieldName = getFormFieldName(cf); + String fieldValue = Utils.oracleSafe(paramValues + .getParamValue(fieldName)); + boolean isMultiValue = paramValues + .isParameterMultiValue(fieldName); + boolean usePipeDelimiterOnly = false; + + FormFieldType fft = getFormFieldByDisplayValue(cf.getArgValue()); + if (fft == null) + // If not FormField => applying default value + fieldValue = nvl(fieldValue, Utils + .oracleSafe(cf.getArgValue())); + else + usePipeDelimiterOnly = fft.getFieldType().equals( + FormField.FFT_CHECK_BOX) + || fft.getFieldType().equals(FormField.FFT_LIST_MULTI); + + if (nvl(fieldValue).length() == 0) + // Does not append filter with missing form + // field argument + applyFilter = false; + else if (isMultiValue || nvl(cf.getExpression()).equals("IN") + || nvl(cf.getExpression()).equals("NOT IN")) + curFilter.append(formatListValue(fieldValue, dc, true, + usePipeDelimiterOnly)); + else + curFilter.append(formatValue(fieldValue, dc, true)); + } // else + curFilter.append(nvl(cf.getCloseBrackets())); + + if (applyFilter) { + filterCl.append(curFilter.toString()); + + if (isHavingCl) { + havingClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + havingClCarryoverBrackets = 0; + } else { + whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + whereClCarryoverBrackets = 0; + } + } else if (nvl(cf.getOpenBrackets()).length() != nvl(cf.getCloseBrackets()) + .length()) + if (nvl(cf.getOpenBrackets()).length() > nvl(cf.getCloseBrackets()) + .length()) { + // Carry over opening brackets + if (isHavingCl) + havingClCarryoverBrackets += (nvl(cf.getOpenBrackets()) + .length() - nvl(cf.getCloseBrackets()).length()); + else + whereClCarryoverBrackets += (nvl(cf.getOpenBrackets()) + .length() - nvl(cf.getCloseBrackets()).length()); + + if (isHavingCl) + havingClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + else + whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + } else { + // Adding closing brackets + if (filterCl.length() > 0) { + for (int b = 0; b < nvl(cf.getCloseBrackets()).length() + - nvl(cf.getOpenBrackets()).length(); b++) + filterCl.append(')'); + + if (isHavingCl) + havingClBracketCount += (nvl(cf.getOpenBrackets()) + .length() - nvl(cf.getCloseBrackets()).length()); + else + whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( + cf.getCloseBrackets()).length()); + } // if + } // else + } // for + } // if + } // for + + // Identifying ORDER BY clause fields + DataColumnType overrideSortByCol = null; + if (overrideSortByColId != null) + overrideSortByCol = getColumnById(overrideSortByColId); + + if (overrideSortByCol != null) { + orderByCl.append(getColumnSelectStr(overrideSortByCol, paramValues)); + orderByCl.append(" "); + orderByCl.append(nvl(overrideSortByAscDesc, AppConstants.SO_ASC)); + } else if (getReportType().equals(AppConstants.RT_CROSSTAB)) { + /* + * for(Iterator iter=reportCols.iterator(); iter.hasNext(); ) { + * DataColumnType dc = (DataColumnType) iter.next(); + * + * if(nvl(dc.getCrossTabValue()).equals(AppConstants.CV_ROW)||nvl(dc.getCrossTabValue()).equals(AppConstants.CV_COLUMN)) { + * if(orderByCl.length()>0) orderByCl.append(", "); + * orderByCl.append(getColumnSelectStr(dc, paramValues)); + * orderByCl.append(" "); + * if(dc.getColType().equals(AppConstants.CT_DATE)) + * orderByCl.append(AppConstants.SO_DESC); else + * orderByCl.append(AppConstants.SO_ASC); } // if } // for + */ + } else { + Collections.sort(reportCols, new OrderBySeqComparator()); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + + if (dc.getOrderBySeq() > 0) { + if (orderByCl.length() > 0) + orderByCl.append(", "); + orderByCl.append(getColumnSelectStr(dc, paramValues)); + orderByCl.append(" "); + orderByCl.append(dc.getOrderByAscDesc()); + } // if + } // for + Collections.sort(reportCols, new OrderSeqComparator()); + } // else + + // Adding up the actual statement + StringBuffer sql = new StringBuffer(); + //sql.append("SELECT "); // Need to add PK for /*+ FIRST_ROWS */ "); + sql.append(Globals.getGenerateSqlVisualSelect()); + // sql.append((selectCl.length() == 0) ? "COUNT(*) cnt" : selectCl.toString()); + sql.append((selectCl.length() == 0) ? Globals.getGenerateSqlVisualCount() : selectCl.toString()); + if (groupByCl.length() == 0) + sql.append(selectExtraIdCl.toString()); + sql.append(selectExtraDateCl.toString()); + // sql.append(" FROM "); + sql.append((fromCl.length() == 0) ? Globals.getGenerateSqlVisualDual() : "FROM "+fromCl.toString()); + if (whereCl.length() > 0) { + if (whereClBracketCount > 0) { + for (int b = 0; b < whereClBracketCount; b++) + whereCl.append(')'); + } else if (whereClBracketCount < 0) { + for (int b = 0; b < Math.abs(whereClBracketCount); b++) + whereCl.insert(0, '('); + } // else + + sql.append(" WHERE "); + sql.append(whereCl.toString()); + } // if + if (groupByCl.length() > 0) { + sql.append(" GROUP BY "); + sql.append(groupByCl.toString()); + + if (havingCl.length() > 0) { + if (havingClBracketCount > 0) { + for (int b = 0; b < havingClBracketCount; b++) + havingCl.append(')'); + } else if (havingClBracketCount < 0) { + for (int b = 0; b < Math.abs(havingClBracketCount); b++) + havingCl.insert(0, '('); + } // else + + sql.append(" HAVING "); + sql.append(havingCl.toString()); + } + } + if (orderByCl.length() > 0) { + sql.append(" ORDER BY "); + sql.append(orderByCl.toString()); + } + + System.out.println("Created SQL statement: "+sql); + + //String sqlStr = Utils.replaceInString(sql.toString(), "[LOGGED_USERID]", userId); + //return sqlStr; + return sql.toString(); + } // generateSQLCrossTabVisual + + + public String generatePagedSQL(int pageNo, String userId, HttpServletRequest request, boolean getColumnNamesFromReportSQL, ReportParamValues paramValues) throws RaptorException { + int counter = 0; + if(!Globals.isMySQL()) + counter = 1; + return generateSubsetSQL(pageNo * getPageSize() + counter, ((pageNo + 1) * getPageSize()) + + ((pageNo == 0) ? 1 : 0), userId, request, getColumnNamesFromReportSQL, paramValues); + } // generatePagedSQL + + public String generateSubsetSQL(int startRow, int endRow, String userId, HttpServletRequest request, boolean getColumnNamesFromReportSQL, ReportParamValues paramValues) throws RaptorException { + //debugLogger.debug(" ******** End Row ********* " + endRow); + String dbInfo = getDBInfo(); + String dbType = ""; + if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { + try { + org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); + dbType = remDbInfo.getDBType(dbInfo); + } catch (Exception ex) { + throw new RaptorException(ex); + } + } + List reportCols = getAllColumns(); + String wholeSQL_OrderBy = getWholeSQL(); + String reportSQL = getWholeSQL(); + reportSQL = reportSQL.replace(";", ""); + setWholeSQL(reportSQL); + if(nvl(reportSQL).length()>0) + reportSQL = generateSQL(userId, request); + + if (reportSQL.toUpperCase().indexOf("ORDER BY ") < 0) { + StringBuffer sortBy = null; + + if (reportSQL.toUpperCase().indexOf("GROUP BY ") < 0) + if (getDataSourceList().getDataSource().size() > 0) { + DataSourceType dst = (DataSourceType) getDataSourceList().getDataSource() + .get(0); + String tId = dst.getTableId(); + String tPK = dst.getTablePK(); + if (nvl(tPK).length() > 0) { + sortBy = new StringBuffer(); + StringTokenizer st = new StringTokenizer(tPK, ", "); + while (st.hasMoreTokens()) { + if (sortBy.length() > 0) + sortBy.append(","); + sortBy.append(tId); + sortBy.append("."); + sortBy.append(st.nextToken()); + } // while + } + } // if + if (reportSQL.trim().toUpperCase().startsWith("SELECT")) { + //if (!(dbType.equals("DAYTONA") && reportSQL.trim().toUpperCase().startsWith("SELECT"))) + // reportSQL += " ORDER BY " + ((sortBy == null) ? "1" : sortBy.toString()); + } + } + + StringBuffer colNames = new StringBuffer(); + StringBuffer colExtraIdNames = new StringBuffer(); + StringBuffer colExtraDateNames = new StringBuffer(); + + if(getColumnNamesFromReportSQL) { + DataSet ds = ConnectionUtils.getDataSet(reportSQL, dbInfo); + List reportCols1 = getAllColumns(); + reportCols = new Vector(); + outer: + for (Iterator iter = reportCols1.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + for (int k=0; k 0) + colNames.append(", "); + colNames.append(dc.getColId()); + //TODO uncomment if it's not working} // if + + // Checking for extra fields necessary for drill-down + if (nvl(dc.getDrillDownURL()).length() > 0) + if (isViewAction(dc.getDrillDownURL())) + addExtraIdSelect(colExtraIdNames, nvl(dc.getDrillDownParams()), false); + else + addExtraDateSelect(colExtraDateNames, nvl(dc.getDrillDownParams()), null, + false); + } // for + + if (reportSQL.toUpperCase().indexOf("GROUP BY ") < 0) + colNames.append(colExtraIdNames.toString()); + //commented to avoid coldId_dde + //colNames.append(colExtraDateNames.toString()); + + /* + * if(pageNo==0) if(reportSQL.toUpperCase().indexOf(" WHERE ")<0) + * if(reportSQL.toUpperCase().indexOf(" GROUP BY ")<0) reportSQL = + * reportSQL.substring(0, reportSQL.toUpperCase().indexOf(" ORDER BY + * "))+" WHERE ROWNUM <= + * "+getPageSize()+reportSQL.substring(reportSQL.toUpperCase().indexOf(" + * ORDER BY ")); else reportSQL = "SELECT "+colNames.toString()+" FROM + * (SELECT ROWNUM rnum, "+colNames.toString()+" FROM ("+reportSQL+") x) + * y WHERE rnum <= "+getPageSize()+" ORDER BY rnum"; else reportSQL = + * reportSQL.substring(0, reportSQL.toUpperCase().indexOf(" WHERE "))+" + * WHERE ROWNUM <= "+getPageSize()+" AND + * "+reportSQL.substring(reportSQL.toUpperCase().indexOf(" WHERE ")+7); + * else reportSQL = "SELECT "+colNames.toString()+" FROM (SELECT ROWNUM + * rnum, "+colNames.toString()+" FROM ("+reportSQL+") x) y WHERE rnum >= + * "+(pageNo*getPageSize()+1)+" AND rnum <= + * "+((pageNo+1)*getPageSize())+" ORDER BY rnum"; + */ + if (dbType.equals("DAYTONA") && reportSQL.trim().toUpperCase().startsWith("SELECT")) { + if(endRow == -1) endRow = (getMaxRowsInExcelDownload()>0)?getMaxRowsInExcelDownload():Globals.getDownloadLimit(); + reportSQL = reportSQL + " LIMIT TO " +(startRow==0?startRow+1:startRow)+"->"+endRow; + return reportSQL; + } else if (dbType.equals("DAYTONA")) { + return reportSQL; + } + + //reportSQL = "SELECT " + colNames.toString() + " FROM (SELECT ROWNUM rnum, " + // + colNames.toString() + " FROM (" + reportSQL + ") x "; + + String rSQL = Globals.getGenerateSubsetSql(); + rSQL = rSQL.replace("[colNames.toString()]", colNames.toString()); + rSQL = rSQL.replace("[reportSQL]", reportSQL); + + reportSQL=rSQL; + //added rownum for total report where row header need to be shown + //reportSQLOnlyFirstPart = "SELECT rnum," + colNames.toString() + " FROM (SELECT ROWNUM rnum, " + //+ colNames.toString() + " FROM (" ; + + reportSQLOnlyFirstPart = Globals.getReportSqlOnlyFirstPart(); + reportSQLOnlyFirstPart = reportSQLOnlyFirstPart.replace("[colNames.toString()]", colNames.toString()); + + + reportSQLWithRowNum = reportSQL; + + /* if( endRow != -1) + reportSQL += " WHERE ROWNUM <= " + endRow; + reportSQL += " ) y WHERE rnum >= " + startRow + " ORDER BY rnum"; + return reportSQL;*/ + String parta = Globals.getReportSqlOnlySecondPartA(); + String partb = Globals.getReportSqlOnlySecondPartB(); + + String partSql = ""; + if(!AppUtils.isNotEmpty(getDBType())){ + setDBType(Globals.getDBType()); + } + + int closeBracketPos = 0; + if(wholeSQL_OrderBy.lastIndexOf(")")!= -1) closeBracketPos = wholeSQL_OrderBy.lastIndexOf(")"); + int idxOrderBy = (closeBracketPos>0)?wholeSQL_OrderBy.toUpperCase().indexOf("ORDER BY", closeBracketPos):wholeSQL_OrderBy.toUpperCase().lastIndexOf("ORDER BY"); + String orderbyclause = ""; + if (idxOrderBy < 0) { + orderbyclause = " ORDER BY 1 "; + partSql += " "+ orderbyclause+ " "; + } + else { + orderbyclause = wholeSQL_OrderBy.substring(idxOrderBy); + partSql += " "+ orderbyclause+ " "; + } + + if(getDBType().equals(AppConstants.MYSQL)) { + partSql = partSql+ " LIMIT "+ String.valueOf(startRow)+" , "+ String.valueOf(endRow); + } else if(getDBType().equals(AppConstants.ORACLE)) { + reportSQL = reportSQL.replace(" AS ", " "); + partSql = "where rownum >= "+ String.valueOf(startRow)+" and rownum <= "+(Integer.parseInt(String.valueOf(startRow)) + Integer.parseInt(String.valueOf(endRow))); + } else if(getDBType().equals(AppConstants.POSTGRESQL)) { + partSql = partSql + " LIMIT "+ String.valueOf(endRow)+" , "+ String.valueOf(startRow);//limit [pageSize] offset [startRow] + } + + // Limit only to MYSQL or MariaDB + //if (reportSQL.toUpperCase().indexOf("ORDER BY ") < 0) + //partSql += " ORDER BY 1"; + //else { + + + + /*if(!Globals.isMySQL()) + parta = parta.replace("[endRow]", String.valueOf(endRow)); + else + parta = parta.replace("[startRow]", String.valueOf(startRow)); + + //String partb = Globals.getReportSqlOnlySecondPartB(); + if(!Globals.isMySQL()) + partb = partb.replace("[startRow]", String.valueOf(startRow)); + else + partb = partb.replace("[pageSize]", String.valueOf(getPageSize())); + + if( endRow != -1) + reportSQL += parta;*/ + reportSQL += partSql; + + return reportSQL; + + } // generateSubsetSQL + + public String generateChartSQL(ReportParamValues paramValues, String userId, HttpServletRequest request ) throws RaptorException { + List reportCols = getAllColumns(); + List chartValueCols = getChartValueColumnsList(AppConstants.CHART_ALL_COLUMNS, null); // parameter is 0 has this requires all columns. + String reportSQL = generateSQL(userId, request); + //if(nvl(reportSQL).length()>0) reportSQL = generatedChartSQL; + logger.debug(EELFLoggerDelegate.debugLogger, ("SQL " + reportSQL)); + String legendCol = "1 a"; + // String valueCol = "1"; + StringBuffer groupCol = new StringBuffer(); + StringBuffer seriesCol = new StringBuffer(); + StringBuffer valueCols = new StringBuffer(); + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, paramValues); + if (nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) + legendCol = getSelectExpr(dc, colName)+" " + dc.getColId(); + // if(dc.getChartSeq()>0) + // valueCol = "NVL("+colName+", 0) "+dc.getColId(); + if ((!nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) + && (dc.getChartSeq()==null || dc.getChartSeq() <= 0) && dc.isGroupBreak()) { + groupCol.append(", "); + groupCol.append(colName + " " + dc.getColId()); + } + } // for + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if(dc.isChartSeries()!=null && dc.isChartSeries().booleanValue()) { + //System.out.println("*****************, "+ " " +getColumnSelectStr(dc, paramValues)+ " "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))); + seriesCol.append(", "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))+ " " + dc.getColId()); + } + } + + /*for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if(!dc.isChartSeries() && !(nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND))) { + //System.out.println("*****************, "+ " " +getColumnSelectStr(dc, paramValues)+ " "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))); + seriesCol.append(", "+ formatChartColumn(getSelectExpr(dc,getColumnSelectStr(dc, paramValues)))+ " " + dc.getColId()); + } + }*/ + + for (Iterator iter = chartValueCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, paramValues); + //valueCols.append(", NVL(" + formatChartColumn(colName) + ",0) " + dc.getColId()); + seriesCol.append("," + formatChartColumn(colName) + " " + dc.getColId()); + } // for + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, paramValues); + if(colName.equals(AppConstants.RI_CHART_TOTAL_COL)) + seriesCol.append(", " + AppConstants.RI_CHART_TOTAL_COL + " " + AppConstants.RI_CHART_TOTAL_COL ); + if (colName.equals(AppConstants.RI_CHART_COLOR)) + seriesCol.append(", " + AppConstants.RI_CHART_COLOR + " " + AppConstants.RI_CHART_COLOR ); + if(colName.equals(AppConstants.RI_CHART_MARKER_START)) + seriesCol.append(", " + AppConstants.RI_CHART_MARKER_START + " " + AppConstants.RI_CHART_MARKER_START ); + if(colName.equals(AppConstants.RI_CHART_MARKER_END)) + seriesCol.append(", " + AppConstants.RI_CHART_MARKER_END + " " + AppConstants.RI_CHART_MARKER_END ); + if(colName.equals(AppConstants.RI_CHART_MARKER_TEXT_LEFT)) + seriesCol.append(", " + AppConstants.RI_CHART_MARKER_TEXT_LEFT + " " + AppConstants.RI_CHART_MARKER_TEXT_LEFT ); + if(colName.equals(AppConstants.RI_CHART_MARKER_TEXT_RIGHT)) + seriesCol.append(", " + AppConstants.RI_CHART_MARKER_TEXT_RIGHT + " " + AppConstants.RI_CHART_MARKER_TEXT_RIGHT ); + if(colName.equals(AppConstants.RI_ANOMALY_TEXT)) + seriesCol.append(", " + AppConstants.RI_ANOMALY_TEXT + " " + AppConstants.RI_ANOMALY_TEXT ); + } + + //debugLogger.debug("ReportSQL Chart " + reportSQL ); + /*for (Iterator iter = chartValueCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, paramValues); + //valueCols.append(", NVL(" + formatChartColumn(colName) + ",0) " + dc.getColId()); + valueCols.append("," + formatChartColumn(colName) + " " + dc.getColId()); + } // for + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, paramValues); + //if(colName.equals(AppConstants.RI_CHART_TOTAL_COL) || colName.equals(AppConstants.RI_CHART_COLOR)) { + if(colName.equals(AppConstants.RI_CHART_TOTAL_COL)) + valueCols.append(", " + AppConstants.RI_CHART_TOTAL_COL + " " + AppConstants.RI_CHART_TOTAL_COL ); + if (colName.equals(AppConstants.RI_CHART_COLOR)) + valueCols.append(", " + AppConstants.RI_CHART_COLOR + " " + AppConstants.RI_CHART_COLOR ); + if (colName.equals(AppConstants.RI_CHART_INCLUDE)) + valueCols.append(", " + AppConstants.RI_CHART_INCLUDE + " " + AppConstants.RI_CHART_INCLUDE ); + //} + }*/ + String final_sql = ""; + reportSQL = Utils.replaceInString(reportSQL, " from ", " FROM "); + reportSQL = Utils.replaceInString(reportSQL, " select ", " SELECT "); + reportSQL = Utils.replaceInString(reportSQL, " union ", " UNION "); + //reportSQL = reportSQL.replaceAll("[\\s]*\\(", "("); +// if(reportSQL.indexOf("UNION") != -1) { +// if(reportSQL.indexOf("FROM(")!=-1) +// final_sql += " "+reportSQL.substring(reportSQL.indexOf("FROM(") ); +// else if (reportSQL.indexOf("FROM (")!=-1) +// final_sql += " "+reportSQL.substring(reportSQL.indexOf("FROM (") ); +// //TODO ELSE THROW ERROR +// } +// else { +// final_sql += " "+reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM ")); +// } + int pos = 0; + int pos_first_select = 0; + int pos_dup_select = 0; + int pos_prev_select = 0; + int pos_last_select = 0; + if (reportSQL.indexOf("FROM", pos)!=-1) { + pos = reportSQL.indexOf("FROM", pos); + pos_dup_select = reportSQL.lastIndexOf("SELECT",pos); + pos_first_select = reportSQL.indexOf("SELECT");//,pos); + logger.debug(EELFLoggerDelegate.debugLogger, ("pos_select " + pos_first_select + " " + pos_dup_select)); + if(pos_dup_select > pos_first_select) { + logger.debug(EELFLoggerDelegate.debugLogger, ("********pos_dup_select ********" + pos_dup_select)); + //pos_dup_select1 = pos_dup_select; + pos_prev_select = pos_first_select; + pos_last_select = pos_dup_select; + while (pos_last_select > pos_prev_select) { + logger.debug(EELFLoggerDelegate.debugLogger, ("pos_last , pos_prev " + pos_last_select + " " + pos_prev_select)); + pos = reportSQL.indexOf("FROM", pos+2); + pos_prev_select = pos_last_select; + pos_last_select = reportSQL.lastIndexOf("SELECT",pos); + logger.debug(EELFLoggerDelegate.debugLogger, ("in WHILE LOOP LAST " + pos_last_select)); + } + } + + } + final_sql += " "+reportSQL.substring(pos); + logger.debug(EELFLoggerDelegate.debugLogger, ("Final SQL " + final_sql)); + String sql = "SELECT " + legendCol + ", " + legendCol+"_1" + seriesCol.toString()+ nvl(valueCols.toString(), ", 1") + + groupCol.toString() + + final_sql; + logger.debug(EELFLoggerDelegate.debugLogger, ("Final sql in generateChartSQL " +sql)); + + return sql; + } // generateChartSQL + + private String formatChartColumn(String colName) { + + logger.debug(EELFLoggerDelegate.debugLogger, ("Format Chart Column Input colName" + colName)); + colName = colName.trim(); + colName = Utils.replaceInString(colName, "TO_CHAR", "to_char"); + colName = Utils.replaceInString(colName, "to_number", "TO_NUMBER"); + //reportSQL = reportSQL.replaceAll("[\\s]*\\(", "("); + colName = colName.replaceAll(",[\\s]*\\(", ",("); + StringBuffer colNameBuf = new StringBuffer(colName); + int pos = 0, posFormatStart = 0, posFormatEnd = 0; + String format = ""; + if(colNameBuf.indexOf("999")==-1 && colNameBuf.indexOf("990")==-1) { + logger.debug(EELFLoggerDelegate.debugLogger, (" return colName " + colNameBuf.toString())); + return colNameBuf.toString(); + } + while (colNameBuf.indexOf("to_char")!=-1) { + if(colNameBuf.indexOf("999")!=-1 || colNameBuf.indexOf("990")!=-1) { + pos = colNameBuf.indexOf("to_char"); + colNameBuf.insert(pos, " TO_NUMBER ( CR_RAPTOR.SAFE_TO_NUMBER ("); + pos = colNameBuf.indexOf("to_char"); + colNameBuf.replace(pos, pos+7, "TO_CHAR"); + //colName = Utils.replaceInString(colNameBuf.toString(), "to_char", " TO_NUMBER ( CR_RAPTOR.SAFE_TO_NUMBER ( TO_CHAR "); + logger.debug(EELFLoggerDelegate.debugLogger, ("After adding to_number " + colNameBuf.toString())); + //posFormatStart = colNameBuf.lastIndexOf(",'")+1; + posFormatStart = colNameBuf.indexOf(",'", pos)+1; + posFormatEnd = colNameBuf.indexOf(")",posFormatStart); + logger.debug(EELFLoggerDelegate.debugLogger, (posFormatStart + " " + posFormatEnd + " "+ pos)); + format = colNameBuf.substring(posFormatStart, posFormatEnd); + //posFormatEnd = colNameBuf.indexOf(")",posFormatEnd); + colNameBuf.insert(posFormatEnd+1, " ," + format + ") , "+ format + ")"); + logger.debug(EELFLoggerDelegate.debugLogger, ("colNameBuf " + colNameBuf.toString())); + } + } + logger.debug(EELFLoggerDelegate.debugLogger, (" return colName " + colNameBuf.toString())); + return colNameBuf.toString(); + } + public String generateTotalSQLLinear(ReportParamValues paramValues, String userId, HttpServletRequest request) throws RaptorException { + List reportCols = getAllColumns(); + String reportSQL = generateSQL(userId,request); + //debugLogger.debug("After GenerateSQL " + reportSQL); + + StringBuffer sbSelect = new StringBuffer(); + StringBuffer sbTotal = new StringBuffer(); + StringBuffer colNames = new StringBuffer(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + + DataColumnType dc = (DataColumnType) iter.next(); + if (colNames.length() > 0) + colNames.append(", "); + colNames.append(dc.getColId()); + } + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + + //if (!dct.isVisible()) + // continue; + + String colName = getColumnSelectStr(dct, paramValues); + + sbSelect.append((sbSelect.length() == 0) ? "SELECT " : ", "); + + sbSelect.append(colName); + sbSelect.append(" "); + sbSelect.append(dct.getColId()); + + + sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); + if (nvl(dct.getDisplayTotal()).length() > 0) { + // sbTotal.append(getSelectExpr(dct, + // dct.getDisplayTotal()+dct.getColId()+")")); + String displayTotal = dct.getDisplayTotal(); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < displayTotal.length(); i++) { + char ch = displayTotal.charAt(i); + if (ch == '+' || ch == '-') + sb.append(dct.getColId() + ")"); + sb.append(ch); + } // for + sb.append(dct.getColId() + ")"); + + //debugLogger.debug("SB " + sb.toString() + "\n " + getSelectExpr(dct, sb.toString())); + sbTotal.append(getSelectExpr(dct, sb.toString())); + //debugLogger.debug("SBTOTAL " + sbTotal.toString()); + } else + sbTotal.append("NULL"); + sbTotal.append(" total_"); + sbTotal.append(dct.getColId()); + } // for + + //debugLogger.debug(" ****** " + sbTotal.toString()); + logger.debug(EELFLoggerDelegate.debugLogger, ("REPORTWRAPPER " + reportSQL)); + int pos = 0; + int pos_first_select = 0; + int pos_dup_select = 0; + int pos_prev_select = 0; + int pos_last_select = 0; + + //reportSQL = Utils.replaceInString(reportSQL, " from ", " FROM "); + //reportSQL = Utils.replaceInString(reportSQL, "select ", "SELECT "); + reportSQL = replaceNewLine(reportSQL, " from ", " FROM "); + reportSQL = replaceNewLine(reportSQL, "from ", " FROM "); + reportSQL = replaceNewLine(reportSQL, "FROM ", " FROM "); + + reportSQL = " "+reportSQL; + reportSQL = replaceNewLine(reportSQL, "select ", " SELECT "); + reportSQL = replaceNewLine(reportSQL, "SELECT ", " SELECT "); + if (reportSQL.indexOf("FROM", pos)!=-1) { + pos = reportSQL.indexOf("FROM", pos); + pos_dup_select = reportSQL.lastIndexOf("SELECT",pos); + pos_first_select = reportSQL.indexOf("SELECT");//,pos); + logger.debug(EELFLoggerDelegate.debugLogger, ("pos_select " + pos_first_select + " " + pos_dup_select)); + if(pos_dup_select > pos_first_select) { + logger.debug(EELFLoggerDelegate.debugLogger, ("********pos_dup_select ********" + pos_dup_select)); + //pos_dup_select1 = pos_dup_select; + pos_prev_select = pos_first_select; + pos_last_select = pos_dup_select; + while (pos_last_select > pos_prev_select) { + logger.debug(EELFLoggerDelegate.debugLogger, ("pos_last , pos_prev " + pos_last_select + " " + pos_prev_select)); + pos = reportSQL.indexOf("FROM", pos+2); + pos_prev_select = pos_last_select; + pos_last_select = reportSQL.lastIndexOf("SELECT",pos); + logger.debug(EELFLoggerDelegate.debugLogger, ("in WHILE LOOP LAST " + pos_last_select)); + } + } + + } + + + //sbSelect.append(reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM "))); + + logger.debug(EELFLoggerDelegate.debugLogger, (" *************** " + pos + " " + reportSQL)); + //sbSelect.append(" "+ reportSQL.substring(pos)); + sbSelect.append(" "+reportSQL.substring(pos)); + logger.debug(EELFLoggerDelegate.debugLogger, (" **************** " + sbSelect.toString())); + sbTotal.append(" FROM ("); + sbTotal.append(sbSelect.toString()); + sbTotal.append(") totalSQL"); + + String dbType = ""; + String dbInfo = getDBInfo(); + if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { + try { + org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); + dbType = remDbInfo.getDBType(dbInfo); + } catch (Exception ex) { + throw new RaptorException(ex); + } + } + if (dbType.equals("DAYTONA")) { + sbTotal.append("("+ colNames+ ")"); + } + String sql = sbTotal.toString(); + sql = Utils.replaceInString(sql, " from ", " FROM "); + sql = Utils.replaceInString(sql, "select ", "SELECT "); + //sql = Utils.replaceInString(sql, " select ", " SELECT "); + logger.debug(EELFLoggerDelegate.debugLogger, ("Before SQL Corrector " + sql)); + String corrected_SQL = new SQLCorrector().fixSQL(new StringBuffer(sql)); + logger.debug(EELFLoggerDelegate.debugLogger, ("************")); + logger.debug(EELFLoggerDelegate.debugLogger, ("Corrected SQL " + corrected_SQL)); + return corrected_SQL; + //return sbTotal.toString(); + } // generateTotalSQLLinear + + public String generateTotalSQLCrossTab(String sql, String rowColPos, + String userId, HttpServletRequest request, ReportParamValues paramValues) throws RaptorException { + List reportCols = getAllColumns(); + String reportSQL = sql; + + StringBuffer sbSelect = new StringBuffer(); + StringBuffer sbGroup = new StringBuffer(); + // StringBuffer sbOrder = new StringBuffer(); + StringBuffer sbTotal = new StringBuffer(); + StringBuffer colNames = new StringBuffer(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + + DataColumnType dc = (DataColumnType) iter.next(); + if (colNames.length() > 0) + colNames.append(", "); + colNames.append(dc.getColId()); + } + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + + if (!dct.isVisible()) + continue; + + + String colName = getColumnSelectStr(dct, paramValues); + String colExpr = getSelectExpr(dct, colName); + + sbSelect.append((sbSelect.length() == 0) ? "SELECT " : ", "); + + if (nvl(dct.getCrossTabValue()).equals(rowColPos)) { + //sbSelect.append(colExpr); + sbSelect.append(dct.getColId()); + sbGroup.append((sbGroup.length() == 0) ? " GROUP BY " : ", "); + sbGroup.append(dct.getColId()); + + /* + * sbOrder.append((sbOrder.length()==0)?" ORDER BY ":", "); + * sbOrder.append(dct.getColId()); + * if(dct.getColType().equals(AppConstants.CT_DATE)) + * sbOrder.append(" DESC"); + */ + + sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); + sbTotal.append(dct.getColId()); + } else if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_VALUE)) { + //sbSelect.append(colName); + sbSelect.append(dct.getColId()); + + String displayTotal = getCrossTabDisplayTotal(rowColPos); + if (displayTotal.length() > 0) { + // displayTotal += dct.getColId()+")"; + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < displayTotal.length(); i++) { + char ch = displayTotal.charAt(i); + if (ch == '+' || ch == '-') + sb.append(dct.getColId() + ")"); + sb.append(ch); + } // for + sb.append(dct.getColId() + ")"); + + displayTotal = sb.toString(); + } else + displayTotal = "COUNT(*)"; + + sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); + sbTotal.append(getSelectExpr(dct, displayTotal)); + sbTotal.append(" total_"); + sbTotal.append(dct.getColId()); + } else { + //sbSelect.append(colExpr); + sbSelect.append(dct.getColId()); + } // if + + sbSelect.append(" "); + sbSelect.append(dct.getColId()); + } // for + + sbSelect.append(reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM "))); + + sbTotal.append(" FROM ("); + sbTotal.append(sbSelect.toString()); + sbTotal.append(") totalSQL"); + sbTotal.append(sbGroup.toString()); + String dbType = ""; + String dbInfo = getDBInfo(); + if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { + try { + org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); + dbType = remDbInfo.getDBType(dbInfo); + } catch (Exception ex) { + throw new RaptorException(ex); + } + } + if (dbType.equals("DAYTONA")) { + sbTotal.append("("+ colNames+ ")"); + } + + // sbTotal.append(sbOrder.toString()); + + //debugLogger.debug(getReportDefType() + " " + AppConstants.RD_SQL_BASED); + //debugLogger.debug("SQL To Delete " + sbTotal.toString()); + sql = ""; + if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) { + sql = Utils.replaceInString(sbTotal.toString(), " from ", " FROM "); + sql = Utils.replaceInString(sql, "select ", "SELECT "); + return new SQLCorrector().fixSQL(new StringBuffer(sql)); + } + + return sbTotal.toString(); + + } // generateTotalSQLCrossTab + + + public String generateTotalSQLCrossTab(ReportParamValues paramValues, String rowColPos, + String userId, HttpServletRequest request) throws RaptorException { + List reportCols = getAllColumns(); + String reportSQL = generateSQL(userId, request); + + StringBuffer sbSelect = new StringBuffer(); + StringBuffer sbGroup = new StringBuffer(); + // StringBuffer sbOrder = new StringBuffer(); + StringBuffer sbTotal = new StringBuffer(); + StringBuffer colNames = new StringBuffer(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + + DataColumnType dc = (DataColumnType) iter.next(); + if (colNames.length() > 0) + colNames.append(", "); + colNames.append(dc.getColId()); + } + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + + if (!dct.isVisible()) + continue; + + String colName = getColumnSelectStr(dct, paramValues); + String colExpr = getSelectExpr(dct, colName); + + sbSelect.append((sbSelect.length() == 0) ? "SELECT " : ", "); + + if (nvl(dct.getCrossTabValue()).equals(rowColPos)) { + sbSelect.append(colExpr); + + sbGroup.append((sbGroup.length() == 0) ? " GROUP BY " : ", "); + sbGroup.append(dct.getColId()); + + /* + * sbOrder.append((sbOrder.length()==0)?" ORDER BY ":", "); + * sbOrder.append(dct.getColId()); + * if(dct.getColType().equals(AppConstants.CT_DATE)) + * sbOrder.append(" DESC"); + */ + + sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); + sbTotal.append(dct.getColId()); + } else if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_VALUE)) { + sbSelect.append(colName); + + String displayTotal = getCrossTabDisplayTotal(rowColPos); + if (displayTotal.length() > 0) { + // displayTotal += dct.getColId()+")"; + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < displayTotal.length(); i++) { + char ch = displayTotal.charAt(i); + if (ch == '+' || ch == '-') + sb.append(dct.getColId() + ")"); + sb.append(ch); + } // for + sb.append(dct.getColId() + ")"); + + displayTotal = sb.toString(); + } else + displayTotal = "COUNT(*)"; + + sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); + sbTotal.append(getSelectExpr(dct, displayTotal)); + sbTotal.append(" total_"); + sbTotal.append(dct.getColId()); + } else { + sbSelect.append(colExpr); + } // if + + sbSelect.append(" "); + sbSelect.append(dct.getColId()); + } // for + + sbSelect.append(reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM "))); + + sbTotal.append(" FROM ("); + sbTotal.append(sbSelect.toString()); + sbTotal.append(") totalSQL"); + sbTotal.append(sbGroup.toString()); + String dbType = ""; + String dbInfo = getDBInfo(); + if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { + try { + org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); + dbType = remDbInfo.getDBType(dbInfo); + } catch (Exception ex) { + throw new RaptorException(ex); + } + } + if (dbType.equals("DAYTONA")) { + sbTotal.append("("+ colNames+ ")"); + } + + // sbTotal.append(sbOrder.toString()); + + //debugLogger.debug(getReportDefType() + " " + AppConstants.RD_SQL_BASED); + //debugLogger.debug("SQL To Delete " + sbTotal.toString()); + String sql = ""; + if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) { + sql = Utils.replaceInString(sbTotal.toString(), " from ", " FROM "); + sql = Utils.replaceInString(sql, "select ", "SELECT "); + return new SQLCorrector().fixSQL(new StringBuffer(sql)); + } + + return sbTotal.toString(); + + } // generateTotalSQLCrossTab + + public String generateDistinctValuesSQL(ReportParamValues paramValues, DataColumnType dct, + String userId, HttpServletRequest request) throws RaptorException { + DataSourceType dst = getColumnTableById(dct.getColId()); + String colName = getColumnSelectStr(dct, paramValues); + String colExpr = getSelectExpr(dct, colName); + ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); + StringBuffer sb = new StringBuffer(); + sb.append("SELECT DISTINCT "); + if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) { + sb.append(dct.getColId()); + sb.append(" FROM ("); + //paramvalues added below to filter distinct values based on formfields. + //sb.append(generateSQL(paramValues, userId, request)); + sb.append(rr.getWholeSQL()); + sb.append(") " + (Globals.isPostgreSQL() || Globals.isMySQL() ?" AS ":"") + " report_sql ORDER BY 1"); + } else { + sb.append(colExpr); + sb.append(" "); + sb.append(dct.getColId()); + if (!colExpr.equals(colName)) { + sb.append(", "); + sb.append(colName); + } // if + sb.append(" FROM "); + sb.append(dst.getTableName()); + sb.append(" "); + sb.append(dst.getTableId()); + sb.append(" ORDER BY "); + sb.append(colName); + if (dct.getColType().equals(AppConstants.CT_DATE)) + sb.append(" DESC"); + } // else + + return sb.toString(); + } // generateDistinctValuesSQL + + /** ************************************************************************************************* */ + + public DataSourceType getTableWithoutColumns() { + List dsList = getDataSourceList().getDataSource(); + for (Iterator iter = dsList.iterator(); iter.hasNext();) { + DataSourceType ds = (DataSourceType) iter.next(); + + if (ds.getDataColumnList().getDataColumn().size() == 0) + return ds; + } // for + + return null; + } // getTableWithoutColumns + + public CustomReportType cloneCustomReportClearTables() throws RaptorException { + ReportWrapper nrw = new ReportWrapper(cloneCustomReport(), reportID, getOwnerID(), + getCreateID(), getCreateDate(), getUpdateID(), getUpdateDate(), getMenuID(), + isMenuApproved()); + + DataSourceType ndst = null; + while ((ndst = nrw.getTableWithoutColumns()) != null) + nrw.deleteDataSourceType(ndst.getTableId()); + + return nrw.getCustomReport(); + } // cloneCustomReportClearTables + + public String marshal() throws RaptorException { + StringWriter sw = new StringWriter(); + ObjectFactory objFactory = new ObjectFactory(); + + try { + JAXBContext jc = JAXBContext.newInstance("org.openecomp.portalsdk.analytics.xmlobj"); + Marshaller m = jc.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + //JAXBElement jaxbElement = new JAXBElement(new QName("customReport"), Object.class, ""); + //m.marshal( System.out ); + //m.marshal(jaxbElement, new StreamResult(sw)); + m.marshal((getTableWithoutColumns() == null) ? objFactory.createCustomReport(cr) : objFactory.createCustomReport(cloneCustomReportClearTables()), + new StreamResult(sw)); + } catch (JAXBException ex) { + throw new RaptorException (ex.getMessage(), ex.getCause()); + } + return sw.toString(); + } // marshal + + public static CustomReportType unmarshalCR(String reportXML) throws RaptorException { + //CustomReport cr = null; + try { + JAXBContext jc = JAXBContext.newInstance("org.openecomp.portalsdk.analytics.xmlobj"); + Unmarshaller u = jc.createUnmarshaller(); + javax.xml.bind.JAXBElement doc = (javax.xml.bind.JAXBElement) u.unmarshal(new java.io.StringReader( + reportXML)); + return doc.getValue(); + } catch (JAXBException ex) { + ex.printStackTrace(); + throw new RaptorException (ex.getMessage(), ex.getCause()); + } + + + } // unmarshal + + protected static CustomReportType createBlankCR() throws RaptorException { + return createBlankCR("N/A"); + } // createBlank + + protected static CustomReportType createBlankCR(String createID) throws RaptorException { + ObjectFactory objFactory = new ObjectFactory(); + CustomReportType cr = objFactory.createCustomReportType(); + //CustomReport cr = null; + try { + //cr = (CustomReport) objFactory.createCustomReport(customReportType); + + cr.setReportName(""); + cr.setReportDescr(""); + cr.setChartType(""); + cr.setPublic(false); + cr.setCreateId(createID); + cr.setCreateDate(DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar())); + // cr.setReportSQL(""); + cr.setReportType(""); + cr.setPageSize(50); + + DataSourceList dataSourceList = objFactory.createDataSourceList(); + cr.setDataSourceList(dataSourceList); + } catch (DatatypeConfigurationException ex) { + throw new RaptorException (ex.getMessage(), ex.getCause()); + } + return cr; + } // createBlank + + protected void replaceCustomReportWithClone() throws RaptorException { + try { + CustomReportType clone = cloneCustomReport(); + this.cr = clone; + } catch (Exception e) { + e.printStackTrace(); + logger.debug(EELFLoggerDelegate.debugLogger, ("[SYSTEM ERROR] ReportWrapper.replaceCustomReportWithClone generated exception for report [" + + reportID + "]. Exception: " + e.getMessage())); + throw new RaptorException("[SYSTEM ERROR] ReportWrapper.replaceCustomReportWithClone generated exception for report [" + + reportID + "]. Exception: " + e.getMessage(), e.getCause()); + } + } // replaceCustomReportWithClone + + /** ************************************************************************************************* */ + + public FormatType cloneFormatType(ObjectFactory objFactory, FormatType ft) + throws JAXBException { + FormatType nft = objFactory.createFormatType(); + + nft.setLessThanValue(ft.getLessThanValue()); + nft.setExpression(ft.getExpression()); + nft.setBold(ft.isBold()); + nft.setItalic(ft.isItalic()); + nft.setUnderline(ft.isUnderline()); + if (nvl(ft.getBgColor()).length() > 0) + nft.setBgColor(ft.getBgColor()); + if (nvl(ft.getFontColor()).length() > 0) + nft.setFontColor(ft.getFontColor()); + if (nvl(ft.getFontFace()).length() > 0) + nft.setFontFace(ft.getFontFace()); + if (nvl(ft.getFontSize()).length() > 0) + nft.setFontSize(ft.getFontSize()); + if (nvl(ft.getAlignment()).length() > 0) + nft.setAlignment(ft.getAlignment()); + if (nvl(ft.getComment()).length() > 0) + nft.setComment(ft.getComment()); + + nft.setFormatId(ft.getFormatId()); + + return nft; + } // cloneFormatType + + public SemaphoreType cloneSemaphoreType(ObjectFactory objFactory, SemaphoreType st) + throws JAXBException { + SemaphoreType nst = objFactory.createSemaphoreType(); + + nst.setSemaphoreName(st.getSemaphoreName()); + nst.setSemaphoreType(st.getSemaphoreType()); + nst.setSemaphoreId(st.getSemaphoreId()); + if (nvl(st.getComment()).length() > 0) + nst.setComment(st.getComment()); + + if (st.getFormatList() != null) { + FormatList formatList = objFactory.createFormatList(); + nst.setFormatList(formatList); + + for (Iterator iter = st.getFormatList().getFormat().iterator(); iter.hasNext();) + formatList.getFormat().add( + cloneFormatType(objFactory, (FormatType) iter.next())); + } // if + + return nst; + } // cloneSemaphoreType + + public Reports cloneDashboardType(ObjectFactory objFactory, Reports rpt) + throws JAXBException { + Reports nrpt = objFactory.createReports(); + + nrpt.setReportId(rpt.getReportId()); + nrpt.setBgcolor(rpt.getBgcolor()); + return nrpt; + } // cloneDashboardType + + public Marker cloneMarkerType(ObjectFactory objFactory, Marker marker) + throws JAXBException { + Marker nMarker = objFactory.createMarker(); + nMarker.setAddressColumn(marker.getAddressColumn()); + nMarker.setDataColumn(marker.getDataColumn()); + nMarker.setDataHeader(marker.getDataHeader()); + nMarker.setMarkerColor(marker.getMarkerColor()); + return nMarker; + } // cloneDashboardType + + public ChartDrillFormfield cloneChartDrillFormfield(ObjectFactory objFactory, ChartDrillFormfield chartDrillFormfield) + throws JAXBException { + ChartDrillFormfield nChartDrillFormfield = objFactory.createChartDrillFormfield(); + nChartDrillFormfield.setFormfield(chartDrillFormfield.getFormfield()); + return nChartDrillFormfield; + } // cloneDashboardType + + public boolean isChartDrillDownContainsName(String name) { + for (Iterator iter = getChartDrillOptions().getTargetFormfield().iterator(); iter + .hasNext();) { + org.openecomp.portalsdk.analytics.xmlobj.ChartDrillFormfield cdf = (org.openecomp.portalsdk.analytics.xmlobj.ChartDrillFormfield) iter.next(); + if(cdf.getFormfield().equals(name)) { + return true; + } + } + return false; + } + public FormFieldType cloneFormFieldType(ObjectFactory objFactory, FormFieldType fft) + throws JAXBException { + FormFieldType nfft = objFactory.createFormFieldType(); + + nfft.setColId(fft.getColId()); + nfft.setFieldName(fft.getFieldName()); + nfft.setFieldType(fft.getFieldType()); + if (nvl(fft.getVisible()).length() > 0) + nfft.setVisible(fft.getVisible()); + if (nvl(fft.getValidationType()).length() > 0) + nfft.setValidationType(fft.getValidationType()); + if (nvl(fft.getMandatory()).length() > 0) + nfft.setMandatory(fft.getMandatory()); + if (nvl(fft.getDefaultValue()).length() > 0) + nfft.setDefaultValue(fft.getDefaultValue()); + nfft.setOrderBySeq(fft.getOrderBySeq()); + if (nvl(fft.getFieldSQL()).length() > 0) + nfft.setFieldSQL(fft.getFieldSQL()); + if (nvl(fft.getFieldDefaultSQL()).length() > 0) + nfft.setFieldDefaultSQL(fft.getFieldDefaultSQL()); + if(fft.getRangeStartDate()!=null) + nfft.setRangeStartDate(fft.getRangeStartDate()); + if(fft.getRangeEndDate()!=null) + nfft.setRangeEndDate(fft.getRangeEndDate()); + if(fft.getRangeStartDateSQL()!=null) + nfft.setRangeStartDateSQL(fft.getRangeStartDateSQL()); + if(fft.getRangeEndDateSQL()!=null) + nfft.setRangeEndDateSQL(fft.getRangeEndDateSQL()); + + if (nvl(fft.getComment()).length() > 0) + nfft.setComment(fft.getComment()); + + if (fft.getPredefinedValueList() != null) { + PredefinedValueList predefinedValueList = objFactory.createPredefinedValueList(); + nfft.setPredefinedValueList(predefinedValueList); + + for (Iterator iter = fft.getPredefinedValueList().getPredefinedValue().iterator(); iter + .hasNext();) + predefinedValueList.getPredefinedValue().add(new String((String) iter.next())); + } // if + if (nvl(fft.getDependsOn()).length() > 0) + nfft.setDependsOn(fft.getDependsOn()); + + nfft.setGroupFormField((fft.isGroupFormField()!=null && fft.isGroupFormField().booleanValue())?true:false); + if (nvl(fft.getMultiSelectListSize()).length() > 0) + nfft.setMultiSelectListSize(fft.getMultiSelectListSize()); + + nfft.setFieldId(fft.getFieldId()); + return nfft; + } // cloneFormFieldType + + public JavascriptItemType cloneJavascriptType(ObjectFactory objFactory, JavascriptItemType jit) + throws JAXBException { + JavascriptItemType njit = objFactory.createJavascriptItemType(); + + njit.setId(jit.getId()); + njit.setFieldId(jit.getFieldId()); + njit.setCallText(jit.getCallText()); + return njit; + } // cloneJavascriptType + + public ColFilterType cloneColFilterType(ObjectFactory objFactory, ColFilterType cft) + throws JAXBException { + ColFilterType ncft = objFactory.createColFilterType(); + + ncft.setColId(cft.getColId()); + ncft.setFilterSeq(cft.getFilterSeq()); + ncft.setJoinCondition(cft.getJoinCondition()); + if (nvl(cft.getOpenBrackets()).length() > 0) + ncft.setOpenBrackets(cft.getOpenBrackets()); + ncft.setExpression(cft.getExpression()); + if (nvl(cft.getArgType()).length() > 0) + ncft.setArgType(cft.getArgType()); + if (nvl(cft.getArgValue()).length() > 0) + ncft.setArgValue(cft.getArgValue()); + if (nvl(cft.getCloseBrackets()).length() > 0) + ncft.setCloseBrackets(cft.getCloseBrackets()); + if (nvl(cft.getComment()).length() > 0) + ncft.setComment(cft.getComment()); + + return ncft; + } // cloneColFilterType + + public DataColumnType cloneDataColumnType(ObjectFactory objFactory, DataColumnType dct) + throws JAXBException { + DataColumnType ndct = objFactory.createDataColumnType(); + + ndct.setTableId(dct.getTableId()); + ndct.setDbColName(dct.getDbColName()); + if (nvl(dct.getCrossTabValue()).length() > 0) + ndct.setCrossTabValue(dct.getCrossTabValue()); + ndct.setColName(dct.getColName()); + ndct.setDisplayName(dct.getDisplayName()); + if (dct.getDisplayWidth() > 0) + ndct.setDisplayWidth(dct.getDisplayWidth()); + if (nvl(dct.getDisplayWidthInPxls()).length()>0) + ndct.setDisplayWidthInPxls(dct.getDisplayWidthInPxls()); + if (nvl(dct.getDisplayAlignment()).length() > 0) + ndct.setDisplayAlignment(dct.getDisplayAlignment()); + if (nvl(dct.getDisplayHeaderAlignment()).length() > 0) + ndct.setDisplayHeaderAlignment(dct.getDisplayHeaderAlignment()); + ndct.setOrderSeq(dct.getOrderSeq()); + ndct.setVisible(dct.isVisible()); + ndct.setCalculated(dct.isCalculated()); + ndct.setColType(dct.getColType()); + if(dct.getColType().equals(AppConstants.CT_HYPERLINK)) { + ndct.setHyperlinkURL(dct.getHyperlinkURL()); + ndct.setHyperlinkType(dct.getHyperlinkType()); + if(dct.getHyperlinkType().equals("IMAGE")) { + ndct.setActionImg(dct.getActionImg()); + } + } + + if(dct.getIndentation()!=null) { + ndct.setIndentation(dct.getIndentation()); + } + + if (nvl(dct.getColFormat()).length() > 0) + ndct.setColFormat(dct.getColFormat()); + ndct.setGroupBreak(dct.isGroupBreak()); + ndct.setNowrap(dct.getNowrap()); + if (nvl(dct.getYAxis()).length() > 0) + ndct.setYAxis(dct.getYAxis()); + if (dct.getOrderBySeq()!=null && dct.getOrderBySeq() > 0) + ndct.setOrderBySeq(dct.getOrderBySeq()); + if (nvl(dct.getOrderByAscDesc()).length() > 0) + ndct.setOrderByAscDesc(dct.getOrderByAscDesc()); + if (nvl(dct.getDisplayTotal()).length() > 0) + ndct.setDisplayTotal(dct.getDisplayTotal()); + if (nvl(dct.getColOnChart()).length() > 0) + ndct.setColOnChart(dct.getColOnChart()); + if (dct.getChartSeq() !=null) + ndct.setChartSeq(dct.getChartSeq()); + if (nvl(dct.getChartColor()).length() > 0) + ndct.setChartColor(dct.getChartColor()); + if (nvl(dct.getChartLineType()).length() > 0) + ndct.setChartLineType(dct.getChartLineType()); + ndct.setChartSeries((dct.isChartSeries()!=null && dct.isChartSeries().booleanValue())?true:false); + ndct.setIsRangeAxisFilled((dct.isIsRangeAxisFilled()!=null && dct.isIsRangeAxisFilled().booleanValue())?true:false); + + if (dct.isCreateInNewChart()!=null) + ndct.setCreateInNewChart(dct.isCreateInNewChart()); + if (nvl(dct.getDrillDownType()).length() > 0) + ndct.setDrillDownType(dct.getDrillDownType()); + ndct.setDrillinPoPUp(dct.isDrillinPoPUp()!=null?dct.isDrillinPoPUp():false); + if (nvl(dct.getDrillDownURL()).length() > 0) + ndct.setDrillDownURL(dct.getDrillDownURL()); + if (nvl(dct.getDrillDownParams()).length() > 0) + ndct.setDrillDownParams(dct.getDrillDownParams()); + if (nvl(dct.getComment()).length() > 0) + ndct.setComment(dct.getComment()); + if (nvl(dct.getDependsOnFormField()).length() > 0) + ndct.setDependsOnFormField(dct.getDependsOnFormField()); + if (dct.getColFilterList() != null) { + ColFilterList colFilterList = objFactory.createColFilterList(); + ndct.setColFilterList(colFilterList); + + for (Iterator iter = dct.getColFilterList().getColFilter().iterator(); iter + .hasNext();) + colFilterList.getColFilter().add( + cloneColFilterType(objFactory, (ColFilterType) iter.next())); + } // if + + if (nvl(dct.getSemaphoreId()).length() > 0) + ndct.setSemaphoreId(dct.getSemaphoreId()); + if (nvl(dct.getDbColType()).length() > 0) + ndct.setDbColType(dct.getDbColType()); + else { + ndct.setDbColType(dct.getColType()); + adjustColumnType(ndct); + } + if (nvl(dct.getChartGroup()).length() > 0) + ndct.setChartGroup(dct.getChartGroup()); + + if (nvl(dct.getYAxis()).length() > 0) + ndct.setYAxis(dct.getYAxis()); + + if (nvl(dct.getDependsOnFormField()).length() > 0) + ndct.setDependsOnFormField(dct.getDependsOnFormField()); + + + + if(nvl(dct.getNowrap()).length() > 0) + ndct.setNowrap(dct.getNowrap()); + + if(dct.getIndentation()!=null) { + ndct.setIndentation(dct.getIndentation()); + } + + ndct.setEnhancedPagination((dct.isEnhancedPagination()!=null && dct.isEnhancedPagination().booleanValue())?true:false); + if(nvl(dct.getDataMiningCol()).length() > 0) + ndct.setDataMiningCol(dct.getDataMiningCol()); + + ndct.setColId(dct.getColId()); + + // ndct.setSemaphoreId(nvl(dct.getSemaphoreId())); + // if(nvl(dct.getDbColType()).length()>0) + // ndct.setDbColType(dct.getDbColType()); + return ndct; + } // cloneDataColumnType + + public DataSourceType cloneDataSourceType(ObjectFactory objFactory, DataSourceType dst) + throws JAXBException { + DataSourceType ndst = objFactory.createDataSourceType(); + + ndst.setTableName(dst.getTableName()); + ndst.setTablePK(dst.getTablePK()); + ndst.setDisplayName(dst.getDisplayName()); + if (nvl(dst.getRefTableId()).length() > 0) + ndst.setRefTableId(dst.getRefTableId()); + if (nvl(dst.getRefDefinition()).length() > 0) + ndst.setRefDefinition(dst.getRefDefinition()); + if (nvl(dst.getComment()).length() > 0) + ndst.setComment(dst.getComment()); + DataColumnList dataColumnList = objFactory.createDataColumnList(); + ndst.setDataColumnList(dataColumnList); + + for (Iterator iter = dst.getDataColumnList().getDataColumn().iterator(); iter + .hasNext();) + dataColumnList.getDataColumn().add( + cloneDataColumnType(objFactory, (DataColumnType) iter.next())); + ndst.setTableId(dst.getTableId()); + + + return ndst; + } // cloneDataSourceType + + public CustomReportType cloneCustomReport() throws RaptorException { + ObjectFactory objFactory = new ObjectFactory(); + CustomReportType ncr = objFactory.createCustomReportType(); + + //CustomReport ncr = null; + try { + //ncr = (CustomReport) objFactory.createCustomReport(customReportType); + ncr.setReportName(cr.getReportName()); + ncr.setReportDescr(cr.getReportDescr()); + if (nvl(cr.getNumDashCols()).length() > 0) + ncr.setNumDashCols(cr.getNumDashCols()); + if (nvl(cr.getDashboardLayoutHTML()).length() > 0) + ncr.setDashboardLayoutHTML(cr.getDashboardLayoutHTML()); + if (nvl(cr.getDbInfo()).length() > 0) + ncr.setDbInfo(cr.getDbInfo()); + ncr.setChartType(cr.getChartType()); + if (nvl(cr.getChartTypeFixed()).length() > 0) + ncr.setChartTypeFixed(cr.getChartTypeFixed()); + if (nvl(cr.getChartMultiSeries()).length() > 0) + ncr.setChartMultiSeries(cr.getChartMultiSeries()); + if (nvl(cr.getChartLeftAxisLabel()).length() > 0) + ncr.setChartLeftAxisLabel(cr.getChartLeftAxisLabel()); + if (nvl(cr.getChartRightAxisLabel()).length() > 0) + ncr.setChartRightAxisLabel(cr.getChartRightAxisLabel()); + if (nvl(cr.getChartWidth()).length() > 0) + ncr.setChartWidth(cr.getChartWidth()); + if (nvl(cr.getChartHeight()).length() > 0) + ncr.setChartHeight(cr.getChartHeight()); + ncr.setShowChartTitle(cr.isShowChartTitle()); + ncr.setPublic(cr.isPublic()); + ncr.setHideFormFieldAfterRun(cr.isHideFormFieldAfterRun()); + ncr.setCreateId(cr.getCreateId()); + ncr.setCreateDate(cr.getCreateDate()); + if (nvl(cr.getReportSQL()).length() > 0) + ncr.setReportSQL(cr.getReportSQL()); + if (nvl(cr.getReportTitle()).length() > 0) + ncr.setReportTitle(cr.getReportTitle()); + if (nvl(cr.getReportSubTitle()).length() > 0) + ncr.setReportSubTitle(cr.getReportSubTitle()); + if (nvl(cr.getReportHeader()).length() > 0) + ncr.setReportHeader(cr.getReportHeader()); + if (cr.getFrozenColumns()!=null) + ncr.setFrozenColumns(cr.getFrozenColumns()); + if (nvl(cr.getPdfImgLogo()).length()>0) + ncr.setPdfImgLogo(cr.getPdfImgLogo()); + if (nvl(cr.getEmptyMessage()).length()>0) + ncr.setEmptyMessage(cr.getEmptyMessage()); + if (nvl(cr.getWidthNoColumn()).length()>0) + ncr.setWidthNoColumn(cr.getWidthNoColumn()); + if (nvl(cr.getDataGridAlign()).length()>0) + ncr.setDataGridAlign(cr.getDataGridAlign()); + + if (nvl(cr.getReportFooter()).length() > 0) + ncr.setReportFooter(cr.getReportFooter()); + if (nvl(cr.getNumFormCols()).length() > 0) + ncr.setNumFormCols(cr.getNumFormCols()); + if (nvl(cr.getDisplayOptions()).length() > 0) + ncr.setDisplayOptions(cr.getDisplayOptions()); + if (nvl(cr.getDataContainerHeight()).length() > 0) + ncr.setDataContainerHeight(cr.getDataContainerHeight()); + if (nvl(cr.getDataContainerWidth()).length() > 0) + ncr.setDataContainerWidth(cr.getDataContainerWidth()); + if (nvl(cr.getAllowSchedule()).length() > 0) + ncr.setAllowSchedule(cr.getAllowSchedule()); + if (nvl(cr.getTopDown()).length() > 0) + ncr.setTopDown(cr.getTopDown()); + if (nvl(cr.getSizedByContent()).length() > 0) + ncr.setSizedByContent(cr.getSizedByContent()); + if (nvl(cr.getComment()).length() > 0) + ncr.setComment(cr.getComment()); + if (nvl(cr.getDashboardOptions()).length()>0) + ncr.setDashboardOptions(cr.getDashboardOptions()); + + if(cr.isDashboardType()!=null) + ncr.setDashboardType(cr.isDashboardType()); + if(cr.isReportInNewWindow()!=null) + ncr.setReportInNewWindow(cr.isReportInNewWindow()); + ncr.setDisplayFolderTree(cr.isDisplayFolderTree()); + if (cr.getDashBoardReports() == null) { + if (cr.getMaxRowsInExcelDownload()!=null && cr.getMaxRowsInExcelDownload()>0) + ncr.setMaxRowsInExcelDownload(cr.getMaxRowsInExcelDownload()); + } + + if (nvl(cr.getJavascriptElement()).length()>0) + ncr.setJavascriptElement(cr.getJavascriptElement()); + if (nvl(cr.getFolderId()).length()>0) + ncr.setFolderId(cr.getFolderId()); + ncr.setDrillURLInPoPUpPresent((cr.isDrillURLInPoPUpPresent()!=null && cr.isDrillURLInPoPUpPresent().booleanValue())?true:false); + + if (nvl(cr.getIsOneTimeScheduleAllowed()).length()>0) + ncr.setIsOneTimeScheduleAllowed(cr.getIsOneTimeScheduleAllowed()); + if (nvl(cr.getIsHourlyScheduleAllowed()).length()>0) + ncr.setIsHourlyScheduleAllowed(cr.getIsHourlyScheduleAllowed()); + if (nvl(cr.getIsDailyScheduleAllowed()).length()>0) + ncr.setIsDailyScheduleAllowed(cr.getIsDailyScheduleAllowed()); + if (nvl(cr.getIsDailyMFScheduleAllowed()).length()>0) + ncr.setIsDailyMFScheduleAllowed(cr.getIsDailyMFScheduleAllowed()); + if (nvl(cr.getIsWeeklyScheduleAllowed()).length()>0) + ncr.setIsWeeklyScheduleAllowed(cr.getIsWeeklyScheduleAllowed()); + if (nvl(cr.getIsMonthlyScheduleAllowed()).length()>0) + ncr.setIsMonthlyScheduleAllowed(cr.getIsMonthlyScheduleAllowed()); + + ncr.setPageSize(cr.getPageSize()); + ncr.setReportType(cr.getReportType()); + + + DataSourceList dataSourceList = objFactory.createDataSourceList(); + ncr.setDataSourceList(dataSourceList); + + for (Iterator iter = cr.getDataSourceList().getDataSource().iterator(); iter.hasNext();) { + dataSourceList.getDataSource().add( + cloneDataSourceType(objFactory, (DataSourceType) iter.next())); + } + + if (cr.getFormFieldList() != null) { + FormFieldList formFieldList = objFactory.createFormFieldList(); + ncr.setFormFieldList(formFieldList); + ncr.getFormFieldList().setComment(formFieldList.getComment()); + + for (Iterator iter = cr.getFormFieldList().getFormField().iterator(); iter + .hasNext();) + formFieldList.getFormField().add( + cloneFormFieldType(objFactory, (FormFieldType) iter.next())); + formFieldList.setComment(cr.getFormFieldList().getComment()); + } // if + + if (cr.getJavascriptList() != null) { + JavascriptList javascriptList = objFactory.createJavascriptList(); + ncr.setJavascriptList(javascriptList); + + for (Iterator iter = cr.getJavascriptList().getJavascriptItem().iterator(); iter + .hasNext();) + javascriptList.getJavascriptItem().add( + cloneJavascriptType(objFactory, (JavascriptItemType) iter.next())); + } // if + + if (cr.getSemaphoreList() != null) { + SemaphoreList semaphoreList = objFactory.createSemaphoreList(); + ncr.setSemaphoreList(semaphoreList); + + for (Iterator iter = cr.getSemaphoreList().getSemaphore().iterator(); iter + .hasNext();) { + semaphoreList.getSemaphore().add( + cloneSemaphoreType(objFactory, (SemaphoreType) iter.next())); + } + } // if + + if (nvl(cr.getDashboardOptions()).length()>0) + ncr.setDashboardOptions(cr.getDashboardOptions()); + if(cr.isDashboardType()!=null) + ncr.setDashboardType(cr.isDashboardType()); + if(cr.isReportInNewWindow()!=null) + ncr.setReportInNewWindow(cr.isReportInNewWindow()); + ncr.setDisplayFolderTree(cr.isDisplayFolderTree()); + if (cr.getDashBoardReports() == null) { + if (cr.getMaxRowsInExcelDownload()!=null && cr.getMaxRowsInExcelDownload()>0) + ncr.setMaxRowsInExcelDownload(cr.getMaxRowsInExcelDownload()); + } + + if (cr.getDashBoardReports() != null) { + DashboardReports dashboardReports = objFactory.createDashboardReports(); + ncr.setDashBoardReports(dashboardReports); + + for (Iterator iter = cr.getDashBoardReports().getReportsList().iterator(); iter + .hasNext();) { + dashboardReports.getReportsList().add( + cloneDashboardType(objFactory, (Reports) iter.next())); + } + } // if + + if (cr.getChartAdditionalOptions() != null) { + ChartAdditionalOptions chartAdditionalOptions = objFactory.createChartAdditionalOptions(); + if(nvl(cr.getChartAdditionalOptions().getChartMultiplePieOrder()).length()>0) + chartAdditionalOptions.setChartMultiplePieOrder(cr.getChartAdditionalOptions().getChartMultiplePieOrder()); + if(nvl(cr.getChartAdditionalOptions().getChartMultiplePieLabelDisplay()).length()>0) + chartAdditionalOptions.setChartMultiplePieLabelDisplay(cr.getChartAdditionalOptions().getChartMultiplePieLabelDisplay()); + + if(nvl(cr.getChartAdditionalOptions().getChartOrientation()).length()>0) + chartAdditionalOptions.setChartOrientation(cr.getChartAdditionalOptions().getChartOrientation()); + if(nvl(cr.getChartAdditionalOptions().getSecondaryChartRenderer()).length()>0) + chartAdditionalOptions.setSecondaryChartRenderer(cr.getChartAdditionalOptions().getSecondaryChartRenderer()); + + if(nvl(cr.getChartAdditionalOptions().getChartDisplay()).length()>0) + chartAdditionalOptions.setChartDisplay(cr.getChartAdditionalOptions().getChartDisplay()); + if(nvl(cr.getChartAdditionalOptions().getHideToolTips()).length()>0) + chartAdditionalOptions.setHideToolTips(cr.getChartAdditionalOptions().getHideToolTips()); + if(nvl(cr.getChartAdditionalOptions().getHidechartLegend()).length()>0) + chartAdditionalOptions.setHidechartLegend(cr.getChartAdditionalOptions().getHidechartLegend()); + if(nvl(cr.getChartAdditionalOptions().getLegendPosition()).length()>0) + chartAdditionalOptions.setLegendPosition(cr.getChartAdditionalOptions().getLegendPosition()); + if(nvl(cr.getChartAdditionalOptions().getLabelAngle()).length()>0) + chartAdditionalOptions.setLabelAngle(cr.getChartAdditionalOptions().getLabelAngle()); + + if(nvl(cr.getChartAdditionalOptions().getIntervalFromdate()).length()>0) + chartAdditionalOptions.setIntervalFromdate(cr.getChartAdditionalOptions().getIntervalFromdate()); + if(nvl(cr.getChartAdditionalOptions().getIntervalTodate()).length()>0) + chartAdditionalOptions.setIntervalTodate(cr.getChartAdditionalOptions().getIntervalTodate()); + if(nvl(cr.getChartAdditionalOptions().getIntervalLabel()).length()>0) + chartAdditionalOptions.setIntervalLabel(cr.getChartAdditionalOptions().getIntervalLabel()); + + if(nvl(cr.getChartAdditionalOptions().getLastSeriesALineChart()).length()>0) + chartAdditionalOptions.setLastSeriesALineChart(cr.getChartAdditionalOptions().getLastSeriesALineChart()); + if(nvl(cr.getChartAdditionalOptions().getLastSeriesABarChart()).length()>0) + chartAdditionalOptions.setLastSeriesABarChart(cr.getChartAdditionalOptions().getLastSeriesABarChart()); + + if(nvl(cr.getChartAdditionalOptions().getMaxLabelsInDomainAxis()).length()>0) + chartAdditionalOptions.setMaxLabelsInDomainAxis(cr.getChartAdditionalOptions().getMaxLabelsInDomainAxis()); + if(nvl(cr.getChartAdditionalOptions().getLinearRegression()).length()>0) + chartAdditionalOptions.setLinearRegression(cr.getChartAdditionalOptions().getLinearRegression()); + if(nvl(cr.getChartAdditionalOptions().getLinearRegressionColor()).length()>0) + chartAdditionalOptions.setLinearRegressionColor(cr.getChartAdditionalOptions().getLinearRegressionColor()); + if(nvl(cr.getChartAdditionalOptions().getExponentialRegressionColor()).length()>0) + chartAdditionalOptions.setExponentialRegressionColor(cr.getChartAdditionalOptions().getExponentialRegressionColor()); + if(nvl(cr.getChartAdditionalOptions().getMaxRegression()).length()>0) + chartAdditionalOptions.setMaxRegression(cr.getChartAdditionalOptions().getMaxRegression()); + if(nvl(cr.getChartAdditionalOptions().getRangeAxisUpperLimit()).length()>0) + chartAdditionalOptions.setRangeAxisUpperLimit(cr.getChartAdditionalOptions().getRangeAxisUpperLimit()); + if(nvl(cr.getChartAdditionalOptions().getRangeAxisLowerLimit()).length()>0) + chartAdditionalOptions.setRangeAxisLowerLimit(cr.getChartAdditionalOptions().getRangeAxisLowerLimit()); + if(nvl(cr.getChartAdditionalOptions().getOverlayItemValueOnStackBar()).length()>0) + chartAdditionalOptions.setOverlayItemValueOnStackBar(cr.getChartAdditionalOptions().getOverlayItemValueOnStackBar()); + chartAdditionalOptions.setAnimate((cr.getChartAdditionalOptions().isAnimate()!=null && cr.getChartAdditionalOptions().isAnimate().booleanValue())?true:false); + + if(nvl(cr.getChartAdditionalOptions().getKeepDomainAxisValueAsString()).length()>0) + chartAdditionalOptions.setKeepDomainAxisValueAsString(cr.getChartAdditionalOptions().getKeepDomainAxisValueAsString()); + + + // Animate + chartAdditionalOptions.setAnimateAnimatedChart((cr.getChartAdditionalOptions().isAnimateAnimatedChart()!=null && cr.getChartAdditionalOptions().isAnimateAnimatedChart().booleanValue())?true:false); + chartAdditionalOptions.setStacked((cr.getChartAdditionalOptions().isStacked()!=null && cr.getChartAdditionalOptions().isStacked().booleanValue())?true:false); + chartAdditionalOptions.setBarControls((cr.getChartAdditionalOptions().isBarControls()!=null && cr.getChartAdditionalOptions().isBarControls().booleanValue())?true:false); + chartAdditionalOptions.setXAxisDateType((cr.getChartAdditionalOptions().isXAxisDateType()!=null && cr.getChartAdditionalOptions().isXAxisDateType().booleanValue())?true:false); + chartAdditionalOptions.setLessXaxisTickers((cr.getChartAdditionalOptions().isLessXaxisTickers()!=null && cr.getChartAdditionalOptions().isLessXaxisTickers().booleanValue())?true:false); + chartAdditionalOptions.setTimeAxis((cr.getChartAdditionalOptions().isTimeAxis()!=null && cr.getChartAdditionalOptions().isTimeAxis().booleanValue())?true:false); + + if(nvl(cr.getChartAdditionalOptions().getTimeSeriesRender()).length()>0) + chartAdditionalOptions.setTimeSeriesRender(cr.getChartAdditionalOptions().getTimeSeriesRender()); + + chartAdditionalOptions.setMultiSeries((cr.getChartAdditionalOptions().isMultiSeries()!=null && cr.getChartAdditionalOptions().isMultiSeries().booleanValue())?true:false); + + chartAdditionalOptions.setTopMargin(cr.getChartAdditionalOptions().getTopMargin()!=null?cr.getChartAdditionalOptions().getTopMargin():new Integer(30)); + chartAdditionalOptions.setBottomMargin(cr.getChartAdditionalOptions().getBottomMargin()!=null?cr.getChartAdditionalOptions().getBottomMargin():new Integer(50)); + chartAdditionalOptions.setLeftMargin(cr.getChartAdditionalOptions().getLeftMargin()!=null?cr.getChartAdditionalOptions().getLeftMargin():new Integer(100)); + chartAdditionalOptions.setRightMargin(cr.getChartAdditionalOptions().getRightMargin()!=null?cr.getChartAdditionalOptions().getRightMargin():new Integer(60)); + + + ncr.setChartAdditionalOptions(chartAdditionalOptions); + } // if + + if (nvl(cr.getJavascriptElement()).length()>0) + ncr.setJavascriptElement(cr.getJavascriptElement()); + if (nvl(cr.getFolderId()).length()>0) + ncr.setFolderId(cr.getFolderId()); + + if (cr.getChartDrillOptions() != null) { + ChartDrillOptions chartDrillOptions = objFactory.createChartDrillOptions(); + + if(nvl(cr.getChartDrillOptions().getDrillReportId()).length()>0) + chartDrillOptions.setDrillReportId(cr.getChartDrillOptions().getDrillReportId()); + + for (Iterator iter = cr.getChartDrillOptions().getTargetFormfield().iterator(); iter + .hasNext();) { + chartDrillOptions.getTargetFormfield().add( + cloneChartDrillFormfield(objFactory, (ChartDrillFormfield)iter.next())); + + } + + if(nvl(cr.getChartDrillOptions().getDrillXAxisFormField()).length()>0) + chartDrillOptions.setDrillXAxisFormField(cr.getChartDrillOptions().getDrillXAxisFormField()); + if(nvl(cr.getChartDrillOptions().getDrillYAxisFormField()).length()>0) + chartDrillOptions.setDrillYAxisFormField(cr.getChartDrillOptions().getDrillYAxisFormField()); + if(nvl(cr.getChartDrillOptions().getDrillSeriesFormField()).length()>0) + chartDrillOptions.setDrillSeriesFormField(cr.getChartDrillOptions().getDrillSeriesFormField()); + + + ncr.setChartDrillOptions(chartDrillOptions); + } + + if (nvl(cr.getIsOneTimeScheduleAllowed()).length()>0) + ncr.setIsOneTimeScheduleAllowed(cr.getIsOneTimeScheduleAllowed()); + if (nvl(cr.getIsHourlyScheduleAllowed()).length()>0) + ncr.setIsHourlyScheduleAllowed(cr.getIsHourlyScheduleAllowed()); + if (nvl(cr.getIsDailyScheduleAllowed()).length()>0) + ncr.setIsDailyScheduleAllowed(cr.getIsDailyScheduleAllowed()); + if (nvl(cr.getIsDailyMFScheduleAllowed()).length()>0) + ncr.setIsDailyMFScheduleAllowed(cr.getIsDailyMFScheduleAllowed()); + if (nvl(cr.getIsWeeklyScheduleAllowed()).length()>0) + ncr.setIsWeeklyScheduleAllowed(cr.getIsWeeklyScheduleAllowed()); + if (nvl(cr.getIsMonthlyScheduleAllowed()).length()>0) + ncr.setIsMonthlyScheduleAllowed(cr.getIsMonthlyScheduleAllowed()); + + ncr.setPageSize(cr.getPageSize()); + ncr.setReportType(cr.getReportType()); + + if (cr.getReportMap() != null){ + ReportMap repMap = objFactory.createReportMap(); + if(nvl(cr.getReportMap().getMarkerColor()).length()>0) + repMap.setMarkerColor(cr.getReportMap().getMarkerColor()); + if(nvl(cr.getReportMap().getUseDefaultSize()).length()>0) + repMap.setUseDefaultSize(cr.getReportMap().getUseDefaultSize()); + if(nvl(cr.getReportMap().getHeight()).length()>0) + repMap.setHeight(cr.getReportMap().getHeight()); + if(nvl(cr.getReportMap().getWidth()).length()>0) + repMap.setWidth(cr.getReportMap().getWidth()); + if(nvl(cr.getReportMap().getIsMapAllowedYN()).length()>0) + repMap.setIsMapAllowedYN(cr.getReportMap().getIsMapAllowedYN()); + if(nvl(cr.getReportMap().getAddAddressInDataYN()).length()>0) + repMap.setAddAddressInDataYN(cr.getReportMap().getAddAddressInDataYN()); + if(nvl(cr.getReportMap().getAddressColumn()).length()>0) + repMap.setAddressColumn(cr.getReportMap().getAddressColumn()); + if(nvl(cr.getReportMap().getDataColumn()).length()>0) + repMap.setDataColumn(cr.getReportMap().getDataColumn()); + if(nvl(cr.getReportMap().getDefaultMapType()).length()>0) + repMap.setDefaultMapType(cr.getReportMap().getDefaultMapType()); + if(nvl(cr.getReportMap().getLatColumn()).length()>0) + repMap.setLatColumn(cr.getReportMap().getLatColumn()); + if(nvl(cr.getReportMap().getLongColumn()).length()>0) + repMap.setLongColumn(cr.getReportMap().getLongColumn()); + if(nvl(cr.getReportMap().getColorColumn()).length()>0) + repMap.setColorColumn(cr.getReportMap().getColorColumn()); + if(nvl(cr.getReportMap().getLegendColumn()).length()>0) + repMap.setLegendColumn(cr.getReportMap().getLegendColumn()); + + + for (Iterator iter = cr.getReportMap().getMarkers().iterator(); iter + .hasNext();) { + repMap.getMarkers().add( + cloneMarkerType(objFactory, (Marker)iter.next())); + + } + + ncr.setReportMap(repMap); + } + + + + } catch (JAXBException ex) { // try + throw new RaptorException(ex.getMessage(), ex.getCause()); + } + + return ncr; + } // cloneCustomReport + + /** ************************************************************************************************* */ + + public void printFormatType(FormatType ft) { + System.out.println("------------------------------------------------"); + System.out.println("Semaphore Col Format"); + System.out.println("------------------------------------------------"); + System.out.println("FormatId: [" + ft.getFormatId() + "]"); + System.out.println("LessThanValue: [" + ft.getLessThanValue() + "]"); + System.out.println("Expression: [" + ft.getExpression() + "]"); + System.out.println("Bold: [" + ft.isBold() + "]"); + System.out.println("Italic: [" + ft.isItalic() + "]"); + System.out.println("Underline: [" + ft.isUnderline() + "]"); + System.out.println("BgColor: [" + ft.getBgColor() + "]"); + System.out.println("FontColor: [" + ft.getFontColor() + "]"); + System.out.println("FontFace: [" + ft.getFontFace() + "]"); + System.out.println("FontSize: [" + ft.getFontSize() + "]"); + System.out.println("Alignment: [" + ft.getAlignment() + "]"); + System.out.println("Comment: [" + ft.getComment() + "]"); + System.out.println("------------------------------------------------"); + } // printFormatType + + public void printSemaphoreType(SemaphoreType st) { + System.out.println("------------------------------------------------"); + System.out.println("Semaphore"); + System.out.println("------------------------------------------------"); + System.out.println("SemaphoreId: [" + st.getSemaphoreId() + "]"); + System.out.println("SemaphoreName: [" + st.getSemaphoreName() + "]"); + System.out.println("SemaphoreType: [" + st.getSemaphoreType() + "]"); + System.out.println("Comment: [" + st.getComment() + "]"); + + if (st.getFormatList() != null) + for (Iterator iter = st.getFormatList().getFormat().iterator(); iter.hasNext();) + printFormatType((FormatType) iter.next()); + + System.out.println("------------------------------------------------"); + } // printSemaphoreType + + public void printFormFieldType(FormFieldType fft) { + System.out.println("------------------------------------------------"); + System.out.println("Form Field"); + System.out.println("------------------------------------------------"); + System.out.println("FieldId: [" + fft.getFieldId() + "]"); + System.out.println("ColId: [" + fft.getColId() + "]"); + System.out.println("FieldName: [" + fft.getFieldName() + "]"); + System.out.println("FieldType: [" + fft.getFieldType() + "]"); + System.out.println("ValidationType: [" + fft.getValidationType() + "]"); + System.out.println("Mandatory: [" + fft.getMandatory() + "]"); + System.out.println("DefaultValue: [" + fft.getDefaultValue() + "]"); + System.out.println("OrderBySeq: [" + fft.getOrderBySeq() + "]"); + System.out.println("FieldSQL: [" + fft.getFieldSQL() + "]"); + System.out.println("Comment: [" + fft.getComment() + "]"); + if (fft.getPredefinedValueList() != null) + for (Iterator iter = fft.getPredefinedValueList().getPredefinedValue().iterator(); iter + .hasNext();) + System.out.println("PredefinedValues: [" + ((String) iter.next()) + "]"); + + System.out.println("------------------------------------------------"); + } // printFormFieldType + + public void printColFilterType(ColFilterType cft) { + System.out.println("------------------------------------------------"); + System.out.println("Col Filter"); + System.out.println("------------------------------------------------"); + System.out.println("ColId: [" + cft.getColId() + "]"); + System.out.println("FilterSeq: [" + cft.getFilterSeq() + "]"); + System.out.println("JoinCondition: [" + cft.getJoinCondition() + "]"); + System.out.println("OpenBrackets: [" + cft.getOpenBrackets() + "]"); + System.out.println("Expression: [" + cft.getExpression() + "]"); + System.out.println("ArgType: [" + cft.getArgType() + "]"); + System.out.println("ArgValue: [" + cft.getArgValue() + "]"); + System.out.println("CloseBrackets: [" + cft.getCloseBrackets() + "]"); + System.out.println("Comment: [" + cft.getComment() + "]"); + System.out.println("------------------------------------------------"); + } // printColFilterType + + public void printDataColumnType(DataColumnType dct) { + System.out.println("------------------------------------------------"); + System.out.println("Data Column"); + System.out.println("------------------------------------------------"); + System.out.println("ColId: [" + dct.getColId() + "]"); + System.out.println("TableId: [" + dct.getTableId() + "]"); + System.out.println("DbColName: [" + dct.getDbColName() + "]"); + System.out.println("CrossTabValue: [" + dct.getCrossTabValue() + "]"); + System.out.println("ColName: [" + dct.getColName() + "]"); + System.out.println("DisplayName: [" + dct.getDisplayName() + "]"); + System.out.println("DisplayWidth: [" + dct.getDisplayWidth() + "]"); + System.out.println("DisplayAlignment: [" + dct.getDisplayAlignment() + "]"); + System.out.println("DisplayHeaderAlignment: [" + dct.getDisplayHeaderAlignment() + "]"); + System.out.println("OrderSeq(): [" + dct.getOrderSeq() + "]"); + System.out.println("Visible: [" + dct.isVisible() + "]"); + System.out.println("Calculated: [" + dct.isCalculated() + "]"); + System.out.println("ColType: [" + dct.getColType() + "]"); + System.out.println("ColFormat: [" + dct.getColFormat() + "]"); + System.out.println("GroupBreak: [" + dct.isGroupBreak() + "]"); + System.out.println("OrderBySeq: [" + dct.getOrderBySeq() + "]"); + System.out.println("OrderByAscDesc: [" + dct.getOrderByAscDesc() + "]"); + System.out.println("DisplayTotal: [" + dct.getDisplayTotal() + "]"); + System.out.println("ColOnChart: [" + dct.getColOnChart() + "]"); + System.out.println("ChartSeq: [" + dct.getChartSeq() + "]"); + System.out.println("ChartColor: [" + dct.getChartColor() + "]"); + System.out.println("DrillDownType: [" + dct.getDrillDownType() + "]"); + System.out.println("DrillDownURL: [" + dct.getDrillDownURL() + "]"); + System.out.println("DrillDownParams: [" + dct.getDrillDownParams() + "]"); + System.out.println("Comment: [" + dct.getComment() + "]"); + + if (dct.getColFilterList() != null) + for (Iterator iter = dct.getColFilterList().getColFilter().iterator(); iter + .hasNext();) + printColFilterType((ColFilterType) iter.next()); + + System.out.println("SemaphoreId: [" + dct.getSemaphoreId() + "]"); + System.out.println("DbColType: [" + dct.getDbColType() + "]"); + System.out.println("------------------------------------------------"); + } // printDataColumnType + + public void printDataSourceType(DataSourceType dst) { + System.out.println("------------------------------------------------"); + System.out.println("Data Source"); + System.out.println("------------------------------------------------"); + System.out.println("TableId: [" + dst.getTableId() + "]"); + System.out.println("TableName: [" + dst.getTableName() + "]"); + System.out.println("TablePK: [" + dst.getTablePK() + "]"); + System.out.println("DisplayName: [" + dst.getDisplayName() + "]"); + System.out.println("RefTableId: [" + dst.getRefTableId() + "]"); + System.out.println("RefDefinition: [" + dst.getRefDefinition() + "]"); + System.out.println("Comment: [" + dst.getComment() + "]"); + + for (Iterator iter = dst.getDataColumnList().getDataColumn().iterator(); iter + .hasNext();) + printDataColumnType((DataColumnType) iter.next()); + + System.out.println("------------------------------------------------"); + } // printDataSourceType + + public void print() { + System.out.println("------------------------------------------------"); + System.out.println("ReportWrapper object"); + System.out.println("------------------------------------------------"); + System.out.println("PageSize: [" + getPageSize() + "]"); + System.out.println("ReportType: [" + getReportType() + "]"); + System.out.println("ReportName: [" + getReportName() + "]"); + System.out.println("ReportDescr: [" + getReportDescr() + "]"); + System.out.println("ChartType: [" + getChartType() + "]"); + System.out.println("ChartTypeFixed: [" + getChartTypeFixed() + "]"); + //System.out.println("ChartLeftAxisLabel: [" + getChartLeftAxisLabel() + "]"); + //System.out.println("ChartRightAxisLabel: [" + getChartRightAxisLabel() + "]"); + System.out.println("ChartWidth: [" + getChartWidth() + "]"); + System.out.println("ChartHeight: [" + getChartHeight() + "]"); + System.out.println("Public: [" + isPublic() + "]"); + System.out.println("CreateId: NOT USED ANYMORE[" + /* getCreateId()+ */"]"); + System.out.println("CreateDate: NOT USED ANYMORE[" + /* getCreateDate()+ */"]"); + System.out.println("ReportSQL: [" + getReportSQL() + "]"); + System.out.println("ReportTitle: [" + getReportTitle() + "]"); + System.out.println("DbInfo: [" + getDBInfo() + "]"); + System.out.println("ReportSubTitle: [" + getReportSubTitle() + "]"); + System.out.println("ReportHeader: [" + getReportHeader() + "]"); + System.out.println("ReportFooter: [" + getReportFooter() + "]"); + System.out.println("NumFormCols: [" + getNumFormCols() + "]"); + System.out.println("DisplayOptions: [" + getDisplayOptions() + "]"); + System.out.println("Comment: [" + getComment() + "]"); + + for (Iterator iter = cr.getDataSourceList().getDataSource().iterator(); iter.hasNext();) + printDataSourceType((DataSourceType) iter.next()); + + if (cr.getFormFieldList() != null) + for (Iterator iter = cr.getFormFieldList().getFormField().iterator(); iter + .hasNext();) + printFormFieldType((FormFieldType) iter.next()); + + if (cr.getSemaphoreList() != null) + for (Iterator iter = cr.getSemaphoreList().getSemaphore().iterator(); iter + .hasNext();) + printSemaphoreType((SemaphoreType) iter.next()); + + System.out.println("------------------------------------------------"); + System.out.println("ReportWrapper object end"); + System.out.println("------------------------------------------------"); + } // print + + private int getIntValue(String value, int defaultValue) { + int iValue = defaultValue; + try { + iValue = Integer.parseInt(value); + } catch (Exception e) { + } + + return iValue; + } // getIntValue + public static String replaceNewLine( String strSource, String strFind, String chrReplace ) + { + // buffer to hold the target string after replacement is done. + StringBuffer sbfTemp = new StringBuffer(); + + try + { + // for each occurrence of strFind in strSource, replace it with chrReplace. + int intIndex = strSource.indexOf( strFind, 0 ); + + // check if there is any instace of strFind in strSource + if( intIndex >= 0 ) + { + // holds the index from where the search is supposed to happen. + int intStart = 0; + + // size of the source string + int intTotalSize = strSource.length(); + + while( intStart < intTotalSize && + ( ( intIndex = strSource.indexOf( strFind, intStart ) ) >= 0 ) ) + { + // check if strFind is at the beginning... i.e., at index intStart + if( intIndex == intStart ) + { + /* + * starts with strFind...just append chrReplace + * to the target + */ + sbfTemp.append( chrReplace ); + } + else + { + // append the sub-string...plus chrReplace + sbfTemp.append( strSource.substring( intStart, intIndex ) ); + sbfTemp.append( chrReplace ); + } + + // advance string index + intStart = intIndex + strFind.length(); + } + + // append the last portion of the source string. + sbfTemp.append( strSource.substring( intStart ) ); + } + else + { + // strFind not found... just copy the text as it is. + sbfTemp.append( strSource ); + } + } + catch( Exception expGeneral ) + { + // in case of any exception, return the source string as it is. + sbfTemp = new StringBuffer( strSource ); + } + + return sbfTemp.toString(); + } + + /*folder id*/ + public String getFolderId() { + return nvl(cr.getFolderId()).length()>0?cr.getFolderId():"NULL"; + } + public void setFolderId(String folderId ) { + cr.setFolderId(folderId); + } + + public String addZero(String num) { + int numInt = 0; + try { + numInt = Integer.parseInt(num); + }catch(NumberFormatException ex){ + numInt = 0; + } + if(numInt < 10) return "0"+numInt; + else return ""+numInt; + } + + public String getIsDailyMFScheduleAllowed() { + return cr.getIsDailyMFScheduleAllowed(); + } + + public void setIsDailyMFScheduleAllowed(String isDailyMFScheduleAllowed) { + cr.setIsDailyMFScheduleAllowed(isDailyMFScheduleAllowed); + } + + public String getIsDailyScheduleAllowed() { + return cr.getIsDailyScheduleAllowed(); + } + + public void setIsDailyScheduleAllowed(String isDailyScheduleAllowed) { + cr.setIsDailyScheduleAllowed(isDailyScheduleAllowed); + } + + public String getIsHourlyScheduleAllowed() { + return cr.getIsHourlyScheduleAllowed(); + } + + public void setIsHourlyScheduleAllowed(String isHourlyScheduleAllowed) { + cr.setIsHourlyScheduleAllowed(isHourlyScheduleAllowed); + } + + public String getIsMonthlyScheduleAllowed() { + return cr.getIsMonthlyScheduleAllowed(); + } + + public void setIsMonthlyScheduleAllowed(String isMonthlyScheduleAllowed) { + cr.setIsMonthlyScheduleAllowed(isMonthlyScheduleAllowed); + } + + public String getIsOneTimeScheduleAllowed() { + return cr.getIsOneTimeScheduleAllowed(); + } + + public void setIsOneTimeScheduleAllowed(String isOneTimeScheduleAllowed) { + cr.setIsOneTimeScheduleAllowed(isOneTimeScheduleAllowed); + } + + public String getIsWeeklyScheduleAllowed() { + return cr.getIsWeeklyScheduleAllowed(); + } + + public void setIsWeeklyScheduleAllowed(String isWeeklyScheduleAllowed) { + cr.setIsWeeklyScheduleAllowed(isWeeklyScheduleAllowed); + + } + + public static boolean isNull(String a) { + if ((a == null) || (a.length() == 0) || a.equalsIgnoreCase("null")) + return true; + else + return false; + } + + public int getDependsOnFormFieldFlag(DataColumnType dc, HashMap formValues) { + int flag = 0; + String fieldValue = ""; + if(nvl(dc.getDependsOnFormField()).length()>0 && nvl(dc.getDependsOnFormField()).indexOf("[")!=-1) { + if(formValues != null) { + Set set = formValues.entrySet(); + String value = ""; + for(Iterator iter1 = set.iterator(); iter1.hasNext(); ) { + Map.Entry entry = (Entry) iter1.next(); + value = (String) entry.getValue(); + if (dc.getDependsOnFormField().equals("["+entry.getKey()+"]")) { + fieldValue = nvl(value); + + if (fieldValue.length()>0 && !fieldValue.equals("NULL")) { + flag = 0; + } else { + flag = 1; + } + + } + } + } + } + + return flag; + } + + /* Datamining Getter Setter */ + + public String getClassifier() { + return (cr.getDataminingOptions()!=null?cr.getDataminingOptions().getClassifier():""); + } + + public void setClassifier( String classifier) { + cr.getDataminingOptions().setClassifier(classifier); + } + + + public int getForecastingPeriod() { + return (cr.getDataminingOptions()!=null? new Integer(cr.getDataminingOptions().getForecastingUnits()).intValue():-1); + } + + public void setForecastingPeriod( String period) { + cr.getDataminingOptions().setForecastingUnits(period); + } + + public String getForecastingTimeFormat() { + return (cr.getDataminingOptions()!=null?cr.getDataminingOptions().getTimeformat():""); + } + + public void setForecastingTimeFormat( String format) { + cr.getDataminingOptions().setTimeformat(format); + } + + /** + * Get Number of Columns to Frozen in Data Grid + */ + + public int getFrozenColumns() { + return cr.getFrozenColumns()==null?0:cr.getFrozenColumns(); + } + + public String getFrozenColumnId() { + int noOfColumns = cr.getFrozenColumns()==null?0:cr.getFrozenColumns(); + if(noOfColumns != 0) { + List reportCols = getOnlyVisibleColumns(); + int colIdx = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + ++colIdx; + DataColumnType dc = (DataColumnType) iter.next(); + if(colIdx == noOfColumns) { + + return dc.getColId(); + } else continue; + } // for + return ""; + } else return ""; + + } + + /** + * Set Number of Columns to Frozen in Data Grid + */ + + public void setFrozenColumns( int frozenColumns) { + cr.setFrozenColumns(frozenColumns); + } + + /** + * @return the reportSQLWithRowNum for ZK Support + */ + public String getReportSQLWithRowNum() { + return reportSQLWithRowNum; + } + + /** + * @param reportSQLWithRowNum the reportSQLWithRowNum to set for ZK Support + */ + public void setReportSQLWithRowNum(String reportSQLWithRowNum) { + this.reportSQLWithRowNum = reportSQLWithRowNum; + } + + //used for Zk sort + public void setReportSQLOnlyFirstPart(String reportSQLOnlyFirstPart) { + this.reportSQLOnlyFirstPart = reportSQLOnlyFirstPart; + } + + public String getReportSQLOnlyFirstPart() { + return this.reportSQLOnlyFirstPart; + } + + public String getTemplateFile() throws RaptorException { + return ReportLoader.getTemplateFile(getReportID()); + } + + public String getPdfImg() { + return cr.getPdfImgLogo(); + } + + + public String getEmptyMessage() { + String emptyMessage = cr.getEmptyMessage(); + if(nvl(emptyMessage).length()<=0) + emptyMessage = Globals.getReportEmptyMessage(); + return emptyMessage; + } + + public void setPdfImg(String img_loc) { + cr.setPdfImgLogo(img_loc); + } + + public void setEmptyMessage(String emptyMessage) { + cr.setEmptyMessage(emptyMessage); + } + + public void setDrillReportIdForChart(String reportId) { + //(cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().setDrillReportId():""; + cr.getChartDrillOptions().setDrillReportId(reportId); + } + + public String getDrillReportIdForChart() { + return (cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().getDrillReportId():""; + } + + public void setDrillXAxisFormField(String formField) { + //(cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().setDrillReportId():""; + cr.getChartDrillOptions().setDrillXAxisFormField(formField); + } + + public String getDrillXAxisFormField() { + return (cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().getDrillXAxisFormField():""; + } + + public void setDrillYAxisFormField(String formField) { + //(cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().setDrillReportId():""; + cr.getChartDrillOptions().setDrillYAxisFormField(formField); + } + + public String getDrillYAxisFormField() { + return (cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().getDrillYAxisFormField():""; + } + + public void setDrillSeriesFormField(String formField) { + //(cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().setDrillReportId():""; + cr.getChartDrillOptions().setDrillSeriesFormField(formField); + } + + public String getDrillSeriesFormField() { + return (cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().getDrillSeriesFormField():""; + } + + public boolean isEnhancedPaginationNeeded() { + List reportCols = getAllColumns(); + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (dc.isEnhancedPagination()!=null && dc.isEnhancedPagination().booleanValue()) + return true; + } // for + return false; + } + + public DataColumnType getColumnWhichNeedEnhancedPagination() { + List reportCols = getAllColumns(); + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if (dc.isEnhancedPagination()!=null && dc.isEnhancedPagination().booleanValue()) + return dc; + } // for + return null; + } + + public void setDataGridAlign(String align) { + cr.setDataGridAlign(align); + } + + + public String getDataGridAlign() { + return (cr.getDataGridAlign()!=null)?cr.getDataGridAlign():"left"; + } + + public void setWidthNoColumn(String width) { + cr.setWidthNoColumn(width); + } + + + public String getWidthNoColumn() { + return (cr.getWidthNoColumn()!=null)?cr.getWidthNoColumn():"30px"; + } + + public void setWholeSQL(String sql) { + wholeSQL = sql; + } + public String getWholeSQL() { + return wholeSQL; + } + +} // ReportWrapper diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DBColumnInfo.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DBColumnInfo.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DBColumnInfo.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DBColumnInfo.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DrillDownParamDef.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DrillDownParamDef.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DrillDownParamDef.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/DrillDownParamDef.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/Marker.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/Marker.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/Marker.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/Marker.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportDefinition.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportDefinition.java new file mode 100644 index 00000000..9d66717a --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportDefinition.java @@ -0,0 +1,1471 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition; + +import java.io.Serializable; +import java.sql.Connection; +import java.util.Calendar; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.bind.JAXBException; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +//import javax.xml.transform.stream.*; + +import org.openecomp.portalsdk.analytics.controller.WizardSequence; +import org.openecomp.portalsdk.analytics.controller.WizardSequenceCrossTab; +import org.openecomp.portalsdk.analytics.controller.WizardSequenceDashboard; +import org.openecomp.portalsdk.analytics.controller.WizardSequenceLinear; +import org.openecomp.portalsdk.analytics.controller.WizardSequenceSQLBasedCrossTab; +import org.openecomp.portalsdk.analytics.controller.WizardSequenceSQLBasedHive; +import org.openecomp.portalsdk.analytics.controller.WizardSequenceSQLBasedLinear; +import org.openecomp.portalsdk.analytics.controller.WizardSequenceSQLBasedLinearDatamining; +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.model.DataCache; +import org.openecomp.portalsdk.analytics.model.ReportLoader; +import org.openecomp.portalsdk.analytics.model.base.OrderBySeqComparator; +import org.openecomp.portalsdk.analytics.model.base.OrderSeqComparator; +import org.openecomp.portalsdk.analytics.model.base.ReportWrapper; +import org.openecomp.portalsdk.analytics.model.runtime.FormField; +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.system.DbUtils; +import org.openecomp.portalsdk.analytics.system.Globals; +import org.openecomp.portalsdk.analytics.util.AppConstants; +import org.openecomp.portalsdk.analytics.util.DataSet; +import org.openecomp.portalsdk.analytics.util.Utils; +import org.openecomp.portalsdk.analytics.xmlobj.ChartAdditionalOptions; +import org.openecomp.portalsdk.analytics.xmlobj.ChartDrillOptions; +import org.openecomp.portalsdk.analytics.xmlobj.ColFilterType; +import org.openecomp.portalsdk.analytics.xmlobj.CustomReportType; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnList; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; +import org.openecomp.portalsdk.analytics.xmlobj.DataSourceType; +import org.openecomp.portalsdk.analytics.xmlobj.DataminingOptions; +import org.openecomp.portalsdk.analytics.xmlobj.FormFieldList; +import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; +import org.openecomp.portalsdk.analytics.xmlobj.FormatList; +import org.openecomp.portalsdk.analytics.xmlobj.FormatType; +import org.openecomp.portalsdk.analytics.xmlobj.JavascriptItemType; +import org.openecomp.portalsdk.analytics.xmlobj.ObjectFactory; +import org.openecomp.portalsdk.analytics.xmlobj.PredefinedValueList; +import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreType; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +/**
+ * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting)
+ *
+ * + * --------------------------------------------------------------------------------------------------
+ * ReportDefinition.java - This involves in creating and modifying RAPTOR reports. + * --------------------------------------------------------------------------------------------------
+ * + * + * Change Log

+ * + * 18-Aug-2009 : Version 8.5.1 (Sundar);
  • request Object is passed to prevent caching user/roles - Datamining/Hosting.
+ * 27-Jul-2009 : Version 8.4 (Sundar);
  • userIsAuthorizedToSeeLog is checked for Admin User instead of Super User.
+ * 22-Jun-2009 : Version 8.4 (Sundar);
  • A new type ChartAdditionalOptions is introduced in RAPTOR XSD. + * For this type a create procedure is added to this class.
+ * + */ + +public class ReportDefinition extends ReportWrapper implements Serializable { + + static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ReportDefinition.class); + + + private ReportSchedule reportSchedule = null; + + private WizardSequence wizardSequence = null; + + + private boolean reportUpdateLogged = false; // Used to avoid multiple + // entries in the report log + // when persisting report on + // each step + + private ReportDefinition(CustomReportType crType, String reportID, String ownerID, + String createID, String createDate, String updateID, String updateDate, + String menuID, boolean menuApproved, HttpServletRequest request) throws RaptorException { + super(crType, reportID, ownerID, createID, createDate, updateID, updateDate, menuID, + menuApproved); + if(reportID.equals("-1")) + reportSchedule = new ReportSchedule(getReportID(), getOwnerID(), false, request); + else + reportSchedule = new ReportSchedule(getReportID(), getOwnerID(), true, request); + generateWizardSequence(null); + } // ReportDefinition + + public ReportDefinition(ReportWrapper rw, HttpServletRequest request)throws RaptorException { + super(rw); + + reportSchedule = new ReportSchedule(reportID, rw.getOwnerID(),false, request); + generateWizardSequence(null); + } // ReportDefinition + + private void setReportID(String reportID) { + this.reportID = reportID; + reportSchedule.setReportID(reportID); + reportSchedule.setScheduleUserID(getOwnerID()); + } // setReportID + + public ReportSchedule getReportSchedule() { + return reportSchedule; + } + + public static ReportDefinition unmarshal(String reportXML, String reportID, HttpServletRequest request) + throws RaptorException { + ReportDefinition rn = null; + CustomReportType crType = ReportWrapper.unmarshalCR(reportXML); + //Log.write("Report [" + reportID + "]: XML unmarshalled", 4); + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Report [" + reportID + "]: XML unmarshalled")); + + rn = new ReportDefinition(crType, reportID, null, null, null, null, null, null, false, request); + return rn; + } // unmarshal + + public static ReportDefinition createBlank(HttpServletRequest request) throws RaptorException { + String curTime = Utils.getCurrentDateTime(); + String userID = AppUtils.getUserID(request); + ReportDefinition rd = new ReportDefinition(ReportWrapper.createBlankCR(userID), "-1", + userID, userID, curTime, userID, curTime, "", false, request); + + // Necessary initialization + + return rd; + } // ReportDefinition + + public void setAsCopy(HttpServletRequest request) throws RaptorException { + verifySQLBasedReportAccess(request); + + replaceCustomReportWithClone(); + + setReportID("-1"); + setReportName("Copy: " + getReportName()); + } // setAsCopy + + public WizardSequence getWizardSequence() { + return wizardSequence; + } // getWizardSequence + + public void generateWizardSequence(HttpServletRequest request) throws RaptorException { + boolean userIsAuthorizedToSeeLog = false; + String userId = null; + if(request!=null) { + userId = AppUtils.getUserID(request); + if (userId != null) + userIsAuthorizedToSeeLog = AppUtils.isAdminUser(request) + || AppUtils.isAdminUser(request); + //System.out.println("******** Report Type "+getReportType() + " userIsAuthorizedToSeeLog " + userIsAuthorizedToSeeLog); + } + if (getReportType().equals(AppConstants.RT_LINEAR)){ + if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) + wizardSequence = new WizardSequenceSQLBasedLinear(userIsAuthorizedToSeeLog); + else if (getReportDefType().equals(AppConstants.RD_SQL_BASED_DATAMIN)) + wizardSequence = new WizardSequenceSQLBasedLinearDatamining(userIsAuthorizedToSeeLog); + else + wizardSequence = new WizardSequenceLinear(userIsAuthorizedToSeeLog); + } else if (getReportType().equals(AppConstants.RT_CROSSTAB)) { + if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) + wizardSequence = new WizardSequenceSQLBasedCrossTab(userIsAuthorizedToSeeLog); + else + wizardSequence = new WizardSequenceCrossTab(userIsAuthorizedToSeeLog); + } else if (getReportType().equals(AppConstants.RT_DASHBOARD)) { + wizardSequence = new WizardSequenceDashboard(userIsAuthorizedToSeeLog); + } else if (getReportType().equals(AppConstants.RT_HIVE)) { + wizardSequence = new WizardSequenceSQLBasedHive(userIsAuthorizedToSeeLog); + } else + wizardSequence = new WizardSequence(); + } // generateWizardSequence + + private boolean canPersistDashboard() { + //System.out.println(" getDashBoardReports().getReportsList().size() " + getDashBoardReports().getReportsList().size()); + /* Commented for New DashBoard + if (getDashBoardReports()!=null && getDashBoardReports().getReportsList()!=null && getDashBoardReports().getReportsList().size() > 0) { + for (Iterator iter = getDashBoardReports().getReportsList().iterator(); iter.hasNext();) { + Reports report = (Reports)iter.next(); + try { + if(Integer.parseInt(report.getReportId())>0) return true; + } catch (NumberFormatException ex) {} + } // for + } //if + */ + + //if( ) + return nvl(getDashboardLayoutHTML()).length() > 0; + } //canPersistDashboard + + private boolean canPersistLinearReport() { + System.out.println("&&&&&&&&&&&&&&&&&&&&&& canPersistLinearReport"); + boolean visibleColExist = false; + + if (getDataSourceList().getDataSource().size() > 0) { + for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + + if (dct.isVisible()) { + visibleColExist = true; + break; + } + } // for + } // if + + System.out.println("&&&&&&&&&&&&&&&&&&&&&& visibleColExist " + visibleColExist); + return visibleColExist; + } // canPersistLinearReport + + private boolean canPersistCrossTabReport() { + boolean rowColExist = false; + boolean colColExist = false; + boolean valColExist = false; + + if (getDataSourceList().getDataSource().size() > 0) { + for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + + if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_ROW)) + rowColExist = true; + if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_COLUMN)) + colColExist = true; + if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_VALUE)) + valColExist = true; + } // for + } // if + + return rowColExist && colColExist && valColExist; + } // canPersistCrossTabReport + + private boolean canPersistReport() { + return getReportType().equals(AppConstants.RT_CROSSTAB) ? canPersistCrossTabReport() + : (getReportType().equals(AppConstants.RT_LINEAR)? canPersistLinearReport():((getReportType().equals(AppConstants.RT_HIVE)? canPersistLinearReport():canPersistDashboard()))); + } // canPersistReport + + public void persistReport(HttpServletRequest request) throws RaptorException { + if (!canPersistReport()) { + System.out.println("&&&&&&&&&&&&&&&&&&&&&& In !canPersistReport ReportType: " + getReportType()); + return; + } else { + System.out.println("&&&&&&&&&&&&&&&&&&&&&& Not In !canPersistReport"); + } + + Connection connection = null; + try { + String userID = AppUtils.getUserID(request); + String reportXML = marshal(); + logger.debug(EELFLoggerDelegate.debugLogger, ("Ocurring during Schedule ")); + System.out.println("&&&&&&&&&&&&&&&&&&&&&& Report ID " + reportID); + if (nvl(reportID, "-1").equals("-1")) { + connection = DbUtils.startTransaction(); + // Add report + String sql = ""; + if (nvl(Globals.getAdhocReportSequence()).length()> 0 && nvl(Globals.getAdhocUserRoldId()).length() > 0 && AppUtils.isUserInRole(request, Globals.getAdhocUserRoldId()) && !AppUtils.isAdminUser(request)) { + //sql = "SELECT "+ Globals.getAdhocReportSequence() + ".nextval FROM dual"; + sql = Globals.getPersistReportAdhoc(); + sql = sql.replace("[Globals.getAdhocReportSequence()]", Globals.getAdhocReportSequence()); + + } else{ + //sql = "SELECT seq_cr_report.nextval FROM dual"; + sql = Globals.getNewReportData(); + } + DataSet ds = DbUtils.executeQuery(connection,sql); + setReportID(ds.getString(0, 0)); + + reportSecurity.reportCreate(reportID, userID, isPublic()); + ReportLoader.createCustomReportRec(connection, this, reportXML); + ReportLoader.createReportLogEntry(connection, reportID, userID, + AppConstants.RLA_CREATE, "", ""); + reportUpdateLogged = true; + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] DB insert report " + reportID + " succesfull")); + } else { + // Update report + verifySQLBasedReportAccess(request); + reportSecurity.reportUpdate(request); + connection = DbUtils.startTransaction(); + ReportLoader.updateCustomReportRec(connection, this, reportXML); + if (!reportUpdateLogged) { + ReportLoader.createReportLogEntry(connection, reportID, userID, + AppConstants.RLA_UPDATE,"",""); + reportUpdateLogged = true; + } // if + logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] DB update report " + reportID + " succesfull")); + } + + getReportSchedule().persistScheduleData(connection, request); + + DbUtils.commitTransaction(connection); + } catch (RaptorException e) { + e.printStackTrace(); + DbUtils.rollbackTransaction(connection); + throw e; + } finally { + DbUtils.clearConnection(connection); + } + } // persistReport + + public String getCrossTabDisplayValue(String crossTabValue) { + return nvl(crossTabValue).equals(AppConstants.CV_ROW) ? "Row headings" : (nvl( + crossTabValue).equals(AppConstants.CV_COLUMN) ? "Column headings" : (nvl( + crossTabValue).equals(AppConstants.CV_VALUE) ? "Report values" : "Invisible/Filter")); + } // getCrossTabDisplayValue + + public String getCrossTabDisplayValue(DataColumnType dct) { + return getCrossTabDisplayValue(dct.getCrossTabValue()); + } // getCrossTabDisplayValue + + public String getColumnLabel(DataColumnType dct) throws Exception { + String tableName = getTableById(dct.getTableId()).getTableName(); + Vector dbColumns = null; + dbColumns = DataCache.getReportTableDbColumns(tableName, cr.getDbInfo()); + if (dbColumns != null) + for (int i = 0; i < dbColumns.size(); i++) { + DBColumnInfo dbCol = (DBColumnInfo) dbColumns.get(i); + if (dct.getDbColName().equals(dbCol.getColName())) + return dbCol.getLabel(); + } // for + + return ""; + } // getCrossTabDisplayValue + + public String getFilterLabel(ColFilterType cft) { + StringBuffer fLabel = new StringBuffer(); + + fLabel.append(cft.getExpression()); + fLabel.append(" "); + if (cft.getArgType() != null) + if (cft.getArgType().equals(AppConstants.AT_FORMULA)) { + fLabel.append("[" + cft.getArgValue() + "]"); + } else if (cft.getArgType().equals(AppConstants.AT_VALUE)) { + fLabel.append(cft.getArgValue()); + } else if (cft.getArgType().equals(AppConstants.AT_LIST)) { + fLabel.append("(" + cft.getArgValue() + ")"); + } else if (cft.getArgType().equals(AppConstants.AT_COLUMN)) { + DataColumnType dctFilter = getColumnById(cft.getArgValue()); + fLabel.append("[" + dctFilter.getDisplayName() + "]"); + } else if (cft.getArgType().equals(AppConstants.AT_FORM)) { + fLabel.append("[Form Field]"); + } + + return fLabel.toString(); + } // getFilterLabel + + public Vector getReportUsers(HttpServletRequest request) throws RaptorException { + return reportSecurity.getReportUsers(request); + } // getReportUsers + + public Vector getReportRoles(HttpServletRequest request) throws RaptorException { + return reportSecurity.getReportRoles(request); + } // getReportRoles + + /** ************************************************************************************************* */ + + public void clearAllDrillDowns() { + List reportCols = getAllColumns(); + for (int i = 0; i < reportCols.size(); i++) { + DataColumnType dct = (DataColumnType) reportCols.get(i); + dct.setDrillDownURL(null); + dct.setDrillDownParams(null); + dct.setDrillDownType(null); + } // for + } // clearAllDrillDowns + + public void setOuterJoin(DataSourceType curTable, String joinType) { + String refDefinition = nvl(curTable.getRefDefinition()); + int outerJoinIdx = refDefinition.indexOf(" (+)"); + if (outerJoinIdx >= 0) + // Clear existing outer join + if (outerJoinIdx == (refDefinition.length() - 4)) + refDefinition = refDefinition.substring(0, outerJoinIdx); + else + refDefinition = refDefinition.substring(0, outerJoinIdx) + + refDefinition.substring(outerJoinIdx + 4); + + int equalSignIdx = refDefinition.indexOf("="); + if (equalSignIdx < 0) + // Ref. definition not present + return; + + if (refDefinition.indexOf(curTable.getTableId()) < equalSignIdx) { + // Cur. table is on the left side + if (nvl(joinType).equals(AppConstants.OJ_CURRENT)) + refDefinition = refDefinition.substring(0, equalSignIdx) + " (+)" + + refDefinition.substring(equalSignIdx); + else if (nvl(joinType).equals(AppConstants.OJ_JOINED)) + refDefinition = refDefinition + " (+)"; + } else { + // Joined table is on the left side + if (nvl(joinType).equals(AppConstants.OJ_CURRENT)) + refDefinition = refDefinition + " (+)"; + else if (nvl(joinType).equals(AppConstants.OJ_JOINED)) + refDefinition = refDefinition.substring(0, equalSignIdx) + " (+)" + + refDefinition.substring(equalSignIdx); + } + + curTable.setRefDefinition(refDefinition); + } // setOuterJoin + + public void addDataSourceType(ObjectFactory objFactory, String tableId, String tableName, + String tablePK, String displayName, String refTableId, String refDefinition, + String comment) throws RaptorException { + DataSourceType dst = objFactory.createDataSourceType(); + + dst.setTableId(tableId); + dst.setTableName(tableName); + dst.setTablePK(tablePK); + dst.setDisplayName(displayName); + if (nvl(refTableId).length() > 0) + dst.setRefTableId(refTableId); + if (nvl(refDefinition).length() > 0) + dst.setRefDefinition(refDefinition); + if (nvl(comment).length() > 0) + dst.setComment(comment); + + DataColumnList dataColumnList = objFactory.createDataColumnList(); + dst.setDataColumnList(dataColumnList); + + getDataSourceList().getDataSource().add(dst); + + resetCache(true); + } // addDataSourceType + + public void deleteDataSourceType(String tableId) { + super.deleteDataSourceType(tableId); + } // deleteDataSourceType + + public String getUniqueColumnId(String colName) { + String colId = ""; + + int colIdN = getAllColumns().size() + 1; + do { + colId = colName.substring(0, 2).toLowerCase() + (colIdN++); + } while (getColumnById(colId) != null); + + return colId; + } // getUniqueColumnId + + public DataColumnType addDataColumnType(ObjectFactory objFactory, String colId, + String tableId, // Table to which the new column belongs + String dbColName, String crossTabValue, String colName, String displayName, + int displayWidth, String displayAlignment, int orderSeq, boolean visible, + boolean calculated, String colType, String colFormat, boolean groupBreak, + int orderBySeq, String orderByAscDesc, String displayTotal, String colOnChart, + int chartSeq, String drillDownType, String drillDownURL, String drillDownParams, + String semaphoreId, String comment) throws RaptorException { + DataColumnType dct = null; + dct = objFactory.createDataColumnType(); + + dct.setColId(colId); + dct.setTableId(tableId); + dct.setDbColName(dbColName); + if (nvl(crossTabValue).length() > 0) + dct.setCrossTabValue(crossTabValue); + dct.setColName(colName); + dct.setDisplayName(displayName); + if (displayWidth > 0) + dct.setDisplayWidth(displayWidth); + if (nvl(displayAlignment).length() > 0) + dct.setDisplayAlignment(displayAlignment); + if (orderSeq > 0) + dct.setOrderSeq(orderSeq); + else + dct.setOrderSeq(getAllColumns().size() + 1); + dct.setVisible(visible); + dct.setCalculated(calculated); + // dct.setColType(colType); + if (nvl(colFormat).length() > 0) + dct.setColFormat(colFormat); + dct.setGroupBreak(groupBreak); + if (orderBySeq > 0) + dct.setOrderBySeq(orderBySeq); + if (nvl(orderByAscDesc).length() > 0) + dct.setOrderByAscDesc(orderByAscDesc); + if (nvl(displayTotal).length() > 0) + dct.setDisplayTotal(displayTotal); + if (nvl(colOnChart).length() > 0) + dct.setColOnChart(colOnChart); + if (chartSeq > 0) + dct.setChartSeq(chartSeq); + if (nvl(drillDownType).length() > 0) + dct.setDrillDownType(drillDownType); + if (nvl(drillDownURL).length() > 0) + dct.setDrillDownURL(drillDownURL); + if (nvl(drillDownParams).length() > 0) + dct.setDrillDownParams(drillDownParams); + if (nvl(semaphoreId).length() > 0) + dct.setSemaphoreId(semaphoreId); + if (nvl(comment).length() > 0) + dct.setComment(comment); + + dct.setDbColType(colType); + adjustColumnType(dct); + + // ColFilterList colFilterList = objFactory.createColFilterList(); + // dct.setColFilterList(colFilterList); + + getTableById(tableId).getDataColumnList().getDataColumn().add(dct); + + resetCache(false); + + return dct; + } // addDataColumnType + + public void deleteDataColumnType(String colId) { + int colOrder = getColumnById(colId).getOrderSeq(); + + List dcList = getColumnTableById(colId).getDataColumnList().getDataColumn(); + for (Iterator iterC = dcList.iterator(); iterC.hasNext();) { + DataColumnType dct = (DataColumnType) iterC.next(); + + if (dct.getColId().equals(colId) && dct.getOrderSeq() == colOrder) + iterC.remove(); + else if (dct.getOrderSeq() > colOrder) + dct.setOrderSeq(dct.getOrderSeq() - 1); + } // for + + if (getFormFieldList() != null) + for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { + FormFieldType fft = (FormFieldType) iter.next(); + if (nvl(fft.getColId()).equals(colId)) { + fft.setColId(""); + fft.setFieldType(FormField.FFT_TEXT); + if (nvl(fft.getDefaultValue()).equals(AppConstants.FILTER_MAX_VALUE) + || nvl(fft.getDefaultValue()) + .equals(AppConstants.FILTER_MIN_VALUE)) + fft.setDefaultValue(""); + } // if + } // for + + resetCache(false); + resetColumnOrderValues(); + } // deleteDataColumnType + + public void shiftColumnOrderUp(String colId) { + List reportCols = getAllColumns(); + for (int i = 0; i < reportCols.size(); i++) { + DataColumnType dct = (DataColumnType) reportCols.get(i); + + if (dct.getColId().equals(colId) && (i > 0)) { + DataColumnType dctUp = (DataColumnType) reportCols.get(i - 1); + dctUp.setOrderSeq(dctUp.getOrderSeq() + 1); + dct.setOrderSeq(dct.getOrderSeq() - 1); + break; + } // if + } // for + + Collections.sort(reportCols, new OrderSeqComparator()); + resetCache(true); + resetColumnOrderValues(); + } // shiftColumnOrderUp + + public void shiftColumnOrderDown(String colId) { + List reportCols = getAllColumns(); + for (int i = 0; i < reportCols.size(); i++) { + DataColumnType dct = (DataColumnType) reportCols.get(i); + + if (dct.getColId().equals(colId) && (i < reportCols.size() - 1)) { + DataColumnType dctDown = (DataColumnType) reportCols.get(i + 1); + dctDown.setOrderSeq(dctDown.getOrderSeq() - 1); + dct.setOrderSeq(dct.getOrderSeq() + 1); + break; + } // if + } // for + + Collections.sort(reportCols, new OrderSeqComparator()); + resetCache(true); + resetColumnOrderValues(); + } // shiftColumnOrderDown + + public void resetColumnOrderValues() { + List reportCols = getAllColumns(); + + int colOrder = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + dct.setOrderSeq(++colOrder); + } // for + + Collections.sort(reportCols, new OrderSeqComparator()); + } // resetColumnOrderValues + + public void addColFilterType(ObjectFactory objFactory, String colId, // Column + // to + // which + // the + // new + // filter + // belongs + String joinCondition, String openBrackets, String expression, String argType, + String argValue, String closeBrackets, String comment) throws RaptorException { + ColFilterType cft = objFactory.createColFilterType(); + + cft.setColId(colId); + cft.setJoinCondition(nvl(joinCondition, "AND")); + if (nvl(openBrackets).length() > 0) + cft.setOpenBrackets(openBrackets); + cft.setExpression(expression); + if (nvl(argType).length() > 0) + cft.setArgType(argType); + if (nvl(argValue).length() > 0) + cft.setArgValue(argValue); + if (nvl(closeBrackets).length() > 0) + cft.setCloseBrackets(closeBrackets); + if (nvl(comment).length() > 0) + cft.setComment(comment); + + DataColumnType dct = getColumnById(colId); + if (dct != null) { + if (dct.getColFilterList() == null) + dct.setColFilterList(objFactory.createColFilterList()); + + cft.setFilterSeq(dct.getColFilterList().getColFilter().size()); + dct.getColFilterList().getColFilter().add(cft); + } // if + + resetCache(true); + } // addColFilterType + + public void removeColumnFilter(String colId, int filterPos) { + DataColumnType dct = getColumnById(colId); + + if (dct.getColFilterList() != null) + try { + dct.getColFilterList().getColFilter().remove(filterPos); + } catch (IndexOutOfBoundsException e) { + } + + resetCache(true); + } // removeColumnFilter + + public void addColumnSort(String colId, String ascDesc) { + addColumnSort(colId, ascDesc, -1); + } // addColumnSort + + public void addColumnSort(String colId, String ascDesc, int sortOrder) { + if (sortOrder <= 0) { + sortOrder = 1; + List reportCols = getAllColumns(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) + if (((DataColumnType) iter.next()).getOrderBySeq() > 0) + sortOrder++; + } // if + + DataColumnType dct = getColumnById(colId); + dct.setOrderBySeq(sortOrder); + dct.setOrderByAscDesc(ascDesc); + + resetCache(true); + } // addColumnSort + + public void removeColumnSort(String colId) { + DataColumnType dct = getColumnById(colId); + int sortOrder = dct.getOrderBySeq(); + + dct.setOrderBySeq(0); + dct.setOrderByAscDesc(null); + + if (sortOrder > 0) { + List reportCols = getAllColumns(); + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dct2 = (DataColumnType) iter.next(); + + if (dct2.getOrderBySeq() > sortOrder) + dct2.setOrderBySeq(dct2.getOrderBySeq() - 1); + } // for + } // if + + resetCache(true); + } // removeColumnSort + + public void shiftColumnSortUp(String colId) { + List reportCols = getAllColumns(); + Collections.sort(reportCols, new OrderBySeqComparator()); + + for (int i = 0; i < reportCols.size(); i++) { + DataColumnType dct = (DataColumnType) reportCols.get(i); + + if (dct.getColId().equals(colId) && (dct.getOrderBySeq() > 0)) { + DataColumnType dctUp = (DataColumnType) reportCols.get(i - 1); + if (dctUp.getOrderBySeq() > 0) + dctUp.setOrderBySeq(dctUp.getOrderBySeq() + 1); + dct.setOrderBySeq(dct.getOrderBySeq() - 1); + break; + } // if + } // for + + Collections.sort(reportCols, new OrderSeqComparator()); + resetCache(true); + } // shiftColumnSortUp + + public void shiftColumnSortDown(String colId) { + List reportCols = getAllColumns(); + Collections.sort(reportCols, new OrderBySeqComparator()); + + for (int i = 0; i < reportCols.size(); i++) { + DataColumnType dct = (DataColumnType) reportCols.get(i); + + if (dct.getColId().equals(colId) && (dct.getOrderBySeq() > 0)) { + DataColumnType dctDown = (DataColumnType) reportCols.get(i + 1); + if (dctDown.getOrderBySeq() > 0) + dctDown.setOrderBySeq(dctDown.getOrderBySeq() - 1); + dct.setOrderBySeq(dct.getOrderBySeq() + 1); + break; + } // if + } // for + + Collections.sort(reportCols, new OrderSeqComparator()); + resetCache(true); + } // shiftColumnSortDown + + /** ************************************************************************************************* */ + + public String generateNewSemaphoreId() { + if (getSemaphoreList() == null) + return "sem1"; + + String semaphoreId = null; + boolean idExists = true; + for (int i = 1; idExists; i++) { + semaphoreId = "sem" + i; + idExists = false; + for (Iterator iter = getSemaphoreList().getSemaphore().iterator(); iter.hasNext();) + if (semaphoreId.equals(((SemaphoreType) iter.next()).getSemaphoreId())) { + idExists = true; + break; + } + } // for + + return semaphoreId; + } // generateNewSemaphoreId + + public SemaphoreType addSemaphore(ObjectFactory objFactory, SemaphoreType semaphoreType) + throws RaptorException { + SemaphoreType sem = null; + try { + if (getSemaphoreList() == null) + setSemaphoreList(objFactory.createSemaphoreList()); + + String semaphoreName = null; + boolean nameExists = true; + for (int i = 1; nameExists; i++) { + semaphoreName = semaphoreType.getSemaphoreName() + ((i > 1) ? (" v" + i) : ""); + nameExists = false; + for (Iterator iter2 = getSemaphoreList().getSemaphore().iterator(); iter2 + .hasNext();) + if (semaphoreName.equals(((SemaphoreType) iter2.next()).getSemaphoreName())) { + nameExists = true; + break; + } + } // for + + sem = cloneSemaphoreType(objFactory, semaphoreType); + getSemaphoreList().getSemaphore().add(sem); + + sem.setSemaphoreId(generateNewSemaphoreId()); + sem.setSemaphoreName(semaphoreName); + } catch (JAXBException ex) { + throw new RaptorException(ex.getMessage(), ex.getCause()); + } + + return sem; + } // addSemaphore + + public SemaphoreType addSemaphoreType(ObjectFactory objFactory, String semaphoreName, + String semaphoreType, String comment) throws RaptorException { + SemaphoreType sem = null; + if (getSemaphoreList() == null) + setSemaphoreList(objFactory.createSemaphoreList()); + + sem = objFactory.createSemaphoreType(); + getSemaphoreList().getSemaphore().add(sem); + + sem.setSemaphoreId(generateNewSemaphoreId()); + sem.setSemaphoreName(semaphoreName); + sem.setSemaphoreType(nvl(semaphoreType)); + if (nvl(comment).length() > 0) + sem.setComment(comment); + + FormatList formatList = objFactory.createFormatList(); + sem.setFormatList(formatList); + return sem; + } // addSemaphoreType + + + public String getNextIdForJavaScriptElement (ObjectFactory objFactory, String fieldId) throws RaptorException { + String id = ""; + JavascriptItemType jit = null; + int incr = 0; + if (getJavascriptList() == null) { + setJavascriptList(objFactory.createJavascriptList()); + return fieldId + "|1"; + } else { + if(getJavascriptList().getJavascriptItem().iterator().hasNext()) { + for (Iterator iter = getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { + jit = (JavascriptItemType) iter.next(); + logger.debug(EELFLoggerDelegate.debugLogger, ("^^^^^JAVASCRIPTITEMTYPE " + jit.getFieldId() + " " + fieldId + " " + id)); + if(nvl(jit.getFieldId()).length()>0 && jit.getFieldId().equals(fieldId)) { + ++incr; + } + } // for + return fieldId + "|"+incr; + } else { + return fieldId + "|1"; + } + + } + //return null; + } + + public JavascriptItemType addJavascriptType(ObjectFactory objFactory, String id) throws RaptorException { + JavascriptItemType javascriptItemType = null; + int flag = 0; // checking whether id existing in the list + if (getJavascriptList() == null) { + setJavascriptList(objFactory.createJavascriptList()); + javascriptItemType = objFactory.createJavascriptItemType(); + getJavascriptList().getJavascriptItem().add(javascriptItemType); + return javascriptItemType; + } else { + + for (Iterator iter = getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { + javascriptItemType = (JavascriptItemType)iter.next(); + if(javascriptItemType.getId().equals(id) && !id.startsWith("-1")) { + flag = 1; + break; + } + } + if(flag == 1) return javascriptItemType; + else { + javascriptItemType = objFactory.createJavascriptItemType(); + getJavascriptList().getJavascriptItem().add(javascriptItemType); + return javascriptItemType; + } + } + + } // addSemaphoreType + + public boolean deleteJavascriptType(String id) throws RaptorException { + JavascriptItemType javascriptType = null; + if (getJavascriptList() == null) + return true; + for (Iterator iter = getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { + javascriptType = (JavascriptItemType)iter.next(); + if(javascriptType.getId().equals(id)) { + iter.remove(); + return true; + } + } + return false; + } // addSemaphoreType + + public static FormatType addEmptyFormatType(ObjectFactory objFactory, + SemaphoreType semaphore) throws RaptorException { + FormatType fmt = null; + fmt = objFactory.createFormatType(); + semaphore.getFormatList().getFormat().add(fmt); + + String formatId = null; + boolean idExists = true; + for (int i = 1; idExists; i++) { + formatId = semaphore.getSemaphoreId() + "_fmt" + i; + idExists = false; + for (Iterator iter = semaphore.getFormatList().getFormat().iterator(); iter + .hasNext();) + if (formatId.equals(((FormatType) iter.next()).getFormatId())) { + idExists = true; + break; + } + } // for + fmt.setFormatId(formatId); + return fmt; + } // addEmptyFormatType + + public static void deleteFormatType(SemaphoreType semaphore, String formatId) { + for (Iterator iter = semaphore.getFormatList().getFormat().iterator(); iter.hasNext();) + if (formatId.equals(((FormatType) iter.next()).getFormatId())) { + iter.remove(); + break; + } // if + } // deleteFormatType + + public FormFieldType addFormFieldType(ObjectFactory objFactory, String fieldName, + String colId, String fieldType, String validationType, String mandatory, + String defaultValue, String fieldSQL, String comment, Calendar rangeStartDate, Calendar rangeEndDate, + String rangeStartDateSQL, String rangeEndDateSQL) throws RaptorException { + FormFieldType fft = null; + fft = objFactory.createFormFieldType(); + + fft.setFieldName(fieldName); + fft.setColId(colId); + fft.setFieldType(fieldType); + fft.setValidationType(validationType); + fft.setMandatory(nvl(mandatory, "N")); + fft.setDefaultValue(nvl(defaultValue)); + fft.setOrderBySeq((getFormFieldList() == null) ? 1 : getFormFieldList().getFormField() + .size() + 1); + fft.setFieldSQL(fieldSQL); + //fft.setRangeStartDate(rangeStartDate); + //fft.setRangeEndDate(rangeEndDate); + + try { + fft.setRangeStartDate(DatatypeFactory.newInstance() + .newXMLGregorianCalendar(rangeStartDate.YEAR, rangeStartDate.MONTH, rangeStartDate.DAY_OF_WEEK, rangeStartDate.HOUR, rangeStartDate.MINUTE, rangeStartDate.SECOND, rangeStartDate.MILLISECOND, rangeStartDate.ZONE_OFFSET)); + fft.setRangeStartDate(DatatypeFactory.newInstance() + .newXMLGregorianCalendar(rangeEndDate.YEAR, rangeEndDate.MONTH, rangeEndDate.DAY_OF_WEEK, rangeEndDate.HOUR, rangeEndDate.MINUTE, rangeEndDate.SECOND, rangeEndDate.MILLISECOND, rangeEndDate.ZONE_OFFSET)); + /*currField.setRangeEndDate(DatatypeFactory.newInstance() + .newXMLGregorianCalendar(end));*/ + } catch (DatatypeConfigurationException ex) { + + } + + fft.setRangeStartDateSQL(rangeStartDateSQL); + fft.setRangeEndDateSQL(rangeEndDateSQL); + if (nvl(comment).length() > 0) + fft.setComment(comment); + + String fieldId = null; + boolean idExists = true; + for (int i = 1; idExists; i++) { + fieldId = "ff" + i; + idExists = false; + if (getFormFieldList() != null) + for (Iterator iter = getFormFieldList().getFormField().iterator(); iter + .hasNext();) + if (fieldId.equals(((FormFieldType) iter.next()).getFieldId())) { + idExists = true; + break; + } + } // for + fft.setFieldId(fieldId); + + if (getFormFieldList() == null) { + FormFieldList formFieldList = objFactory.createFormFieldList(); + setFormFieldList(formFieldList); + } + + getFormFieldList().getFormField().add(fft); + return fft; + } // addFormFieldType + + //addCustomizedTextForParameters + public void addCustomizedTextForParameters(String comment) throws RaptorException { + getFormFieldList().setComment(comment); + } + + public FormFieldType addFormFieldBlank(ObjectFactory objFactory) throws RaptorException { + FormFieldType fft = null; + fft = objFactory.createFormFieldType(); + + fft.setFieldName("BLANK"); + fft.setColId("bk"); + fft.setFieldType(FormField.FFT_BLANK); + fft.setOrderBySeq((getFormFieldList() == null) ? 1 : getFormFieldList().getFormField() + .size() + 1); + String fieldId = null; + boolean idExists = true; + for (int i = 1; idExists; i++) { + fieldId = "ff" + i; + idExists = false; + if (getFormFieldList() != null) + for (Iterator iter = getFormFieldList().getFormField().iterator(); iter + .hasNext();) + if (fieldId.equals(((FormFieldType) iter.next()).getFieldId())) { + idExists = true; + break; + } + } // for + fft.setFieldId(fieldId); + + if (getFormFieldList() == null) { + FormFieldList formFieldList = objFactory.createFormFieldList(); + setFormFieldList(formFieldList); + } + + getFormFieldList().getFormField().add(fft); + return fft; + } // addFormFieldBlank + + public void replaceFormFieldReferences(String fieldName, String replaceWith) { + if (fieldName.equals(replaceWith)) + return; + + for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) { + DataColumnType dct = (DataColumnType) iter.next(); + + if (dct.isCalculated() && dct.getColName().indexOf(fieldName) >= 0) + dct.setColName(Utils.replaceInString(dct.getColName(), fieldName, nvl( + replaceWith, "NULL"))); + + if (dct.getColFilterList() != null) + for (Iterator iter2 = dct.getColFilterList().getColFilter().iterator(); iter2 + .hasNext();) { + ColFilterType cft = (ColFilterType) iter2.next(); + + if (nvl(cft.getArgType()).equals(AppConstants.AT_FORM) + && nvl(cft.getArgValue()).equals(fieldName)) + cft.setArgValue(replaceWith); + } // for + } // for + } // replaceFormFieldReferences + + public void deleteFormField(String fieldId) { + String fieldDisplayName = null; + + int orderBySeq = Integer.MAX_VALUE; + if (getFormFieldList() != null) + for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { + FormFieldType fft = (FormFieldType) iter.next(); + + if (fieldId.equals(fft.getFieldId())) { + //orderBySeq = fft.getOrderBySeq(); + fieldDisplayName = getFormFieldDisplayName(fft); + iter.remove(); + } else if (fft.getOrderBySeq()!=null && (fft.getOrderBySeq().intValue() > orderBySeq)) + fft.setOrderBySeq(fft.getOrderBySeq() - 1); + } // for + + if (fieldDisplayName != null) + replaceFormFieldReferences(fieldDisplayName, ""); + } // deleteFormField + + public void shiftFormFieldUp(String fieldId) { + if (getFormFieldList() == null) + return; + + for (int i = 0; i < getFormFieldList().getFormField().size(); i++) { + FormFieldType fft = (FormFieldType) getFormFieldList().getFormField().get(i); + + if (fft.getFieldId().equals(fieldId) && (i > 0)) { + FormFieldType prevFft = (FormFieldType) getFormFieldList().getFormField().get( + i - 1); + prevFft.setOrderBySeq(prevFft.getOrderBySeq() + 1); + fft.setOrderBySeq((fft.getOrderBySeq() == null)?0:fft.getOrderBySeq() - 1); + + getFormFieldList().getFormField().remove(i); + getFormFieldList().getFormField().add(i - 1, fft); + return; + } // if + } // for + } // shiftFormFieldUp + + public void shiftFormFieldDown(String fieldId) { + if (getFormFieldList() == null) + return; + + for (int i = 0; i < getFormFieldList().getFormField().size(); i++) { + FormFieldType fft = (FormFieldType) getFormFieldList().getFormField().get(i); + + if (fft.getFieldId().equals(fieldId) + && (i < getFormFieldList().getFormField().size() - 1)) { + FormFieldType nextFft = (FormFieldType) getFormFieldList().getFormField().get( + i + 1); + nextFft.setOrderBySeq((nextFft.getOrderBySeq() == null)?0:nextFft.getOrderBySeq() - 1); + fft.setOrderBySeq((fft.getOrderBySeq() == null)?0:fft.getOrderBySeq() + 1); + + getFormFieldList().getFormField().remove(i + 1); + getFormFieldList().getFormField().add(i, nextFft); + return; + } // if + } // for + } // shiftFormFieldDown + + public static void addFormFieldPredefinedValue(ObjectFactory objFactory, + FormFieldType formField, String predefinedValue) throws RaptorException { + if (formField.getPredefinedValueList() == null) { + PredefinedValueList predefinedValueList = objFactory.createPredefinedValueList(); + formField.setPredefinedValueList(predefinedValueList); + } // if + + if (predefinedValue.length() > 0) { + formField.getPredefinedValueList().getPredefinedValue().add(predefinedValue); + Collections.sort(formField.getPredefinedValueList().getPredefinedValue()); + } // if + } // addFormFieldPredefinedValue + + public static void deleteFormFieldPredefinedValue(FormFieldType formField, + String predefinedValue) { + if (formField != null && formField.getPredefinedValueList() != null + && predefinedValue.length() > 0) + for (Iterator iter = formField.getPredefinedValueList().getPredefinedValue() + .iterator(); iter.hasNext();) + if (predefinedValue.equals((String) iter.next())) { + iter.remove(); + break; + } // if + } // deleteFormFieldPredefinedValue + + /** ************************************************************************************************* */ + + private int curSQLParsePos = 0; + + private String getNextSQLParseToken(String sql, boolean updateParsePos) { + int braketCount = 0; + boolean isInsideQuote = false; + StringBuffer nextToken = new StringBuffer(); + for (int idxNext = curSQLParsePos; idxNext < sql.length(); idxNext++) { + char ch = sql.charAt(idxNext); + + if (Character.isWhitespace(ch) || ch == ',') { + if (ch == ',') + nextToken.append(ch); + + if (nextToken.length() == 0) + continue; + else if (braketCount == 0 && (!isInsideQuote)) { + if (updateParsePos) + curSQLParsePos = idxNext + ((ch == ',') ? 1 : 0); + break; + } else if (ch != ',' && nextToken.charAt(nextToken.length() - 1) != ' ') + nextToken.append(' '); + } else { + nextToken.append(ch); + + if (ch == '(' || ch == '[') + braketCount++; + else if (ch == ')' || ch == ']') + braketCount--; + else if (ch == '\''/* ||ch=='\"' */) + isInsideQuote = (!isInsideQuote); + } // else + } // for + + return nextToken.toString(); + } // getNextSQLParseToken + + private boolean isParseSQLColID(String token) { + if (nvl(token).length() == 0) + return false; + + for (int i = 0; i < token.length(); i++) { + char ch = token.charAt(i); + + if (i == 0 && ch == '_') + return false; + + if (!(Character.isLetterOrDigit(ch) || ch == '_')) + return false; + } // for + + return true; + } // isParseSQLColID + + private DataColumnType getParseSQLDataColumn(String sqlExpression, String colId, + StringBuffer parsedSQL, Vector updatedReportCols, boolean isCYMBALScript) throws RaptorException { + DataColumnType dct = null; + + if (colId != null) { + if (!isParseSQLColID(colId)) + throw new org.openecomp.portalsdk.analytics.error.ValidationException( + "[" + + colId + + "] must either be a valid column id consisting only of letters, numbers, and underscores, or there must be a comma in front of it."); + + dct = getColumnById(colId); + } else { + // Getting unique column id + colId = ""; + int colIdN = 0; + for (int i = 0; (i < sqlExpression.length()) && (colIdN < 2); i++) + if (Character.isLetter(sqlExpression.charAt(i))) { + colId += sqlExpression.toLowerCase().charAt(i); + colIdN++; + } // if + + colIdN = getAllColumns().size() + updatedReportCols.size(); + for (boolean idAlreadyUsed = true; idAlreadyUsed; colIdN++) { + String newColId = colId + colIdN; + idAlreadyUsed = false; + + for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) + if (newColId.equals(((DataColumnType) iter.next()).getColId())) { + idAlreadyUsed = true; + break; + } + + if (!idAlreadyUsed) + for (Iterator iter = updatedReportCols.iterator(); iter.hasNext();) + if (newColId.equals(((DataColumnType) iter.next()).getColId())) { + idAlreadyUsed = true; + break; + } + } // for + + colId += (colIdN - 1); + } // else + + if (dct == null) { + dct = (new ObjectFactory()).createDataColumnType(); + dct.setColId(colId); + dct.setDisplayWidth(10); + dct.setDisplayAlignment("Left"); + dct.setVisible(true); + dct.setGroupBreak(false); // ??? + if(!isCYMBALScript) { + boolean isValidIdentifier = Character.isLetterOrDigit(sqlExpression.charAt(0)); + for (int i = 0; i < sqlExpression.length(); i++) + if (!(Character.isLetterOrDigit(sqlExpression.charAt(i)) + || (sqlExpression.charAt(i) == '_') || (sqlExpression.charAt(i) == '$'))) { + isValidIdentifier = false; + break; + } // if + + if (isValidIdentifier) { + dct.setDisplayName(sqlExpression); + } else { + dct.setDisplayName(colId); + } // else + } else dct.setDisplayName(colId); + } // if + if(!isCYMBALScript) + sqlExpression = sqlExpression.replaceAll(", '", ",'"); + dct.setDbColName(sqlExpression); + dct.setColName(sqlExpression); + dct.setCalculated(true); + dct.setColType(AppConstants.CT_CHAR); + dct.setDbColType(AppConstants.CT_CHAR); + adjustColumnType(dct); // ??? + if(!isCYMBALScript) { + if (parsedSQL.toString().equals("SELECT ") + || parsedSQL.toString().equals("SELECT DISTINCT ")) + parsedSQL.append("\n\t"); + else + parsedSQL.append(", \n\t"); + parsedSQL.append(sqlExpression); + parsedSQL.append(" "); + parsedSQL.append(colId); + } + + return dct; + } // getParseSQLDataColumn + + public void parseReportSQL(String sql) throws RaptorException { + StringBuffer parsedSQL = new StringBuffer(); + + Vector updatedReportCols = new Vector(); + + curSQLParsePos = 0; + int lastParsePos = curSQLParsePos; + String lastToken = null; + String nextToken = getNextSQLParseToken(sql, true); + + String dbInfo = getDBInfo(); + boolean isCYMBALScript = false; + if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { + try { + org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); + String dbType = remDbInfo.getDBType(dbInfo); + if (dbType.equals("DAYTONA") && !(nextToken.toUpperCase().equals("SELECT"))) { + isCYMBALScript = true; + } + } catch (Exception ex) { + throw new RaptorException(ex); + } + } + if ( isCYMBALScript == false ) { + while (nextToken.length() > 0) { + if (parsedSQL.length() == 0) { + if (nextToken.toUpperCase().equals("SELECT")) + parsedSQL.append("SELECT "); + else + throw new org.openecomp.portalsdk.analytics.error.ValidationException( + "The SQL must start with the SELECT keyword."); + } else if (nextToken.toUpperCase().equals("DISTINCT") + && parsedSQL.toString().equals("SELECT ")) { + parsedSQL.append("DISTINCT "); + } else if (nextToken.equals("*") + && (parsedSQL.toString().equals("SELECT ") || parsedSQL.toString().equals( + "SELECT DISTINCT "))) { + throw new org.openecomp.portalsdk.analytics.error.ValidationException( + "You cannot use \"SELECT *\". Please specify select columns/expressions."); + } else if (nextToken.toUpperCase().equals("FROM")) { + if (lastToken != null) { + updatedReportCols.add(getParseSQLDataColumn(lastToken, null, parsedSQL, + updatedReportCols, false)); + lastToken = null; + } + + parsedSQL.append(" \n"); + while (lastParsePos < sql.length() + && Character.isWhitespace(sql.charAt(lastParsePos))) + lastParsePos++; + parsedSQL.append(sql.substring(lastParsePos)); + break; + } else { + if (nextToken.charAt(nextToken.length() - 1) == ',') { + // The token ends with , + nextToken = nextToken.substring(0, nextToken.length() - 1); + + if (nextToken.length() == 0) { + if (lastToken != null) { + updatedReportCols.add(getParseSQLDataColumn(lastToken, null, + parsedSQL, updatedReportCols, false)); + lastToken = null; + } // else just comma => ignore it + } else { + if (lastToken != null) { + updatedReportCols.add(getParseSQLDataColumn(lastToken, nextToken, + parsedSQL, updatedReportCols, false)); + lastToken = null; + } else + updatedReportCols.add(getParseSQLDataColumn(nextToken, null, + parsedSQL, updatedReportCols, false)); + } + } else { + // The token doesn't end with , + if (lastToken == null) + lastToken = nextToken; + else { + String token = getNextSQLParseToken(sql, false); + if (!token.toUpperCase().equals("FROM")) + throw new org.openecomp.portalsdk.analytics.error.ValidationException( + "|FROM keyword or a comma expected after [" + nextToken + + "]."); + + updatedReportCols.add(getParseSQLDataColumn(lastToken, nextToken, + parsedSQL, updatedReportCols, false)); + lastToken = null; + } // else + } // else + } // else + + lastParsePos = curSQLParsePos; + nextToken = getNextSQLParseToken(sql, true); + } // while + } else { // if CYMBAL Script + curSQLParsePos = 0; + Pattern re = null; + Matcher matcher = null; + String extracted = null; + nextToken = getNextCYMBALSQLParseToken(sql,true); + while (nextToken.length() > 0) { + if (lastToken == null) lastToken = nextToken; + + if( lastToken.toUpperCase().startsWith("DO DISPLAY")) { + re = Pattern.compile("each(.*)\\[.(.*?)\\]"); //\\[(.*?)\\] + matcher = re.matcher(nextToken); + if (matcher.find()) { + extracted = matcher.group(); + re = Pattern.compile("\\[(.*?)\\]"); + matcher = re.matcher(nextToken); + if(matcher.find()) { + extracted = matcher.group(); + extracted = extracted.substring(1,extracted.length()-1); + StringTokenizer sToken = new StringTokenizer(extracted, ","); + while(sToken.hasMoreTokens()) { + String str1 = sToken.nextToken().trim().substring(1); + updatedReportCols.add(getParseSQLDataColumn("", str1, + new StringBuffer(""), updatedReportCols, true)); + } + } + + } + + } + lastToken = nextToken; + nextToken = getNextCYMBALSQLParseToken(sql, true); + } + + } + if (updatedReportCols.size() == 0) + throw new org.openecomp.portalsdk.analytics.error.ValidationException( + "The SQL statement must have at least one column in the SELECT clause."); + if (getDataSourceList().getDataSource().size() == 0) + addDataSourceType(new ObjectFactory(), "du0", "DUAL", "", "DUAL", null, null, null); + DataSourceType dst = (DataSourceType) getDataSourceList().getDataSource().get(0); + dst.getDataColumnList().getDataColumn().clear(); + + for (int i = 0; i < updatedReportCols.size(); i++) { + DataColumnType dct = (DataColumnType) updatedReportCols.get(i); + dct.setTableId(dst.getTableId()); + dct.setOrderSeq(i + 1); + dst.getDataColumnList().getDataColumn().add(dct); + } // for + setReportSQL(parsedSQL.toString()); + resetCache(false); + } // parseReportSQL + + private String getNextCYMBALSQLParseToken(String sql, boolean updateParsePos) { + int braketCount = 0; + boolean isInsideQuote = false; + StringBuffer nextToken = new StringBuffer(); + for (int idxNext = curSQLParsePos; idxNext < sql.length(); idxNext++) { + char ch = sql.charAt(idxNext); + + if (ch!='\n') { + nextToken.append(ch); + if (updateParsePos) + curSQLParsePos = idxNext; + } + else { + curSQLParsePos = idxNext+1; + break; + } + } // for + + return nextToken.toString(); + } // getNextSQLParseToken + + public void addChartAdditionalOptions(ObjectFactory objFactory) throws RaptorException { + ChartAdditionalOptions chartOptions = objFactory.createChartAdditionalOptions(); + cr.setChartAdditionalOptions(chartOptions); + } + + public void addChartDrillOptions(ObjectFactory objFactory) throws RaptorException { + ChartDrillOptions chartOptions = objFactory.createChartDrillOptions(); + cr.setChartDrillOptions(chartOptions); +} + + public void addDataminingOptions(ObjectFactory objFactory) throws RaptorException { + DataminingOptions dataminingOptions = objFactory.createDataminingOptions(); + cr.setDataminingOptions(dataminingOptions); + } + /*public void addChartAdditionalOptions(ObjectFactory objFactory, String chartType, String chartMultiplePieOrder, String chartMultiplePieLabelDisplay, + String chartOrientation, String secondaryChartRenderer, String chartDisplay, String legendPosition, + String labelAngle) throws RaptorException { + try { + ChartAdditionalOptions chartOptions = objFactory.createChartAdditionalOptions(); + + if (nvl(chartMultiplePieOrder).length() > 0) + chartOptions.setChartMultiplePieOrder(chartMultiplePieOrder); + if (nvl(chartMultiplePieLabelDisplay).length() > 0) + chartOptions.setChartMultiplePieLabelDisplay(chartMultiplePieLabelDisplay); + if (nvl(chartOrientation).length() > 0) + chartOptions.setChartOrientation(chartOrientation); + if (nvl(secondaryChartRenderer).length() > 0) + chartOptions.setSecondaryChartRenderer(secondaryChartRenderer); + if (nvl(chartDisplay).length() > 0) + chartOptions.setChartDisplay(chartDisplay); + if (nvl(legendPosition).length() > 0) + chartOptions.setLegendPosition(legendPosition); + if (nvl(labelAngle).length() > 0) + chartOptions.setLabelAngle(labelAngle); + + cr.setChartAdditionalOptions(chartOptions); + } catch (JAXBException ex) { + throw new RaptorException(ex.getMessage(), ex.getCause()); + } + } // addChartAdditionalOptions*/ + + +} // ReportDefinition diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportLogEntry.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportLogEntry.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportLogEntry.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportLogEntry.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportMap.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportMap.java new file mode 100644 index 00000000..e3c417a1 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportMap.java @@ -0,0 +1,86 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.openecomp.portalsdk.analytics.RaptorObject; +import org.openecomp.portalsdk.analytics.view.DataRow; +import org.openecomp.portalsdk.analytics.view.DataValue; +import org.openecomp.portalsdk.analytics.view.ReportData; + +public class ReportMap extends RaptorObject { + String markerColor = ""; + String addressColumn = ""; + String dataColumn = ""; + String isMapAllowedYN = ""; + String addAddressInDataYN = ""; + List markers = new ArrayList(); + + public String getIsMapAllowedYN() { + return isMapAllowedYN; + } + public void setIsMapAllowedYN(String isMapAllowedYN) { + this.isMapAllowedYN = isMapAllowedYN; + } + public ReportMap(String markerColor, String addressColumn, String dataColumn, String isMapAllowed, String addAddressInDataYN){ + this.setMarkerColor(markerColor); + this.setAddressColumn(addressColumn); + this.setDataColumn(dataColumn); + this.setIsMapAllowedYN(isMapAllowed); + this.setAddAddressInDataYN(addAddressInDataYN); + } + public String getAddressColumn() { + return addressColumn; + } + public void setAddressColumn(String addressColumn) { + this.addressColumn = addressColumn; + } + public String getDataColumn() { + return dataColumn; + } + public void setDataColumn(String dataColumn) { + this.dataColumn = dataColumn; + } + public String getMarkerColor() { + return markerColor; + } + public void setMarkerColor(String markerColor) { + this.markerColor = markerColor; + } + public List getMarkers() { + return markers; + } + public void setMarkers(List markers) { + this.markers = markers; + } + public String getAddAddressInDataYN() { + return addAddressInDataYN; + } + public void setAddAddressInDataYN(String addAddressInDataYN) { + this.addAddressInDataYN = addAddressInDataYN; + } + + + + +} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportSchedule.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportSchedule.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportSchedule.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportSchedule.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/SecurityEntry.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/SecurityEntry.java new file mode 100644 index 00000000..c5edb12a --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/SecurityEntry.java @@ -0,0 +1,44 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition; + +import org.openecomp.portalsdk.analytics.model.base.*; + +public class SecurityEntry extends IdNameValue { + private boolean readOnly = true; + + public SecurityEntry() { + super(); + } + + public SecurityEntry(String id, String name, boolean readOnly) { + super(id, name); + setReadOnly(readOnly); + } // SecurityEntry + + public boolean isReadOnly() { + return readOnly; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + +} // SecurityEntry diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableJoin.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableJoin.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableJoin.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableJoin.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableSource.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableSource.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableSource.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/TableSource.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ColumnEditJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ColumnEditJSON.java new file mode 100644 index 00000000..4e08a697 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ColumnEditJSON.java @@ -0,0 +1,110 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +public class ColumnEditJSON implements WizardJSON { + + private String tabId; + private String tabName; + + private String colId; + private String colName; + private String displayAlignment; + private String displayHeaderAlignment; + private boolean sortable; + private boolean visible; + + private String drilldownURL; + private String drilldownParams; + private String drilldownType; + + public String getTabId() { + return tabId; + } + public void setTabId(String tabId) { + this.tabId = tabId; + } + public String getTabName() { + return tabName; + } + public void setTabName(String tabName) { + this.tabName = tabName; + } + public String getColId() { + return colId; + } + public void setColId(String colId) { + this.colId = colId; + } + public String getColName() { + return colName; + } + public void setColName(String colName) { + this.colName = colName; + } + public String getDisplayAlignment() { + return displayAlignment; + } + public void setDisplayAlignment(String displayAlignment) { + this.displayAlignment = displayAlignment; + } + public String getDisplayHeaderAlignment() { + return displayHeaderAlignment; + } + public void setDisplayHeaderAlignment(String displayHeaderAlignment) { + this.displayHeaderAlignment = displayHeaderAlignment; + } + public boolean isSortable() { + return sortable; + } + public void setSortable(boolean sortable) { + this.sortable = sortable; + } + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + public String getDrilldownURL() { + return drilldownURL; + } + public void setDrilldownURL(String drilldownURL) { + this.drilldownURL = drilldownURL; + } + public String getDrilldownParams() { + return drilldownParams; + } + public void setDrilldownParams(String drilldownParams) { + this.drilldownParams = drilldownParams; + } + public String getDrilldownType() { + return drilldownType; + } + public void setDrilldownType(String drilldownType) { + this.drilldownType = drilldownType; + } + + + + + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ColumnJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ColumnJSON.java new file mode 100644 index 00000000..8f83c3ea --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ColumnJSON.java @@ -0,0 +1,41 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +public class ColumnJSON implements ElementJSON { + + private String id; + private String name; + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/DefinitionJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/DefinitionJSON.java new file mode 100644 index 00000000..68211005 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/DefinitionJSON.java @@ -0,0 +1,215 @@ +package org.openecomp.portalsdk.analytics.model.definition.wizard; + +import java.util.List; + +public class DefinitionJSON implements WizardJSON { + + private String tabName; + private String tabId; + + private String reportId; + private String reportName; + private String reportDescr; + private String reportType; + private String dbInfo; + private String formHelpText; + private Integer pageSize; + private List displayArea = null; + private Boolean hideFormFieldsAfterRun; + private Integer maxRowsInExcelCSVDownload; + private Integer frozenColumns; + private String dataGridAlign; + private String emptyMessage; + private String dataContainerHeight; + private String dataContainerWidth; + private List displayOptions = null; + private Boolean runtimeColSortDisabled; + private Integer numFormCols; + private String reportTitle; + private String reportSubTitle; + + @Override + public String getTabName() { + return tabName; + } + + @Override + public void setTabName(String tabName) { + this.tabName = tabName; + } + + @Override + public String getTabId() { + return tabId; + } + + @Override + public void setTabId(String tabId) { + this.tabId = tabId; + } + + + + public String getReportId() { + return reportId; + } + + public void setReportId(String reportId) { + this.reportId = reportId; + } + + public String getReportName() { + return reportName; + } + + public void setReportName(String reportName) { + this.reportName = reportName; + } + + public String getReportDescr() { + return reportDescr; + } + + public void setReportDescr(String reportDescr) { + this.reportDescr = reportDescr; + } + + public String getReportType() { + return reportType; + } + + public void setReportType(String reportType) { + this.reportType = reportType; + } + + public String getDbInfo() { + return dbInfo; + } + + public void setDbInfo(String dbInfo) { + this.dbInfo = dbInfo; + } + + public String getFormHelpText() { + return formHelpText; + } + + public void setFormHelpText(String formHelpText) { + this.formHelpText = formHelpText; + } + + public Integer getPageSize() { + return pageSize; + } + + public void setPageSize(Integer pageSize) { + this.pageSize = pageSize; + } + + public List getDisplayArea() { + return displayArea; + } + + public void setDisplayArea(List displayArea) { + this.displayArea = displayArea; + } + + public Boolean getHideFormFieldsAfterRun() { + return hideFormFieldsAfterRun; + } + + public void setHideFormFieldsAfterRun(Boolean hideFormFieldsAfterRun) { + this.hideFormFieldsAfterRun = hideFormFieldsAfterRun; + } + + public Integer getMaxRowsInExcelCSVDownload() { + return maxRowsInExcelCSVDownload; + } + + public void setMaxRowsInExcelCSVDownload(Integer maxRowsInExcelCSVDownload) { + this.maxRowsInExcelCSVDownload = maxRowsInExcelCSVDownload; + } + + public Integer getFrozenColumns() { + return frozenColumns; + } + + public void setFrozenColumns(Integer frozenColumns) { + this.frozenColumns = frozenColumns; + } + + public String getDataGridAlign() { + return dataGridAlign; + } + + public void setDataGridAlign(String dataGridAlign) { + this.dataGridAlign = dataGridAlign; + } + + public String getEmptyMessage() { + return emptyMessage; + } + + public void setEmptyMessage(String emptyMessage) { + this.emptyMessage = emptyMessage; + } + + public String getDataContainerHeight() { + return dataContainerHeight; + } + + public void setDataContainerHeight(String dataContainerHeight) { + this.dataContainerHeight = dataContainerHeight; + } + + public String getDataContainerWidth() { + return dataContainerWidth; + } + + public void setDataContainerWidth(String dataContainerWidth) { + this.dataContainerWidth = dataContainerWidth; + } + + public List getDisplayOptions() { + return displayOptions; + } + + public void setDisplayOptions(List displayOptions) { + this.displayOptions = displayOptions; + } + + public Boolean getRuntimeColSortDisabled() { + return runtimeColSortDisabled; + } + + public void setRuntimeColSortDisabled(Boolean runtimeColSortDisabled) { + this.runtimeColSortDisabled = runtimeColSortDisabled; + } + + public Integer getNumFormCols() { + return numFormCols; + } + + public void setNumFormCols(Integer numFormCols) { + this.numFormCols = numFormCols; + } + + public String getReportTitle() { + return reportTitle; + } + + public void setReportTitle(String reportTitle) { + this.reportTitle = reportTitle; + } + + public String getReportSubTitle() { + return reportSubTitle; + } + + public void setReportSubTitle(String reportSubTitle) { + this.reportSubTitle = reportSubTitle; + } + + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ElementJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ElementJSON.java new file mode 100644 index 00000000..aba1e8b4 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ElementJSON.java @@ -0,0 +1,33 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +import java.util.ArrayList; +import java.util.Map; + +import org.openecomp.portalsdk.analytics.view.ColumnHeader; + +public interface ElementJSON { + + // To be defined by child class + public String getId(); + public String getName(); + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/FormEditJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/FormEditJSON.java new file mode 100644 index 00000000..47b6d1b0 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/FormEditJSON.java @@ -0,0 +1,113 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +import java.util.List; + +public class FormEditJSON implements WizardJSON { + + private String tabId; + private String tabName; + + private String fieldId; + private String fieldName; + private String fieldType; + private boolean visible; + private String defaultValue; + private String fieldDefaultSQL; + private String fieldSQL; + private String validationType; + private List predefinedValueList; + + + public String getTabId() { + return tabId; + } + public void setTabId(String tabId) { + this.tabId = tabId; + } + public String getTabName() { + return tabName; + } + public void setTabName(String tabName) { + this.tabName = tabName; + } + + + public String getFieldId() { + return fieldId; + } + public void setFieldId(String fieldId) { + this.fieldId = fieldId; + } + public String getFieldName() { + return fieldName; + } + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public String getFieldType() { + return fieldType; + } + public void setFieldType(String fieldType) { + this.fieldType = fieldType; + } + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + public String getDefaultValue() { + return defaultValue; + } + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + public String getFieldDefaultSQL() { + return fieldDefaultSQL; + } + public void setFieldDefaultSQL(String fieldDefaultSQL) { + this.fieldDefaultSQL = fieldDefaultSQL; + } + public String getValidationType() { + return validationType; + } + public void setValidationType(String validationType) { + this.validationType = validationType; + } + public List getPredefinedValueList() { + return predefinedValueList; + } + public void setPredefinedValueList(List predefinedValueList) { + this.predefinedValueList = predefinedValueList; + } + public String getFieldSQL() { + return fieldSQL; + } + public void setFieldSQL(String fieldSQL) { + this.fieldSQL = fieldSQL; + } + + + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/IdNameBooleanJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/IdNameBooleanJSON.java new file mode 100644 index 00000000..50add1f4 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/IdNameBooleanJSON.java @@ -0,0 +1,32 @@ +package org.openecomp.portalsdk.analytics.model.definition.wizard; + +public class IdNameBooleanJSON { + + private String id; + private String name; + private boolean selected; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public boolean isSelected() { + return selected; + } + public void setSelected(boolean selected) { + this.selected = selected; + } + + + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ImportJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ImportJSON.java new file mode 100644 index 00000000..282b7c41 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ImportJSON.java @@ -0,0 +1,54 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +import java.util.List; + +public class ImportJSON implements WizardJSON { + + private String tabId; + private String tabName; + + private String reportXML; + + + public String getTabId() { + return tabId; + } + public void setTabId(String tabId) { + this.tabId = tabId; + } + public String getTabName() { + return tabName; + } + public void setTabName(String tabName) { + this.tabName = tabName; + } + public String getReportXML() { + return reportXML; + } + public void setReportXML(String reportXML) { + this.reportXML = reportXML; + } + + + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ListJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ListJSON.java new file mode 100644 index 00000000..34c2c99b --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/ListJSON.java @@ -0,0 +1,40 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +import java.util.ArrayList; +import java.util.Map; + +import org.openecomp.portalsdk.analytics.view.ColumnHeader; + +public class ListJSON { + + private ArrayList elements; + + public ArrayList getElements() { + return elements; + } + + public void setElements(ArrayList elements) { + this.elements = elements; + } + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/MessageJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/MessageJSON.java new file mode 100644 index 00000000..d3955448 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/MessageJSON.java @@ -0,0 +1,55 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; + +import org.json.JSONObject; +import org.openecomp.portalsdk.analytics.model.base.IdNameValue; +import org.openecomp.portalsdk.analytics.view.ColumnHeader; +import org.openecomp.portalsdk.analytics.view.DataValue; +import org.openecomp.portalsdk.analytics.xmlobj.ColFilterList; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnList; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; + +public class MessageJSON { + + private String message; + private String anyStacktrace; + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + public String getAnyStacktrace() { + return anyStacktrace; + } + public void setAnyStacktrace(String anyStacktrace) { + this.anyStacktrace = anyStacktrace; + } + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/NameBooleanJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/NameBooleanJSON.java new file mode 100644 index 00000000..7f191d93 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/NameBooleanJSON.java @@ -0,0 +1,25 @@ +package org.openecomp.portalsdk.analytics.model.definition.wizard; + +public class NameBooleanJSON { + + private String name; + private boolean selected; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public boolean isSelected() { + return selected; + } + public void setSelected(boolean selected) { + this.selected = selected; + } + + + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/QueryJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/QueryJSON.java new file mode 100644 index 00000000..ece9a02c --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/QueryJSON.java @@ -0,0 +1,60 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +import java.util.ArrayList; +import java.util.Map; + +import org.openecomp.portalsdk.analytics.model.definition.wizard.WizardJSON; +import org.openecomp.portalsdk.analytics.view.ColumnHeader; + +public class QueryJSON implements WizardJSON { + + private String query; + private String tabName; + private String tabId; + + + public String getTabName() { + return tabName; + } + + public void setTabName(String tabName) { + this.tabName = tabName; + } + + public String getTabId() { + return tabId; + } + + public void setTabId(String tabId) { + this.tabId = tabId; + } + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/QueryResultJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/QueryResultJSON.java new file mode 100644 index 00000000..41c8bca0 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/QueryResultJSON.java @@ -0,0 +1,70 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +import java.util.ArrayList; +import java.util.Map; + +import org.openecomp.portalsdk.analytics.view.ColumnHeader; + +public class QueryResultJSON { + + private String query; + + private int totalRows; + private ArrayList reportDataColumns; + private ArrayList> reportDataRows; + + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + public int getTotalRows() { + return totalRows; + } + + public void setTotalRows(int totalRows) { + this.totalRows = totalRows; + } + + public ArrayList getReportDataColumns() { + return reportDataColumns; + } + + public void setReportDataColumns(ArrayList reportDataColumns) { + this.reportDataColumns = reportDataColumns; + } + + public ArrayList> getReportDataRows() { + return reportDataRows; + } + + public void setReportDataRows(ArrayList> reportDataRows) { + this.reportDataRows = reportDataRows; + } + + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/SearchFieldJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/SearchFieldJSON.java new file mode 100644 index 00000000..3689619c --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/SearchFieldJSON.java @@ -0,0 +1,41 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.definition.wizard; + +public class SearchFieldJSON implements ElementJSON { + + private String id; + private String name; + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/WizardJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/WizardJSON.java new file mode 100644 index 00000000..8ef937c1 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/wizard/WizardJSON.java @@ -0,0 +1,9 @@ +package org.openecomp.portalsdk.analytics.model.definition.wizard; + +public interface WizardJSON { + + public String getTabName(); + public void setTabName(String tabName); + public String getTabId(); + public void setTabId(String tabId); +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PageEvent.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PageEvent.java new file mode 100644 index 00000000..c724a20a --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PageEvent.java @@ -0,0 +1,256 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.pdf; + +import java.awt.Color; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; + +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.system.Globals; + +import com.lowagie.text.BadElementException; +import com.lowagie.text.Cell; +import com.lowagie.text.Document; +import com.lowagie.text.ExceptionConverter; +import com.lowagie.text.Font; +import com.lowagie.text.FontFactory; +import com.lowagie.text.Image; +import com.lowagie.text.Paragraph; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.PdfContentByte; +import com.lowagie.text.pdf.PdfDestination; +import com.lowagie.text.pdf.PdfOutline; +import com.lowagie.text.pdf.PdfPCell; +import com.lowagie.text.pdf.PdfPTable; +import com.lowagie.text.pdf.PdfPageEventHelper; +import com.lowagie.text.pdf.PdfWriter; + +class PageEvent extends PdfPageEventHelper { + private PdfBean pb; + private int pageNo = 0; + private int omit_page_count = 0; + private int DEFAULT_LOGO_SIZE = 100; + + public PageEvent(PdfBean pb) { + this.pb = pb; + } + + private int getWidthEntries(int howManyLogos){ + int widthEntries = 0; + + if(howManyLogos == 2) + widthEntries = 3; + else + if(howManyLogos == 1) + widthEntries = 2; + else + widthEntries = 0; + + return widthEntries; + } + + private int getHowManyLogos(){ + int howManyLogos = 0; + + if(AppUtils.isNotEmpty(pb.getLogo1Url()) && !pb.getLogo1Url().equalsIgnoreCase("")) + howManyLogos ++; + + if(AppUtils.isNotEmpty(pb.getLogo2Url()) && !pb.getLogo2Url().equalsIgnoreCase("")) + howManyLogos ++; + + return howManyLogos; + } + + private float[] fillWidthsArray(int howManyLogos){ + float[] widthsArray = new float[howManyLogos + 1]; + + //If one logo, we will need two columns in the header[left log, spacer] + if(howManyLogos == 1){ + widthsArray = new float[2]; + widthsArray[0] = 0.1f; + widthsArray[1] = 0.1f; + } + //If two logs, we will need three columns in the header [left log, spacer, right log] + else + if(howManyLogos == 2){ + widthsArray = new float[3]; + widthsArray[0] = 0.1f; + widthsArray[1] = 0.5f; + widthsArray[2] = 0.1f; + } + + return widthsArray; + } + public void onStartPage(PdfWriter writer, Document document) { + + Font font = FontFactory.getFont(Globals.getFooterFontFamily(), Globals.getFooterFontSize(), Font.NORMAL, Color.BLACK); + int howManyLogos = getHowManyLogos(); + + //No need to draw anything in the header if no logo was set in the report. + if(howManyLogos == 0) + return; + + float[] widths = fillWidthsArray(howManyLogos); + + PdfPTable foot = new PdfPTable(widths); + + if(AppUtils.isNotEmpty(pb.getLogo1Url()) && !pb.getLogo1Url().equalsIgnoreCase("")) + addLogo(foot, font, pb.getLogo1Url().substring(pb.getLogo1Url().indexOf("|") + 1).trim(), Cell.ALIGN_LEFT, pb.getLogo1Size() == null ? DEFAULT_LOGO_SIZE : pb.getLogo1Size()); + + PdfPCell spacingCell = new PdfPCell(); + spacingCell.setBorderColor(Color.WHITE); + foot.addCell(spacingCell); + + //Using logo1 size for now - use logo2 size if it is required to deal it separately. + if(AppUtils.isNotEmpty(pb.getLogo2Url()) && !pb.getLogo2Url().equalsIgnoreCase("")) + addLogo(foot, font, pb.getLogo2Url().substring(pb.getLogo2Url().indexOf("|") + 1).trim(), Cell.ALIGN_RIGHT, pb.getLogo2Size() == null ? DEFAULT_LOGO_SIZE : pb.getLogo2Size()); + + foot.setTotalWidth(getPageWidth(document)); + foot.writeSelectedRows(0, -1, 36, 600, writer.getDirectContent()); + } + + public void onEndPage(PdfWriter writer, Document document) { + + Font font = FontFactory.getFont(Globals.getFooterFontFamily(), Globals.getFooterFontSize(), Font.NORMAL, Color.BLACK); + + try { + + // footer + float[] f = { 1f, 0.4f, 1f }; + PdfPTable foot = new PdfPTable(f); + foot.getDefaultCell().setBorderWidth(0); + foot.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + foot.getDefaultCell().setVerticalAlignment(Rectangle.ALIGN_BOTTOM); + + foot.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_LEFT); + addLeftFooter(foot, font); + + foot.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + addPageNumber(foot, font, pb.isPageNumberAtFooter(), document.getPageNumber()); + + foot.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_RIGHT); + foot.getDefaultCell().setNoWrap(true); + + foot.addCell(new Paragraph(" " + PdfReportHandler.currentTime(pb.getTimestampPattern()), font)); + + foot.setTotalWidth(getPageWidth(document)); + foot.writeSelectedRows(0, -1, document.leftMargin(), document.bottomMargin(), writer.getDirectContent()); + + // bookmark + pageNo++; + PdfContentByte cb = writer.getDirectContent(); + PdfDestination destination = new PdfDestination(PdfDestination.FITH); + String bookmark = "Data Page " + (pageNo - omit_page_count); + if (pageNo == 1) { + if (pb.isCoverPageIncluded()) { + bookmark = "Cover Page"; + omit_page_count++; + } else if (pb.isDisplayChart()) { + bookmark = "Chart"; + omit_page_count++; + } + } + if (pageNo == 2 && pb.isCoverPageIncluded() && pb.isDisplayChart()) { + bookmark = "Chart"; + omit_page_count++; + } + + PdfOutline outline = new PdfOutline(cb.getRootOutline(), destination, bookmark); + + } catch (Exception e) { + throw new ExceptionConverter(e); + } + } + + private void addPageNumber(PdfPTable table, Font font, boolean isAdd, int pageNum) { + if (isAdd) + table.addCell(new Paragraph(Globals.getWordBeforePageNumber() + " " + pageNum + " " + Globals.getWordAfterPageNumber(), font)); + else + table.addCell(""); + } + + private void addLeftFooter(PdfPTable table, Font font) { + Font font1 = new Font(font); + font1.setSize(Globals.getPDFFooterFontSize()); + + if (isEmpty(pb.getLeftFooter())) + table.addCell(new Paragraph(" " + Globals.getPDFFooter(), font1)); + else + table.addCell(new Paragraph(pb.getLeftFooter(), font)); + } + + private void addHeaderDummy(PdfPTable table, Font font) { + Font font1 = new Font(font); + font1.setSize(Globals.getPDFFooterFontSize()); + + table.addCell(new Paragraph("Header row", font1)); + } + + private void addLogo(PdfPTable table, Font font, String imgSrc, int alignment, int absoluteSize) { + + Image img = null; + try { + img = Image.getInstance(pb.getFullWebContextPath() + AppUtils.getImgFolderURL() + File.separator + imgSrc); + } catch (BadElementException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + img = null; + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + img = null; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + + } + if(img == null){ + //log that the input file couldnt be loaded - + } + else{ + //img.scaleAbsolute(absoluteSize, absoluteSize); + img.scalePercent(absoluteSize, absoluteSize); + PdfPCell cell = new PdfPCell(img); + cell.setBorderColor(Color.WHITE); + cell.setHorizontalAlignment(alignment); + table.addCell(cell); + } + + } + + public static float getPageWidth(Document doc) { + return doc.getPageSize().width() - doc.leftMargin() - doc.rightMargin(); + } + + public static float getPageHeight(Document doc) { + return doc.getPageSize().height() - doc.topMargin() - doc.bottomMargin(); + } + + private float getHeadTopMargin(Document doc, PdfPTable table) { + return doc.getPageSize().height() - doc.topMargin() + table.getTotalHeight(); + } + + private boolean isEmpty(String str) { + return str == null || str.trim().length() == 0; + } + +} // PageEvent diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfBean.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfBean.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfBean.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfBean.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfReportHandler.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfReportHandler.java new file mode 100644 index 00000000..c27ba0c5 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfReportHandler.java @@ -0,0 +1,1898 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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. + * ================================================================================ + */ + +/* =========================================================================================== + * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) + * Raptor : This tool is used to generate different kinds of reports with lot of utilities + * =========================================================================================== + * + * ------------------------------------------------------------------------------------------- + * PdfReportHandler.java - This class is used to generate reports in PDF using iText + * ------------------------------------------------------------------------------------------- + * + * + * Changes + * ------- + * 14-Jul-2009 : Version 8.4 (Sundar);
    + *
  • Dashboard reports can be downloaded with each report occupying separate page including its charts.
  • + *
+ * + */ +package org.openecomp.portalsdk.analytics.model.pdf; + +import java.awt.Color; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringReader; +import java.net.MalformedURLException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeMap; +import java.util.Vector; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.error.ReportSQLException; +import org.openecomp.portalsdk.analytics.model.ReportHandler; +import org.openecomp.portalsdk.analytics.model.ReportLoader; +import org.openecomp.portalsdk.analytics.model.base.IdNameValue; +import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; +import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.system.ConnectionUtils; +import org.openecomp.portalsdk.analytics.system.Globals; +import org.openecomp.portalsdk.analytics.util.AppConstants; +import org.openecomp.portalsdk.analytics.util.DataSet; +import org.openecomp.portalsdk.analytics.util.HtmlStripper; +import org.openecomp.portalsdk.analytics.util.Utils; +import org.openecomp.portalsdk.analytics.view.ColumnHeader; +import org.openecomp.portalsdk.analytics.view.ColumnHeaderRow; +import org.openecomp.portalsdk.analytics.view.DataRow; +import org.openecomp.portalsdk.analytics.view.DataValue; +import org.openecomp.portalsdk.analytics.view.HtmlFormatter; +import org.openecomp.portalsdk.analytics.view.ReportData; +import org.openecomp.portalsdk.analytics.view.RowHeader; +import org.openecomp.portalsdk.analytics.view.RowHeaderCol; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +import com.lowagie.text.BadElementException; +import com.lowagie.text.Chunk; +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.ElementTags; +import com.lowagie.text.Font; +import com.lowagie.text.FontFactory; +import com.lowagie.text.Image; +import com.lowagie.text.PageSize; +import com.lowagie.text.Paragraph; +import com.lowagie.text.Phrase; +import com.lowagie.text.Rectangle; +import com.lowagie.text.html.simpleparser.HTMLWorker; +import com.lowagie.text.html.simpleparser.StyleSheet; +import com.lowagie.text.pdf.PdfPCell; +import com.lowagie.text.pdf.PdfPTable; +import com.lowagie.text.pdf.PdfWriter; + +/** + * @author mwliu and sundar + * + */ +public class PdfReportHandler extends org.openecomp.portalsdk.analytics.RaptorObject{ + + /** + * + */ + private PdfBean pb; + private HtmlStripper strip = new HtmlStripper(); + private static final int RetryCreateNewImage = 3; + private int retryCreateNewImageCount=0; + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PdfReportHandler.class); + + private String FONT_FAMILY = "Arial"; + private int FONT_SIZE = 9; + + public PdfReportHandler() { } + + public void createPdfFileContent(HttpServletRequest request, HttpServletResponse response, int type) throws IOException, RaptorException { + + Document document = new Document(); + ReportHandler rh = new ReportHandler(); + String formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); + String pdfFName = ""; + String user_id = AppUtils.getUserID(request); + response.reset(); + response.setContentType("application/pdf"); + OutputStream outStream = response.getOutputStream(); + + String formattedReportName = ""; + PdfWriter writer = null; + ReportRuntime firstReportRuntimeObj = null; + int returnValue = 0; + + ReportRuntime rr = null; + if(rr==null) rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); + + boolean isDashboard = false; + if ((request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) && ( ((String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)).equals(rr.getReportID())) ) { + isDashboard = true; + } + if(isDashboard) { + try { + String reportID = (String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID); + ReportRuntime rrDash = rh.loadReportRuntime(request, reportID, true, 1); + pb = preparePdfBean(request,rrDash); + + // Setting pb Values + document.setPageSize(PageSize.getRectangle(pb.getPagesize())); + if(!pb.isPortrait()) // get this from properties file + document.setPageSize(document.getPageSize().rotate()); + + // + writer = PdfWriter.getInstance(document, response.getOutputStream()); + writer.setPageEvent(new PageEvent(pb));//header,footer,bookmark + document.open(); + + formattedReportName = new HtmlStripper().stripSpecialCharacters(rrDash.getReportName()); + if(pb.isAttachmentOfEmail()) + response.setHeader("Content-disposition", "inline"); + else + response.setHeader("Content-disposition", "attachment;filename="+ formattedReportName+formattedDate+user_id+".pdf"); + + pdfFName = "dashboard"+formattedReportName+formattedDate+user_id+".pdf"; + Map reportRuntimeMap = null; + Map reportDataMap = null; + Map reportDisplayTypeMap = null; + + reportRuntimeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); + reportDataMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); + reportDisplayTypeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); + + if(reportRuntimeMap!=null) { + //ServletOutputStream sos = response.getOutputStream(); + Set setReportRuntime = reportRuntimeMap.entrySet(); + Set setReportDataMap = reportDataMap.entrySet(); + Set setReportDisplayTypeMap = reportDisplayTypeMap.entrySet(); + + Iterator iter2 = setReportDataMap.iterator(); + Iterator iter3 = setReportDisplayTypeMap.iterator(); + int count = 0; + for(Iterator iter = setReportRuntime.iterator(); iter.hasNext(); ) { + count++; + Map.Entry entryData = (Entry) iter2.next(); + Map.Entry entry = (Entry) iter.next(); + Map.Entry entryCheckChart = (Entry) iter3.next(); + //String rep_id = (String) entry.getKey(); + ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); + + if(count == 1) { + firstReportRuntimeObj = (ReportRuntime) entry.getValue(); + if(pb.isCoverPageIncluded()) { + document = paintDashboardCoverPage(document, rrDash, firstReportRuntimeObj, request); + } + } + ReportData rdDashRep = (ReportData) entryData.getValue(); + int col = 0; + //pb.setDisplayChart(nvl(rr.getChartType()).trim().length()>0 && rr.getDisplayChart()); + if( ((rrDashRep.getChartType()).trim().length()>0 && rrDashRep.getDisplayChart()) && entryCheckChart.getValue().toString().equals("c")) { + document.newPage(); + pb.setTitle(nvl(rrDashRep.getReportTitle()).length()>0?rrDashRep.getReportTitle():rrDashRep.getReportName()); + paintPdfImage(request, document,AppUtils.getTempFolderPath()+"cr_"+ pb.getUserId()+"_"+request.getSession().getId()+"_"+rrDashRep.getReportID()+".png", rrDashRep); + } else { + document.newPage(); + pb.setTitle(nvl(rrDashRep.getReportTitle()).length()>0?rrDashRep.getReportTitle():rrDashRep.getReportName()); + paintPdfData(request, document,rdDashRep,rrDashRep, ""); + } + } + + } + } catch (DocumentException dex) {dex.printStackTrace();} + catch (RaptorException rex) {rex.printStackTrace();} + } else { + + //ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); + //ReportData rd = (ReportData) request.getSession().getAttribute(AppConstants.RI_REPORT_DATA); + rr = null; + ReportData rd = null; + String parent = ""; + int parentFlag = 0; + if(!nvl(request.getParameter("parent"), "").equals("N")) parent = nvl(request.getParameter("parent"), ""); + if(parent.startsWith("parent_")) parentFlag = 1; + if(parentFlag == 1) { + rr = (ReportRuntime) request.getSession().getAttribute(parent+"_rr"); + rd = (ReportData) request.getSession().getAttribute(parent+"_rd"); + } + if(rr==null) rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); + if(rd==null) rd = (ReportData) request.getSession().getAttribute(AppConstants.RI_REPORT_DATA); + + pb = preparePdfBean(request,rr); + FONT_FAMILY = rr.getPDFFont(); + FONT_SIZE = rr.getPDFFontSize(); + //System.out.println(pb); + + formattedReportName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); + + + + response.setContentType("application/pdf"); + if(pb.isAttachmentOfEmail()) + response.setHeader("Content-disposition", "inline"); + else + response.setHeader("Content-disposition", "attachment;filename="+ formattedReportName+formattedDate+user_id+".pdf"); + + document.setPageSize(PageSize.getRectangle(pb.getPagesize())); + + if(!pb.isPortrait()) // get this from properties file + document.setPageSize(document.getPageSize().rotate()); + + try { + + writer = PdfWriter.getInstance(document, outStream); + writer.setPageEvent(new PageEvent(pb));//header,footer,bookmark + document.open(); + + //System.out.println("Document 1 " + document); + if(pb.isCoverPageIncluded()) { + document = paintCoverPage(document, rr, request); + } + + //boolean isImageRotate = false; + //System.out.println("Document 2 " + document); + + if(pb.isDisplayChart()) { + paintPdfImage(request, document,AppUtils.getTempFolderPath()+"cr_"+ pb.getUserId()+"_"+request.getSession().getId()+"_"+rr.getReportID()+".png", rr); + } + //System.out.println("Document 4" + document); + + document.newPage(); + if(type == 3 && rr.getSemaphoreList()==null && !(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) ) { //type = 3 is whole + String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + returnValue = paintPdfData(request, document, rd, rr, sql_whole); + } else if(type == 2) { + returnValue = paintPdfData(request, document, rd, rr, ""); + } else { + //String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); + int downloadLimit = (rr.getMaxRowsInExcelDownload()>0)?rr.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); + String action = request.getParameter(AppConstants.RI_ACTION); + + if(!(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) && !action.endsWith("session")) + rd = rr.loadReportData(-1, AppUtils.getUserID(request), downloadLimit,request, false /*download*/); + if(rr.getSemaphoreList()!=null) { + rd = rr.loadReportData(-1, AppUtils.getUserID(request), downloadLimit,request, true); + returnValue = paintPdfData(request, document, rd, rr, ""); + } else { + returnValue = paintPdfData(request, document, rd, rr, rr.getWholeSQL()); + } + + + } + + + //paintPdfData(document,rd,rr); + + + } catch (DocumentException de) { + de.printStackTrace(); + //System.err.println("document: " + de.getMessage()); + } + + } + document.close(); + int mb = 1024*1024; + Runtime runtime = Runtime.getRuntime(); + logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); + logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" + + (runtime.maxMemory() - runtime.freeMemory()) / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" + + runtime.freeMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); + logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); + + } + + private Document paintCoverPage(Document doc, ReportRuntime rr, HttpServletRequest request) throws IOException, DocumentException { + + //System.out.println("PDFREPORTHANDLER STARTED ... " ); + if(nvl(rr.getPdfImg()).length()>0) { + Image image1 = Image.getInstance(AppUtils.getExcelTemplatePath()+"../../"+AppUtils.getImgFolderURL()+rr.getPdfImg()); + image1.scalePercent(20f, 20f); + doc.add(image1); + } + float firstColumnSize = Globals.getCoverPageFirstColumnSize(); + float[] relativeWidths = {firstColumnSize,1f-firstColumnSize}; + PdfPTable table = new PdfPTable(relativeWidths); + table.getDefaultCell().setBorderWidth(0); + addEmptyRows(table,6); + HTMLWorker worker = new HTMLWorker(doc); + StyleSheet style = new StyleSheet(); + style.loadTagStyle("body", "leading", "16,0"); + StringBuffer reportDescrBuf = new StringBuffer(""); + ArrayList descr = HTMLWorker.parseToList(new StringReader(nvl(rr.getReportDescr())), style); + ArrayList paraList = null; + if(nvl(rr.getReportTitle()).length()>0) { + add2Cells(table,"Report Title : ",nvl(rr.getReportTitle())); + if(nvl(rr.getReportSubTitle()).length()>0) { + add2Cells(table,"Report Sub-Title : ",nvl(rr.getReportSubTitle())); + System.out.println("Adding the report sub-title "); + } + + } else { + add2Cells(table,"Report Name : ",nvl(rr.getReportName())); + } + if((descr!=null && descr.size()>0)) { + paraList = (com.lowagie.text.Paragraph)descr.get(0); + for (int i=0 ; i0) { + String nameValue[] = Globals.getSessionInfoForTheCoverPage().split(","); + String name=nameValue[0]; + String value=nameValue[1]; + add2Cells(table,name+" : ",(AppUtils.getRequestNvlValue(request, value).length()>0?AppUtils.getRequestNvlValue(request, value):nvl((String)request.getSession().getAttribute(value)))); + } + + if(Globals.isCreatedOwnerInfoNeeded()) { + add2Cells(table,"Created By : ",nvl(AppUtils.getUserName(rr.getCreateID()))); + add2Cells(table,"Owner : ",nvl(AppUtils.getUserName(rr.getOwnerID()))); + } + if(Globals.displayLoginIdForDownloadedBy()) + add2Cells(table,"Downloaded by : ",nvl(AppUtils.getUserBackdoorLoginId(request))); + else + add2Cells(table,"Downloaded by : ",nvl(AppUtils.getUserName(AppUtils.getUserID(request)))); + + addEmptyRows(table,1); + + boolean isFirstRow = true; + ArrayList al = rr.getParamNameValuePairsforPDFExcel(request, 1); + if(al.size()<=0) { + al = (ArrayList) request.getSession().getAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); + } + + Iterator it = al.iterator(); + addEmptyRows(table,1); + //if(!Globals.customizeFormFieldInfo()) { + if(rr.getFormFieldComments(request).length()<=0) { + while(it.hasNext()) { + + if(isFirstRow) { + add2Cells(table, "Run-time Criteria : ", " "); + isFirstRow = false; + } + + IdNameValue value = (IdNameValue)it.next(); + if(!value.getId().trim().equals("BLANK")) + //System.out.println("PDFREPORTHANDLER " + value.getId()+" : "+value.getName()); + add2Cells(table, value.getId()+" : ",value.getName().replaceAll("~",",")); + //add2Cells(table, rr.getFormFieldComments(request), " "); + } + addEmptyRows(table,1); + doc.add(table); + + } else { + it = al.iterator(); + if(it.hasNext()) { + //add2Cells(table, "Run-time Criteria : ", " "); + addEmptyRows(table,1); + doc.add(table); + //com.lowagie.text.html.HtmlParser.parse(doc, new StringReader(rr.getFormFieldComments(request))); + ArrayList p = HTMLWorker.parseToList(new StringReader(rr.getFormFieldComments(request).replaceAll("~",",")), style); + + for (int k = 0; k < p.size(); ++k){ + doc.add((com.lowagie.text.Element)p.get(k)); + } + } + } + + return doc; + } + + + private Document paintDashboardCoverPage(Document doc, ReportRuntime rrDashRep, ReportRuntime firstReportRuntimeObj, HttpServletRequest request) throws IOException, DocumentException { + + //System.out.println("PDFREPORTHANDLER STARTED ... " ); + float firstColumnSize = Globals.getCoverPageFirstColumnSize(); + float[] relativeWidths = {firstColumnSize,1f-firstColumnSize}; + PdfPTable table = new PdfPTable(relativeWidths); + table.getDefaultCell().setBorderWidth(0); + addEmptyRows(table,6); + + add2Cells(table,"Report Name : ",rrDashRep.getReportName()); + add2Cells(table,"Description : ",rrDashRep.getReportDescr()); + if(Globals.getSessionInfoForTheCoverPage().length()>0) { + String nameValue[] = Globals.getSessionInfoForTheCoverPage().split(","); + String name=nameValue[0]; + String value=nameValue[1]; + add2Cells(table,name+" : ",(AppUtils.getRequestNvlValue(request, value).length()>0?AppUtils.getRequestNvlValue(request, value):nvl((String)request.getSession().getAttribute(value)))); + } + + if(Globals.isCreatedOwnerInfoNeeded()) { + add2Cells(table,"Created By : ",AppUtils.getUserName(rrDashRep.getCreateID())); + add2Cells(table,"Owner : ",AppUtils.getUserName(rrDashRep.getOwnerID())); + } + if(Globals.displayLoginIdForDownloadedBy()) + add2Cells(table,"Downloaded by : ",AppUtils.getUserBackdoorLoginId(request)); + else + add2Cells(table,"Downloaded by : ",AppUtils.getUserName(request)); + + addEmptyRows(table,1); + + boolean isFirstRow = true; + ArrayList al = firstReportRuntimeObj.getParamNameValuePairsforPDFExcel(request, 2); + Iterator it = al.iterator(); + addEmptyRows(table,1); + //if(!Globals.customizeFormFieldInfo()) { + if(firstReportRuntimeObj.getFormFieldComments(request).length()<=0) { + while(it.hasNext()) { + + if(isFirstRow) { + add2Cells(table, "Run-time Criteria : ", " "); + isFirstRow = false; + } + + IdNameValue value = (IdNameValue)it.next(); + if(!value.getId().trim().equals("BLANK")) + //System.out.println("PDFREPORTHANDLER " + value.getId()+" : "+value.getName()); + add2Cells(table, value.getId()+" : ",value.getName()); + //add2Cells(table, rr.getFormFieldComments(request), " "); + } + addEmptyRows(table,1); + doc.add(table); + + } else { + it = al.iterator(); + if(it.hasNext()) { + //add2Cells(table, "Run-time Criteria : ", " "); + addEmptyRows(table,1); + doc.add(table); + //com.lowagie.text.html.HtmlParser.parse(doc, new StringReader(rr.getFormFieldComments(request))); + HTMLWorker worker = new HTMLWorker(doc); + StyleSheet style = new StyleSheet(); + style.loadTagStyle("body", "leading", "16,0"); + ArrayList p = HTMLWorker.parseToList(new StringReader(firstReportRuntimeObj.getFormFieldComments(request)), style); + + for (int k = 0; k < p.size(); ++k){ + doc.add((com.lowagie.text.Element)p.get(k)); + } + } + } + + return doc; + } + + + public static void addEmptyRows(PdfPTable table, int rows) throws DocumentException { + for (int i=0; i0?AppUtils.getRequestNvlValue(request, "multiplePieOrder").equals("row"):rr.isMultiplePieOrderByRow())) ); + additionalChartOptionsMap.put("multiplePieLabelDisplay", AppUtils.getRequestNvlValue(request, "multiplePieLabelDisplay").length()>0? AppUtils.getRequestNvlValue(request, "multiplePieLabelDisplay"):rr.getMultiplePieLabelDisplay()); + additionalChartOptionsMap.put("chartDisplay", new Boolean(AppUtils.getRequestNvlValue(request, "chartDisplay").length()>0? AppUtils.getRequestNvlValue(request, "chartDisplay").equals("3D"):rr.isChartDisplayIn3D())); + } else if (chartType.equals(AppConstants.GT_BAR_3D)) { + additionalChartOptionsMap.put("chartOrientation", new Boolean((AppUtils.getRequestNvlValue(request, "chartOrientation").length()>0?AppUtils.getRequestNvlValue(request, "chartOrientation").equals("vertical"):rr.isVerticalOrientation())) ); + additionalChartOptionsMap.put("secondaryChartRenderer", AppUtils.getRequestNvlValue(request, "secondaryChartRenderer").length()>0? AppUtils.getRequestNvlValue(request, "secondaryChartRenderer"):rr.getSecondaryChartRenderer()); + additionalChartOptionsMap.put("chartDisplay", new Boolean(AppUtils.getRequestNvlValue(request, "chartDisplay").length()>0? AppUtils.getRequestNvlValue(request, "chartDisplay").equals("3D"):rr.isChartDisplayIn3D())); + additionalChartOptionsMap.put("lastSeriesALineChart", new Boolean(rr.isLastSeriesALineChart())); + } else if (chartType.equals(AppConstants.GT_LINE)) { + additionalChartOptionsMap.put("chartOrientation", new Boolean((AppUtils.getRequestNvlValue(request, "chartOrientation").length()>0?AppUtils.getRequestNvlValue(request, "chartOrientation").equals("vertical"):rr.isVerticalOrientation())) ); + //additionalChartOptionsMap.put("secondaryChartRenderer", AppUtils.getRequestNvlValue(request, "secondaryChartRenderer").length()>0? AppUtils.getRequestNvlValue(request, "secondaryChartRenderer"):rr.getSecondaryChartRenderer()); + additionalChartOptionsMap.put("chartDisplay", new Boolean(AppUtils.getRequestNvlValue(request, "chartDisplay").length()>0? AppUtils.getRequestNvlValue(request, "chartDisplay").equals("3D"):rr.isChartDisplayIn3D())); + additionalChartOptionsMap.put("lastSeriesABarChart", new Boolean(rr.isLastSeriesABarChart())); + } else if (chartType.equals(AppConstants.GT_TIME_DIFFERENCE_CHART)) { + additionalChartOptionsMap.put("intervalFromDate",AppUtils.getRequestNvlValue(request, "intervalFromDate").length()>0?AppUtils.getRequestNvlValue(request, "intervalFromDate"):rr.getIntervalFromdate()); + additionalChartOptionsMap.put("intervalToDate", AppUtils.getRequestNvlValue(request, "intervalToDate").length()>0? AppUtils.getRequestNvlValue(request, "intervalToDate"):rr.getIntervalTodate()); + additionalChartOptionsMap.put("intervalLabel", AppUtils.getRequestNvlValue(request, "intervalLabel").length()>0? AppUtils.getRequestNvlValue(request, "intervalLabel"):rr.getIntervalLabel()); + } else if (chartType.equals(AppConstants.GT_REGRESSION)) { + additionalChartOptionsMap.put("regressionType",AppUtils.getRequestNvlValue(request, "regressionType").length()>0?AppUtils.getRequestNvlValue(request, "regressionType"):rr.getLinearRegression()); + additionalChartOptionsMap.put("linearRegressionColor",nvl(rr.getLinearRegressionColor())); + additionalChartOptionsMap.put("expRegressionColor",nvl(rr.getExponentialRegressionColor())); + additionalChartOptionsMap.put("maxRegression",nvl(rr.getCustomizedRegressionPoint())); + } else if (chartType.equals(AppConstants.GT_STACK_BAR) ||chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR) || chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR_LINES) + || chartType.equals(AppConstants.GT_STACKED_VERT_BAR) || chartType.equals(AppConstants.GT_STACKED_VERT_BAR_LINES) + ) { + additionalChartOptionsMap.put("overlayItemValue",new Boolean(nvl(rr.getOverlayItemValueOnStackBar()).equals("Y"))); + } + additionalChartOptionsMap.put("legendPosition", nvl(rr.getLegendPosition())); + additionalChartOptionsMap.put("hideToolTips", new Boolean(rr.hideChartToolTips())); + additionalChartOptionsMap.put("hideLegend", new Boolean(AppUtils.getRequestNvlValue(request, "hideLegend").length()>0? AppUtils.getRequestNvlValue(request, "hideLegend").equals("Y"):rr.hideChartLegend())); + additionalChartOptionsMap.put("labelAngle", nvl(rr.getLegendLabelAngle())); + additionalChartOptionsMap.put("maxLabelsInDomainAxis", nvl(rr.getMaxLabelsInDomainAxis())); + additionalChartOptionsMap.put("rangeAxisLowerLimit", nvl(rr.getRangeAxisLowerLimit())); + additionalChartOptionsMap.put("rangeAxisUpperLimit", nvl(rr.getRangeAxisUpperLimit())); + + + boolean totalOnChart = false; + totalOnChart = AppUtils.getRequestNvlValue(request, "totalOnChart").equals("Y"); + String filename = null; + ArrayList graphURL = new ArrayList(); + ArrayList chartNames = new ArrayList(); + ArrayList fileNames = new ArrayList(); + List l = rr.getAllColumns(); + List lGroups = rr.getAllChartGroups(); + HashMap mapYAxis = rr.getAllChartYAxis(rr.getReportParamValues()); + String chartLeftAxisLabel = rr.getFormFieldFilled(nvl(rr.getChartLeftAxisLabel())); + String chartRightAxisLabel = rr.getFormFieldFilled(nvl(rr.getChartRightAxisLabel())); + int displayTotalOnChart = 0; + HashMap formValues = Globals.getRequestParamtersMap(request, false); + + for (Iterator iterC = l.iterator(); iterC.hasNext();) { + DataColumnType dc = (DataColumnType) iterC.next(); + if(nvl(dc.getColName()).equals(AppConstants.RI_CHART_TOTAL_COL)) { + displayTotalOnChart = 1; + } + } + + String legendColumnName = (rr.getChartLegendColumn()!=null)?rr.getChartLegendColumn().getDisplayName():"Legend Column"; + + + + if(ds!=null) + { + if(rr.hasSeriesColumn() && chartType.equals(AppConstants.GT_TIME_SERIES) && (lGroups==null || lGroups.size() <= 0)) { /** Check whether Report has only category columns if so then all the columns will open in seperate chart - sundar**/ + for (int i=0; i0) + tempChartGroupCurrent = chartGroupOrg.substring(0,chartGroupOrg.lastIndexOf("|")); + if(i>0) tempChartGroupPrev = ((String) lGroups.get(i-1)).substring(0,((String) lGroups.get(i-1)).lastIndexOf("|")); + //System.out.println("TEMPCHARTGROUP " + tempChartGroupCurrent + " " + tempChartGroupPrev); + if(tempChartGroupCurrent.equals(tempChartGroupPrev)) continue; + //System.out.println("CHARTGROUPORG " + chartGroupOrg + " " + lGroups) ; + //String chartGroup = chartGroupOrg.substring(0,chartGroupOrg.lastIndexOf("|")); + String chartGroup = chartGroupOrg; + + //System.out.println("$$$$CHARTGROUP in JSP " +chartGroup+ " "+ chartGroupOrg ); + //System.out.println(" rr.getChartGroupDisplayNamesList(chartGroup) " + rr.getChartGroupDisplayNamesList(chartGroup)); + //System.out.println(" rr.getChartGroupColumnColorsList(chartGroup) " + rr.getChartGroupColumnColorsList(chartGroup)); + //System.out.println(" rr.getChartGroupColumnAxisList(chartGroup) " + rr.getChartGroupColumnAxisList(chartGroup)); + //System.out.println(" rr.getChartGroupValueColumnAxisList(chartGroupOrg) " + rr.getChartGroupValueColumnAxisList(chartGroupOrg)); + + downloadFileName = AppUtils.getTempFolderPath()+"cr_"+pb.getUserId()+"_"+request.getSession().getId()+"_"+rr.getReportID()+"_"+i+".png"; + String chartTitle = (Globals.getDisplayChartTitle()? (chartGroup!=null && chartGroup.indexOf("|") > 0 ?chartGroup.substring(0,chartGroup.lastIndexOf("|")):rr.getReportName()):""); + chartTitle = rr.getFormFieldFilled(chartTitle); + String leftAxisLabel = ""; + //if(!rr.isChartMultiSeries()) { + if(!rr.isMultiSeries()) { + leftAxisLabel = ((chartYAxis!=null && chartYAxis.indexOf("|") > 0) ? chartYAxis.substring(0,chartYAxis.lastIndexOf("|")): chartLeftAxisLabel ); + } else { + leftAxisLabel = chartLeftAxisLabel; + } + + filename = null;/*(String) ChartGen.generateChart( chartType, + request.getSession(), + ds, + legendColumnName, + leftAxisLabel, + chartRightAxisLabel, + ((chartType.indexOf("Stacked")>0 || chartType.equals(AppConstants.GT_PIE_MULTIPLE) || chartType.equals(AppConstants.GT_BAR_3D))?rr.getChartDisplayNamesList(AppConstants.CHART_ALL_COLUMNS, formValues):rr.getChartGroupDisplayNamesList(chartGroup, formValues)), + ((chartType.indexOf("Stacked")>0 || chartType.equals(AppConstants.GT_PIE_MULTIPLE) || chartType.equals(AppConstants.GT_BAR_3D))?rr.getChartColumnColorsList(AppConstants.CHART_ALL_COLUMNS, formValues):rr.getChartGroupColumnColorsList(chartGroup, formValues)), + ((chartType.indexOf("Stacked")>0 || chartType.equals(AppConstants.GT_PIE_MULTIPLE) || chartType.equals(AppConstants.GT_BAR_3D))?rr.getChartValueColumnAxisList(AppConstants.CHART_ALL_COLUMNS, formValues):rr.getChartGroupValueColumnAxisList(chartGroupOrg, formValues)), + "", + chartTitle, + null, + rr.getChartWidthAsInt(), + rr.getChartHeightAsInt(), + ((chartType.indexOf("Stacked")>0 || chartType.equals(AppConstants.GT_PIE_MULTIPLE))?rr.getChartValueColumnsList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues):rr.getChartGroupValueColumnAxisList(chartGroupOrg, formValues)), + rr.hasSeriesColumn(), + //rr.isChartMultiSeries(), + rr.isMultiSeries(), + rr.getAllColumns(), + downloadFileName, + totalOnChart, + AppConstants.WEB_VERSION deviceType, + additionalChartOptionsMap, + true + );*/ + try { + Image image = Image.getInstance(downloadFileName); + images.add(image); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + catch (BadElementException e) { + e.printStackTrace(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if(!chartType.equals(AppConstants.GT_PIE_MULTIPLE)) { + for (int i=0; i 0))) { + + if(/*chartType.equals(AppConstants.GT_TIME_SERIES) && */rr.getChartDisplayNamesList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues)!=null && rr.getChartDisplayNamesList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues).size()>0) { + downloadFileName = AppUtils.getTempFolderPath()+"cr_"+ pb.getUserId()+"_"+request.getSession().getId()+"_"+rr.getReportID()+"_All.png"; + String chartTitle = Globals.getDisplayChartTitle()? rr.getReportName():""; + chartTitle = rr.getFormFieldFilled(chartTitle); + + filename = null; /*(String) ChartGen.generateChart( chartType, + request.getSession(), + ds, + legendColumnName, + chartLeftAxisLabel, + chartRightAxisLabel, + rr.getChartDisplayNamesList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues), + rr.getChartColumnColorsList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues), + rr.getChartValueColumnAxisList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues), + "", + chartTitle, + null, + rr.getChartWidthAsInt(), + rr.getChartHeightAsInt(), + rr.getChartValueColumnsList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues), + rr.hasSeriesColumn(), + //rr.isChartMultiSeries(), + rr.isMultiSeries(), + rr.getAllColumns(), + downloadFileName, + totalOnChart, + AppConstants.WEB_VERSION, + additionalChartOptionsMap, + true + );*/ + try { + Image image = Image.getInstance(downloadFileName); + images.add(image); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + catch (BadElementException e) { + e.printStackTrace(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } // Stacked Chart Check + } // else no Series Column + + }// if(ds!=null) + + }catch (Exception e) { + e.printStackTrace(); + } +// System.out.println("Total Images " + images.size()); + return images.size()>0?images:null; + + } + +/* + private boolean isImageRotate(Document doc, Image image) { + + System.out.println("image size="+image.getWidthPercentage()+ " "+ image.scaledWidth()+ + " "+image.scaledHeight()+" "+image.getXYRatio()); + System.out.println("page size = "+ doc.getPageSize().width() + " " +doc.getPageSize().height() +" "+ + doc.topMargin() + " " +doc.bottomMargin() + " " + doc.leftMargin() + " " + + doc.rightMargin()); + System.out.println(image.scaledWidth()/image.scaledHeight()); + System.out.println((PageEvent.getPageWidth(doc)/PageEvent.getPageHeight(doc))); +// System.out.println(doc.getPageSize().getRotation()); + + float image_w = image.scaledWidth(); + float image_h = image.scaledHeight(); + float image_ratio = image_w/image_h; + + float page_w = PageEvent.getPageWidth(doc); + float page_h = PageEvent.getPageHeight(doc); + float page_ratio = page_w/page_h; + + return (image_w > page_w && image_ratio > page_ratio) || + (image_h > page_h && image_ratio < page_ratio); + + } + +*/ + private final int DEFAULT_PDF_DISPLAY_WIDTH = 10; + private int paintPdfData(HttpServletRequest request, Document document, ReportData rd, ReportRuntime rr, String sql_whole) throws DocumentException, RaptorException, IOException { + + int mb = 1024*1024; + Runtime runtime = Runtime.getRuntime(); + int returnValue = 0; + //sql_whole = rr.getWholeSQL(); + //if(rd.getDataRowCount() >= rr.getReportDataSize()) { + //sql_whole=""; + //} + float f[] = getRelativeWidths(rd, rr.getReportType().equals(AppConstants.RT_CROSSTAB)); + PdfPTable table = new PdfPTable(f); + table.setWidthPercentage(100f); + table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + table.getDefaultCell().setVerticalAlignment(Rectangle.ALIGN_BOTTOM); + + ReportDefinition rdef = (new ReportHandler()).loadReportDefinition(request, rr.getReportID()); + + List allColumns = rdef.getAllColumns(); + + float[] repotWidths = new float[rdef.getVisibleColumnCount()]; + int columnIdx = 0; + float pdfDisplayWidth = 0; + for(Iterator iter = allColumns.iterator(); iter.hasNext();){ + DataColumnType dct = (DataColumnType) iter.next(); + if(dct.isVisible()) { + + if(dct.getPdfDisplayWidthInPxls() == null || dct.getPdfDisplayWidthInPxls().equals("") || dct.getPdfDisplayWidthInPxls().startsWith("null")) + pdfDisplayWidth = DEFAULT_PDF_DISPLAY_WIDTH; + else + pdfDisplayWidth = Float.parseFloat(dct.getPdfDisplayWidthInPxls()); + + repotWidths [columnIdx++] = pdfDisplayWidth; + } + } + + table.setWidths(repotWidths); + + //table.setH + + //TODO: check title and subtitle + HttpSession session = request.getSession(); + String drilldown_index = (String) session.getAttribute("drilldown_index"); + int index = 0; + try { + index = Integer.parseInt(drilldown_index); + } catch (NumberFormatException ex) { + index = 0; + } + String titleRep = (String) session.getAttribute("TITLE_"+index); + String subtitle = (String) session.getAttribute("SUBTITLE_"+index); + + if(nvl(titleRep).length()>0 && nvl(subtitle).length()>0) + table.setHeaderRows(3); + else if (nvl(titleRep).length()>0) + table.setHeaderRows(2); + else + table.setHeaderRows(1); + table = paintPdfReportHeader(request, document, table, rr, f); + paintPdfTableHeader(document, rd, table); + + int idx = 0; + int fragmentsize = 30; //for memory management + + ResultSet rs = null; + Connection conn = null; + Statement st = null; + ResultSetMetaData rsmd = null; + rd.reportDataRows.resetNext(); + DataRow dr = rd.reportDataRows.getNext(); + + //addRowHeader(table,dr,idx,rd); + + //addRowColumns(table,dr,idx); + if(nvl(sql_whole).length() >0 && rr.getReportType().equals(AppConstants.RT_LINEAR)) { + try { + conn = ConnectionUtils.getConnection(rr.getDbInfo()); + st = conn.createStatement(); + logger.debug(EELFLoggerDelegate.debugLogger, ("************* Map Whole SQL *************")); + logger.debug(EELFLoggerDelegate.debugLogger, (sql_whole)); + logger.debug(EELFLoggerDelegate.debugLogger, ("*****************************************")); + rs = st.executeQuery(sql_whole); + rsmd = rs.getMetaData(); + int numberOfColumns = rsmd.getColumnCount(); + HashMap colHash = new HashMap(); + dr = null; + int j = 0; + int rowCount = 0; + String title = ""; + while(rs.next()) { + +/* if(runtime.freeMemory()/mb <= ((runtime.maxMemory()/mb)*Globals.getMemoryThreshold()/100) ) { + returnValue = 1; + String cellValue = Globals.getUserDefinedMessageForMemoryLimitReached() + " "+ rowCount +" records out of " + rr.getReportDataSize() + " were downloaded to PDF."; + Font cellFont = FontFactory.getFont(Globals.getDataFontFamily(), + Globals.getDataFontSize(), + Font.NORMAL, Color.BLACK); + PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); + table.addCell(cell); + document.add(table); + return returnValue; + } +*/ rowCount++; + colHash = new HashMap(); + for (int i = 1; i <= numberOfColumns; i++) { + colHash.put(rsmd.getColumnLabel(i).toUpperCase(), rs.getString(i)); + } + rd.reportDataRows.resetNext(); + + dr = rd.reportDataRows.getNext(); + + j = 0; + /*if(rd.reportTotalRowHeaderCols!=null) { + + HtmlFormatter rfmt = dr.getRowFormatter(); + + Font cellFont = FontFactory.getFont(Globals.getDataFontFamily(), + Globals.getDataFontSize(), + Font.NORMAL, Color.BLACK); + if(rfmt != null) { + cellFormatterFont(rfmt,cellFont); + } + + String cellValue = new Integer(rowCount).toString(); + PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); + + //row background color can be overwritten by cell background color + cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); + + cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); + + if(rfmt != null) { + formatterCell(rfmt,cell); + } + table.addCell(cell); + }*/ + + for (dr.resetNext(); dr.hasNext();j++) { + DataValue dv = dr.getNext(); + /*if(j == 0) { + HtmlFormatter cfmt = dv.getCellFormatter(); + HtmlFormatter rfmt = dv.getRowFormatter(); + + Font cellFont = FontFactory.getFont(Globals.getDataFontFamily(), + Globals.getDataFontSize(), + Font.NORMAL, Color.BLACK); + if(cfmt!= null) { + cellFormatterFont(cfmt,cellFont); + } + else if(rfmt != null) { + cellFormatterFont(rfmt,cellFont); + } + else { + if(dv.isBold()) { + cellFont.setStyle(Font.BOLD); + } + } + + //String cellValue = strip.stripHtml(value.trim()); + PdfPCell cell = new PdfPCell(new Paragraph(rowCount+"",cellFont)); + + //row background color can be overwritten by cell background color + cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); + + if(nvl(dv.getAlignment()).trim().length()>0) + cell.setHorizontalAlignment(ElementTags.alignmentValue(dv.getAlignment())); + else + cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); + + if(cfmt!= null) { + formatterCell(cfmt,cell); + } + else if(rfmt != null) { + formatterCell(rfmt,cell); + } + table.addCell(cell); + }*/ + + //for (chr.resetNext(); chr.hasNext();) { + //ColumnHeader ch = chr.getNext(); + String value = nvl((String)colHash.get(dv.getColId().toUpperCase())); + if(dv.isVisible()) { + + HtmlFormatter cfmt = dv.getCellFormatter(); + HtmlFormatter rfmt = dv.getRowFormatter(); + + Font cellFont = FontFactory.getFont(FONT_FAMILY, + FONT_SIZE, + Font.NORMAL, Color.BLACK); + if(cfmt!= null) { + cellFormatterFont(cfmt,cellFont); + } + else if(rfmt != null) { + cellFormatterFont(rfmt,cellFont); + } + else { + if(dv.isBold()) { + cellFont.setStyle(Font.BOLD); + } + } + + String cellValue = strip.stripHtml(value.trim()); + PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); + + //row background color can be overwritten by cell background color + cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); + + if(nvl(dv.getAlignment()).trim().length()>0) + cell.setHorizontalAlignment(ElementTags.alignmentValue(dv.getAlignment())); + else + cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); + + if(cfmt!= null) { + formatterCell(cfmt,cell); + } + else if(rfmt != null) { + formatterCell(rfmt,cell); + } + + + + table.addCell(cell); + + }//if isVisible() + + + } + + } + if(rd.reportDataTotalRow!=null) { + for (rd.reportDataTotalRow.resetNext(); rd.reportDataTotalRow.hasNext();idx++) { + dr = rd.reportDataTotalRow.getNext(); + table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + Font rowHeaderFont = FontFactory.getFont(FONT_FAMILY, + FONT_SIZE, + Font.NORMAL, Color.BLACK); + rowHeaderFont.setStyle(Font.BOLD); + rowHeaderFont.setSize(FONT_SIZE+1f); + table.getDefaultCell().setBackgroundColor(getRowBackgroundColor(dr, idx)); + table.addCell(new Paragraph("Total",rowHeaderFont)); + + + addTotalRowColumns(table,dr,idx); + if (idx % fragmentsize == fragmentsize - 1) { + document.add(table); + table.deleteBodyRows(); + table.setSkipFirstHeader(true); + } + + } + } + } catch (SQLException ex) { + throw new RaptorException(ex); + } catch (ReportSQLException ex) { + throw new RaptorException(ex); + } catch (Exception ex) { + if(!(ex.getCause() instanceof java.net.SocketException) ) + throw new RaptorException (ex); + } finally { + try { + if(conn!=null) + conn.close(); + if(st!=null) + st.close(); + if(rs!=null) + rs.close(); + } catch (SQLException ex) { + throw new RaptorException(ex); + } + } + + +// if (idx % fragmentsize == fragmentsize - 1) { +// document.add(table); +// table.deleteBodyRows(); +// table.setSkipFirstHeader(true); +// } + + //document.add(table); + } else { + if(rr.getReportType().equals(AppConstants.RT_LINEAR)) { + int rowCount = 0; + for(rd.reportDataRows.resetNext();rd.reportDataRows.hasNext();idx++) + { + rowCount++; + + /*if(rd.reportTotalRowHeaderCols!=null) { + HtmlFormatter rfmt = dr.getRowFormatter(); + + Font cellFont = FontFactory.getFont(Globals.getDataFontFamily(), + Globals.getDataFontSize(), + Font.NORMAL, Color.BLACK); + if(rfmt != null) { + cellFormatterFont(rfmt,cellFont); + } + + //String cellValue = new Integer(rowCount).toString(); + //PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); + + //row background color can be overwritten by cell background color + //cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); + + //cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); + + //if(rfmt != null) { + //formatterCell(rfmt,cell); + //} + //table.addCell(cell); + }*/ + + + + if(runtime.freeMemory()/mb <= ((runtime.maxMemory()/mb)*Globals.getMemoryThreshold()/100) ) { + returnValue = 1; + } + + dr = rd.reportDataRows.getNext(); + + addRowHeader(table,dr,idx,rd); + + addRowColumns(table,dr,idx); + + if (idx % fragmentsize == fragmentsize - 1) { + document.add(table); + table.deleteBodyRows(); + table.setSkipFirstHeader(true); + } + } + + if(rd.reportDataTotalRow!=null) { + for (rd.reportDataTotalRow.resetNext(); rd.reportDataTotalRow.hasNext();idx++) { + dr = rd.reportDataTotalRow.getNext(); + table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + Font rowHeaderFont = FontFactory.getFont(FONT_FAMILY, + FONT_SIZE, + Font.NORMAL, Color.BLACK); + rowHeaderFont.setStyle(Font.BOLD); + rowHeaderFont.setSize(FONT_SIZE+1f); + table.getDefaultCell().setBackgroundColor(getRowBackgroundColor(dr, idx)); + table.addCell(new Paragraph("Total",rowHeaderFont)); + + + addTotalRowColumns(table,dr,idx); + if (idx % fragmentsize == fragmentsize - 1) { + document.add(table); + table.deleteBodyRows(); + table.setSkipFirstHeader(true); + } + + } + } + + } else if (rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { + int rowCount = 0; + List l = rd.getReportDataList(); + boolean first = true; + for (int dataRow = 0; dataRow < l.size(); dataRow++) { + first = true; + rowCount++; + dr = (DataRow) l.get(dataRow); + Vector rowNames = dr.getRowValues(); + for(dr.resetNext(); dr.hasNext(); ) { + + if(first) { + HtmlFormatter rfmt = dr.getRowFormatter(); + + Font cellFont = FontFactory.getFont(FONT_FAMILY, + FONT_SIZE, + Font.NORMAL, Color.BLACK); + if(rfmt != null) { + cellFormatterFont(rfmt,cellFont); + } + String cellValue = ""; + PdfPCell cell = null; + //String cellValue = new Integer(rowCount).toString(); + //PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); + //row background color can be overwritten by cell background color + //cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); + + //cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); + + //if(rfmt != null) { + //formatterCell(rfmt,cell); + // } + //table.addCell(cell); + if(rowNames!=null) { + for(int i=0; i0) { + table.getDefaultCell().setColspan(rh.getColSpan()); + table.getDefaultCell().setBackgroundColor(getRowBackgroundColor(dr, idx)); + table.addCell(new Paragraph(strip.stripHtml(rh.getRowTitle()),rowHeaderFont)); + } + } + } + + private void addRowColumns(PdfPTable table, DataRow dr, int idx) { + + table.getDefaultCell().setColspan(1); + + for(dr.resetNext();dr.hasNext();) + { + DataValue dv = dr.getNext(); + //System.out.println(columnCount +" --> "+dv); + if(dv.isVisible()) { + HtmlFormatter cfmt = dv.getCellFormatter(); + HtmlFormatter rfmt = dv.getRowFormatter(); + + Font cellFont = FontFactory.getFont(FONT_FAMILY, + FONT_SIZE, + Font.NORMAL, Color.BLACK); + if(cfmt!= null) { + cellFormatterFont(cfmt,cellFont); + } + else if(rfmt != null) { + cellFormatterFont(rfmt,cellFont); + } + else { + if(dv.isBold()) { + cellFont.setStyle(Font.BOLD); + } + } + + String cellValue = strip.stripHtml(dv.getDisplayValue().trim()); + PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); + + //row background color can be overwritten by cell background color + cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); + + if(nvl(dv.getAlignment()).trim().length()>0) + cell.setHorizontalAlignment(ElementTags.alignmentValue(dv.getAlignment())); + else + cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); + + if(cfmt!= null) { + formatterCell(cfmt,cell); + } + else if(rfmt != null) { + formatterCell(rfmt,cell); + } + + table.addCell(cell); + + }//if isVisible() + } + } + + + private void addTotalRowColumns(PdfPTable table, DataRow dr, int idx) { + + table.getDefaultCell().setColspan(1); + dr.resetNext(); + dr.getNext(); + for(;dr.hasNext();) + { + DataValue dv = dr.getNext(); + //System.out.println(columnCount +" --> "+dv); + if(dv.isVisible()) { + HtmlFormatter cfmt = dv.getCellFormatter(); + HtmlFormatter rfmt = dv.getRowFormatter(); + + Font cellFont = FontFactory.getFont(FONT_FAMILY, + FONT_SIZE, + Font.NORMAL, Color.BLACK); + if(cfmt!= null) { + cellFormatterFont(cfmt,cellFont); + } + else if(rfmt != null) { + cellFormatterFont(rfmt,cellFont); + } + else { + if(dv.isBold()) { + cellFont.setStyle(Font.BOLD); + } + } + + String cellValue = strip.stripHtml(dv.getDisplayValue().trim()); + PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); + + //row background color can be overwritten by cell background color + cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); + + if(nvl(dv.getAlignment()).trim().length()>0) + cell.setHorizontalAlignment(ElementTags.alignmentValue(dv.getAlignment())); + else + cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); + + if(cfmt!= null) { + formatterCell(cfmt,cell); + } + else if(rfmt != null) { + formatterCell(rfmt,cell); + } + + table.addCell(cell); + + }//if isVisible() + } + } + + + private void formatterCell(HtmlFormatter fmt, PdfPCell cell) { + + if(nvl(fmt.getBgColor()).trim().length()>0) + cell.setBackgroundColor(Color.decode(fmt.getBgColor())); + if(nvl(fmt.getAlignment()).trim().length()>0) + cell.setHorizontalAlignment(ElementTags.alignmentValue(fmt.getAlignment())); + } + + private void cellFormatterFont(HtmlFormatter fmt, Font font) { + + if(fmt.isBold()) + font.setStyle(Font.BOLD); + if(fmt.isItalic()) + font.setStyle(Font.ITALIC); + if(fmt.isUnderline()) + font.setStyle(Font.UNDERLINE); + if(fmt.getFontColor().trim().length()>0) + font.setColor(Color.decode(fmt.getFontColor())); + if(fmt.getFontSize().trim().length()>0) + font.setSize(Float.parseFloat(fmt.getFontSize())-Globals.getDataFontSizeOffset()); +// if(fmt.getFontFace().trim().length()>0) +// cellFont.setFamily() + + } + + private Color getRowBackgroundColor(DataRow dr, int idx) { + + Color color = Color.decode(Globals.getDataDefaultBackgroundHexCode()); + + HtmlFormatter rhf = dr.getRowFormatter(); + if(rhf!=null && nvl(rhf.getBgColor()).trim().length()>0) + + color = Color.decode(rhf.getBgColor()); + + else if(pb.isAlternateColor() && idx%2==0) + + color = Color.decode(Globals.getDataBackgroundAlternateHexCode()); + + return color; + + } + + private int getTotalVisbleColumns(ReportData rd) { + + int totalVisbleColumn = rd.getTotalColumnCount(); + for(rd.reportDataRows.resetNext();rd.reportDataRows.hasNext();) + { + DataRow dr = rd.reportDataRows.getNext(); + for(dr.resetNext();dr.hasNext();) { + DataValue dv = dr.getNext(); + if(!dv.isVisible()) totalVisbleColumn--; + } + + break; + } + + return totalVisbleColumn; + } + + /* + private int getFirstRowIndex(ReportRuntime rr) { + return (pb.getCurrentPage()>0)?pb.getCurrentPage()*rr.getPageSize()+1 : 1; + } + */ + private float[] getRelativeWidths(ReportData rd, boolean crosstab){ + + int totalColumns = getTotalVisbleColumns(rd); + /*if(rd.reportTotalRowHeaderCols!=null) { + totalColumns += 1; + }*/ + if(crosstab) { + totalColumns += 1; + } + + if(totalColumns == 0 ) + totalColumns=1; + + float[] relativeWidths = new float[totalColumns]; + //initial widths are even + for(int i=0; i0) { + //PdfPTable table = new PdfPTable(1); + table.setWidthPercentage(100f); + table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + table.getDefaultCell().setVerticalAlignment(Rectangle.ALIGN_BOTTOM); + + + Font font = FontFactory.getFont(FONT_FAMILY, + FONT_SIZE-2f, + Font.BOLD, + Color.BLACK); + + //addEmptyRows(table,1); + table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + //table.getDefaultCell().setBackgroundColor(Color.decode(Globals.getDataTableHeaderBackgroundFontColor())); + title = Utils.replaceInString(title, "
", " "); + title = Utils.replaceInString(title, "
", " "); + title = Utils.replaceInString(title, "
", " "); + title = strip.stripHtml(nvl(title).trim()); + //subtitle = Utils.replaceInString(subtitle, "
", " "); + //subtitle = Utils.replaceInString(subtitle, "
", " "); + //subtitle = Utils.replaceInString(subtitle, "
", " "); + //subtitle = strip.stripHtml(nvl(subtitle).trim()); + StyleSheet styles = new StyleSheet(); + + HTMLWorker htmlWorker = new HTMLWorker(document); + ArrayList cc = new ArrayList(); + cc = htmlWorker.parseToList(new StringReader(subtitle), styles); + + Phrase p1 = new Phrase(); + for (int i = 0; i < cc.size(); i++){ + Element elem = (Element)cc.get(i); + ArrayList al = elem.getChunks(); + for (int j = 0; j < al.size(); j++) { + Chunk chunk = (Chunk) al.get(j); + chunk.font().setSize(6.0f); + } + p1.add(elem); + } + //cell = new PdfPCell(p1); + StyleSheet style = new StyleSheet(); + style.loadTagStyle("font", "font-size", "3"); + style.loadTagStyle("font", "size", "3"); + styles.loadStyle("pdfFont1", "size", "11px"); + styles.loadStyle("pdfFont1", "font-size", "11px"); + /*ArrayList p = HTMLWorker.parseToList(new StringReader(nvl(title)), style); + for (int k = 0; k < p.size(); ++k){ + document.add((com.lowagie.text.Element)p.get(k)); + }*/ + //p1.font().setSize(3.0f); + PdfPCell titleCell = new PdfPCell(new Phrase(title, font)); + titleCell.setColspan(rr.getVisibleColumnCount()); + PdfPCell subtitleCell = new PdfPCell(p1); + subtitleCell.setColspan(rr.getVisibleColumnCount()); + titleCell.setHorizontalAlignment(1); + subtitleCell.setHorizontalAlignment(1); + table.addCell(titleCell); + table.addCell(subtitleCell); + //document.add(table); + } + return table; + } + + + private void paintPdfReportFooter(HttpServletRequest request, Document document, ReportRuntime rr, float[] f) + throws DocumentException, IOException { + + HttpSession session = request.getSession(); + String drilldown_index = (String) session.getAttribute("drilldown_index"); + int index = 0; + try { + index = Integer.parseInt(drilldown_index); + } catch (NumberFormatException ex) { + index = 0; + } + + String title = (String) session.getAttribute("FOOTER_"+index); + if(nvl(title).length()>0) { + PdfPTable table = new PdfPTable(1); + table.setWidthPercentage(100f); + table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + table.getDefaultCell().setVerticalAlignment(Rectangle.ALIGN_BOTTOM); + + Font font = FontFactory.getFont(FONT_FAMILY, + FONT_SIZE-3f, + Font.BOLD, + Color.BLACK); + + + //addEmptyRows(table,1); + table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + //table.getDefaultCell().setBackgroundColor(Color.decode(Globals.getDataTableHeaderBackgroundFontColor())); + /*title = Utils.replaceInString(title, "
", " "); + title = Utils.replaceInString(title, "
", " "); + title = Utils.replaceInString(title, "
", " "); + title = strip.stripHtml(nvl(title).trim());*/ + StyleSheet style = new StyleSheet(); + + HTMLWorker htmlWorker = new HTMLWorker(document); + ArrayList cc = new ArrayList(); + cc = htmlWorker.parseToList(new StringReader(title), style); + + Phrase p1 = new Phrase(); + for (int i = 0; i < cc.size(); i++){ + Element elem = (Element)cc.get(i); + ArrayList al = elem.getChunks(); + for (int j = 0; j < al.size(); j++) { + Chunk chunk = (Chunk) al.get(j); + chunk.font().setSize(6.0f); + } + p1.add(elem); + } + +/* + HTMLWorker.parseToList(new StringReader(nvl(title)), style);*/ + PdfPCell titleCell = new PdfPCell(p1); + titleCell.setHorizontalAlignment(Element.ALIGN_LEFT); + table.addCell(titleCell); + //table. + document.add(table); + } + //return table; + } + + + private void paintPdfTableHeader(Document document, ReportData rd, PdfPTable table) + throws DocumentException { + + Font font = FontFactory.getFont(FONT_FAMILY, + FONT_SIZE+1f, + Font.BOLD, + Color.decode(Globals.getDataTableHeaderFontColor())); + //table.setHeaderRows(1); + table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); + table.getDefaultCell().setBackgroundColor(Color.decode(Globals.getDataTableHeaderBackgroundFontColor())); + String title = ""; + + boolean firstPass = true; + + /*if(rd.reportTotalRowHeaderCols!=null) { + if(firstPass) { + table.addCell(new Paragraph("No.", font)); + firstPass = false; + } + }*/ + for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) + { + if(firstPass) { + for(rd.reportRowHeaderCols.resetNext();rd.reportRowHeaderCols.hasNext();) { + /*if(firstPass) { + table.addCell(new Paragraph("No.", font)); + firstPass = false; + } else {*/ + RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); + title = rhc.getColumnTitle(); + title = Utils.replaceInString(title,"_nl_", " \n"); + table.addCell(new Paragraph(title,font)); + //} + } + } + + ColumnHeaderRow chr = rd.reportColumnHeaderRows.getNext(); + for (chr.resetNext(); chr.hasNext();) { + ColumnHeader ch = chr.getNext(); + //System.out.println(ch); + if(ch.isVisible()) { + title = ch.getColumnTitle(); + title = Utils.replaceInString(title,"_nl_", " \n"); + table.addCell(new Paragraph(title,font)); + } + } + } + } + + public static String currentTime(String pattern) { + try { + SimpleDateFormat oracleDateFormat = new SimpleDateFormat("MM/dd/yyyy kk:mm:ss"); + Date sysdate = oracleDateFormat.parse(ReportLoader.getSystemDateTime()); + SimpleDateFormat dtimestamp = new SimpleDateFormat(Globals.getScheduleDatePattern()); + return dtimestamp.format(sysdate)+" "+Globals.getTimeZone(); + //paramList.add(new IdNameValue("DATE", dtimestamp.format(sysdate)+" "+Globals.getTimeZone())); + } catch(Exception ex) {} + + SimpleDateFormat s = new SimpleDateFormat(pattern); + s.setTimeZone(TimeZone.getTimeZone(Globals.getTimeZone())); + //System.out.println("^^^^^^^^^^^^^^^^^^^^ " + Calendar.getInstance().getTime()); + //System.out.println("^^^^^^^^^^^^^^^^^^^^ " + s.format(Calendar.getInstance().getTime())); + return s.format(Calendar.getInstance().getTime()); + } + + private PdfBean preparePdfBean(HttpServletRequest request,ReportRuntime rr) { + PdfBean pb = new PdfBean(); + + pb.setUserId(AppUtils.getUserID(request)); + + pb.setWhereToShowPageNumber(Globals.getPageNumberPosition()); + pb.setAlternateColor(Globals.isDataAlternateColor()); + pb.setTimestampPattern(Globals.getDatePattern()); + + int temp = -1; + try { + temp = Integer.parseInt(request.getParameter(AppConstants.RI_NEXT_PAGE)); + } catch (NumberFormatException e) {} + pb.setCurrentPage(temp); + + //pb.setPortrait( trueORfalse(request.getParameter("isPortrait"),true)); + pb.setPortrait(trueORfalse(rr.getPDFOrientation() == "portait"?"true":"false", true)); + //pb.setCoverPageIncluded( trueORfalse(request.getParameter("isCoverPageIncluded"), true)); + //if(Globals.isCoverPageNeeded()) { + pb.setCoverPageIncluded(Globals.isCoverPageNeeded()?rr.isPDFCoverPage():false); + //} + pb.setTitle(nvl(request.getParameter("title"))); + pb.setPagesize(nvls(request.getParameter("pagesize"),"LETTER")); + + pb.setLogo1Url(rr.getPDFLogo1()); + pb.setLogo2Url(rr.getPDFLogo2()); + pb.setLogo1Size(rr.getPDFLogo1Size()); + pb.setLogo2Size(rr.getPDFLogo2Size()); + pb.setFullWebContextPath(request.getSession().getServletContext().getRealPath(File.separator)); + + + pb.setDisplayChart(nvl(rr.getChartType()).trim().length()>0 && rr.getDisplayChart()); + + String id = nvl(request.getParameter("pdfAttachmentKey")).trim(); + String log_id = nvl(request.getParameter("log_id")).trim(); + if(id.length()>0 && log_id.length()>0) + pb.setAttachmentOfEmail(true); + + return pb; + } + + private boolean trueORfalse(String str) { + return (str != null) && (str.equalsIgnoreCase("true")); + } + + private boolean trueORfalse(String str,boolean b_default) { + return str==null ? b_default : (str.equalsIgnoreCase("true")); + } + + +} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/BarChartOptions.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/BarChartOptions.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/BarChartOptions.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/BarChartOptions.java diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CategoryAxisJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CategoryAxisJSON.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CategoryAxisJSON.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CategoryAxisJSON.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartD3Helper.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartD3Helper.java new file mode 100644 index 00000000..18d31278 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartD3Helper.java @@ -0,0 +1,4073 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.runtime; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.time.DateUtils; +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.model.ReportHandler; +import org.openecomp.portalsdk.analytics.model.base.ChartSeqComparator; +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.system.ConnectionUtils; +import org.openecomp.portalsdk.analytics.util.AppConstants; +import org.openecomp.portalsdk.analytics.util.DataSet; +import org.openecomp.portalsdk.analytics.util.HtmlStripper; +import org.openecomp.portalsdk.analytics.util.Utils; +import org.openecomp.portalsdk.analytics.view.ReportData; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; +import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.web.support.UserUtils; + +public class ChartD3Helper { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ChartD3Helper.class); + + + private ReportRuntime reportRuntime; + private String chartType; + + public static final long HOUR = 3600*1000; + public static final long DAY = 3600*1000*24; + public static final long MONTH = 3600*1000*24*31; + public static final long YEAR = 3600*1000*24*365; + + + public ChartD3Helper() { + + } + + /** + * @return the chartType + */ + public String getChartType() { + return chartType; + } + + /** + * @param chartType the chartType to set + */ + public void setChartType(String chartType) { + this.chartType = chartType; + } + + public ChartD3Helper(ReportRuntime rr) { + this.reportRuntime = rr; + } + + public String createVisualization(String reportID, HttpServletRequest request) throws RaptorException { + //From annotations chart + clearReportRuntimeBackup(request); + + //HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest(); + final Long user_id = new Long((long) UserUtils.getUserId(request)); + //String action = request.getParameter(AppConstants.RI_ACTION); + //String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); + + ReportHandler rh = new ReportHandler(); + ReportData reportData = null; + HashMap chartOptionsMap = new HashMap(); + try { + if(reportID !=null) { + reportRuntime = rh.loadReportRuntime(request, reportID, true, 1); + setChartType(reportRuntime.getChartType()); + reportData = reportRuntime.loadReportData(0, user_id.toString(), 10000,request, false); + } + + + + String rotateLabelsStr = ""; + rotateLabelsStr = AppUtils.nvl(reportRuntime.getLegendLabelAngle()); + if(rotateLabelsStr.toLowerCase().equals("standard")) { + rotateLabelsStr = "0"; + } else if (rotateLabelsStr.toLowerCase().equals("up45")) { + rotateLabelsStr = "45"; + } else if (rotateLabelsStr.toLowerCase().equals("down45")) { + rotateLabelsStr = "-45"; + } else if (rotateLabelsStr.toLowerCase().equals("up90")) { + rotateLabelsStr = "90"; + } else if (rotateLabelsStr.toLowerCase().equals("down90")) { + rotateLabelsStr = "-90"; + } else + rotateLabelsStr = "0"; + + String width = (AppUtils.getRequestNvlValue(request, "width").length()>0?AppUtils.getRequestNvlValue(request, "width"):(AppUtils.nvl(reportRuntime.getChartWidth()).length()>0?reportRuntime.getChartWidth():"700")); + String height = (AppUtils.getRequestNvlValue(request, "height").length()>0?AppUtils.getRequestNvlValue(request, "height"):(AppUtils.nvl(reportRuntime.getChartHeight()).length()>0?reportRuntime.getChartHeight():"300")); + String animationStr = (AppUtils.getRequestNvlValue(request, "animation").length()>0?AppUtils.getRequestNvlValue(request, "animation"):new Boolean(reportRuntime.isAnimateAnimatedChart()).toString()); + + String rotateLabels = (AppUtils.getRequestNvlValue(request, "rotateLabels").length()>0?AppUtils.getRequestNvlValue(request, "rotateLabels"):(rotateLabelsStr.length()>0?rotateLabelsStr:"0")); + String staggerLabelsStr = (AppUtils.getRequestNvlValue(request, "staggerLabels").length()>0?AppUtils.getRequestNvlValue(request, "staggerLabels"):"false"); + String showMaxMinStr = (AppUtils.getRequestNvlValue(request, "showMaxMin").length()>0?AppUtils.getRequestNvlValue(request, "showMaxMin"):"false"); + String showControlsStr = (AppUtils.getRequestNvlValue(request, "showControls").length()>0?AppUtils.getRequestNvlValue(request, "showControls"):new Boolean(reportRuntime.displayBarControls()).toString()); + String showLegendStr = (AppUtils.getRequestNvlValue(request, "showLegend").length()>0?AppUtils.getRequestNvlValue(request, "showLegend"):new Boolean(!new Boolean(reportRuntime.hideChartLegend())).toString()); + String topMarginStr = AppUtils.getRequestNvlValue(request, "topMargin"); + String topMargin = (AppUtils.nvl(topMarginStr).length()<=0)?(reportRuntime.getTopMargin()!=null?reportRuntime.getTopMargin().toString():"30"):topMarginStr; + String bottomMarginStr = AppUtils.getRequestNvlValue(request, "bottomMargin"); + String bottomMargin = (AppUtils.nvl(bottomMarginStr).length()<=0)?(reportRuntime.getBottomMargin()!=null?reportRuntime.getBottomMargin().toString():"50"):bottomMarginStr; + String leftMarginStr = AppUtils.getRequestNvlValue(request, "leftMargin"); + String leftMargin = (AppUtils.nvl(leftMarginStr).length()<=0)?(reportRuntime.getLeftMargin()!=null?reportRuntime.getLeftMargin().toString():"100"):leftMarginStr; + String rightMarginStr = AppUtils.getRequestNvlValue(request, "rightMargin"); + String rightMargin = (AppUtils.nvl(rightMarginStr).length()<=0)?(reportRuntime.getRightMargin()!=null?reportRuntime.getRightMargin().toString():"160"):rightMarginStr; + String showTitleStr = (AppUtils.getRequestNvlValue(request, "showTitle").length()>0?AppUtils.getRequestNvlValue(request, "showTitle"):new Boolean(reportRuntime.displayChartTitle()).toString()); + String subType = AppUtils.getRequestNvlValue(request, "subType").length()>0?AppUtils.getRequestNvlValue(request, "subType"):(AppUtils.nvl(reportRuntime.getTimeSeriesRender()).equals("area")?reportRuntime.getTimeSeriesRender():""); + String stackedStr = AppUtils.getRequestNvlValue(request, "stacked").length()>0?AppUtils.getRequestNvlValue(request, "stacked"):new Boolean(reportRuntime.isChartStacked()).toString(); + String horizontalBar = AppUtils.getRequestNvlValue(request, "horizontalBar").length()>0?AppUtils.getRequestNvlValue(request, "horizontalBar"):new Boolean(reportRuntime.isHorizontalOrientation()).toString(); + String barRealTimeAxis = AppUtils.getRequestNvlValue(request, "barRealTimeAxis"); + String barReduceXAxisLabels = AppUtils.getRequestNvlValue(request, "barReduceXAxisLabels").length()>0?AppUtils.getRequestNvlValue(request, "barReduceXAxisLabels"):new Boolean(reportRuntime.isLessXaxisTickers()).toString();; + String timeAxis = AppUtils.getRequestNvlValue(request, "timeAxis").length()>0?AppUtils.getRequestNvlValue(request, "timeAxis"):new Boolean(reportRuntime.isTimeAxis()).toString(); + String logScale = AppUtils.getRequestNvlValue(request, "logScale").length()>0?AppUtils.getRequestNvlValue(request, "logScale"):new Boolean(reportRuntime.isLogScale()).toString(); + String precision = AppUtils.getRequestNvlValue(request, "precision").length()>0?AppUtils.getRequestNvlValue(request, "precision"):"2"; + + + chartOptionsMap.put("width", width); + chartOptionsMap.put("height", height); + chartOptionsMap.put("animation", animationStr); + chartOptionsMap.put("rotateLabels", rotateLabels); + chartOptionsMap.put("staggerLabels", staggerLabelsStr); + chartOptionsMap.put("showMaxMin", showMaxMinStr); + chartOptionsMap.put("showControls", showControlsStr); + chartOptionsMap.put("showLegend", showLegendStr); + chartOptionsMap.put("topMargin", topMargin); + chartOptionsMap.put("bottomMargin", bottomMargin); + chartOptionsMap.put("leftMargin", leftMargin); + chartOptionsMap.put("rightMargin", rightMargin); + chartOptionsMap.put("showTitle", showTitleStr); + chartOptionsMap.put("subType", subType); + chartOptionsMap.put("stacked", stackedStr); + chartOptionsMap.put("horizontalBar", horizontalBar); + chartOptionsMap.put("timeAxis", timeAxis); + chartOptionsMap.put("barRealTimeAxis", barRealTimeAxis); + chartOptionsMap.put("barReduceXAxisLabels", barReduceXAxisLabels); + + chartOptionsMap.put("logScale", logScale); + chartOptionsMap.put("precision", precision); + + + } catch (RaptorException ex) { + ex.printStackTrace(); + } + return createVisualization(reportRuntime, chartOptionsMap, request); + } + + public String createVisualization(ReportRuntime reportRuntime, HttpServletRequest request) throws RaptorException { + + String rotateLabelsStr = ""; + rotateLabelsStr = AppUtils.nvl(reportRuntime.getLegendLabelAngle()); + if(rotateLabelsStr.toLowerCase().equals("standard")) { + rotateLabelsStr = "0"; + } else if (rotateLabelsStr.toLowerCase().equals("up45")) { + rotateLabelsStr = "45"; + } else if (rotateLabelsStr.toLowerCase().equals("down45")) { + rotateLabelsStr = "-45"; + } else if (rotateLabelsStr.toLowerCase().equals("up90")) { + rotateLabelsStr = "90"; + } else if (rotateLabelsStr.toLowerCase().equals("down90")) { + rotateLabelsStr = "-90"; + } else + rotateLabelsStr = "0"; + + HashMap chartOptionsMap = new HashMap(); + chartOptionsMap.put("width", reportRuntime.getChartWidth()); + chartOptionsMap.put("height", reportRuntime.getChartHeight()); + chartOptionsMap.put("animation", new Boolean(reportRuntime.isAnimateAnimatedChart()).toString()); + chartOptionsMap.put("rotateLabels", rotateLabelsStr); + chartOptionsMap.put("staggerLabels", "false"); + chartOptionsMap.put("showMaxMin", "false"); + chartOptionsMap.put("showControls", new Boolean(reportRuntime.displayBarControls()).toString()); + chartOptionsMap.put("showLegend", new Boolean(!reportRuntime.hideChartLegend()).toString()); + chartOptionsMap.put("topMargin", reportRuntime.getTopMargin()!=null?reportRuntime.getTopMargin().toString():"30"); + chartOptionsMap.put("bottomMargin", reportRuntime.getBottomMargin()!=null?reportRuntime.getBottomMargin().toString():"50"); + chartOptionsMap.put("leftMargin", reportRuntime.getLeftMargin()!=null?reportRuntime.getLeftMargin().toString():"100"); + chartOptionsMap.put("rightMargin", reportRuntime.getRightMargin()!=null?reportRuntime.getRightMargin().toString():"160"); + chartOptionsMap.put("showTitle", new Boolean(reportRuntime.displayChartTitle()).toString()); + chartOptionsMap.put("subType", (AppUtils.nvl(reportRuntime.getTimeSeriesRender()).equals("area")?reportRuntime.getTimeSeriesRender():"")); + chartOptionsMap.put("stacked", new Boolean(reportRuntime.isChartStacked()).toString()); + chartOptionsMap.put("horizontalBar", new Boolean(reportRuntime.isHorizontalOrientation()).toString()); + chartOptionsMap.put("timeAxis", new Boolean(reportRuntime.isTimeAxis()).toString()); + chartOptionsMap.put("barReduceXAxisLabels", new Boolean(reportRuntime.isLessXaxisTickers()).toString()); + + chartOptionsMap.put("logScale", new Boolean(reportRuntime.isLogScale()).toString()); + chartOptionsMap.put("precision", "2"); + + + + return createVisualization(reportRuntime, chartOptionsMap, request); + } + + public String createVisualization(ReportRuntime reportRuntime, HashMap chartOptionsMap, HttpServletRequest request) throws RaptorException { + + //String width, String height, boolean animation, String rotateLabels, boolean staggerLabels, boolean showMaxMin, boolean showLegend, boolean showControls, String topMargin, String bottomMargin, boolean showTitle, String subType + + boolean isEmbedded = false; + if(request.getParameter("embedded")!=null) { + isEmbedded = true; + } + String width = chartOptionsMap.get("width"); + String height = chartOptionsMap.get("height"); + boolean animation = getBooleanValue(chartOptionsMap.get("animation"), true); + String rotateLabels = chartOptionsMap.get("rotateLabels"); + boolean staggerLabels = getBooleanValue(chartOptionsMap.get("staggerLabels")); + boolean showMaxMin = getBooleanValue(chartOptionsMap.get("showMaxMin"), false); + boolean showLegend = getBooleanValue(chartOptionsMap.get("showLegend"), true); + boolean showControls = getBooleanValue(chartOptionsMap.get("showControls"), true); + String topMargin = chartOptionsMap.get("topMargin"); + String bottomMargin = chartOptionsMap.get("bottomMargin"); + String leftMargin = chartOptionsMap.get("leftMargin"); + String rightMargin = chartOptionsMap.get("rightMargin"); + boolean showTitle = getBooleanValue(chartOptionsMap.get("showTitle"), true); + String subType = chartOptionsMap.get("subType"); + boolean stacked = getBooleanValue(chartOptionsMap.get("stacked"), false); + boolean horizontalBar = getBooleanValue(chartOptionsMap.get("horizontalBar"), false); + boolean barRealTimeAxis = getBooleanValue(chartOptionsMap.get("barRealTimeAxis"), true); + boolean barReduceXAxisLabels= getBooleanValue(chartOptionsMap.get("barReduceXAxisLabels"), false); + boolean timeAxis = getBooleanValue(chartOptionsMap.get("timeAxis"), true); + + + boolean logScale = getBooleanValue(chartOptionsMap.get("logScale"), false); + + int precision = 2; + + try { + precision = Integer.parseInt(chartOptionsMap.get("precision")); + } catch (NumberFormatException ex) { + + } + + final Long user_id = new Long((long) UserUtils.getUserId(request)); + + HttpSession session = null; + session = request.getSession(); + String chartType = reportRuntime.getChartType(); + List l = reportRuntime.getAllColumns(); + List lGroups = reportRuntime.getAllChartGroups(); + HashMap mapYAxis = reportRuntime.getAllChartYAxis(reportRuntime.getReportParamValues()); + //ReportParamValues reportParamValues = reportRuntime.getReportParamValues(); + String chartLeftAxisLabel = reportRuntime.getFormFieldFilled(nvl(reportRuntime.getChartLeftAxisLabel())); + String chartRightAxisLabel = reportRuntime.getFormFieldFilled(nvl(reportRuntime.getChartRightAxisLabel())); + + boolean multipleSeries = reportRuntime.isMultiSeries(); + + java.util.HashMap formValues = null; + formValues = getRequestParametersMap(reportRuntime, request); + + + String legendColumnName = (reportRuntime.getChartLegendColumn()!=null)?reportRuntime.getChartLegendColumn().getDisplayName():"Legend Column"; + boolean displayChart = (nvl(chartType).length()>0)&&reportRuntime.getDisplayChart(); + HashMap additionalChartOptionsMap = new HashMap(); + + StringBuffer wholeScript = new StringBuffer(""); + + String title = reportRuntime.getReportTitle(); + + title = parseTitle(title, formValues); + + String chartScriptsPath = (isEmbedded?AppUtils.getChartScriptsPath(""):AppUtils.getChartScriptsPath()); + + if(displayChart) { + DataSet ds = null; + try { + if (!(chartType.equals(AppConstants.GT_HIERARCHICAL) || chartType.equals(AppConstants.GT_HIERARCHICAL_SUNBURST) || chartType.equals(AppConstants.GT_ANNOTATION_CHART))) { + ds = (DataSet) loadChartData(new Long(user_id).toString(), request); + } else if(chartType.equals(AppConstants.GT_ANNOTATION_CHART)) { + String reportSQL = reportRuntime.getWholeSQL(); + String dbInfo = reportRuntime.getDBInfo(); + ds = ConnectionUtils.getDataSet(reportSQL, dbInfo); + if(ds.getRowCount()<=0) { + logger.debug(EELFLoggerDelegate.debugLogger, ("********************************************************************************")); + logger.debug(EELFLoggerDelegate.debugLogger, (chartType.toUpperCase()+" - " + "Report ID : " + reportRuntime.getReportID() + " DATA IS EMPTY")); + logger.debug(EELFLoggerDelegate.debugLogger, ("QUERY - " + reportSQL)); + logger.debug(EELFLoggerDelegate.debugLogger, ("********************************************************************************")); + } + } else if(chartType.equals(AppConstants.GT_HIERARCHICAL)||chartType.equals(AppConstants.GT_HIERARCHICAL_SUNBURST)) { + String reportSQL = reportRuntime.getWholeSQL(); + String dbInfo = reportRuntime.getDBInfo(); + ds = ConnectionUtils.getDataSet(reportSQL, dbInfo); + } + } catch (RaptorException ex) { + //throw new RaptorException("Error while loading chart data", ex); + logger.error(EELFLoggerDelegate.debugLogger, ("********************************************************************************")); + logger.error(EELFLoggerDelegate.debugLogger, (chartType.toUpperCase()+" - " + "Report ID : " + reportRuntime.getReportID() + " ERROR THROWN FOR GIVEN QUERY ")); + logger.error(EELFLoggerDelegate.debugLogger, ("QUERY - " + reportRuntime.getWholeSQL())); + logger.error(EELFLoggerDelegate.debugLogger, ("ERROR STACK TRACE" + ex.getMessage())); + logger.error(EELFLoggerDelegate.debugLogger, ("********************************************************************************")); + + } + if(ds==null) { + //displayChart = false; + if(chartType.equals(AppConstants.GT_ANNOTATION_CHART)) + ds = new DataSet(); + else + displayChart = false; + } + if(displayChart) { + + if (chartType.equals(AppConstants.GT_BAR_3D)) { + + // get category if not give the column name for the data column use this to develop series. + boolean hasCategoryAxis = reportRuntime.hasSeriesColumn(); + + boolean hasCustomizedChartColor = false; + int flag = 0; + flag = hasCategoryAxis?1:0; + Object uniqueElements [] = null; + ArrayList uniqueElementsList = new ArrayList(); + Object uniqueXAxisElements[] = null; + ArrayList ts = new ArrayList(); + //Set ts1 = new HashSet(); + ArrayList ts1 = new ArrayList(); + HashMap columnMap = new HashMap(); + String uniqueXAxisStr = ""; + if(!timeAxis){ + for (int i = 0; i < ds.getRowCount(); i++) { + uniqueXAxisStr = ds.getString(i, 0); + ts1.add(uniqueXAxisStr); + } + } + uniqueElementsList.addAll(ts1); + uniqueXAxisElements = ts1.toArray(); + + if(flag == 1) { + StringBuffer catStr = new StringBuffer(""); + String color=""; + for (int i = 0; i < ds.getRowCount(); i++) { + catStr = new StringBuffer(""); + catStr.append(ds.getString(i, 2)); + try { + if(ds.getString(i, "chart_color")!=null) { + color = ds.getString(i, "chart_color"); + hasCustomizedChartColor = true; + catStr.append("|"+color); + } + } catch (ArrayIndexOutOfBoundsException ex) { + //System.out.println("No Chart Color"); + } + + if(catStr.length()>0) { + //duplicates are avoided + if(!ts.contains(catStr.toString())) + ts.add(catStr.toString()); + + } + /* Get Chart LeftAxis Label even from Range Axis definition. */ + DataColumnType dct = null; + for (Iterator iter = l.iterator(); iter.hasNext();) { + dct = (DataColumnType) iter.next(); + if(!(nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND))) { + if(nvl(chartLeftAxisLabel).length()<=0) { + chartLeftAxisLabel = nvl(dct.getYAxis()); + chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; + } + } + } + + } + //Object uniqueElements [] = ts.toArray(); + //SortedSet s = Collections.synchronizedSortedSet(ts); + uniqueElements = ts.toArray(); + } else { + DataColumnType dct = null; + List yTextSeries = reportRuntime.getChartDisplayNamesList(AppConstants.CHART_ALL_COLUMNS, formValues); + //if(columnValuesList.size() == 1) { + for (Iterator iter = l.iterator(); iter.hasNext();) { + dct = (DataColumnType) iter.next(); + + if(!(nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND))) { + if((dct.isChartSeries()!=null && dct.isChartSeries().booleanValue()) || (dct.getChartSeq()!=null && dct.getChartSeq()>0) ) { + + if(nvl(dct.getChartColor()).length()>0) hasCustomizedChartColor = true; + if(hasCustomizedChartColor) { + //duplicates are avoided + if(!ts.contains(dct.getDisplayName()+"|"+nvl(dct.getChartColor()))) + ts.add(dct.getDisplayName()+"|"+nvl(dct.getChartColor())); + } else { + //duplicates are avoided + if(!ts.contains(dct.getDisplayName())) + ts.add(dct.getDisplayName()); + } + if(nvl(chartLeftAxisLabel).length()<=0) { + chartLeftAxisLabel = nvl(dct.getYAxis()); + chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; + } + columnMap.put(dct.getDisplayName(), dct.getColId()); + /* + ts.add(dct.getDisplayName()); + if(nvl(chartLeftAxisLabel).length()<=0) { + chartLeftAxisLabel = nvl(dct.getYAxis()); + chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; + } + columnMap.put(dct.getDisplayName(), dct.getColId()); + */ + } + } + + } + //SortedSet s = Collections.synchronizedSortedSet(ts); + uniqueElements = ts.toArray(); + + } + + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + //wholeScript.append("") + wholeScript.append(" \n" ); + wholeScript.append(" \n"); + if(showTitle) + wholeScript.append("

" + title +"

"); + + wholeScript.append("
\n"); + //js files + wholeScript.append(""); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + //wholeScript.append(" \n"); + //wholeScript.append(" \n"); + wholeScript.append(" \n"); + //json + wholeScript.append(" \n"); + + } else if (chartType.equals(AppConstants.GT_TIME_SERIES)) { + + // get category if not give the column name for the data column use this to develop series. + boolean hasCategoryAxis = reportRuntime.hasSeriesColumn(); + + + final int YEARFLAG = 1; + final int MONTHFLAG = 2; + final int DAYFLAG = 3; + final int HOURFLAG = 4; + final int MINFLAG = 5; + final int SECFLAG = 6; + final int MILLISECFLAG = 7; + final int DAYOFTHEWEEKFLAG = 8; + final int FLAGDATE = 9; + + int flag = 0; + flag = hasCategoryAxis?1:0; + String uniqueElements [] = null; + //TreeSet ts = new TreeSet(); + ArrayList ts = new ArrayList(); + HashMap columnMap = new HashMap(); + //check timeAxis + String dateStr = null; + java.util.Date date = null; + if( ds.getRowCount() > 0) { + dateStr = ds.getString(0, 1); + if(!timeAxis) { + date = getDateFromDateStr(dateStr); + if(date!=null) { + reportRuntime.setTimeAxis(true); + timeAxis = reportRuntime.isTimeAxis(); + + + } + } + } + + ArrayList ts1 = new ArrayList(); + ArrayList uniqueElementsList = new ArrayList(); + Object uniqueXAxisElements[] = null; + String uniqueXAxisStr = ""; + if(!timeAxis){ + for (int i = 0; i < ds.getRowCount(); i++) { + uniqueXAxisStr = ds.getString(i, 0); + ts1.add(uniqueXAxisStr); + } + } + uniqueElementsList.addAll(ts1); + uniqueXAxisElements = ts1.toArray(); + //test start + /* int TOTAL = 0; + int VALUE = 0; + int flagNull = 0; + String KEY = ""; + String COLOR = ""; + TreeSet colorList = new TreeSet(); + for (int i = 0; i < ds.getRowCount(); i++) { + VALUE = 0; + try { + VALUE = Integer.parseInt(ds.getString(i, 2)); + TOTAL = TOTAL+VALUE; + } catch (NumberFormatException ex) { + flagNull = 1; + } + KEY = ds.getString(i, 0); + try { + if(ds.getString(i, "chart_color")!=null) { + colorList.add(KEY+"|"+ds.getString(i, "chart_color")); + } + } catch (ArrayIndexOutOfBoundsException ex) { + System.out.println("No Chart Color"); + } + wholeScript.append("{ \""+ "key" +"\":\""+ KEY+"\", \""+ "y" +"\":"+VALUE+"}, \n"); + + } + StringBuffer color = new StringBuffer(""); + if(colorList.size()>0) { + SortedSet s = Collections.synchronizedSortedSet(colorList); + Object[] colorElements = (Object[]) s.toArray(); + + String element = ""; + + for (int i = 0; i < colorElements.length; i++) { + element = ((String)colorElements[i]); + color.append("'"+element.substring(element.indexOf("|")+1)+"',"); + } + color.deleteCharAt(color.length()-1); + }*/ + + //test end + boolean hasCustomizedChartColor = false; + if(flag == 1) { + StringBuffer catStr = new StringBuffer(""); + String color=""; + for (int i = 0; i < ds.getRowCount(); i++) { + catStr = new StringBuffer(""); + catStr.append(ds.getString(i, 2)); + try { + if(ds.getString(i, "chart_color")!=null) { + color = ds.getString(i, "chart_color"); + hasCustomizedChartColor = true; + catStr.append("|"+color); + } + } catch (ArrayIndexOutOfBoundsException ex) { + //System.out.println("No Chart Color"); + } + + if(catStr.length()>0) { + //duplicates are avoided + if(!ts.contains(catStr.toString())) + ts.add(catStr.toString()); + + } + } + //Object uniqueElements [] = ts.toArray(); + //SortedSet s = Collections.synchronizedSortedSet(ts); + //uniqueElements = (String[]) ts.toArray(); + DataColumnType dct = null; + List yTextSeries = reportRuntime.getChartDisplayNamesList(AppConstants.CHART_ALL_COLUMNS, formValues); + if(yTextSeries.size()==1) { + for (Iterator iter = l.iterator(); iter.hasNext();) { + dct = (DataColumnType) iter.next(); + //System.out.println(dct.getDisplayName() + " " + yText); + if(!(nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND))) { + if(nvl(chartLeftAxisLabel).length()<=0) { + chartLeftAxisLabel = nvl(dct.getYAxis()); + chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; + } + } + } + } + Object tempArray[] = ts.toArray(); + uniqueElements = Arrays.copyOf(tempArray, tempArray.length, String[].class); + + } else { + DataColumnType dct = null; + + List yTextSeries = reportRuntime.getChartDisplayNamesList(AppConstants.CHART_ALL_COLUMNS, formValues); + //if(columnValuesList.size() == 1) { + int dctIndex = 0; + for (Iterator iter = l.iterator(); iter.hasNext();) { + dct = (DataColumnType) iter.next(); + //System.out.println(dct.getDisplayName() + " " + yText); + if(!(nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND))) { + if(yTextSeries.contains((String)dct.getDisplayName())) { + if(nvl(dct.getChartColor()).length()>0) hasCustomizedChartColor = true; + if(hasCustomizedChartColor) { + //duplicates are avoided + if(!ts.contains(dct.getDisplayName()+"|"+nvl(dct.getChartColor()))) + ts.add(dct.getDisplayName()+"|"+nvl(dct.getChartColor())); + } else { + //duplicates are avoided + if(!ts.contains(dct.getDisplayName())) + ts.add(dct.getDisplayName()); + } + if(nvl(chartLeftAxisLabel).length()<=0) { + chartLeftAxisLabel = nvl(dct.getYAxis()); + chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; + } + if(nvl(chartRightAxisLabel).length()>0) { + String dctYAxis = nvl(dct.getYAxis()); + String yAxis = (dctYAxis.indexOf("|")!=-1)?dctYAxis.substring(0,dctYAxis.indexOf("|")):dctYAxis; + if(chartRightAxisLabel.equals(yAxis)) { + if(ts.contains(dct.getDisplayName())) { + if(hasCustomizedChartColor) { + ts.set(dctIndex, dct.getDisplayName()+"|R|"+nvl(dct.getChartColor())); + } else { + ts.set(dctIndex, dct.getDisplayName()+"|R"); + } + } + } + } + columnMap.put(dct.getDisplayName(), dct.getColId()); + } + dctIndex++; + } + + } + + //SortedSet s = Collections.synchronizedSortedSet(ts); + Object tempArray[] = ts.toArray(); + uniqueElements = Arrays.copyOf(tempArray, tempArray.length, String[].class); + //uniqueElements = (String[]) ts.toArray(); + + } + + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append(" \n" ); + + wholeScript.append(" \n"); + + if(showTitle) + wholeScript.append("

" + title +"

"); + + + wholeScript.append("
\n"); + //js files + wholeScript.append("\n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + //wholeScript.append(" \n"); + //if(multipleSeries) + //wholeScript.append(" \n"); + + //json + wholeScript.append(" \n"); + + } else if (chartType.equals(AppConstants.GT_PIE) || chartType.equals(AppConstants.GT_PIE_3D)) { + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append(" \n" ); + wholeScript.append(" \n"); + + if(showTitle) + wholeScript.append("

" + title +"

"); + + wholeScript.append("
"); + //"\n"); + //js files + wholeScript.append("\n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + + } else if (chartType.equals(AppConstants.GT_ANNOTATION_CHART) || chartType.equals(AppConstants.GT_FLEX_TIME_CHARTS)) { + + boolean timeCharts = chartType.equals(AppConstants.GT_FLEX_TIME_CHARTS); + + String dateStr = null; + java.util.Date date = null; + + final int YEARFLAG = 1; + final int MONTHFLAG = 2; + final int DAYFLAG = 3; + final int HOURFLAG = 4; + final int MINFLAG = 5; + final int SECFLAG = 6; + final int MILLISECFLAG = 7; + final int DAYOFTHEWEEKFLAG = 8; + final int FLAGDATE = 9; + + int flagNoDate = 0; + + int MAXNUM = 0; + int YAXISNUM = 0; + int flagNull = 0; + + double YAXISDOUBLENUM = 0.0; + double MAXDOUBLENUM = 0.0; + int MAXNUMDECIMALPLACES = 0; + + int formatFlag = 0; + + TreeSet dateStrList = new TreeSet(); + // added to store all date elements + SortedSet sortSet = new TreeSet(); + int count = 0; + + int flag = 0; + boolean hasCategoryAxis = reportRuntime.hasSeriesColumn(); + flag = hasCategoryAxis?1:0; + + + String anomalyText = ""; + + StringBuffer dataStrBuf = new StringBuffer(""); + StringBuffer annotationsStrBuf = new StringBuffer(""); + + String xAxisLabel = (reportRuntime.getChartLegendColumn()!=null)?reportRuntime.getChartLegendColumn().getDisplayName():""; + + //finding actual string + String actualText = ""; + DataColumnType dct = null; + for (Iterator iter = l.iterator(); iter.hasNext();) { + dct = (DataColumnType) iter.next(); + if((dct.getChartSeq()!=null && dct.getChartSeq() >=0) && !AppUtils.nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND)) { + //if(AppUtils.nvl(dct.getDisplayName()).toLowerCase().contains("actual")) { + actualText = dct.getDisplayName(); + break; + //} + } + } + + int anomalyRec = 0; + int columnIndex = 1; + ArrayList columnNames = new ArrayList(); + ArrayList columnValues = new ArrayList(); + Set set = null; + String columnName = ""; + String columnValue = ""; + long minDate = 0L; + long maxDate = 0L; + StringBuffer seriesBuffer = new StringBuffer(""); + + for (int i = 0; i < ds.getRowCount(); i++) { + columnNames = new ArrayList(); + columnValues = new ArrayList(); + columnName = ""; + columnValue = ""; + columnIndex = 1; + anomalyText = ""; + dateStr = ds.getString(i, 0); + date = getDateFromDateStr(dateStr); + if(date.getTime() > maxDate ) + maxDate = date.getTime(); + + formatFlag = getFlagFromDateStr(dateStr); + + + for (;columnIndex=0) && !AppUtils.nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND)) { + if((!timeCharts && !AppUtils.nvl(dct.getColId()).toLowerCase().equals("anomaly_text")) && AppUtils.nvl(dct.getColId()).toLowerCase().equals(columnName.toLowerCase())) { + dataStrBuf.append(","+columnValue); + break; + } else if(timeCharts && AppUtils.nvl(dct.getColId()).toLowerCase().equals(columnName.toLowerCase())){ + dataStrBuf.append(","+columnValue); + //break; + } + } + } + } + + dataStrBuf.append("],\n"); + if(!timeCharts) { + if(AppUtils.nvl(anomalyText).length()>0) { + ++anomalyRec; + annotationsStrBuf.append("anns.push( {\n"); + annotationsStrBuf.append(" series: '"+actualText+"',\n"); + annotationsStrBuf.append(" x: moment(\""+dateStr+"\"),\n"); + annotationsStrBuf.append(" shortText: '"+ IntToLetter(anomalyRec).toUpperCase() +"',\n"); + annotationsStrBuf.append(" text: '"+ anomalyText + "'\n"); + annotationsStrBuf.append("});\n"); + //anomalyRec++; + } + + } + } + + //if(!timeCharts) + //anomalyRec = anomalyRec - 1; + + minDate = maxDate - (new Long(reportRuntime.getZoomIn()).longValue()*60*60*1000); + System.out.println(new java.util.Date(maxDate) + " " + new java.util.Date(minDate) + " " + reportRuntime.getZoomIn()); + if(dataStrBuf.lastIndexOf(",")!= -1) + dataStrBuf.deleteCharAt(dataStrBuf.lastIndexOf(",")); + + wholeScript = new StringBuffer(""); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append(" \n"); + //wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append("\n"); + + wholeScript.append("\n "); + wholeScript.append("\n"); + wholeScript.append("\n"); + wholeScript.append(" \n"); + +/* if(showTitle) + wholeScript.append("

" + (AppUtils.nvl(reportRuntime.getReportTitle()).length()>0?reportRuntime.getReportTitle():reportRuntime.getReportName()) + "

\n"); +*/ + wholeScript.append(" \n"); + if(showTitle) { + wholeScript.append(" \n "); + wholeScript.append(" \n "); + } + + wholeScript.append(" \n "); + + wholeScript.append(" \n "); + wholeScript.append(" \n "); + + wholeScript.append(" \n "); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + if(AppUtils.nvl(reportRuntime.getLegendPosition()).length()>=0 && reportRuntime.getLegendPosition().equals("right")) { + wholeScript.append(" \n"); + } + wholeScript.append(" \n"); + if(anomalyRec > 0) { + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + } + wholeScript.append("
\n "); + wholeScript.append("
"+title+"
\n"); + wholeScript.append("
\n "); + if(AppUtils.nvl(reportRuntime.getLegendPosition()).length()<=0 || reportRuntime.getLegendPosition().equals("top")) { + wholeScript.append("
\n"); + } + wholeScript.append("
\n"); + wholeScript.append("
\n"); + + int heightInt = 0; + if(nvl(height).length() > 0) { + try { + heightInt = new Integer(height).intValue(); + heightInt -= 50; + } catch(Exception ex) { + if(height.endsWith("px")) { + try { + heightInt = new Integer(height.substring(0, height.indexOf("px"))); + heightInt -= 50; + } catch (Exception ex1) { + heightInt = 420; + } + } else { + heightInt = 420; + } + } + } else heightInt = 420; + if(AppUtils.nvl(reportRuntime.getLegendPosition()).length()>=0 && reportRuntime.getLegendPosition().equals("right")) { + wholeScript.append("
\n"); + wholeScript.append("
\n"); + wholeScript.append("
\n"); + wholeScript.append("
\n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n" ); + wholeScript.append(" \n"); + wholeScript.append("
Anomaly Description
\n"); + wholeScript.append("
\n"); + + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(""); + + + } else if (chartType.equals(AppConstants.GT_SCATTER)) { + + wholeScript.append("\n"); + wholeScript.append(" \n" ); + wholeScript.append(" \n"); + wholeScript.append("
"); + //js files + wholeScript.append("\n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append(" \n"); + wholeScript.append("\n"); + } else if (chartType.equals(AppConstants.GT_HIERARCHICAL_SUNBURST)) { + + StringBuffer dataStr = new StringBuffer(""); + StringBuffer groupBuffer = new StringBuffer(""); + StringBuffer s = new StringBuffer(""); + dataStr.append("{"); + dataStr.append(" \"ss4262\":{\n"); + String mid = ""; + String mid_old = ""; + String level = "-1"; + String level_old = "-1"; + String eid = ""; + for (int i = 0; i < ds.getRowCount(); i++) { + mid = ds.getString(i, "mid"); + level = ds.getString(i, "level1"); + eid = ds.getString(i, "eid"); + if(mid.equals(mid_old)) { + dataStr.append("\""+ eid +"\": 9956,\n"); + } else { + if(dataStr.lastIndexOf(",")!= -1) + dataStr.deleteCharAt(dataStr.lastIndexOf(",")); + //if(Integer.parseInt(level_old)==Integer.parseInt(level)) + //dataStr.append("},\n"); + if (Integer.parseInt(level_old)0) { + /*sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( + paramValue, "NULL"));*/ + reportSQL = Utils.replaceInString(reportSQL, fieldDisplay, nvl( + paramValue, "NULL")); + } + /*sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( + paramValue, "NULL"));*/ + reportSQL = Utils.replaceInString(reportSQL, "'" + fieldDisplay + "'", nvl( + paramValue, "NULL")); + reportSQL = Utils.replaceInString(reportSQL, fieldDisplay , nvl( + paramValue, "NULL")); + } + } + logger.debug(EELFLoggerDelegate.debugLogger, ("SQL " + reportSQL)); + String legendCol = "1 a"; + // String valueCol = "1"; + StringBuffer groupCol = new StringBuffer(); + StringBuffer seriesCol = new StringBuffer(); + StringBuffer valueCols = new StringBuffer(); + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, request); + if (nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) + legendCol = getSelectExpr(dc, colName)+" " + dc.getColId(); + // if(dc.getChartSeq()>0) + // valueCol = "NVL("+colName+", 0) "+dc.getColId(); + if ((!nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) + && (dc.getChartSeq()!=null && dc.getChartSeq().intValue() <= 0) && dc.isGroupBreak()) { + groupCol.append(", "); + groupCol.append(colName + " " + dc.getColId()); + } + } // for + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if(dc.isChartSeries()!=null && dc.isChartSeries().booleanValue()) { + //System.out.println("*****************, "+ " " +getColumnSelectStr(dc, paramValues)+ " "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))); + seriesCol.append(", "+ getSelectExpr(dc,getColumnSelectStr(dc, request))+ " " + dc.getColId()); + } + } + + /*for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + if(!dc.isChartSeries() && !(nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND))) { + //System.out.println("*****************, "+ " " +getColumnSelectStr(dc, paramValues)+ " "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))); + seriesCol.append(", "+ formatChartColumn(getSelectExpr(dc,getColumnSelectStr(dc, paramValues)))+ " " + dc.getColId()); + } + }*/ + + for (Iterator iter = chartValueCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, request); + String paramValue = ""; + if(AppUtils.nvl(colName).startsWith("[")) { + if (reportRuntime.getFormFieldList() != null) { + for (Iterator iterC = reportRuntime.getFormFieldList().getFormField().iterator(); iterC.hasNext();) { + FormFieldType fft = (FormFieldType) iterC.next(); + String fieldId = fft.getFieldId(); + String fieldDisplay = reportRuntime.getFormFieldDisplayName(fft); + String formfield_value = ""; + if(AppUtils.nvl(fieldDisplay).equals(colName)) { + formfield_value = AppUtils.getRequestNvlValue(request, fieldId); + paramValue = nvl(formfield_value); + } + } + + } + + seriesCol.append("," + (AppUtils.nvl(paramValue).length()>0? paramValue:"null") + " " + dc.getColId()); + } else { + //valueCols.append(", NVL(" + formatChartColumn(colName) + ",0) " + dc.getColId()); + seriesCol.append("," + (AppUtils.nvl(paramValue).length()>0? paramValue:formatChartColumn(colName)) + " " + dc.getColId()); + } + } // for + + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = dc.getDisplayName(); + String colValue = getColumnSelectStr(dc, request); + //String colName = getColumnSelectStr(dc, formGrid); + if(colName.equals(AppConstants.RI_CHART_TOTAL_COL)) + seriesCol.append(", " + AppConstants.RI_CHART_TOTAL_COL + " " + AppConstants.RI_CHART_TOTAL_COL ); + if (colName.equals(AppConstants.RI_CHART_COLOR)) + seriesCol.append(", " + colValue + " " + AppConstants.RI_CHART_COLOR ); + if(colName.equals(AppConstants.RI_CHART_MARKER_START)) + seriesCol.append(", " + AppConstants.RI_CHART_MARKER_START + " " + AppConstants.RI_CHART_MARKER_START ); + if(colName.equals(AppConstants.RI_CHART_MARKER_END)) + seriesCol.append(", " + AppConstants.RI_CHART_MARKER_END + " " + AppConstants.RI_CHART_MARKER_END ); + if(colName.equals(AppConstants.RI_CHART_MARKER_TEXT_LEFT)) + seriesCol.append(", " + AppConstants.RI_CHART_MARKER_TEXT_LEFT + " " + AppConstants.RI_CHART_MARKER_TEXT_LEFT ); + if(colName.equals(AppConstants.RI_CHART_MARKER_TEXT_RIGHT)) + seriesCol.append(", " + AppConstants.RI_CHART_MARKER_TEXT_RIGHT + " " + AppConstants.RI_CHART_MARKER_TEXT_RIGHT ); + //if(colName.equals(AppConstants.RI_ANOMALY_TEXT)) + //seriesCol.append(", " + AppConstants.RI_ANOMALY_TEXT + " " + AppConstants.RI_ANOMALY_TEXT ); + } + + //debugLogger.debug("ReportSQL Chart " + reportSQL ); + /*for (Iterator iter = chartValueCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, paramValues); + //valueCols.append(", NVL(" + formatChartColumn(colName) + ",0) " + dc.getColId()); + valueCols.append("," + formatChartColumn(colName) + " " + dc.getColId()); + } // for + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + DataColumnType dc = (DataColumnType) iter.next(); + String colName = getColumnSelectStr(dc, paramValues); + //if(colName.equals(AppConstants.RI_CHART_TOTAL_COL) || colName.equals(AppConstants.RI_CHART_COLOR)) { + if(colName.equals(AppConstants.RI_CHART_TOTAL_COL)) + valueCols.append(", " + AppConstants.RI_CHART_TOTAL_COL + " " + AppConstants.RI_CHART_TOTAL_COL ); + if (colName.equals(AppConstants.RI_CHART_COLOR)) + valueCols.append(", " + AppConstants.RI_CHART_COLOR + " " + AppConstants.RI_CHART_COLOR ); + if (colName.equals(AppConstants.RI_CHART_INCLUDE)) + valueCols.append(", " + AppConstants.RI_CHART_INCLUDE + " " + AppConstants.RI_CHART_INCLUDE ); + //} + }*/ + String final_sql = ""; + reportSQL = Utils.replaceInString(reportSQL, " from ", " FROM "); + reportSQL = Utils.replaceInString(reportSQL, " From ", " FROM "); + reportSQL = Utils.replaceInString(reportSQL, " select ", " SELECT "); + reportSQL = Utils.replaceInString(reportSQL, " union ", " UNION "); + //reportSQL = reportSQL.replaceAll("[\\s]*\\(", "("); +// if(reportSQL.indexOf("UNION") != -1) { +// if(reportSQL.indexOf("FROM(")!=-1) +// final_sql += " "+reportSQL.substring(reportSQL.indexOf("FROM(") ); +// else if (reportSQL.indexOf("FROM (")!=-1) +// final_sql += " "+reportSQL.substring(reportSQL.indexOf("FROM (") ); +// //TODO ELSE THROW ERROR +// } +// else { +// final_sql += " "+reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM ")); +// } + int pos = 0; + int pos_first_select = 0; + int pos_dup_select = 0; + int pos_prev_select = 0; + int pos_last_select = 0; + if (reportSQL.indexOf("FROM", pos)!=-1) { + pos = reportSQL.indexOf("FROM", pos); + pos_dup_select = reportSQL.lastIndexOf("SELECT",pos); + pos_first_select = reportSQL.indexOf("SELECT");//,pos); + logger.debug(EELFLoggerDelegate.debugLogger, ("pos_select " + pos_first_select + " " + pos_dup_select)); + if(pos_dup_select > pos_first_select) { + logger.debug(EELFLoggerDelegate.debugLogger, ("********pos_dup_select ********" + pos_dup_select)); + //pos_dup_select1 = pos_dup_select; + pos_prev_select = pos_first_select; + pos_last_select = pos_dup_select; + while (pos_last_select > pos_prev_select) { + logger.debug(EELFLoggerDelegate.debugLogger, ("pos_last , pos_prev " + pos_last_select + " " + pos_prev_select)); + pos = reportSQL.indexOf("FROM", pos+2); + pos_prev_select = pos_last_select; + pos_last_select = reportSQL.lastIndexOf("SELECT",pos); + logger.debug(EELFLoggerDelegate.debugLogger, ("in WHILE LOOP LAST " + pos_last_select)); + } + } + + } + final_sql += " "+reportSQL.substring(pos); + logger.debug(EELFLoggerDelegate.debugLogger, ("Final SQL " + final_sql)); + String sql = "SELECT " + legendCol + ", " + legendCol+"_1" + seriesCol.toString()+ nvl(valueCols.toString(), ", 1") + + groupCol.toString() + + final_sql; + logger.debug(EELFLoggerDelegate.debugLogger, ("Final sql in generateChartSQL " +sql)); + + return sql; + } // generateChartSQL + + private String getColumnSelectStr(DataColumnType dc, HttpServletRequest request) { + //String colName = dc.isCalculated() ? dc.getColName() + // : ((nvl(dc.getTableId()).length() > 0) ? (dc.getTableId() + "." + dc + // .getColName()) : dc.getColName()); + String colName = dc.getColName(); + String paramValue = null; + //if (dc.isCalculated()) { + if (reportRuntime.getFormFieldList() != null) { + for (Iterator iter = reportRuntime.getFormFieldList().getFormField().iterator(); iter.hasNext();) { + FormFieldType fft = (FormFieldType) iter.next(); + String fieldId = fft.getFieldId(); + String fieldDisplay = reportRuntime.getFormFieldDisplayName(fft); + String formfield_value = ""; + formfield_value = AppUtils.getRequestNvlValue(request, fieldId); + paramValue = nvl(formfield_value); + if(paramValue.length()>0) { + /*sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( + paramValue, "NULL"));*/ + colName = Utils.replaceInString(colName, "'" + fieldDisplay + "'", "'"+nvl( + paramValue, "NULL")+"'"); + colName = Utils.replaceInString(colName, fieldDisplay, nvl( + paramValue, "NULL")); + } + } + return colName; + } + //} + return colName; + } // getColumnSelectStr + + + + public String getSelectExpr(DataColumnType dct) { + // String colName = + // dct.isCalculated()?dct.getColName():((nvl(dct.getTableId()).length()>0)?(dct.getTableId()+"."+dct.getColName()):dct.getColName()); + return getSelectExpr(dct, dct.getColName() /* colName */); + } // getSelectExpr + + private String getSelectExpr(DataColumnType dct, String colName) { + String colType = dct.getColType(); + if (colType.equals(AppConstants.CT_CHAR) + || ((nvl(dct.getColFormat()).length() == 0) && (!colType + .equals(AppConstants.CT_DATE)))) + return colName; + else + return "DATE_FORMAT(" + colName + ", '" + + nvl(dct.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT) + "')"; + } // getSelectExpr + + private String formatChartColumn(String colName) { + logger.debug(EELFLoggerDelegate.debugLogger, ("Format Chart Column Input colName " + colName)); + colName = colName.trim(); + colName = Utils.replaceInString(colName, "TO_CHAR", "to_char"); + colName = Utils.replaceInString(colName, "to_number", "TO_NUMBER"); + //reportSQL = reportSQL.replaceAll("[\\s]*\\(", "("); + colName = colName.replaceAll(",[\\s]*\\(", ",("); + StringBuffer colNameBuf = new StringBuffer(colName); + int pos = 0, posFormatStart = 0, posFormatEnd = 0; + String format = ""; + + if(colNameBuf.indexOf("999")==-1 && colNameBuf.indexOf("990")==-1) { + logger.debug(EELFLoggerDelegate.debugLogger, (" return colName " + colNameBuf.toString())); + return colNameBuf.toString(); + } + + while (colNameBuf.indexOf("to_char")!=-1) { + if(colNameBuf.indexOf("999")!=-1 || colNameBuf.indexOf("990")!=-1) { + pos = colNameBuf.indexOf("to_char"); + colNameBuf.insert(pos, " TO_NUMBER ( CR_RAPTOR.SAFE_TO_NUMBER ("); + pos = colNameBuf.indexOf("to_char"); + colNameBuf.replace(pos, pos+7, "TO_CHAR"); + //colName = Utils.replaceInString(colNameBuf.toString(), "to_char", " TO_NUMBER ( CR_RAPTOR.SAFE_TO_NUMBER ( TO_CHAR "); + logger.debug(EELFLoggerDelegate.debugLogger, ("After adding to_number " + colNameBuf.toString())); + //posFormatStart = colNameBuf.lastIndexOf(",'")+1; + posFormatStart = colNameBuf.indexOf(",'", pos)+1; + posFormatEnd = colNameBuf.indexOf(")",posFormatStart); + logger.debug(EELFLoggerDelegate.debugLogger, (posFormatStart + " " + posFormatEnd + " "+ pos)); + format = colNameBuf.substring(posFormatStart, posFormatEnd); + //posFormatEnd = colNameBuf.indexOf(")",posFormatEnd); + colNameBuf.insert(posFormatEnd+1, " ," + format + ") , "+ format + ")"); + logger.debug(EELFLoggerDelegate.debugLogger, ("colNameBuf " + colNameBuf.toString())); + } + } + logger.debug(EELFLoggerDelegate.debugLogger, (" return colName " + colNameBuf.toString())); + return colNameBuf.toString(); + } + + public List getChartValueColumnsList( int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ + List reportCols = reportRuntime.getAllColumns(); + + ArrayList chartValueCols = new ArrayList(); + int flag = 0; + for (Iterator iter = reportCols.iterator(); iter.hasNext();) { + flag = 0; + DataColumnType dc = (DataColumnType) iter.next(); +// if(filter == 2 || filter == 1) { + flag = reportRuntime.getDependsOnFormFieldFlag(dc, formValues); + + if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 && !(nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND))) { + if(nvl(dc.getChartGroup()).length()<=0) { + if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue())) { + chartValueCols.add(dc); + } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { + chartValueCols.add(dc); + } + else if(filter == 0) chartValueCols.add(dc); + } else chartValueCols.add(dc); + } +// } else +// chartValueCols.add(dc); + } // for + Collections.sort(chartValueCols, new ChartSeqComparator()); + return chartValueCols; + } // getChartValueColumnsList + + public String parseTitle(String title, HashMap formValues) { + Set set = formValues.entrySet(); + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + if(title.indexOf("["+ entry.getKey() + "]")!= -1) { + title = Utils.replaceInString(title, "["+entry.getKey()+"]", nvl( + (String) entry.getValue(), "")); + } + } + return title; + } + + public java.util.Date getDateFromDateStr(String dateStr) { + SimpleDateFormat MMDDYYYYFormat = new SimpleDateFormat("MM/dd/yyyy"); + SimpleDateFormat EEEMMDDYYYYFormat = new SimpleDateFormat("EEE, MM/dd/yyyy"); //2012-11-01 00:00:00 + SimpleDateFormat YYYYMMDDFormat = new SimpleDateFormat("yyyy/MM/dd"); + SimpleDateFormat MONYYYYFormat = new SimpleDateFormat("MMM yyyy"); + SimpleDateFormat MMYYYYFormat = new SimpleDateFormat("MM/yyyy"); + SimpleDateFormat MMMMMDDYYYYFormat = new SimpleDateFormat("MMMMM dd, yyyy"); + SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat timestampHrFormat = new SimpleDateFormat("yyyy-MM-dd HH"); + SimpleDateFormat timestampDayFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat DDMONYYYYFormat = new SimpleDateFormat("dd-MMM-yyyy"); + SimpleDateFormat MONTHYYYYFormat = new SimpleDateFormat("MMMMM, yyyy"); + SimpleDateFormat MMDDYYYYHHFormat = new SimpleDateFormat("MM/dd/yyyy HH"); + SimpleDateFormat MMDDYYYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + SimpleDateFormat MMDDYYYYHHMMFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm"); + SimpleDateFormat YYYYMMDDHHMMSSFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + SimpleDateFormat YYYYMMDDHHMMFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); + SimpleDateFormat DDMONYYYYHHMMSSFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); + SimpleDateFormat DDMONYYYYHHMMFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); + SimpleDateFormat MMDDYYFormat = new SimpleDateFormat("MM/dd/yy"); + SimpleDateFormat MMDDYYHHMMFormat = new SimpleDateFormat("MM/dd/yy HH:mm"); + SimpleDateFormat MMDDYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); + SimpleDateFormat timestampFormat1 = new SimpleDateFormat("yyyy-M-d.HH.mm. s. S"); + SimpleDateFormat timestamp_W_dash = new SimpleDateFormat("yyyyMMddHHmmss"); + SimpleDateFormat MMDDYYYYHHMMZFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm z"); + SimpleDateFormat YYYYFormat = new SimpleDateFormat("yyyy"); + java.util.Date date = null; + + int formatFlag = 0; + + final int YEARFLAG = 1; + final int MONTHFLAG = 2; + final int DAYFLAG = 3; + final int HOURFLAG = 4; + final int MINFLAG = 5; + final int SECFLAG = 6; + final int MILLISECFLAG = 7; + final int DAYOFTHEWEEKFLAG = 8; + final int FLAGDATE = 9; + /*int yearFlag = 1; + int monthFlag = 2; + int dayFlag = 3; + int hourFlag = 4; + int minFlag = 5; + int secFlag = 6; + int milliSecFlag = 7; + int dayoftheweekFlag = 8; + int flagDate = 10; + */ + + date = MMDDYYYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + if(date==null) { + date = EEEMMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYOFTHEWEEKFLAG; + } + if(date==null) { + date = MMDDYYYYHHMMFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + if(date==null) { + //MMDDYYYYHHFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + date = MMDDYYYYHHFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = HOURFLAG; + } + if(date==null) { + date = MMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + if(date==null) { + date = YYYYMMDDFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + if(date==null) { + date = timestampFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + if(date==null) { + date = timestampHrFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = HOURFLAG; + } + if(date==null) { + date = timestampDayFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + + if(date==null) { + date = MONYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MONTHFLAG; + } + if(date==null) { + date = MMYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MONTHFLAG; + } + if(date==null) { + date = MMMMMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + if(date==null) { + date = MONTHYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MONTHFLAG; + } + + if(date==null) { + date = YYYYMMDDHHMMSSFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + + if(date==null) { + date = YYYYMMDDHHMMFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + + if(date==null) { + date = DDMONYYYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + + if(date==null) { + date = DDMONYYYYHHMMFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + + if(date==null) { + date = DDMONYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + + if(date==null) { + date = MMDDYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + + if(date==null) { + date = MMDDYYHHMMFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + + if(date==null) { + date = MMDDYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + + if(date==null) { + date = timestampFormat1.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + + if(date==null) { + date = MMDDYYYYHHMMZFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + + if(date==null) { + date = YYYYFormat.parse(dateStr, new ParsePosition(0)); + /* Some random numbers should not satisfy this year format. */ + if(dateStr.length()>4) date = null; + if(date!=null) formatFlag = YEARFLAG; + } + if(date==null) { + date = timestamp_W_dash.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + if(date==null) + date = null; + return date; + } + + public int getFlagFromDateStr(String dateStr) { + SimpleDateFormat MMDDYYYYFormat = new SimpleDateFormat("MM/dd/yyyy"); + SimpleDateFormat EEEMMDDYYYYFormat = new SimpleDateFormat("EEE, MM/dd/yyyy"); //2012-11-01 00:00:00 + SimpleDateFormat YYYYMMDDFormat = new SimpleDateFormat("yyyy/MM/dd"); + SimpleDateFormat MONYYYYFormat = new SimpleDateFormat("MMM yyyy"); + SimpleDateFormat MMYYYYFormat = new SimpleDateFormat("MM/yyyy"); + SimpleDateFormat MMMMMDDYYYYFormat = new SimpleDateFormat("MMMMM dd, yyyy"); + SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat timestampHrFormat = new SimpleDateFormat("yyyy-MM-dd HH"); + SimpleDateFormat timestampDayFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat DDMONYYYYFormat = new SimpleDateFormat("dd-MMM-yyyy"); + SimpleDateFormat MONTHYYYYFormat = new SimpleDateFormat("MMMMM, yyyy"); + SimpleDateFormat MMDDYYYYHHFormat = new SimpleDateFormat("MM/dd/yyyy HH"); + SimpleDateFormat MMDDYYYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + SimpleDateFormat MMDDYYYYHHMMFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm"); + SimpleDateFormat YYYYMMDDHHMMSSFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + SimpleDateFormat YYYYMMDDHHMMFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); + SimpleDateFormat DDMONYYYYHHMMSSFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); + SimpleDateFormat DDMONYYYYHHMMFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); + SimpleDateFormat MMDDYYFormat = new SimpleDateFormat("MM/dd/yy"); + SimpleDateFormat MMDDYYHHMMFormat = new SimpleDateFormat("MM/dd/yy HH:mm"); + SimpleDateFormat MMDDYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); + SimpleDateFormat timestampFormat1 = new SimpleDateFormat("yyyy-M-d.HH.mm. s. S"); + SimpleDateFormat timestamp_W_dash = new SimpleDateFormat("yyyyMMddHHmmss"); + SimpleDateFormat MMDDYYYYHHMMZFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm z"); + SimpleDateFormat YYYYFormat = new SimpleDateFormat("yyyy"); + java.util.Date date = null; + + int formatFlag = 0; + + final int YEARFLAG = 1; + final int MONTHFLAG = 2; + final int DAYFLAG = 3; + final int HOURFLAG = 4; + final int MINFLAG = 5; + final int SECFLAG = 6; + final int MILLISECFLAG = 7; + final int DAYOFTHEWEEKFLAG = 8; + final int FLAGDATE = 9; + /*int yearFlag = 1; + int monthFlag = 2; + int dayFlag = 3; + int hourFlag = 4; + int minFlag = 5; + int secFlag = 6; + int milliSecFlag = 7; + int dayoftheweekFlag = 8; + int flagDate = 10; + */ + + date = MMDDYYYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + if(date==null) { + date = EEEMMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYOFTHEWEEKFLAG; + } + if(date==null) { + date = MMDDYYYYHHMMFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + if(date==null) { + //MMDDYYYYHHFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + date = MMDDYYYYHHFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = HOURFLAG; + } + if(date==null) { + date = MMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + if(date==null) { + date = YYYYMMDDFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + if(date==null) { + date = timestampFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + if(date==null) { + date = timestampHrFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = HOURFLAG; + } + if(date==null) { + date = timestampDayFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + if(date==null) { + date = MONYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MONTHFLAG; + } + if(date==null) { + date = MMYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MONTHFLAG; + } + if(date==null) { + date = MMMMMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + if(date==null) { + date = MONTHYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MONTHFLAG; + } + + if(date==null) { + date = YYYYMMDDHHMMSSFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + + if(date==null) { + date = YYYYMMDDHHMMFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + + if(date==null) { + date = DDMONYYYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + + if(date==null) { + date = DDMONYYYYHHMMFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + + if(date==null) { + date = DDMONYYYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + + if(date==null) { + date = MMDDYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + + if(date==null) { + date = MMDDYYHHMMFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + + if(date==null) { + date = MMDDYYFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = DAYFLAG; + } + + if(date==null) { + date = timestampFormat1.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + + if(date==null) { + date = MMDDYYYYHHMMZFormat.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = MINFLAG; + } + + if(date==null) { + date = YYYYFormat.parse(dateStr, new ParsePosition(0)); + /* Some random numbers should not satisfy this year format. */ + if(dateStr.length()>4) date = null; + if(date!=null) formatFlag = YEARFLAG; + } + if(date==null) { + date = timestamp_W_dash.parse(dateStr, new ParsePosition(0)); + if(date!=null) formatFlag = SECFLAG; + } + if(date==null) + date = null; + return formatFlag; + } + + public static String[] reverse(String[] arr) { + List list = Arrays.asList(arr); + Collections.reverse(list); + return (String[])list.toArray(); + } + + public int getNumberOfDecimalPlaces(double num) { + Double d = num; + String[] splitter = d.toString().split("\\."); + splitter[0].length(); // Before Decimal Count + splitter[1].length(); // After Decimal Count + return splitter[1].length(); + } + + public boolean getBooleanValue(String s) { + return getBooleanValue(s,null); + } + + public boolean getBooleanValue(String s, Boolean defaultValue) { + s = nvl(s); + if(s.length()<=0 && defaultValue!=null) return defaultValue.booleanValue(); + else if(s.length()<=0) return false; + else { + if(s.toUpperCase().startsWith("Y") || s.toLowerCase().equals("true")) + return true; + else + return false; + } + } + + + public String IntToLetter(int Int) { + if (Int<27){ + return Character.toString((char)(Int+96)); + } else { + if (Int%26==0) { + return IntToLetter((Int/26)-1)+IntToLetter((Int%26)+1); + } else { + return IntToLetter(Int/26)+IntToLetter(Int%26); + } + } + } + + + + + private void clearReportRuntimeBackup(HttpServletRequest request) { + //Session sess = Sessions.getCurrent(true)getCurrent(); + //HttpSession session = (HttpSession)sess.getNativeSession(); + HttpSession session = request.getSession(); + session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); + request.removeAttribute(AppConstants.DRILLDOWN_INDEX); + session.removeAttribute(AppConstants.DRILLDOWN_INDEX); + request.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); + session.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); + Enumeration enum1 = session.getAttributeNames(); + String attributeName = ""; + while(enum1.hasMoreElements()) { + attributeName = enum1.nextElement(); + if(attributeName.startsWith("parent_")) { + session.removeAttribute(attributeName); + } + } + session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); + session.removeAttribute(AppConstants.SI_BACKUP_FOR_REP_ID); + session.removeAttribute(AppConstants.SI_COLUMN_LOOKUP); + session.removeAttribute(AppConstants.SI_DASHBOARD_REP_ID); + session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); + session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME); + session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); + session.removeAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP); + session.removeAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); + session.removeAttribute(AppConstants.SI_DATA_SIZE_FOR_TEXTFIELD_POPUP); + session.removeAttribute(AppConstants.SI_MAP); + session.removeAttribute(AppConstants.SI_MAP_OBJECT); + session.removeAttribute(AppConstants.SI_REPORT_DEFINITION); + session.removeAttribute(AppConstants.SI_REPORT_RUNTIME); + session.removeAttribute(AppConstants.SI_REPORT_RUN_BACKUP); + session.removeAttribute(AppConstants.SI_REPORT_SCHEDULE); + session.removeAttribute(AppConstants.RI_REPORT_DATA); + session.removeAttribute(AppConstants.RI_CHART_DATA); + session.removeAttribute(AppConstants.SI_FORMFIELD_INFO); + session.removeAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); + + } // clearReportRuntimeBackup + + + public static synchronized java.util.HashMap getRequestParametersMap(ReportRuntime rr, HttpServletRequest request) + { + HashMap valuesMap = new HashMap(); + + ReportFormFields rff = rr.getReportFormFields(); + + int idx = 0; + FormField ff = null; + + Map fieldNameMap = new HashMap(); + int countOfFields = 0 ; + + + for(rff.resetNext(); rff.hasNext(); idx++) { + ff = rff.getNext(); + fieldNameMap.put(ff.getFieldName(), ff.getFieldDisplayName()); + countOfFields++; + } + + List formParameter = new ArrayList(); + String formField = ""; + for(int i = 0 ; i < rff.size(); i++) { + ff = ((FormField)rff.getFormField(i)); + formField = ff.getFieldName(); + boolean isMultiValue = false; + isMultiValue = ff.getFieldType().equals(FormField.FFT_CHECK_BOX) + || ff.getFieldType().equals(FormField.FFT_LIST_MULTI); + boolean isTextArea = (ff.getFieldType().equals(FormField.FFT_TEXTAREA) && rr.getReportDefType() + .equals(AppConstants.RD_SQL_BASED)); + + if(request.getParameterValues(formField) != null && isMultiValue ) { + String[] vals = request.getParameterValues(formField); + StringBuffer value = new StringBuffer(""); + if(!AppUtils.getRequestFlag(request, AppConstants.RI_RESET_ACTION)) { + + if ( isMultiValue ) { + value.append("("); + } + for(int j = 0 ; j < vals.length; j++) { + if(isMultiValue) value.append("'"); + try { + if(vals[j] !=null && vals[j].length() > 0) { + vals[j] = Utils.oracleSafe(vals[j]); + value.append(java.net.URLDecoder.decode(vals[j], "UTF-8"));// + ","; + } + else + value.append(vals[j]); + } catch (UnsupportedEncodingException ex) {value.append(vals[j]);} + catch (IllegalArgumentException ex1){value.append(vals[j]);} + catch (Exception ex2){ + value.append(vals[j]); + } + + + if(isMultiValue) value.append("'"); + + if(j != vals.length -1) { + value.append(","); + } + } + if(vals.length > 0) { + value.append(")"); + } + } + + //value = value.substring(0 , value.length()); + + valuesMap.put(fieldNameMap.get(formField), value.toString()); + value = new StringBuffer(""); + } else if(request.getParameter(formField) != null) { + if(isTextArea) { + String value = ""; + value = request.getParameter(formField); + + value = Utils.oracleSafe(value); + value = "('" + Utils.replaceInString(value, ",", "'|'") + "')"; + value = Utils.replaceInString(value, "|", ","); + valuesMap.put(fieldNameMap.get(formField), value); + value = ""; + } else { + String value = ""; + if(!AppUtils.getRequestFlag(request, AppConstants.RI_RESET_ACTION)) + value = request.getParameter(formField); + valuesMap.put(fieldNameMap.get(formField), Utils.oracleSafe(value)); + } + + } else { + valuesMap.put(fieldNameMap.get(formField), "" ); + } + + } + + return valuesMap; + + } + +} diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSON.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSON.java new file mode 100644 index 00000000..c03fb7ae --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSON.java @@ -0,0 +1,451 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.runtime; + +import java.util.ArrayList; +import java.util.Map; + +import org.openecomp.portalsdk.analytics.view.ColumnHeader; + +class Row { + private String displayValue; + private String dataType; + private String colId; + //private boolean visible; + + + /*public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + }*/ + public String getDisplayValue() { + return displayValue; + } + public void setDisplayValue(String displayValue) { + this.displayValue = displayValue; + } + public String getDataType() { + return dataType; + } + public void setDataType(String dataType) { + this.dataType = dataType; + } + public String getColId() { + return colId; + } + public void setColId(String colId) { + this.colId = colId; + } + + +} +class IndexValueJSON { + private int index; + private String value; + private String title; + public int getIndex() { + return index; + } + public void setIndex(int index) { + this.index = index; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + +} + +class DomainAxisJSON extends IndexValueJSON {} + +class ChartColumnJSON extends IndexValueJSON {} + +class ChartTypeJSON extends IndexValueJSON {} + +class PieChartOptions { + +} + +public class ChartJSON { + + private String reportID; + private String reportName; + private String reportDescr; + private String reportTitle; + private String reportSubTitle; + private ArrayList formFieldList; + private ArrayList chartColumnJSONList; + private String formfield_comments; + private int totalRows; + private String chartSqlWhole; + private boolean chartAvailable; + private ChartTypeJSON chartTypeJSON; + private BarChartOptions barChartOptions; + private PieChartOptions pieChartOptions; + private TimeSeriesChartOptions timeSeriesChartOptions; + private FlexTimeSeriesChartOptions flexTimeSeriesChartOptions; + private CommonChartOptions commonChartOptions; + private String width; + private String height; + private boolean animation; + private String rotateLabels; + private boolean staggerLabels; + private boolean showTitle; + private DomainAxisJSON domainAxisJSON; + private CategoryAxisJSON categoryAxisJSON; + private boolean hasCategoryAxis; + + + public boolean isHasCategoryAxis() { + return hasCategoryAxis; + } + public void setHasCategoryAxis(boolean hasCategoryAxis) { + this.hasCategoryAxis = hasCategoryAxis; + } + private ArrayList rangeAxisList; + private ArrayList > wholeList; + + private String primaryAxisLabel; + private String secondaryAxisLabel; + private String minRange; + private String maxRange; + //private int topMargin; + //private int bottomMargin; + //private int leftMargin; + //private int rightMargin; + + /*private boolean showMaxMin; + private boolean showLegend; + private boolean showControls; + private String topMargin; + private String bottomMargin; + private String leftMargin; + private String rightMargin; + private String subType; + private boolean stacked; + private boolean horizontalBar; + private boolean barRealTimeAxis; + private boolean barReduceXAxisLabels; + private boolean timeAxis;*/ + + public String getReportID() { + return reportID; + } + public void setReportID(String reportID) { + this.reportID = reportID; + } + public String getReportName() { + return reportName; + } + public void setReportName(String reportName) { + this.reportName = reportName; + } + public String getReportDescr() { + return reportDescr; + } + public void setReportDescr(String reportDescr) { + this.reportDescr = reportDescr; + } + public String getReportTitle() { + return reportTitle; + } + public void setReportTitle(String reportTitle) { + this.reportTitle = reportTitle; + } + public String getReportSubTitle() { + return reportSubTitle; + } + public void setReportSubTitle(String reportSubTitle) { + this.reportSubTitle = reportSubTitle; + } + public ArrayList getFormFieldList() { + return formFieldList; + } + public void setFormFieldList(ArrayList formFieldList) { + this.formFieldList = formFieldList; + } + public String getFormfield_comments() { + return formfield_comments; + } + public void setFormfield_comments(String formfield_comments) { + this.formfield_comments = formfield_comments; + } + public int getTotalRows() { + return totalRows; + } + public void setTotalRows(int totalRows) { + this.totalRows = totalRows; + } + public String getChartSqlWhole() { + return chartSqlWhole; + } + public void setChartSqlWhole(String chartSqlWhole) { + this.chartSqlWhole = chartSqlWhole; + } + public boolean isChartAvailable() { + return chartAvailable; + } + public void setChartAvailable(boolean chartAvailable) { + this.chartAvailable = chartAvailable; + } + public String getWidth() { + return width; + } + public void setWidth(String width) { + this.width = width; + } + public String getHeight() { + return height; + } + public void setHeight(String height) { + this.height = height; + } + public boolean isAnimation() { + return animation; + } + public void setAnimation(boolean animation) { + this.animation = animation; + } + public String getRotateLabels() { + return rotateLabels; + } + public void setRotateLabels(String rotateLabels) { + this.rotateLabels = rotateLabels; + } + public boolean isStaggerLabels() { + return staggerLabels; + } + public void setStaggerLabels(boolean staggerLabels) { + this.staggerLabels = staggerLabels; + } + public boolean isShowTitle() { + return showTitle; + } + public void setShowTitle(boolean showTitle) { + this.showTitle = showTitle; + } + /*public boolean isShowMaxMin() { + return showMaxMin; + } + public void setShowMaxMin(boolean showMaxMin) { + this.showMaxMin = showMaxMin; + } + public boolean isShowLegend() { + return showLegend; + } + public void setShowLegend(boolean showLegend) { + this.showLegend = showLegend; + } + public boolean isShowControls() { + return showControls; + } + public void setShowControls(boolean showControls) { + this.showControls = showControls; + } + public String getTopMargin() { + return topMargin; + } + public void setTopMargin(String topMargin) { + this.topMargin = topMargin; + } + public String getBottomMargin() { + return bottomMargin; + } + public void setBottomMargin(String bottomMargin) { + this.bottomMargin = bottomMargin; + } + public String getLeftMargin() { + return leftMargin; + } + public void setLeftMargin(String leftMargin) { + this.leftMargin = leftMargin; + } + public String getRightMargin() { + return rightMargin; + } + public void setRightMargin(String rightMargin) { + this.rightMargin = rightMargin; + } + + public String getSubType() { + return subType; + } + public void setSubType(String subType) { + this.subType = subType; + } + public boolean isStacked() { + return stacked; + } + public void setStacked(boolean stacked) { + this.stacked = stacked; + } + public boolean isHorizontalBar() { + return horizontalBar; + } + public void setHorizontalBar(boolean horizontalBar) { + this.horizontalBar = horizontalBar; + } + public boolean isBarRealTimeAxis() { + return barRealTimeAxis; + } + public void setBarRealTimeAxis(boolean barRealTimeAxis) { + this.barRealTimeAxis = barRealTimeAxis; + } + public boolean isBarReduceXAxisLabels() { + return barReduceXAxisLabels; + } + public void setBarReduceXAxisLabels(boolean barReduceXAxisLabels) { + this.barReduceXAxisLabels = barReduceXAxisLabels; + } + public boolean isTimeAxis() { + return timeAxis; + } + public void setTimeAxis(boolean timeAxis) { + this.timeAxis = timeAxis; + }*/ + public ChartTypeJSON getChartTypeJSON() { + return chartTypeJSON; + } + public void setChartTypeJSON(ChartTypeJSON chartTypeJSON) { + this.chartTypeJSON = chartTypeJSON; + } + public String getChartType() { + return chartTypeJSON.getValue(); + } + public DomainAxisJSON getDomainAxisJSON() { + return domainAxisJSON; + } + public void setDomainAxisJSON(DomainAxisJSON domainAxisJSON) { + this.domainAxisJSON = domainAxisJSON; + } + public CategoryAxisJSON getCategoryAxisJSON() { + return categoryAxisJSON; + } + public void setCategoryAxisJSON(CategoryAxisJSON categoryAxisJSON) { + this.categoryAxisJSON = categoryAxisJSON; + } + public ArrayList getRangeAxisList() { + return rangeAxisList; + } + public void setRangeAxisList(ArrayList rangeAxisList) { + this.rangeAxisList = rangeAxisList; + } + public String getPrimaryAxisLabel() { + return primaryAxisLabel; + } + public void setPrimaryAxisLabel(String primaryAxisLabel) { + this.primaryAxisLabel = primaryAxisLabel; + } + public String getSecondaryAxisLabel() { + return secondaryAxisLabel; + } + public void setSecondaryAxisLabel(String secondaryAxisLabel) { + this.secondaryAxisLabel = secondaryAxisLabel; + } + public String getMinRange() { + return minRange; + } + public void setMinRange(String minRange) { + this.minRange = minRange; + } + public String getMaxRange() { + return maxRange; + } + public void setMaxRange(String maxRange) { + this.maxRange = maxRange; + } + /*public ArrayList getRowList() { + return rowList; + } + public void setRowList(ArrayList rowList) { + this.rowList = rowList; + }*/ + + public ArrayList> getWholeList() { + return wholeList; + } + public void setWholeList(ArrayList> wholeList) { + this.wholeList = wholeList; + } + //private ArrayList reportDataColumns; + //private ArrayList> reportDataRows; + public ArrayList getChartColumnJSONList() { + return chartColumnJSONList; + } + public void setChartColumnJSONList(ArrayList chartColumnJSONList) { + this.chartColumnJSONList = chartColumnJSONList; + } + + public BarChartOptions getBarChartOptions() { + return barChartOptions; + } + public void setBarChartOptions(BarChartOptions barChartOptions) { + this.barChartOptions = barChartOptions; + } + public PieChartOptions getPieChartOptions() { + return pieChartOptions; + } + public void setPieChartOptions(PieChartOptions pieChartOptions) { + this.pieChartOptions = pieChartOptions; + } + public TimeSeriesChartOptions getTimeSeriesChartOptions() { + return timeSeriesChartOptions; + } + public void setTimeSeriesChartOptions(TimeSeriesChartOptions timeSeriesChartOptions) { + this.timeSeriesChartOptions = timeSeriesChartOptions; + } + public FlexTimeSeriesChartOptions getFlexTimeSeriesChartOptions() { + return flexTimeSeriesChartOptions; + } + public void setFlexTimeSeriesChartOptions(FlexTimeSeriesChartOptions flexTimeSeriesChartOptions) { + this.flexTimeSeriesChartOptions = flexTimeSeriesChartOptions; + } + public CommonChartOptions getCommonChartOptions() { + return commonChartOptions; + } + public void setCommonChartOptions(CommonChartOptions commonChartOptions) { + this.commonChartOptions = commonChartOptions; + } + + public String getDomainAxis() { + if(getDomainAxisJSON() !=null) + return getDomainAxisJSON().getValue(); + else + return ""; + } + + public String getCategoryAxis() { + if(getCategoryAxisJSON()!=null) + return getCategoryAxisJSON().getValue(); + else + return ""; + } + +} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSONHelper.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSONHelper.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSONHelper.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSONHelper.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartWebRuntime.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartWebRuntime.java new file mode 100644 index 00000000..b035187d --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartWebRuntime.java @@ -0,0 +1,423 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.runtime; + + + + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.model.ReportHandler; +import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; +import org.openecomp.portalsdk.analytics.system.AppUtils; +import org.openecomp.portalsdk.analytics.util.AppConstants; +import org.openecomp.portalsdk.analytics.view.ReportData; +import org.openecomp.portalsdk.core.web.support.UserUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + + +public class ChartWebRuntime implements Serializable { + + + // Not used - planned to use if Hibernate used as data access layer + private String runningDataQuery = ""; + private String runningCountQuery = ""; + //CONSTANTS FOR QUERY + public final String QRY_COUNT_REPORT = ""; + public final String QRY_DATA_REPORT = ""; + + // Not used planning to use when filter is used + private StringBuffer whereClause = new StringBuffer(""); + // request used to grab request parameters + private HttpServletRequest request; + + + public ReportRuntime reportRuntime; + public ReportData reportData; + + //Used to pass user information + private final Map params = new HashMap(); + + //from chart generator retrieves list of charts to render + public ArrayList chartList; + public ArrayList infoList; + + private String totalSql; + + + // + private String drilldown_index = "0"; + + public List getRolesCommaSeperated(HttpServletRequest request) { + HashMap roles = UserUtils.getRoles(request); + List roleList = null; + StringBuffer roleBuf = new StringBuffer(""); + int count = 0; + if( roles != null ) { + roleList = Arrays.asList(roles.keySet().toArray()); + } + + return roleList; + } + + + public String getUserId(HttpServletRequest request) { + return AppUtils.getUserID(request); + } + + public String generateChart(HttpServletRequest request) { + return generateChart(request, true); + } + + + public String generateChart(HttpServletRequest request, boolean showData) { + //wire variables + //processRecursive(this, this); + long currentTime = System.currentTimeMillis(); + HttpSession session = request.getSession(); + String action = nvl(request.getParameter(AppConstants.RI_ACTION), request.getParameter("action")); + boolean genReportData = (!action.equals("chart.json") || action.equals("chart.data.json")); + + + + final Long user_id = new Long((long) UserUtils.getUserId(request)); + + + boolean adminUser = false; + try { + adminUser = AppUtils.isAdminUser(request) || AppUtils.isSuperUser(request); + } catch (RaptorException ex) { + ex.printStackTrace(); + } + List roleList = getRolesCommaSeperated(request); + //final Map params = new HashMap(); + params.put("user_id", user_id); + params.put("role_list", roleList); + //params.put("public_yn", "Y"); + + //String action = request.getParameter(AppConstants.RI_ACTION); + String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); + + ReportHandler rh = new ReportHandler(); + ReportRuntime rr = null; + try { + if(reportID !=null) + rr = rh.loadReportRuntime(request, reportID, true, 1); + if(rr.getReportType().equals(AppConstants.RT_HIVE)) { + String sql = rr.getReportSQL(); + rr.setWholeSQL(sql); + //if(genReportData) + //reportData = rr.loadHiveLinearReportData(rr.getWholeSQL(),user_id.toString(), 10000,request); + } else { + if(genReportData) + reportData = rr.loadReportData(0, user_id.toString(), 10000,request, false /*download*/); + } + } catch (RaptorException ex) { + ex.printStackTrace(); + } + setReportRuntime(rr); + setReportData( reportData); + + reportRuntime = getReportRuntime(); + reportData = getReportData(); + + + HashMap chartOptionsMap = new HashMap(); + + String rotateLabelsStr = ""; + rotateLabelsStr = AppUtils.nvl(reportRuntime.getLegendLabelAngle()); + if(rotateLabelsStr.toLowerCase().equals("standard")) { + rotateLabelsStr = "0"; + } else if (rotateLabelsStr.toLowerCase().equals("up45")) { + rotateLabelsStr = "45"; + } else if (rotateLabelsStr.toLowerCase().equals("down45")) { + rotateLabelsStr = "-45"; + } else if (rotateLabelsStr.toLowerCase().equals("up90")) { + rotateLabelsStr = "90"; + } else if (rotateLabelsStr.toLowerCase().equals("down90")) { + rotateLabelsStr = "-90"; + } else + rotateLabelsStr = "0"; + + String width = (AppUtils.getRequestNvlValue(request, "width").length()>0?AppUtils.getRequestNvlValue(request, "width"):(AppUtils.nvl(reportRuntime.getChartWidth()).length()>0?reportRuntime.getChartWidth():"700")); + String height = (AppUtils.getRequestNvlValue(request, "height").length()>0?AppUtils.getRequestNvlValue(request, "height"):(AppUtils.nvl(reportRuntime.getChartHeight()).length()>0?reportRuntime.getChartHeight():"300")); + String animationStr = (AppUtils.getRequestNvlValue(request, "animation").length()>0?AppUtils.getRequestNvlValue(request, "animation"):new Boolean(reportRuntime.isAnimateAnimatedChart()).toString()); + + String rotateLabels = (AppUtils.getRequestNvlValue(request, "rotateLabels").length()>0?AppUtils.getRequestNvlValue(request, "rotateLabels"):(rotateLabelsStr.length()>0?rotateLabelsStr:"0")); + String staggerLabelsStr = (AppUtils.getRequestNvlValue(request, "staggerLabels").length()>0?AppUtils.getRequestNvlValue(request, "staggerLabels"):"false"); + String showMaxMinStr = (AppUtils.getRequestNvlValue(request, "showMaxMin").length()>0?AppUtils.getRequestNvlValue(request, "showMaxMin"):"false"); + String showControlsStr = (AppUtils.getRequestNvlValue(request, "showControls").length()>0?AppUtils.getRequestNvlValue(request, "showControls"):new Boolean(reportRuntime.displayBarControls()).toString()); + String showLegendStr = (AppUtils.getRequestNvlValue(request, "showLegend").length()>0?AppUtils.getRequestNvlValue(request, "showLegend"):new Boolean(!new Boolean(reportRuntime.hideChartLegend())).toString()); + String topMarginStr = AppUtils.getRequestNvlValue(request, "topMargin"); + String topMargin = (AppUtils.nvl(topMarginStr).length()<=0)?(reportRuntime.getTopMargin()!=null?reportRuntime.getTopMargin().toString():"30"):topMarginStr; + String bottomMarginStr = AppUtils.getRequestNvlValue(request, "bottomMargin"); + String bottomMargin = (AppUtils.nvl(bottomMarginStr).length()<=0)?(reportRuntime.getBottomMargin()!=null?reportRuntime.getBottomMargin().toString():"50"):bottomMarginStr; + String leftMarginStr = AppUtils.getRequestNvlValue(request, "leftMargin"); + String leftMargin = (AppUtils.nvl(leftMarginStr).length()<=0)?(reportRuntime.getLeftMargin()!=null?reportRuntime.getLeftMargin().toString():"100"):leftMarginStr; + String rightMarginStr = AppUtils.getRequestNvlValue(request, "rightMargin"); + String rightMargin = (AppUtils.nvl(rightMarginStr).length()<=0)?(reportRuntime.getRightMargin()!=null?reportRuntime.getRightMargin().toString():"160"):rightMarginStr; + String showTitleStr = (AppUtils.getRequestNvlValue(request, "showTitle").length()>0?AppUtils.getRequestNvlValue(request, "showTitle"):new Boolean(reportRuntime.displayChartTitle()).toString()); + String subType = AppUtils.getRequestNvlValue(request, "subType").length()>0?AppUtils.getRequestNvlValue(request, "subType"):(AppUtils.nvl(reportRuntime.getTimeSeriesRender()).equals("area")?reportRuntime.getTimeSeriesRender():""); + String stackedStr = AppUtils.getRequestNvlValue(request, "stacked").length()>0?AppUtils.getRequestNvlValue(request, "stacked"):new Boolean(reportRuntime.isChartStacked()).toString(); + String horizontalBar = AppUtils.getRequestNvlValue(request, "horizontalBar").length()>0?AppUtils.getRequestNvlValue(request, "horizontalBar"):new Boolean(reportRuntime.isHorizontalOrientation()).toString(); + String barRealTimeAxis = AppUtils.getRequestNvlValue(request, "barRealTimeAxis"); + String barReduceXAxisLabels = AppUtils.getRequestNvlValue(request, "barReduceXAxisLabels").length()>0?AppUtils.getRequestNvlValue(request, "barReduceXAxisLabels"):new Boolean(reportRuntime.isLessXaxisTickers()).toString();; + String timeAxis = AppUtils.getRequestNvlValue(request, "timeAxis").length()>0?AppUtils.getRequestNvlValue(request, "timeAxis"):new Boolean(reportRuntime.isTimeAxis()).toString(); + String logScale = AppUtils.getRequestNvlValue(request, "logScale").length()>0?AppUtils.getRequestNvlValue(request, "logScale"):new Boolean(reportRuntime.isLogScale()).toString(); + String precision = AppUtils.getRequestNvlValue(request, "precision").length()>0?AppUtils.getRequestNvlValue(request, "precision"):"2"; + + /* boolean animation = AppUtils.getRequestFlag(request, "animation"); + boolean staggerLabels = AppUtils.getRequestFlag(request, "staggerLabels"); + boolean showMaxMin = (showMaxMinStr.length()<=0)?false:Boolean.parseBoolean(showMaxMinStr); + boolean showControls = (showControlsStr.length()<=0)?true:Boolean.parseBoolean(showControlsStr); + boolean showLegend = (showLegendStr.length()<=0)?true:Boolean.parseBoolean(showLegendStr); + boolean showTitle = (showTitleStr.length()<=0)?true:Boolean.parseBoolean(showTitleStr); + boolean stacked = (stackedStr.length()<=0)?true:Boolean.parseBoolean(stackedStr); + */ + // Add all options to Map + chartOptionsMap.put("width", width); + chartOptionsMap.put("height", height); + chartOptionsMap.put("animation", animationStr); + chartOptionsMap.put("rotateLabels", rotateLabels); + chartOptionsMap.put("staggerLabels", staggerLabelsStr); + chartOptionsMap.put("showMaxMin", showMaxMinStr); + chartOptionsMap.put("showControls", showControlsStr); + chartOptionsMap.put("showLegend", showLegendStr); + chartOptionsMap.put("topMargin", topMargin); + chartOptionsMap.put("bottomMargin", bottomMargin); + chartOptionsMap.put("leftMargin", leftMargin); + chartOptionsMap.put("rightMargin", rightMargin); + chartOptionsMap.put("showTitle", showTitleStr); + chartOptionsMap.put("subType", subType); + chartOptionsMap.put("stacked", stackedStr); + chartOptionsMap.put("horizontalBar", horizontalBar); + chartOptionsMap.put("timeAxis", timeAxis); + chartOptionsMap.put("barRealTimeAxis", barRealTimeAxis); + chartOptionsMap.put("barReduceXAxisLabels", barReduceXAxisLabels); + + chartOptionsMap.put("logScale", logScale); + chartOptionsMap.put("precision", precision); + + + + if(reportRuntime!=null) { + StringBuffer title = new StringBuffer(""); + title.append(reportRuntime.getReportName()); + } + + if(! (action.equals("chart.json") || action.equals("chart.data.json"))) { + + + //Chart + String chartType = reportRuntime.getChartType(); + return drawD3Charts(chartOptionsMap, request); + //drawD3Charts(); + } else /*if (action.equals("chart.json"))*/ { + String chartType = reportRuntime.getChartType(); + return returnChartJSON(chartOptionsMap, request, showData); + + + } /*else { + + return ("Internal Error Occurred."); + }*/ + + } + + + public String nvl(String s) { + return (s == null) ? "" : s; + } + + /** + * @return the reportRuntime + */ + public ReportRuntime getReportRuntime() { + return reportRuntime; + } + + /** + * @param reportRuntime the reportRuntime to set + */ + public void setReportRuntime(ReportRuntime reportRuntime) { + this.reportRuntime = reportRuntime; + } + + /** + * @return the reportData + */ + public ReportData getReportData() { + return reportData; + } + + /** + * @param reportData the reportData to set + */ + public void setReportData(ReportData reportData) { + this.reportData = reportData; + } + + public boolean isNull(String a) { + if ((a == null) || (a.length() == 0) || a.equalsIgnoreCase("null")) + return true; + else + return false; + } + + + protected String nvl(String s, String sDefault) { + return nvl(s).equals("") ? sDefault : s; + } + + protected static String nvls(String s) { + return (s == null) ? "" : s; + } + + protected static String nvls(String s, String sDefault) { + return nvls(s).equals("") ? sDefault : s; + } + + protected boolean getFlagInBoolean(String s) { + return nvl(s).toUpperCase().startsWith("Y") || nvl(s).toLowerCase().equals("true"); + } + + + /** + * @return the chartList + */ + public ArrayList getChartList() { + return chartList; + } + + /** + * @param chartList the chartList to set + */ + public void setChartList(ArrayList chartList) { + this.chartList = chartList; + } + + /** + * @return the infoList + */ + public ArrayList getInfoList() { + return infoList; + } + + /** + * @param infoList the infoList to set + */ + public void setInfoList(ArrayList infoList) { + this.infoList = infoList; + } + + + + private void clearReportRuntimeBackup(HttpSession session, HttpServletRequest request) { + session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); + request.removeAttribute(AppConstants.DRILLDOWN_INDEX); + session.removeAttribute(AppConstants.DRILLDOWN_INDEX); + request.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); + session.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); + Enumeration enum1 = session.getAttributeNames(); + String attributeName = ""; + while(enum1.hasMoreElements()) { + attributeName = enum1.nextElement(); + if(attributeName.startsWith("parent_")) { + session.removeAttribute(attributeName); + } + } + session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); + session.removeAttribute(AppConstants.SI_BACKUP_FOR_REP_ID); + session.removeAttribute(AppConstants.SI_COLUMN_LOOKUP); + session.removeAttribute(AppConstants.SI_DASHBOARD_REP_ID); + session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); + session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME); + session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); + session.removeAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP); + session.removeAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); + session.removeAttribute(AppConstants.SI_DATA_SIZE_FOR_TEXTFIELD_POPUP); + session.removeAttribute(AppConstants.SI_MAP); + session.removeAttribute(AppConstants.SI_MAP_OBJECT); + session.removeAttribute(AppConstants.SI_REPORT_DEFINITION); + session.removeAttribute(AppConstants.SI_REPORT_RUNTIME); + session.removeAttribute(AppConstants.SI_REPORT_RUN_BACKUP); + session.removeAttribute(AppConstants.SI_REPORT_SCHEDULE); + session.removeAttribute(AppConstants.RI_REPORT_DATA); + session.removeAttribute(AppConstants.RI_CHART_DATA); + session.removeAttribute(AppConstants.SI_FORMFIELD_INFO); + session.removeAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); + } // clearReportRuntimeBackup + + + public String getTotalSql() { + return totalSql; + } + + public void setTotalSql(String totalSql) { + this.totalSql = totalSql; + } + + + + /* public void drawD3Charts(HashMap chartOptionsMap) { + drawD3Charts(chartOptionsMap); + + } + */ + + public String drawD3Charts(HashMap chartOptionsMap, HttpServletRequest request) { + + ChartD3Helper chartHelper = new ChartD3Helper(reportRuntime); + chartHelper.setChartType(reportRuntime.getChartType()); + try { + return chartHelper.createVisualization(reportRuntime, chartOptionsMap, request); + } catch(RaptorException ex) { + ex.printStackTrace(); + } + return ""; + + } + + public String returnChartJSON(HashMap chartOptionsMap, HttpServletRequest request, boolean showData) { + + ChartJSONHelper chartJSONHelper = new ChartJSONHelper(reportRuntime); + chartJSONHelper.setChartType(reportRuntime.getChartType()); + try { + return chartJSONHelper.generateJSON(reportRuntime, chartOptionsMap, request, showData); + } catch(RaptorException ex) { + ex.printStackTrace(); + } + return ""; + + } + + } + diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CommonChartOptions.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CommonChartOptions.java new file mode 100644 index 00000000..e3e9fc67 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CommonChartOptions.java @@ -0,0 +1,81 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.runtime; + +public class CommonChartOptions { + + private String legendPosition = "top"; + private String legendLabelAngle = "up45"; + private boolean hideLegend = false; + private boolean animateAnimatedChart = true; + private int topMargin = 30; + private int bottomMargin = 50; + private int leftMargin = 100; + private int rightMargin = 60; + + public String getLegendPosition() { + return legendPosition; + } + public void setLegendPosition(String legendPosition) { + this.legendPosition = legendPosition; + } + public String getLegendLabelAngle() { + return legendLabelAngle; + } + public void setLegendLabelAngle(String legendLabelAngle) { + this.legendLabelAngle = legendLabelAngle; + } + public boolean isHideLegend() { + return hideLegend; + } + public void setHideLegend(boolean hideLegend) { + this.hideLegend = hideLegend; + } + public boolean isAnimateAnimatedChart() { + return animateAnimatedChart; + } + public void setAnimateAnimatedChart(boolean animateAnimatedChart) { + this.animateAnimatedChart = animateAnimatedChart; + } + public int getTopMargin() { + return topMargin; + } + public void setTopMargin(int topMargin) { + this.topMargin = topMargin; + } + public int getBottomMargin() { + return bottomMargin; + } + public void setBottomMargin(int bottomMargin) { + this.bottomMargin = bottomMargin; + } + public int getLeftMargin() { + return leftMargin; + } + public void setLeftMargin(int leftMargin) { + this.leftMargin = leftMargin; + } + public int getRightMargin() { + return rightMargin; + } + public void setRightMargin(int rightMargin) { + this.rightMargin = rightMargin; + } +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ErrorJSONRuntime.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ErrorJSONRuntime.java new file mode 100644 index 00000000..04068ef2 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ErrorJSONRuntime.java @@ -0,0 +1,58 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.analytics.model.runtime; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; + +import org.json.JSONObject; +import org.openecomp.portalsdk.analytics.model.base.IdNameValue; +import org.openecomp.portalsdk.analytics.view.ColumnHeader; +import org.openecomp.portalsdk.analytics.view.DataValue; +import org.openecomp.portalsdk.analytics.xmlobj.ColFilterList; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnList; +import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; + +public class ErrorJSONRuntime { + + private String errormessage; + private String stacktrace; + + public String getErrormessage() { + return errormessage; + } + public void setErrormessage(String errormessage) { + this.errormessage = errormessage; + } + public String getStacktrace() { + return stacktrace; + } + public void setStacktrace(String stacktrace) { + this.stacktrace = stacktrace; + } + + + + +} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FlexTimeSeriesChartOptions.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FlexTimeSeriesChartOptions.java similarity index 100% rename from ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FlexTimeSeriesChartOptions.java rename to ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FlexTimeSeriesChartOptions.java diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormField.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormField.java new file mode 100644 index 00000000..6d9730a5 --- /dev/null +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormField.java @@ -0,0 +1,2103 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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. + * ================================================================================ + */ +/* =========================================================================================== + * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) + * Raptor : This tool is used to generate different kinds of reports with lot of utilities + * =========================================================================================== + * + * ------------------------------------------------------------------------------------------- + * FormField.java - This class is used to generate all types of form field. + * ------------------------------------------------------------------------------------------- + * + * Created By : Stan Pishamanov + * Modified & Maintained By : Sundar Ramalingam + * + * Changes + * ------- + * 18-Aug-2009 : Version 8.5 (Sundar); Populating predefined formfields bug has been resolved. + * 13-Aug-2009 : Version 8.5 (RS); Form field chaining is supported even for hidden variables. + * 13-Aug-2009 : Version 8.5 (RS); Nothing changed just comment. + * 10-Aug-2009 : Version 9.0 (RS); required logic is added for Multiple Dropdown. + * 06-Aug-2009 : Version 9.0 (RS); B getAjaxHtml is added for converting form field chain from Iframe to AJAX. + * 08-Jun-2009 : Version 8.3 (RS); Hidden formfields now is displayed even when the sql is not provided. + * + */ +package org.openecomp.portalsdk.analytics.model.runtime; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.swing.text.html.HTMLDocument.HTMLReader.HiddenAction; + +import org.openecomp.portalsdk.analytics.error.RaptorException; +import org.openecomp.portalsdk.analytics.error.RaptorRuntimeException; +import org.openecomp.portalsdk.analytics.error.UserDefinedException; +import org.openecomp.portalsdk.analytics.model.base.*; +import org.openecomp.portalsdk.analytics.system.*; +import org.openecomp.portalsdk.analytics.util.*; +import org.openecomp.portalsdk.analytics.xmlobj.*; + +public class FormField extends org.openecomp.portalsdk.analytics.RaptorObject implements Serializable { + private static final String HTML_FORM = "formd"; + + private String fieldName = null; + + private String fieldDisplayName = null; + + private String fieldType = FFT_TEXT_W_POPUP; + + private String validationType = VT_NONE; + + private boolean required = false; + + public boolean hasPredefinedList = false; + + private String defaultValue = null; + + private Calendar rangeStartDate = null; + + private Calendar rangeEndDate = null; + + private String rangeStartDateSQL = null; + + private String rangeEndDateSQL = null; + + private String fieldDefaultSQL = null; + + private String multiSelectListSize = null; + + private String helpText = null; + + private IdNameList lookupList = null; + + private String dbInfo = null; + + private String userId = null; + + private boolean visible = true; + + private String dependsOn = null; + + private boolean triggerOtherFormFields = false; + + private boolean triggerThisFormfield = false; + + // Form field types + public static final String FFT_TEXT_W_POPUP = "TEXT_WITH_POPUP"; + + public static final String FFT_TEXT = "TEXT"; + + public static final String FFT_TEXTAREA = "TEXTAREA"; + + public static final String FFT_COMBO_BOX = "COMBO_BOX"; + + public static final String FFT_LIST_BOX = "LIST_BOX"; + + public static final String FFT_RADIO_BTN = "RADIO_BTN"; + + public static final String FFT_CHECK_BOX = "CHECK_BOX"; + + public static final String FFT_LIST_MULTI = "LIST_MULTI_SELECT"; + + public static final String FFT_HIDDEN = "HIDDEN"; + + public static final String FFT_BLANK = "BLANK"; + + // Validation types + public static final String VT_NONE = "NONE"; + + public static final String VT_DATE = "DATE"; + + public static final String VT_TIMESTAMP_HR = "TIMESTAMP_HR"; + + public static final String VT_TIMESTAMP_MIN = "TIMESTAMP_MIN"; + + public static final String VT_TIMESTAMP_SEC = "TIMESTAMP_SEC"; + + public static final String VT_INT = "INTEGER"; + + public static final String VT_INT_POSITIVE = "POSITIVE_INTEGER"; + + public static final String VT_INT_NON_NEGATIVE = "NON_NEGATIVE_INTEGER"; + + public static final String VT_FLOAT = "FLOAT"; + + public static final String VT_FLOAT_POSITIVE = "POSITIVE_FLOAT"; + + public static final String VT_FLOAT_NON_NEGATIVE = "NON_NEGATIVE_FLOAT"; + + private FormField(String fieldName, String fieldDisplayName, String fieldType, + String validationType, boolean required, String defaultValue, String helpText, boolean visible, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, + String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize ) { + //super(); + this (fieldName,fieldDisplayName,fieldType,validationType,required,defaultValue,helpText, dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); + setVisible(visible); + } // FormField + + private FormField(String fieldName, String fieldDisplayName, String fieldType, + String validationType, boolean required, String defaultValue, String helpText, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, + String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize ) { + super(); + setFieldName(fieldName); + setFieldDisplayName(fieldDisplayName); + setFieldType(nvl(fieldType, FFT_TEXT)); + setValidationType(validationType); + setRequired(required); + setDefaultValue(defaultValue); + setHelpText(helpText); + setDependsOn(dependsOn); + setRangeStartDate(rangeStartDate); + setRangeEndDate(rangeEndDate); + setRangeStartDateSQL(rangeStartDateSQL); + setRangeEndDateSQL(rangeEndDateSQL); + setMultiSelectListSize(multiSelectListSize); + } + public FormField(String fieldName, String fieldDisplayName, String fieldType, + String validationType, boolean required, String defaultValue, String helpText, + List predefinedValues, boolean visible, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, + String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize) { + this(fieldName, fieldDisplayName, fieldType, validationType, required, defaultValue, + helpText,visible, dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); + if (predefinedValues != null) + setPredefinedListLookup(predefinedValues); + } // FormField + + public FormField(String fieldName, String fieldDisplayName, String fieldType, + String validationType, boolean required, String defaultValue, String helpText, + String lookupSql, boolean visible, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, + String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize ) { + this(fieldName, fieldDisplayName, fieldType, validationType, required, defaultValue, + helpText,visible, dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); + if (defaultValue!=null && defaultValue.length()>10 && defaultValue.substring(0,10).trim().toLowerCase().startsWith("select")) { + setFieldDefaultSQL(defaultValue); + setDefaultValue(""); + } + setLookupList(new IdNameSql(lookupSql,defaultValue)); + } // FormField + + public FormField(String fieldName, String fieldDisplayName, String fieldType, + String validationType, boolean required, String defaultValue, String helpText, + String dbTableName, String dbIdField, String dbNameField, String dbSortByField, boolean visible, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, + String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize) { + this(fieldName, fieldDisplayName, fieldType, validationType, required, defaultValue, + helpText,dbTableName,dbIdField,dbNameField,dbSortByField, dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); + setVisible(visible); + } + + public FormField(String fieldName, String fieldDisplayName, String fieldType, + String validationType, boolean required, String defaultValue, String helpText, + String dbTableName, String dbIdField, String dbNameField, String dbSortByField, String dependsOn, + Calendar rangeStartDate, Calendar rangeEndDate, + String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize ) { + this(fieldName, fieldDisplayName, fieldType, validationType, required, defaultValue, + helpText,dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); + //if(dependsOn !=null){ this.dependsOn = dependsOn; }else { this.dependsOn = "" + if (defaultValue!=null && defaultValue.length()>10 && defaultValue.substring(0,10).trim().toLowerCase().startsWith("select")) { + setFieldDefaultSQL(defaultValue); + setDefaultValue(""); + if(fieldType.equals(FFT_TEXT)) + setLookupList(new IdNameLookup(dbTableName, dbIdField, dbNameField, dbSortByField,defaultValue,true)); + else + setLookupList(new IdNameLookup(dbTableName, dbIdField, dbNameField, dbSortByField,defaultValue,false)); + } + else { + if(fieldType.equals(FFT_TEXT)) + setLookupList(new IdNameLookup(dbTableName, dbIdField, dbNameField, dbSortByField, true)); + else + setLookupList(new IdNameLookup(dbTableName, dbIdField, dbNameField, dbSortByField, false)); + } + + this.setRangeStartDate(rangeStartDate); + this.setRangeEndDate(rangeEndDate); + this.setRangeStartDateSQL(rangeStartDateSQL); + this.setRangeEndDateSQL(rangeEndDateSQL); + + } // FormField + + + private void setPredefinedListLookup(List predefinedValues) { + IdNameList lookup = new IdNameList(); + for (Iterator iter = predefinedValues.iterator(); iter.hasNext();) { + String value = (String) iter.next(); + lookup.addValue(value, value); + } // for + setHasPredefinedList(true); + setLookupList(lookup); + } // setPredefinedListLookup + + public String getFieldName() { + return fieldName; + } + + public String getFieldDisplayName() { + return fieldDisplayName; + } + + public String getFieldType() { + return fieldType; + } + + public String getValidationType() { + return validationType; + } + + public boolean isRequired() { + return required; + } + + public String getDefaultValue() { + return defaultValue; + } + + public String getHelpText() { + return helpText; + } + + public IdNameList getLookupList() { + return lookupList; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public void setFieldDisplayName(String fieldDisplayName) { + this.fieldDisplayName = fieldDisplayName; + } + + public void setFieldType(String fieldType) { + this.fieldType = fieldType; + } + + public void setValidationType(String validationType) { + this.validationType = nvl(validationType, VT_NONE); + } + + public void setRequired(boolean required) { + this.required = required; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + public void setHelpText(String helpText) { + this.helpText = helpText; + } + + public void setLookupList(IdNameList lookupList) { + this.lookupList = lookupList; + } + + public void setDefaultList(IdNameList lookupList) { + this.lookupList = lookupList; + } + + public String getBaseSQL() { + return (lookupList == null) ? null : lookupList.getBaseSQL(); + } // getBaseSQL + + public String getBaseWholeSQL() { + return (lookupList == null) ? null : lookupList.getBaseWholeSQL(); + } // getBaseWholeSQL + + public String getBaseWholeReadonlySQL() { + return (lookupList == null) ? null : lookupList.getBaseWholeReadonlySQL(); + } // getBaseWholeReadonlySQL + + public String getBaseSQLForPDFExcel() { + return (lookupList == null) ? null : lookupList.getBaseSQLForPDFExcel(getFieldType().equals(FFT_LIST_MULTI)||getFieldType().equals(FFT_CHECK_BOX)?true:false); + } // getBaseSQLForPDFExcel + + public String getDisplayNameHtml() { + if (nvl(helpText).length() > 0) + return "" + fieldDisplayName + ""; + else + return fieldDisplayName; + } // getDisplayNameHtml + + /*public String getHtml() throws RaptorRuntimeException { + return getHtml("" , null, null, false); + } // getHtml*/ + + public String getHtml(String fieldValue, HashMap formValues, ReportRuntime rr)throws RaptorRuntimeException { + return getHtml(fieldValue,formValues, rr, false); + } + + public String getHelpLink(String fieldName) { + //return "\"\""; + return ((getHelpText()!=null && getHelpText().length()>0)? "tooltipText=\""+ getHelpText()+"\">": ">"); + //return ((getHelpText()!=null && getHelpText().length()>0)? "": ""); + } + + + public String getCallableAfterChainingJavascript(String fieldName, ReportRuntime rr) { + JavascriptItemType javascriptItemType = null; + StringBuffer callJavascriptText = new StringBuffer(""); + if(rr.getJavascriptList()!=null) { + for (Iterator iter = rr.getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { + javascriptItemType = (JavascriptItemType)iter.next(); + if(javascriptItemType.getFieldId().equals(fieldName)) { + if(nvl(javascriptItemType.getCallText()).toLowerCase().startsWith("afterchaining")) + callJavascriptText.append(" "+javascriptItemType.getCallText()); + } + } + } + return callJavascriptText.toString()+" "; + } + public String getCallableJavascript(String fieldName, ReportRuntime rr) { + JavascriptItemType javascriptItemType = null; + StringBuffer callJavascriptText = new StringBuffer(""); + if(rr.getJavascriptList()!=null) { + for (Iterator iter = rr.getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { + javascriptItemType = (JavascriptItemType)iter.next(); + if(javascriptItemType.getFieldId().equals(fieldName)) { + if(!nvl(javascriptItemType.getCallText()).toLowerCase().startsWith("afterchaining")) + callJavascriptText.append(" "+javascriptItemType.getCallText()); + } + } + } + return callJavascriptText.toString()+" "; + } + + public String getCallableOnChangeJavascript(String fieldName, ReportRuntime rr) { + String callText = getCallableJavascript(fieldName, rr); + if(callText != null && callText.trim().toLowerCase().indexOf("onchange")>=0) { + Pattern re1 = Pattern.compile("\\=(.*?)\\)"); + Matcher matcher = re1.matcher(callText); + while (matcher.find()) { + callText = matcher.group(); + if(callText!=null && callText.startsWith("=\"")) { + callText = callText.substring(2); + } else if (callText!=null) + callText = callText.substring(1); + } + callText = callText.replaceAll("this", "documentForm."+fieldName); + } else callText = null; + return callText; + } + + public String getAjaxHtml(String fieldValue, HashMap formValues, ReportRuntime rr, boolean inSchedule) throws RaptorRuntimeException { + fieldValue = nvl(fieldValue, defaultValue); + String readOnly = "ff_readonly"; + try { + if(fieldValue !=null && fieldValue.length() > 0) + fieldValue = java.net.URLDecoder.decode(fieldValue, "UTF-8"); + } catch (UnsupportedEncodingException ex) {} + catch (IllegalArgumentException ex1){} + catch (Exception ex2){} + if (fieldType.equals(FFT_COMBO_BOX)) { + StringBuffer sb = new StringBuffer(); + //System.out.println("COMBO BOX " + fieldName); + String oldSQL = ""; + if (!required) + sb.append("obj.options[obj.options.length] = new Option('-->select value<--','');"); + + IdNameList lookup = getLookupList(); + try { + if(!hasPredefinedList) { + //if(dependsOn != null && dependsOn != "") { + //if(dependsOn != null && dependsOn != "" ) { + IdNameSql lu = (IdNameSql) lookup; + String SQL = ""; + SQL = lu.getSql(); + /*if(nvl(fieldValue,"").length()<=0) + SQL = lu.getSql(); + else + SQL = lu.getBaseSQLForPDFExcel(false); + */ + //System.out.println("FORMFIELD 6666667 First" + ((IdNameSql)lookup).getSql()); + oldSQL = lu.getSql(); + //SQL = Utils.replaceInString(SQL, "[VALUE]", fieldValue); + if(formValues != null) { + Set set = formValues.entrySet(); + String value = ""; + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + value = (String) entry.getValue(); + if(inSchedule) { + try { + value = java.net.URLDecoder.decode(Utils.oracleSafe(value), "UTF-8"); + } catch (UnsupportedEncodingException ex) { + + } + } + if (value!=null && (value.length() <=0 || value.equals("NULL"))) { + value = "NULL"; + SQL = Utils.replaceInString(SQL, "'["+entry.getKey()+"]'", value); + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); + } else { + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); + } + } + lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); + } + //} + lookupList = lookup; + + //} + try { + lookup.loadUserData(0, "", getDbInfo(), getUserId()); + } catch (Exception e ){ e.printStackTrace(); //throw new RaptorRuntimeException(e); + } + } + lookup.trimToSize(); + + String selectedValue = ""; + int count = 0; + for (lookup.resetNext(); lookup.hasNext();) { + IdNameValue value = lookup.getNext(); + if(value != null && value.getId() != null && value.getName() != null ) { + /*if (count == 0 && required) { + selectedValue = value.getId(); + count++; + } else if (nvl(fieldValue).length()>0){ + if (fieldValue != null && fieldValue.equals(value.getId())){ + selectedValue = value.getId(); + } + count++; + } else { + count++; + } */ + if (count == 0) { + if(required){ + selectedValue = value.getId(); + } + count++; + } + sb.append("obj.options[obj.options.length] = new Option('" + Utils.singleQuoteEncode(value.getName())+"','"+Utils.singleQuoteEncode(value.getId())+"');"); + if ((fieldValue != null && fieldValue.equals(value.getId()))){ + sb.append("obj.options[obj.options.length-1].selected=true;"); + selectedValue = value.getId(); + } + if(value.isReadOnly()) + sb.append("obj.disabled=true;"); + else + sb.append("obj.disabled=false;"); + + } + } // for + if (formValues.containsKey(fieldDisplayName)){ + formValues.remove(fieldDisplayName); + } + formValues.put(fieldDisplayName, selectedValue); + } catch (Exception e) { + //throw new RaptorRuntimeException(e); + } + if(!hasPredefinedList) { + if(oldSQL != null && !oldSQL.equals("")) { + ((IdNameSql)lookup).setSQL(oldSQL); + } + } + //System.out.println("FORMFIELD 6666667 " + ((IdNameSql)lookup).getSql()); + if( isVisible()) + return sb.toString(); + else return ""; + } else if (fieldType.equals(FFT_LIST_MULTI)) { + StringBuffer sb = new StringBuffer(); + String oldSQL = ""; + + fieldValue = '|' + fieldValue + '|'; + IdNameList lookup = getLookupList(); + try { + if(!hasPredefinedList) { + //if(dependsOn != null && dependsOn != "") { + //if(dependsOn != null && dependsOn != "" ) { + IdNameSql lu = (IdNameSql) lookup; + String SQL = ""; + SQL = lu.getSql(); + /*if(nvl(fieldValue,"").length()<=0) + SQL = lu.getSql(); + else + SQL = lu.getBaseSQLForPDFExcel(false); + SQL = Utils.replaceInString(SQL, "[VALUE]", fieldValue); + */ + oldSQL = lu.getSql(); + if(formValues != null) { + Set set = formValues.entrySet(); + String value = ""; + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + value = (String) entry.getValue(); + if(inSchedule) { //('1347') + try { + value = java.net.URLDecoder.decode(value, "UTF-8"); + } catch (UnsupportedEncodingException ex) { + + } + } + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); + } + lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); + } + //} + lookupList = lookup; + //} + + lookup.loadUserData(0, "", getDbInfo(),getUserId()); + } + + for (lookup.resetNext(); lookup.hasNext();) { + IdNameValue value = lookup.getNext(); + sb.append("obj.options[obj.options.length] = new Option('" + Utils.singleQuoteEncode(value.getName()) +"','"+Utils.singleQuoteEncode(value.getId())+"');"); + if (fieldValue.indexOf('|' + value.getId() + '|') >= 0) + sb.append("obj.options[obj.options.length-1].selected=true;"); + if(value.isReadOnly()) + sb.append("obj.disabled=true;"); + else + sb.append("obj.disabled=false;"); + + } // for + + // lookup.clearData(); + } catch (Exception e) { + //throw new RaptorRuntimeException(e); + } + if(!hasPredefinedList) { + if(oldSQL != null && !oldSQL.equals("")) { + ((IdNameSql)lookup).setSQL(oldSQL); + } + } + if(isVisible()) + return sb.toString(); + else + return ""; + } else if (fieldType.equals(FFT_TEXT_W_POPUP)) { + //System.out.println("TEXT POPUP " + fieldName); + String oldSQL = ""; + IdNameValue idNamevalue = null; + String fieldDefValue=""; + String fieldDefDisplay=""; + try { + IdNameList lookup = getLookupList(); + if(dependsOn != null && dependsOn != "" ) { + IdNameSql lu = (IdNameSql) lookup; + String SQL = getBaseWholeSQL(); + if(SQL.toLowerCase().indexOf(readOnly) != -1) { + SQL = getBaseWholeReadonlySQL(); + } + oldSQL = lu.getSql(); + if(formValues != null) { + Set set = formValues.entrySet(); + String value = ""; + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + value = (String) entry.getValue(); + if(inSchedule) { + try { + value = java.net.URLDecoder.decode(Utils.oracleSafe(value), "UTF-8"); + } catch (UnsupportedEncodingException ex) { + + } + } + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); +// if(SQL.indexOf("'"+"["+entry.getKey()+"]"+"'")!=-1) { + if(SQL.indexOf("'"+"["+entry.getKey()+"]"+"'")!=-1 || SQL.indexOf("'"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"'")!=-1 + || SQL.indexOf("'%"+"["+entry.getKey()+"]"+"%'")!=-1 || SQL.indexOf("'%"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"%'")!=-1 + || SQL.indexOf("'_"+"["+entry.getKey()+"]"+"_'")!=-1 || SQL.indexOf("'_"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"_'")!=-1 + || SQL.indexOf("'%_"+"["+entry.getKey()+"]"+"_%'")!=-1 || SQL.indexOf("'%_"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"_%'")!=-1) { + + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", nvl( + value, "NULL")); + } else { + // Added to prevent SQL Injection + if(SQL.indexOf("["+entry.getKey()+"]")!=-1) { + try { + double vD = Double.parseDouble(value); + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", nvl( + value, "NULL")); + } catch (NumberFormatException ex) { + throw new UserDefinedException("Expected number, Given String for the form field \"" + "["+entry.getKey()+"]"+"\""); + } + } + } + } + if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.trim().length()<=0)) + lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); + else + lookup = new IdNameSql(-1,SQL,null); + } + } + //lookupList = lookup; + + if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.trim().length()<=0)) { + lookup.loadUserData(0, "", getDbInfo(), getUserId()); + for (lookup.resetNext(); lookup.hasNext();) { + idNamevalue = lookup.getNext(); + break; + + } + fieldDefValue = nvl(idNamevalue.getId()); + fieldDefDisplay = nvl(idNamevalue.getName()); + } else { + try { + // -2 indicates to run the whole sql for matching value + lookup.loadUserData(-2, "", getDbInfo(), getUserId()); + lookup.trimToSize(); + for (lookup.resetNext(); lookup.hasNext();) { + IdNameValue value = lookup.getNext(); + if(value != null && value.getId() != null && value.getName() != null ) { + fieldDefValue = nvl(value.getId()); + if (fieldValue != null && fieldValue.equals(value.getId())) { + fieldDefDisplay = nvl(value.getName()); + break; + } + else { + fieldDefValue = ""; + fieldDefDisplay = ""; + } + } + } + if (fieldDefDisplay == null || fieldDefDisplay.length()<=0) { + fieldDefDisplay = nvl(fieldDefValue); + } + + if(oldSQL != null && !oldSQL.equals("")) { + ((IdNameSql)lookup).setSQL(oldSQL); + } + + } catch (Exception e) { + //throw new RaptorRuntimeException(e); + } + + + //----- END ---// + + + if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.length()<=0)) { + fieldDefValue = nvl((idNamevalue!=null)?idNamevalue.getId():""); + fieldDefDisplay = nvl((idNamevalue!=null)?idNamevalue.getName():""); + } else { + if(fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.length()<=0) fieldValue=""; + fieldDefValue = nvl(fieldDefValue); + fieldDefDisplay = nvl(fieldDefDisplay); + } + + } + }catch(Exception e) { //throw new RaptorRuntimeException(e); + } + if(isVisible()) { + /* return "\n" + "0 && (dependsOn == null || dependsOn.length()<=0)) { + sb.append((fieldValue!=null)?"obj.value=\""+nvl(fieldValue)+"\";":""); + } else if (lookup != null) { + lookup.loadUserData(0, "", getDbInfo(), getUserId()); + int iCnt = 0; + for (lookup.resetNext(); lookup.hasNext(); iCnt++) { + IdNameValue value = lookup.getNext(); + //System.out.println("HIDDEN " + value.getId() + " " + value.getName()); + sb.append((value!=null)?"obj.value=\""+nvl(value.getId())+"\";":""); + if(value.isReadOnly()) + sb.append("obj.disabled=true;"); + else + sb.append("obj.disabled=false;"); + break; + } // for + if(lookup.size()<=0) { + sb.append("obj.value=\"\""); + + } + } else { + sb.append((fieldValue!=null)?"obj.value=\""+Utils.singleQuoteEncode(nvl(fieldValue))+"\";":""); + } + if(oldSQL != null && !oldSQL.equals("")) { + ((IdNameSql)lookup).setSQL(oldSQL); + } + // lookup.clearData(); + } catch (Exception e) { + //throw new RaptorRuntimeException(e); + } + //if(isVisible()) + return sb.toString() ; + } else if (fieldType.equals(FFT_LIST_BOX)) { + StringBuffer sb = new StringBuffer(); + //System.out.println("COMBO BOX " + fieldName); + String oldSQL = ""; + if (!required) + sb.append("obj.options[obj.options.length] = new Option('-->select value<--','');"); + + IdNameList lookup = getLookupList(); + try { + if(!hasPredefinedList) { + //if(dependsOn != null && dependsOn != "") { + //if(dependsOn != null && dependsOn != "" ) { + IdNameSql lu = (IdNameSql) lookup; + String SQL = ""; + SQL = lu.getSql(); + /*if(nvl(fieldValue,"").length()<=0) + SQL = lu.getSql(); + else + SQL = lu.getBaseSQLForPDFExcel(false); + */ + //System.out.println("FORMFIELD 6666667 First" + ((IdNameSql)lookup).getSql()); + oldSQL = lu.getSql(); + //SQL = Utils.replaceInString(SQL, "[VALUE]", fieldValue); + if(formValues != null) { + Set set = formValues.entrySet(); + String value = ""; + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + value = (String) entry.getValue(); + if(inSchedule) { + try { + value = java.net.URLDecoder.decode(Utils.oracleSafe(value), "UTF-8"); + } catch (UnsupportedEncodingException ex) { + + } + } + if (value!=null && (value.length() <=0 || value.equals("NULL"))) { + value = "NULL"; + SQL = Utils.replaceInString(SQL, "'["+entry.getKey()+"]'", value); + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); + } else { + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); + } + } + lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); + } + //} + lookupList = lookup; + + //} + try { + lookup.loadUserData(0, "", getDbInfo(), getUserId()); + } catch (Exception e ){ e.printStackTrace(); //throw new RaptorRuntimeException(e); + } + } + lookup.trimToSize(); + + String selectedValue = ""; + int count = 0; + for (lookup.resetNext(); lookup.hasNext();) { + IdNameValue value = lookup.getNext(); + if(value != null && value.getId() != null && value.getName() != null ) { + /*if (count == 0 && required) { + selectedValue = value.getId(); + count++; + } else if (nvl(fieldValue).length()>0){ + if (fieldValue != null && fieldValue.equals(value.getId())){ + selectedValue = value.getId(); + } + count++; + } else { + count++; + } */ + if (count == 0) { + if(required){ + selectedValue = value.getId(); + } + count++; + } + sb.append("obj.options[obj.options.length] = new Option('" + Utils.singleQuoteEncode(value.getName())+"','"+Utils.singleQuoteEncode(value.getId())+"');"); + if ((fieldValue != null && fieldValue.equals(value.getId()))){ + sb.append("obj.options[obj.options.length-1].selected=true;"); + selectedValue = value.getId(); + } + if(value.isReadOnly()) + sb.append("obj.disabled=true;"); + else + sb.append("obj.disabled=false;"); + + } + } // for + if (formValues.containsKey(fieldDisplayName)){ + formValues.remove(fieldDisplayName); + } + formValues.put(fieldDisplayName, selectedValue); + } catch (Exception e) { + //throw new RaptorRuntimeException(e); + } + if(!hasPredefinedList) { + if(oldSQL != null && !oldSQL.equals("")) { + ((IdNameSql)lookup).setSQL(oldSQL); + } + } + //System.out.println("FORMFIELD 6666667 " + ((IdNameSql)lookup).getSql()); + if( isVisible()) + return sb.toString(); + else return ""; + } + + return ""; + } + + public String getHtml(String fieldValue, HashMap formValues, ReportRuntime rr, boolean inSchedule) throws RaptorRuntimeException { + fieldValue = nvl(fieldValue, defaultValue); + int MILLIS_IN_DAY = 1000 * 60 * 60 * 24; + String readOnlyInSql = "ff_readonly"; + boolean readOnly = false; + try { + if(fieldValue !=null && fieldValue.length() > 0) + fieldValue = java.net.URLDecoder.decode(fieldValue, "UTF-8"); + } catch (UnsupportedEncodingException ex) {} + catch (IllegalArgumentException ex1){} + catch (Exception ex2){} + //System.out.println(fieldName + " " + fieldType + " " + fieldValue); + if (fieldType.equals(FFT_TEXT_W_POPUP)) { + //System.out.println("TEXT POPUP " + fieldName); + String oldSQL = ""; + IdNameValue idNamevalue = null; + String fieldDefValue=""; + String fieldDefDisplay=""; + IdNameList lookup = null; + try { + lookup = getLookupList(); + if(!hasPredefinedList) { + if(dependsOn != null && dependsOn != "" ) { + IdNameSql lu = (IdNameSql) lookup; + String SQL = getBaseWholeSQL(); + if(SQL.toLowerCase().indexOf(readOnlyInSql) != -1) { + SQL = getBaseWholeReadonlySQL(); + } + oldSQL = lu.getSql(); + if(formValues != null) { + Set set = formValues.entrySet(); + String value = ""; + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + value = (String) entry.getValue(); + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); +// if(SQL.indexOf("'"+"["+entry.getKey()+"]"+"'")!=-1) { + if(SQL.indexOf("'"+"["+entry.getKey()+"]"+"'")!=-1 || SQL.indexOf("'"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"'")!=-1 + || SQL.indexOf("'%"+"["+entry.getKey()+"]"+"%'")!=-1 || SQL.indexOf("'%"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"%'")!=-1 + || SQL.indexOf("'_"+"["+entry.getKey()+"]"+"_'")!=-1 || SQL.indexOf("'_"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"_'")!=-1 + || SQL.indexOf("'%_"+"["+entry.getKey()+"]"+"_%'")!=-1 || SQL.indexOf("'%_"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"_%'")!=-1) { + + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", nvl( + value, "NULL")); + } else { + // Added to prevent SQL Injection + if(SQL.indexOf("["+entry.getKey()+"]")!=-1) { + try { + double vD = Double.parseDouble(value); + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", nvl( + value, "NULL")); + } catch (NumberFormatException ex) { + throw new UserDefinedException("Expected number, Given String for the form field \"" + "["+entry.getKey()+"]"+"\""); + } + } + } + } + if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.trim().length()<=0)) + lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); + else + lookup = new IdNameSql(-1,SQL,null); + } + } + //lookupList = lookup; + + if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.trim().length()<=0)) { + lookup.loadUserData(0, "", getDbInfo(), getUserId()); + for (lookup.resetNext(); lookup.hasNext();) { + idNamevalue = lookup.getNext(); + break; + + } + fieldDefValue = nvl(idNamevalue.getId()); + fieldDefDisplay = nvl(idNamevalue.getName()); + } else { + try { + // -2 indicates to run the whole sql for matching value + lookup.loadUserData(-2, "", getDbInfo(), getUserId()); + } catch (Exception e) { + //throw new RaptorRuntimeException(e); + } + + lookup.trimToSize(); + for (lookup.resetNext(); lookup.hasNext();) { + IdNameValue value = lookup.getNext(); + if(value != null && value.getId() != null && value.getName() != null ) { + fieldDefValue = nvl(value.getId()); + if (fieldValue != null && fieldValue.equals(value.getId())) { + fieldDefDisplay = nvl(value.getName()); + break; + } + else { + fieldDefValue = ""; + fieldDefDisplay = ""; + } + } + } + if (fieldDefDisplay == null || fieldDefDisplay.length()<=0) { + fieldDefDisplay = nvl(fieldDefValue); + } + + + + //----- END ---// + + + if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.length()<=0)) { + fieldDefValue = nvl((idNamevalue!=null)?idNamevalue.getId():""); + fieldDefDisplay = nvl((idNamevalue!=null)?idNamevalue.getName():""); + } else { + if(fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.length()<=0) fieldValue=""; + fieldDefValue = nvl(fieldDefValue); + fieldDefDisplay = nvl(fieldDefDisplay); + } + + } + } else { + lookup.trimToSize(); + for (lookup.resetNext(); lookup.hasNext();) { + IdNameValue value = lookup.getNext(); + if(value != null && value.getId() != null && value.getName() != null ) { + fieldDefValue = nvl(value.getId()); + if (fieldValue != null && fieldValue.equals(value.getId())) { + fieldDefDisplay = nvl(value.getName()); + break; + } + else { + fieldDefValue = ""; + fieldDefDisplay = ""; + } + } + } + if (fieldDefDisplay == null || fieldDefDisplay.length()<=0) { + fieldDefDisplay = nvl(fieldDefValue); + } + } + }catch(Exception e) { //throw new RaptorRuntimeException(e); + } + + if(!hasPredefinedList) { + if(oldSQL != null && !oldSQL.equals("")) { + ((IdNameSql)lookup).setSQL(oldSQL); + } + } + + if(isVisible()) { + /* return "\n" + " \"Loading, "; + + return progress+" \n  \n" + + " 0) { + valueSQL = lu.getSql(); + avail_ReadOnly = (valueSQL.toLowerCase().indexOf(readOnlyInSql)!=-1); + //System.out.println("OLD SQL TEXT" + valueSQL); + //oldSQL = lu.getSql(); + if(formValues != null) { + Set set = formValues.entrySet(); + String value1 = ""; + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + value1 = (String) entry.getValue(); + if (value1.length() <=0) { + value1 = "NULL"; + valueSQL = Utils.replaceInString(valueSQL, "'["+entry.getKey()+"]'", value1); + valueSQL = Utils.replaceInString(valueSQL, "["+entry.getKey()+"]", value1); + } else { + valueSQL = Utils.replaceInString(valueSQL, "["+entry.getKey()+"]", value1); + } + } + // should be value one. + //lookup = new IdNameSql(-1,valueSQL,lu.getDefaultSQL()); + } + } + //lookupList = lookup; + //System.out.println("8888888 88 " + valueSQL); + } + if(valueSQL!=null && valueSQL.length()>0) { + DataSet ds = ConnectionUtils.getDataSet(valueSQL.toString(), dbInfo); + strValue = ds.getString(0,1); + if(avail_ReadOnly) readOnly = ds.getString(0, 2).toUpperCase().startsWith("Y")||ds.getString(0, 2).toUpperCase().startsWith("T");; + } + }catch(Exception e) { //throw new RaptorRuntimeException(e); + } + String returnString = ""; + String timestamp ="", timestamphr = "", timestampmin = "", timestampsec = ""; + + returnString = "0 && (!(fieldValue.toUpperCase().indexOf("SELECT ")!= -1 && fieldValue.toUpperCase().indexOf("FROM")!= -1)) ) { + if(validationType.startsWith("TIMESTAMP")) { + returnString += nvl((fieldValue!=null)?fieldValue.split(" ")[0]:""); + if(fieldValue!=null && fieldValue.length()>0) { + timestamp = (fieldValue.split(" ").length > 1)?fieldValue.split(" ")[1]:""; + String timestampArr[] = timestamp.split(":"); + if((timestampArr.length == 1) || (timestampArr.length == 2) || (timestampArr.length == 3)) + timestamphr = timestampArr[0]; + if((timestampArr.length == 2) || (timestampArr.length == 3)) + timestampmin = timestampArr[1]; + if(timestampArr.length == 3) + timestampsec = timestampArr[2]; + } + + } else returnString += fieldValue; + + } else if(getFieldDefaultSQL()!=null) { + + if(validationType.startsWith("TIMESTAMP")) { + returnString += nvl((strValue.length()>0)?strValue.split(" ")[0]:""); + if(strValue.length()>0) { + timestamp = (strValue.split(" ").length > 1)?strValue.split(" ")[1]:""; + String timestampArr[] = timestamp.split(":"); + if((timestampArr.length == 1) || (timestampArr.length == 2) || (timestampArr.length == 3)) + timestamphr = timestampArr[0]; + if((timestampArr.length == 2) || (timestampArr.length == 3)) + timestampmin = timestampArr[1]; + if(timestampArr.length == 3) + timestampsec = timestampArr[2]; + } + + } else if (nvl(strValue).length()>0) { + returnString += strValue; + } else + returnString += nvl((value!=null)?value.getId():""); + } else if (nvl(strValue).length()>0) { + returnString += strValue; + } else + returnString += nvl((value!=null)?value.getId():""); + + + /*returnString += "\">" + + (validationType.equals(VT_DATE) ? "\n\t\t\t" + + "\n\t\t\t\t" + : ""); */ + + SimpleDateFormat dtf = new SimpleDateFormat("MM/dd/yyyy"); + String stRangeText = this.getRangeStartDate() == null ? null : dtf.format(this.getRangeStartDate().getTime()); + String endRangeText = this.getRangeEndDate() == null ? null : dtf.format(this.getRangeEndDate().getTime()); + ///////////////////////// + + //get the date sqls + + //System.out.println("////////////start range date before Start" + this.getRangeStartDateSQL()); + + if (this.getRangeStartDateSQL() != null && this.getRangeStartDateSQL().trim().toLowerCase().startsWith("select")){ + //System.out.println("////////////start range date Starting"); + String SQL = this.getRangeStartDateSQL(); + if(formValues != null) { + Set set = formValues.entrySet(); + String v = ""; + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + v = (String) entry.getValue(); + //System.out.println("///////// key is " + entry.getKey() + " = " + v); + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", v); + } + + } + //System.out.println("////////////start range date sql created" + SQL); + try{ + DataSet ds = ConnectionUtils.getDataSet(SQL.toString(), dbInfo); + //System.out.println("////////////start range date is : " + ds.get(0)); + dtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Calendar tStart = Calendar.getInstance(); + tStart.setTime(dtf.parse(ds.getString(0,0))); + dtf = new SimpleDateFormat("MM/dd/yyyy"); + stRangeText = dtf.format(tStart.getTime().getTime()-MILLIS_IN_DAY); + + }catch(Exception e){ + System.out.println("Exception////////// : start range date is : " + e); + } + } + + if (this.getRangeEndDateSQL() != null && this.getRangeEndDateSQL().trim().toLowerCase().startsWith("select")){ + //System.out.println("////////////end range date Starting"); + String SQL = this.getRangeEndDateSQL(); + if(formValues != null) { + Set set = formValues.entrySet(); + String v = ""; + for(Iterator iter = set.iterator(); iter.hasNext(); ) { + Map.Entry entry = (Entry) iter.next(); + v = (String) entry.getValue(); + SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", v); + } + + } + try{ + DataSet ds = ConnectionUtils.getDataSet(SQL.toString(), dbInfo); + //System.out.println("////////////end range date is : " + ds.get(0)); + dtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Calendar tStart = Calendar.getInstance(); + tStart.setTime(dtf.parse(ds.getString(0,0))); + dtf = new SimpleDateFormat("MM/dd/yyyy"); + //endRangeText = dtf.format(tStart.getTime()); + endRangeText = dtf.format(tStart.getTime().getTime()+MILLIS_IN_DAY); + }catch(Exception e){ + System.out.println("Exception////////// : end range date is : " + e); + } + } + + + ////////////////////// + String calendarOnClickMethodCall = ""; + String timeStampStr = ""; + if (stRangeText == null || endRangeText == null) + calendarOnClickMethodCall = "'oCalendar.select(document." + HTML_FORM + "." + fieldName + ", event,\""+ Globals.getCalendarOutputDateFormat() +"\"); return false;'"; + else + calendarOnClickMethodCall = "'oCalendar=new CalendarPopup(\"calendarDiv\", \"calendarFrame\");oCalendar.setCssPrefix(\"raptor\");oCalendar.addDisabledDates(null, \"" + stRangeText + "\"); oCalendar.addDisabledDates(\"" + endRangeText + "\", null); oCalendar.select(document." + HTML_FORM + "." + fieldName + ", event,\""+ Globals.getCalendarOutputDateFormat() +"\"); return false;'"; + returnString += "\" " + getHelpLink(fieldName) + + (validationType.equals(VT_DATE) || validationType.equals(VT_TIMESTAMP_HR) || validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC) + ? "\n\t\t\t" + : ""); + if(validationType.equals(VT_TIMESTAMP_HR) || validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC) ) { + //Add Hours/Minutes and Seconds. + timeStampStr = " Hour "; + } + //Minutes + if( validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC) ) { + int minutes = 0; + int t_min = 0; + try { + minutes = Integer.parseInt(nvl(rr.getParamValue(fieldName+"_Min"),"0")); + if(minutes == 0) { + if(inSchedule) minutes = Integer.parseInt(nvl(((String)formValues.get(fieldName+"_Min")),"0")); + } + } catch (NumberFormatException ex) {minutes = 0;} + try { + t_min = Integer.parseInt(timestampmin); + } catch (NumberFormatException ex) { t_min = 0;} + + if(minutes <= 0) minutes = t_min; + /*if (formValues.containsKey(fieldDisplayName+"_Min")){ + formValues.remove(fieldDisplayName+"_Min"); + formValues.put(fieldDisplayName+"_Min", minutes); + } else + formValues.put(fieldDisplayName+"_Min", minutes); + */ + timeStampStr += " Min "; + } + //Seconds + if( validationType.equals(VT_TIMESTAMP_SEC) ) { + int seconds = 0; + int t_sec = 0; + try { + seconds = Integer.parseInt(nvl(rr.getParamValue(fieldName+"_Sec"),"0")); + if(seconds == 0) { + if(inSchedule) seconds = Integer.parseInt(nvl(((String)formValues.get(fieldName+"_Sec")),"0")); + } + } catch (NumberFormatException ex) {seconds = 0;} + try { + t_sec = Integer.parseInt(timestampsec); + } catch (NumberFormatException ex) { t_sec = 0;} + + if(seconds <= 0) seconds = t_sec; + /*if (formValues.containsKey(fieldDisplayName+"_Sec")){ + formValues.remove(fieldDisplayName+"_Sec"); + formValues.put(fieldDisplayName+"_Sec", seconds); + } else + formValues.put(fieldDisplayName+"_Sec", seconds); + */ + timeStampStr += " Sec "; + } + + returnString += timeStampStr; + String checkboxStr = ""; + if(inSchedule && (validationType.equals(VT_DATE) || validationType.equals(VT_TIMESTAMP_HR) || validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC)) ) { + if(!Globals.isScheduleDateParamAutoIncr()) { + checkboxStr = /*checkboxStr +" "+ */ ""; + } else { + checkboxStr = /*checkboxStr +" "+ */""; + } + /*if(validationType.equals(VT_TIMESTAMP_HR) || validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC)) { + checkboxStr = checkboxStr +" "+ ""; + } + if(validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC)) { + checkboxStr = checkboxStr +" "+ ""; + } + if(validationType.equals(VT_TIMESTAMP_SEC)) { + checkboxStr = checkboxStr +" "+ ""; + }*/ + } + if(isVisible()) + return returnString+checkboxStr; + else return ""; + } else if (fieldType.equals(FFT_TEXTAREA)) { + + if(nvl(fieldValue).length()>0) { + fieldValue = Pattern.compile("(^[\r\n])|\\([\\']", Pattern.DOTALL).matcher(fieldValue).replaceAll(""); + fieldValue = Pattern.compile("[\\']\\)", Pattern.DOTALL).matcher(fieldValue).replaceAll(""); + fieldValue = fieldValue.replaceAll("','",","); // changed from "|" + fieldValue = fieldValue.replaceAll("' , '","\r\n"); + } + + if(isVisible()) + return " + +
+
+
+ + +
+ +
+
+ + +
+ +
+
+ +
+ + +
+
+
+
+
+
+
+ +
+ + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/broadcast_list.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/broadcast_list.jsp new file mode 100644 index 00000000..401f413b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/broadcast_list.jsp @@ -0,0 +1,201 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ page import="java.util.*" %> +<%@ page import="com.fasterxml.jackson.databind.ObjectMapper" %> +<%@ page import="org.json.JSONObject" %> +<%@ page import="java.io.StringWriter" %> +<%@ page import="org.openecomp.portalsdk.core.web.support.ControllerProperties" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + + + + +
+

+ Broadcast Messages +

+
+ + <%-- Display a table for the broadcast messages of each message location --%> +
+ +
+ {{location.label}} Messages +
+ + + + + + + + + + + + + + + + + {{message.id}} + + + + + + + + + + + +
No.Message TextStart DateEnd DateSort OrderServerActive?Delete?
{{$index+1}}{{message.messageText}} + {{message.displayStartDate}} + {{message.displayEndDate}}{{message.sortOrder}}{{message.siteCd}} +
+ +
+
+
+
+
+ +


+
+
+ + \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/data_out.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/data_out.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/data_out.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/data_out.jsp diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ds2/template.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ds2/template.jsp new file mode 100644 index 00000000..ac210a3f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ds2/template.jsp @@ -0,0 +1,101 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> + + + + +<%-- <%@ include file="/WEB-INF/fusion/jsp/ds2/meta.jsp" %> --%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +<%--
+ +
--%> + +
+
+
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp new file mode 100644 index 00000000..bd5206eb --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp @@ -0,0 +1,41 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> + + + + + +
+
+
+
+
+ +
+
+ +
+
+
+
+
+ \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp new file mode 100644 index 00000000..1d3ba8e7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp @@ -0,0 +1,747 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@ page isELIgnored="false"%> +<%@ page import="org.openecomp.portalsdk.core.util.SystemProperties"%> +<%@ page import="org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties"%> +<%@ page import="org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants"%> +<%@ page import="org.openecomp.portalsdk.core.domain.MenuData"%> + + + + + + + + + + + + + + + + + + + + + + + + + + + +" /> +" /> + +<% + String contactUsLink = SystemProperties.getProperty(SystemProperties.CONTACT_US_LINK); + String redirectUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); + String portalUrl = redirectUrl.substring(0, redirectUrl.lastIndexOf('/')) + "/process_csp"; + String getAccessLink = redirectUrl.substring(0, redirectUrl.lastIndexOf('/')) + "/get_access"; +%> + + + + +<%@include file="/WEB-INF/fusion/jsp/ebz/loginSnippet.html" %> + +
+
+ +
+
+
+ + +
+
+
+
+
  • + +> ECOMP Portal +
  • +
    +
    + +
    +
    + + +
    + + +
    +
    +
    +
  • + Unable to load menus +
  • +
    + +
    +
  • +
    + + +
    +
  • +
  •  
  • +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + + +     {{app_name}} + +
    +
    +
    +
    + + + + + +
    +
    +
    +
    +
    +
    +
    +
    + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/loginSnippet.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/loginSnippet.html new file mode 100644 index 00000000..ae5e13ec --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz/loginSnippet.html @@ -0,0 +1,115 @@ + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template.jsp new file mode 100644 index 00000000..93f96369 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template.jsp @@ -0,0 +1,45 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> + + + + + <%@ include file="/WEB-INF/fusion/jsp/meta.jsp" %> + + + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_noheader_nofooter.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_noheader_nofooter.jsp new file mode 100644 index 00000000..a579fdc0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_noheader_nofooter.jsp @@ -0,0 +1,35 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> + + + <%@ include file="/WEB-INF/fusion/jsp/meta.jsp" %> + +
    + +
    +
    + +
    +
    + +
    + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_report_embedded.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_report_embedded.jsp new file mode 100644 index 00000000..4cdfe51d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_report_embedded.jsp @@ -0,0 +1,48 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> + + + <%@ include file="/WEB-INF/fusion/jsp/meta.jsp" %> + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/es_search_demo.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/es_search_demo.jsp new file mode 100644 index 00000000..61458524 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/es_search_demo.jsp @@ -0,0 +1,97 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> + + + +
    +
    Elastic Search - Corporate Location Data System
    +
    +
    + +   +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Customer NamePhoneStreetCityStateZIPCLLI
    {{options._source.name}}{{options._source.suggest.payload.tn}}{{options._source.suggest.payload.addr}}{{options._source.suggest.payload.city}}{{options._source.suggest.payload.st}}{{options._source.suggest.payload.zip}}{{options._source.suggest.payload.clli}}
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp new file mode 100644 index 00000000..abae598b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp @@ -0,0 +1,97 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> + + + +
    +
    Elastic Search - Corporate Location Data System
    +
    +
    + +   +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Customer NamePhoneStreetCityStateZIPCLLI
    {{options.text}}{{options.payload.tn}}{{options.payload.addr}}{{options.payload.city}}{{options.payload.st}}{{options.payload.zip}}{{options.payload.clli}}
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/frame_insert.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/frame_insert.jsp new file mode 100644 index 00000000..ed50b5dd --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/frame_insert.jsp @@ -0,0 +1,44 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> + + + \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/include.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/include.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/include.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/include.jsp diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/meta.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/meta.jsp new file mode 100644 index 00000000..0a361803 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/meta.jsp @@ -0,0 +1,36 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/popup_modal.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/popup_modal.html similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/popup_modal.html rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/popup_modal.html diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_role.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_role.html similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_role.html rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_role.html diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_rolefunction.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_rolefunction.html similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_rolefunction.html rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/popup_modal_rolefunction.html diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/sequence/details.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/sequence/details.jsp new file mode 100644 index 00000000..eacdfbe0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/sequence/details.jsp @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/webrtc/collaboration.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/webrtc/collaboration.jsp new file mode 100644 index 00000000..9bf0ed74 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/jsp/webrtc/collaboration.jsp @@ -0,0 +1,494 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    +
    + + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + + + + + diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/orm/Fusion.hbm.xml b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/orm/Fusion.hbm.xml similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/orm/Fusion.hbm.xml rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/orm/Fusion.hbm.xml diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/orm/Workflow.hbm.xml b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/orm/Workflow.hbm.xml similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/orm/Workflow.hbm.xml rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/orm/Workflow.hbm.xml diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/custom_header_include.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/custom_header_include.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/custom_header_include.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/custom_header_include.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/custom_js_include.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/custom_js_include.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/custom_js_include.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/custom_js_include.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/date_end_field_run_sql.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/date_end_field_run_sql.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/date_end_field_run_sql.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/date_end_field_run_sql.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/date_start_field_run_sql.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/date_start_field_run_sql.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/date_start_field_run_sql.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/date_start_field_run_sql.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/default_field_run_sql.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/default_field_run_sql.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/default_field_run_sql.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/default_field_run_sql.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/disclaimer.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/disclaimer.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/disclaimer.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/disclaimer.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/error_include.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/error_include.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/error_include.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/error_include.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/error_page.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/error_page.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/error_page.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/error_page.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/footer.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/footer.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/footer.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/footer.jsp diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_drill_down_report.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_drill_down_report.jsp new file mode 100644 index 00000000..6838f3ac --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_drill_down_report.jsp @@ -0,0 +1,623 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ page import="java.util.*" %> + +<%@ page import="org.openecomp.portalsdk.analytics.xmlobj.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.model.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.model.definition.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.model.runtime.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.system.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.util.*" %> + +<% ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute(AppConstants.SI_REPORT_DEFINITION); + List reportCols = rdef.getAllColumns(); + List rFormFields = null; + if(rdef.getFormFieldList()!=null&&rdef.getFormFieldList().getFormField().size()>0) + rFormFields = rdef.getFormFieldList().getFormField(); + + ReportFormFields ddReportFormFields = (ReportFormFields) request.getAttribute(AppConstants.RI_FORM_FIELDS); + + String drillDownSuppress = AppUtils.getRequestNvlValue(request, "drillDownSuppress"); + String drillDownParams = AppUtils.getRequestNvlValue(request, "drillDownParams"); + String drillDownRequest = AppUtils.getRequestNvlValue(request, "drillDownRequest"); + + Hashtable paramDefinitions = new Hashtable(); + StringTokenizer st = new StringTokenizer(drillDownParams, "&"); + //Added for passing request parameters in Drill Down + String[] reqParameters = Globals.getRequestParams().split(","); + int icnt=0; + // + while(st.hasMoreTokens()) { + String param = st.nextToken(); + DrillDownParamDef paramDef = new DrillDownParamDef(param); + if(paramDef.getFieldName().length()>0) + paramDefinitions.put(paramDef.getFieldName(), paramDef); + } // while +%> + + + + Drill-down Parameters Configuration + + + + + + + +
    + + + + + +<% if(ddReportFormFields!=null) + for(ddReportFormFields.resetNext(); ddReportFormFields.hasNext(); ) { + FormField ff = ddReportFormFields.getNext(); + if(!ff.getFieldType().equals(FormField.FFT_BLANK)) { + + DrillDownParamDef paramDef = (DrillDownParamDef) paramDefinitions.get(ff.getFieldName()); + if(paramDef==null) + paramDef = new DrillDownParamDef(""); %> + + <% if (ff!=null && (ff.getValidationType().equals(FormField.VT_TIMESTAMP_HR) || ff.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || ff.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) ) { + %> + + + + + + + + + + + + + + + +<% if(rFormFields!=null) { %> + + + + + + + + +<% } // if + +%> + + <% + paramDef = (DrillDownParamDef) paramDefinitions.get(ff.getFieldName()+"_Hr"); + if(paramDef==null) + paramDef = new DrillDownParamDef(""); + %> + + + + + + + + + + + +<% + if (ff.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || ff.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { +%> + <% + paramDef = (DrillDownParamDef) paramDefinitions.get(ff.getFieldName()+"_Min"); + if(paramDef==null) + paramDef = new DrillDownParamDef(""); + %> + + + + + + + + + + + +<% + } + if(ff.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { +%> + <% + paramDef = (DrillDownParamDef) paramDefinitions.get(ff.getFieldName()+"_Sec"); + if(paramDef==null) + paramDef = new DrillDownParamDef(""); + %> + + + + + + + + + + + +<% + + } + + } else { +%> + + + + + + + + + + + + + + + +<% if(rFormFields!=null) { %> + + + + + + + + +<% } // if + } // else + } // if BLANK + } // for +%> + + + + + + + + + + + + + + + + + <% if(!Globals.getPassRequestParamInDrilldown() && (!(reqParameters.length==1 && reqParameters[0].length()<=0))) { + %> + + + + + <% + icnt=0; + + for (int i = 0; i < reqParameters.length; i++) { + icnt++; + + %> + > + + + + + <% + } //for + %> + + <% + } // if requestParam + %> + + + + + + + +
    + DRILL-DOWN PARAMETERS CONFIGURATION +
    +  <%= ff.getFieldDisplayName() %> +
    +       + >No value + + Accept default +
    +       + >Fixed value + + " onChange="document.dataform.r_<%= ff.getFieldName() %>[1].click();"> +
    +       + >Value of column + + +
    +       + >Value of form field + + +
    +       + >Value set + + Pass the value of the selected column if not empty,
    + otherwise pass the value of the selected form field
    +
    +  <%= ff.getFieldDisplayName() %> (Hour) +
    +       + >No value + + Accept default +
    +       + >Value of column + + + + +
    +  <%= ff.getFieldDisplayName() %> (Minutes) +
    +       + >No value + + Accept default +
    +       + >Value of column + + + + +
    +  <%= ff.getFieldDisplayName() %> (Seconds) +
    +       + >No value + + Accept default +
    +       + >Value of column + + + + +
    +  <%= ff.getFieldDisplayName() %> +
    +       + >No value + + Accept default +
    +       + >Fixed value + + " onChange="document.dataform.r_<%= ff.getFieldName() %>[1].click();"> +
    +       + >Value of column + + +
    +       + >Value of form field + + +
    +       + >Value set + + Pass the value of the selected column if not empty,
    + otherwise pass the value of the selected form field
    +
     
    +  Parameter values not to be passed to the drill-down report
    +       + Suppress values + + +
    separate by | if multiple values
    +
     
    +  Request Parameter values to be passed to the drill-down report
    <%= reqParameters[i]%> + > +
    + Show Drilled Down Report In Popup Window: +
    +
    +

    + + + + +<%! private String nvl(String s) { return (s==null)?"":s; } + private String nvl(String s, String sDefault) { return nvl(s).equals("")?sDefault:s; } %> + diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_import_semaphore.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_import_semaphore.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_import_semaphore.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_import_semaphore.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_semaphore.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_semaphore.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_semaphore.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_semaphore.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_sql.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_sql.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_sql.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_sql.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_table_cols.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_table_cols.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_table_cols.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_table_cols.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_testrun_sql.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_testrun_sql.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_testrun_sql.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/popup_testrun_sql.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_download_csv.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_download_csv.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_download_csv.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_download_csv.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_download_pdf.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_download_pdf.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_download_pdf.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_download_pdf.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_download_xls.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_download_xls.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_download_xls.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_download_xls.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_ebz.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_ebz.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_ebz.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_ebz.jsp diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_import.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_import.jsp new file mode 100644 index 00000000..bb62def0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_import.jsp @@ -0,0 +1,84 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ page import="java.util.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.system.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.util.*" %> + + + + Import + + + + + + +

    + + +
    +
    + + + + + + + + + + + + + +
    + <%= Globals.getBaseTitle() %> > IMPORT REPORT XML +
    + + + +
    +
    + +
    + + + +
    + +<%-- --%> +
    + + + +<%! private String nvl(String s) { return (s==null)?"":s; } + private String nvl(String s, String sDefault) { return nvl(s).equals("")?sDefault:s; } %> + diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_sample.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_sample.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_sample.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_sample.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_search.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_search.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_search.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_search.jsp diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_wizard.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_wizard.jsp new file mode 100644 index 00000000..8448b249 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/report_wizard.jsp @@ -0,0 +1,322 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%-- + Name: report_wizard.jsp + Use : Master JSP which navigates to specific JSP when different tab is selected. Default it navigates to the wizard_definition.jsp + + Change Log + ========== + + 22-Jun-2009 : Version 8.4 (Sundar); + +
      +
    • Save button is suppressed from showing when wizard is in the last page (Run page).
    • +
    • width of the content_iframe is changed back to default one when navigated from >100% report's run page.
    • +
    +--%> +<%@ page import="java.util.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.xmlobj.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.model.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.model.base.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.model.definition.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.model.runtime.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.controller.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.system.*" %> +<%@ page import="org.openecomp.portalsdk.analytics.util.*" %> + +<%@ page errorPage="error_page.jsp" %> + + + + +<% ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute(AppConstants.SI_REPORT_DEFINITION); + + String reportID = rdef.getReportID(); + WizardSequence ws = rdef.getWizardSequence(); + + String curStep = ws.getCurrentStep(); + String curSubStep = ws.getCurrentSubStep(); + + String dbInfo = null; + dbInfo = rdef.getDBInfo(); + int sessionflag = 0; + if(dbInfo == null || dbInfo.length() == 0) { + dbInfo = (String) session.getAttribute("remoteDB"); + sessionflag = 1; + } + session.setAttribute("remoteDB", dbInfo); + if((dbInfo == null) && (request.getParameter("dataSource")!=null)) + session.setAttribute("remoteDB", request.getParameter("dataSource")); + + String title = (reportID.equals("-1")?"Create Report":"Edit Report"); + String navTitle = Globals.getBaseTitle()+" > " + title; + + boolean isCrossTab = rdef.getReportType().equals(AppConstants.RT_CROSSTAB); + boolean isSQLBased = rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED); +%> + +<% + request.setAttribute(AppConstants.SI_REPORT_DEFINITION,rdef); +%> + + + + + + + + + + + +
    + + + + +
    + +
    +
    +
    + +
    + + + + + + + + + + +
    + + +<% for(ws.resetNext(); ws.hasNext(); ) { + String sTab = ws.getNext(); %> + + + +<% } // for +%> + + +
    " width="9" height="24"> align="center" valign="middle"> + <% if(sTab.equals(curStep)) { %> +  <%= clearSpaces(sTab) %>  + <% } else if(reportID.equals("-1")) { %> +  <%= clearSpaces(sTab) %>  + <% } else { %> +  <%= clearSpaces(sTab) %>  + <% } %> + " width="9" height="24"> 
    +
    + + + + +
    <%= navTitle %>
    +
    <% if(curStep.equals(AppConstants.WS_DEFINITION)) { %> + <% if(sessionflag == 1) dbInfo = ""; %> + +<% } else if(curStep.equals(AppConstants.WS_SQL)) { %> + +<% } else if(curStep.equals(AppConstants.WS_TABLES)&&curSubStep.equals("")) { %> + +<% } else if(curStep.equals(AppConstants.WS_TABLES)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT))) { %> + +<% } else if(curStep.equals(AppConstants.WS_COLUMNS)&&curSubStep.equals("")) { %> + +<% } else if(curStep.equals(AppConstants.WS_COLUMNS)&&curSubStep.equals(AppConstants.WSS_ADD_MULTI)) { %> + +<% } else if(curStep.equals(AppConstants.WS_COLUMNS)&&curSubStep.equals(AppConstants.WSS_ORDER_ALL)) { %> + +<% } else if(curStep.equals(AppConstants.WS_COLUMNS)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT) ||curSubStep.equals(AppConstants.WA_MODIFY))) { %> + +<% } else if(curStep.equals(AppConstants.WS_FORM_FIELDS)&&curSubStep.equals("")||curSubStep.equals(AppConstants.WSS_ADD_BLANK)) { %> + +<% } else if(curStep.equals(AppConstants.WS_FORM_FIELDS)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT))) { %> + +<% } else if(curStep.equals(AppConstants.WS_FILTERS)&&curSubStep.equals("")) { %> + +<% } else if(curStep.equals(AppConstants.WS_FILTERS)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT))) { %> + +<% } else if(curStep.equals(AppConstants.WS_SORTING)&&curSubStep.equals("")) { %> + +<% } else if(curStep.equals(AppConstants.WS_SORTING)&&curSubStep.equals(AppConstants.WSS_ORDER_ALL)) { %> + +<% } else if(curStep.equals(AppConstants.WS_SORTING)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT))) { %> + +<% } else if(curStep.equals(AppConstants.WS_JAVASCRIPT)) { %> + +<% } else if(curStep.equals(AppConstants.WS_CHART)) { %> + +<% } else if(curStep.equals(AppConstants.WS_USER_ACCESS)) { %> + +<% } else if(curStep.equals(AppConstants.WS_SCHEDULE)) { %> + +<% } else if(curStep.equals(AppConstants.WS_REPORT_LOG)) { %> + +<% } else if(curStep.equals(AppConstants.WS_MAP)) { %> + +<% } else if(curStep.equals(AppConstants.WS_DATA_FORECASTING)) { %> + +<% } else { %> + +<% } %> + +
    + + + + + +
    +   + + <% if(! ws.isInitialStep()) { %> + + <% } %> + + <% if(! ws.isFinalStep()) { %> + + + <% } %> +
    +
    + +
    + + + + + +
    +
    +
    +<%----%> + +<%! private String HTMLEncode(String value) { + StringBuffer sb = new StringBuffer(value); + + for(int i=0; i') + sb.replace(i, i+1, ">"); + else if(sb.charAt(i)=='"') + sb.replace(i, i+1, """); + + return sb.toString(); + } // HTMLEncode + + private String clearSpaces(String value) { + StringBuffer sb = new StringBuffer(value); + + for(int i=0; i + + diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/test_field_run_sql.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/test_field_run_sql.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/test_field_run_sql.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/test_field_run_sql.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/test_run_sql.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/test_run_sql.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/test_run_sql.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/test_run_sql.jsp diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/tree/folderNav.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/tree/folderNav.jsp new file mode 100644 index 00000000..38951994 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/tree/folderNav.jsp @@ -0,0 +1,464 @@ +<%@page import="org.openecomp.portalsdk.analytics.system.AppUtils" %> +<%@page import="org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime"%> +<%@page import="org.openecomp.portalsdk.analytics.util.AppConstants"%> +<%@page import="org.openecomp.portalsdk.analytics.system.Globals"%> + +<% + boolean isFolderAllowed = false; + ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); + boolean adminUser = AppUtils.isAdminUser(request); + if (Globals.isFolderTreeAllowed()) { + if(adminUser) { + isFolderAllowed = true; + } else if (!Globals.isFolderTreeAllowedOnlyForAdminUsers()) { + isFolderAllowed = true; + } else isFolderAllowed = false; + } + + + +%> + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + <% if(isFolderAllowed) { %> + + <% } %> + + + + <% if(isFolderAllowed) { %> +
    + Show Folder Tree +
    + <% } %> + + + +
    + + + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/tree/testTree.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/tree/testTree.jsp new file mode 100644 index 00000000..1521790d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/tree/testTree.jsp @@ -0,0 +1,229 @@ +<%@page import="org.openecomp.portalsdk.analytics.system.AppUtils" %> + + + + + + + + Folder tree with Drag and Drop capabilities + + + + + + + + + + + + + +
    + + + + + + + + + +
    + +
    +
    + + + + +
    + Hide Folder Tree +     + + Create Folder | + Delete Fodler | + Run Report | + Edit Report +
    +
    +
    +
    + + + + + + + +
    +
    + + + + +
    + <%=request.getAttribute("folderList")%> +
    +
    +
    + + + +
    + Collapse all | + Expand all +
    + + +
    + +
    +
    +
    +
    + +
    +
    +
    + + + +
    + + + + +
    + + + \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_adhoc_schedule.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_adhoc_schedule.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_adhoc_schedule.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_adhoc_schedule.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_chart.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_chart.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_chart.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_chart.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_add_multi.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_add_multi.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_add_multi.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_add_multi.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_edit.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_edit.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_edit.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_edit.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_list.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_list.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_list.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_list.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_order_all.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_order_all.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_order_all.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_columns_order_all.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_data_forecasting.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_data_forecasting.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_data_forecasting.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_data_forecasting.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_definition.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_definition.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_definition.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_definition.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_edit.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_edit.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_edit.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_edit.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_list.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_list.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_list.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_filters_list.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_edit.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_edit.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_edit.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_edit.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_list.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_list.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_list.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_form_fields_list.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_javascript.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_javascript.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_javascript.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_javascript.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_log.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_log.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_log.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_log.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_map.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_map.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_map.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_map.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_run.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_run.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_run.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_run.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_formfield_include.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_formfield_include.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_formfield_include.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_formfield_include.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_multiple.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_multiple.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_multiple.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_multiple.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only_from_search.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only_from_search.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only_from_search.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_schedule_only_from_search.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_edit.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_edit.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_edit.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_edit.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_list.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_list.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_list.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_list.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_order_all.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_order_all.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_order_all.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_sorting_order_all.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_sql_def.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_sql_def.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_sql_def.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_sql_def.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_edit.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_edit.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_edit.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_edit.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_list.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_list.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_list.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_tables_list.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_user_access.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_user_access.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/wizard_user_access.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/raptor/wizard_user_access.jsp diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/error.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/error.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/error.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/error.jsp diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/leafletMap.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/leafletMap.jsp new file mode 100644 index 00000000..e11070d1 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/leafletMap.jsp @@ -0,0 +1,216 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> + + + + + + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + +
    SiteUsage
    + + + + + + + + + +
    LinkUsage
    +
    + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/login_external_ng.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/login_external_ng.jsp new file mode 100644 index 00000000..cb6def1e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/login_external_ng.jsp @@ -0,0 +1,79 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ page import="org.openecomp.portalsdk.core.util.SystemProperties" %> + +" /> + + + + + + + Login + + + + + + + + +
    +
    +
    +
    +
    +
    + +

    ECOMP Portal

    +
    ${model.error}
    +
    + + +
    +
    + + +
    +
    +                + +
    +
    +
    +






    + +
    + + \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/net_map.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/net_map.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/net_map.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/jsp/net_map.jsp diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/web.xml b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..3f84f06a --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,10 @@ + + + + + ecomp-sdk-app-common + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-animate.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-animate.js new file mode 100644 index 00000000..30610044 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-animate.js @@ -0,0 +1,3930 @@ +/** + * @license AngularJS v1.4.8 + * (c) 2010-2015 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +/* jshint ignore:start */ +var noop = angular.noop; +var extend = angular.extend; +var jqLite = angular.element; +var forEach = angular.forEach; +var isArray = angular.isArray; +var isString = angular.isString; +var isObject = angular.isObject; +var isUndefined = angular.isUndefined; +var isDefined = angular.isDefined; +var isFunction = angular.isFunction; +var isElement = angular.isElement; + +var ELEMENT_NODE = 1; +var COMMENT_NODE = 8; + +var ADD_CLASS_SUFFIX = '-add'; +var REMOVE_CLASS_SUFFIX = '-remove'; +var EVENT_CLASS_PREFIX = 'ng-'; +var ACTIVE_CLASS_SUFFIX = '-active'; + +var NG_ANIMATE_CLASSNAME = 'ng-animate'; +var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren'; + +// Detect proper transitionend/animationend event names. +var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT; + +// If unprefixed events are not supported but webkit-prefixed are, use the latter. +// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them. +// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend` +// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`. +// Register both events in case `window.onanimationend` is not supported because of that, +// do the same for `transitionend` as Safari is likely to exhibit similar behavior. +// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit +// therefore there is no reason to test anymore for other vendor prefixes: +// http://caniuse.com/#search=transition +if (isUndefined(window.ontransitionend) && isDefined(window.onwebkittransitionend)) { + CSS_PREFIX = '-webkit-'; + TRANSITION_PROP = 'WebkitTransition'; + TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend'; +} else { + TRANSITION_PROP = 'transition'; + TRANSITIONEND_EVENT = 'transitionend'; +} + +if (isUndefined(window.onanimationend) && isDefined(window.onwebkitanimationend)) { + CSS_PREFIX = '-webkit-'; + ANIMATION_PROP = 'WebkitAnimation'; + ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend'; +} else { + ANIMATION_PROP = 'animation'; + ANIMATIONEND_EVENT = 'animationend'; +} + +var DURATION_KEY = 'Duration'; +var PROPERTY_KEY = 'Property'; +var DELAY_KEY = 'Delay'; +var TIMING_KEY = 'TimingFunction'; +var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount'; +var ANIMATION_PLAYSTATE_KEY = 'PlayState'; +var SAFE_FAST_FORWARD_DURATION_VALUE = 9999; + +var ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY; +var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY; +var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY; +var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY; + +var isPromiseLike = function(p) { + return p && p.then ? true : false; +}; + +function assertArg(arg, name, reason) { + if (!arg) { + throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required")); + } + return arg; +} + +function mergeClasses(a,b) { + if (!a && !b) return ''; + if (!a) return b; + if (!b) return a; + if (isArray(a)) a = a.join(' '); + if (isArray(b)) b = b.join(' '); + return a + ' ' + b; +} + +function packageStyles(options) { + var styles = {}; + if (options && (options.to || options.from)) { + styles.to = options.to; + styles.from = options.from; + } + return styles; +} + +function pendClasses(classes, fix, isPrefix) { + var className = ''; + classes = isArray(classes) + ? classes + : classes && isString(classes) && classes.length + ? classes.split(/\s+/) + : []; + forEach(classes, function(klass, i) { + if (klass && klass.length > 0) { + className += (i > 0) ? ' ' : ''; + className += isPrefix ? fix + klass + : klass + fix; + } + }); + return className; +} + +function removeFromArray(arr, val) { + var index = arr.indexOf(val); + if (val >= 0) { + arr.splice(index, 1); + } +} + +function stripCommentsFromElement(element) { + if (element instanceof jqLite) { + switch (element.length) { + case 0: + return []; + break; + + case 1: + // there is no point of stripping anything if the element + // is the only element within the jqLite wrapper. + // (it's important that we retain the element instance.) + if (element[0].nodeType === ELEMENT_NODE) { + return element; + } + break; + + default: + return jqLite(extractElementNode(element)); + break; + } + } + + if (element.nodeType === ELEMENT_NODE) { + return jqLite(element); + } +} + +function extractElementNode(element) { + if (!element[0]) return element; + for (var i = 0; i < element.length; i++) { + var elm = element[i]; + if (elm.nodeType == ELEMENT_NODE) { + return elm; + } + } +} + +function $$addClass($$jqLite, element, className) { + forEach(element, function(elm) { + $$jqLite.addClass(elm, className); + }); +} + +function $$removeClass($$jqLite, element, className) { + forEach(element, function(elm) { + $$jqLite.removeClass(elm, className); + }); +} + +function applyAnimationClassesFactory($$jqLite) { + return function(element, options) { + if (options.addClass) { + $$addClass($$jqLite, element, options.addClass); + options.addClass = null; + } + if (options.removeClass) { + $$removeClass($$jqLite, element, options.removeClass); + options.removeClass = null; + } + } +} + +function prepareAnimationOptions(options) { + options = options || {}; + if (!options.$$prepared) { + var domOperation = options.domOperation || noop; + options.domOperation = function() { + options.$$domOperationFired = true; + domOperation(); + domOperation = noop; + }; + options.$$prepared = true; + } + return options; +} + +function applyAnimationStyles(element, options) { + applyAnimationFromStyles(element, options); + applyAnimationToStyles(element, options); +} + +function applyAnimationFromStyles(element, options) { + if (options.from) { + element.css(options.from); + options.from = null; + } +} + +function applyAnimationToStyles(element, options) { + if (options.to) { + element.css(options.to); + options.to = null; + } +} + +function mergeAnimationOptions(element, target, newOptions) { + var toAdd = (target.addClass || '') + ' ' + (newOptions.addClass || ''); + var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || ''); + var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove); + + if (newOptions.preparationClasses) { + target.preparationClasses = concatWithSpace(newOptions.preparationClasses, target.preparationClasses); + delete newOptions.preparationClasses; + } + + // noop is basically when there is no callback; otherwise something has been set + var realDomOperation = target.domOperation !== noop ? target.domOperation : null; + + extend(target, newOptions); + + // TODO(matsko or sreeramu): proper fix is to maintain all animation callback in array and call at last,but now only leave has the callback so no issue with this. + if (realDomOperation) { + target.domOperation = realDomOperation; + } + + if (classes.addClass) { + target.addClass = classes.addClass; + } else { + target.addClass = null; + } + + if (classes.removeClass) { + target.removeClass = classes.removeClass; + } else { + target.removeClass = null; + } + + return target; +} + +function resolveElementClasses(existing, toAdd, toRemove) { + var ADD_CLASS = 1; + var REMOVE_CLASS = -1; + + var flags = {}; + existing = splitClassesToLookup(existing); + + toAdd = splitClassesToLookup(toAdd); + forEach(toAdd, function(value, key) { + flags[key] = ADD_CLASS; + }); + + toRemove = splitClassesToLookup(toRemove); + forEach(toRemove, function(value, key) { + flags[key] = flags[key] === ADD_CLASS ? null : REMOVE_CLASS; + }); + + var classes = { + addClass: '', + removeClass: '' + }; + + forEach(flags, function(val, klass) { + var prop, allow; + if (val === ADD_CLASS) { + prop = 'addClass'; + allow = !existing[klass]; + } else if (val === REMOVE_CLASS) { + prop = 'removeClass'; + allow = existing[klass]; + } + if (allow) { + if (classes[prop].length) { + classes[prop] += ' '; + } + classes[prop] += klass; + } + }); + + function splitClassesToLookup(classes) { + if (isString(classes)) { + classes = classes.split(' '); + } + + var obj = {}; + forEach(classes, function(klass) { + // sometimes the split leaves empty string values + // incase extra spaces were applied to the options + if (klass.length) { + obj[klass] = true; + } + }); + return obj; + } + + return classes; +} + +function getDomNode(element) { + return (element instanceof angular.element) ? element[0] : element; +} + +function applyGeneratedPreparationClasses(element, event, options) { + var classes = ''; + if (event) { + classes = pendClasses(event, EVENT_CLASS_PREFIX, true); + } + if (options.addClass) { + classes = concatWithSpace(classes, pendClasses(options.addClass, ADD_CLASS_SUFFIX)); + } + if (options.removeClass) { + classes = concatWithSpace(classes, pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX)); + } + if (classes.length) { + options.preparationClasses = classes; + element.addClass(classes); + } +} + +function clearGeneratedClasses(element, options) { + if (options.preparationClasses) { + element.removeClass(options.preparationClasses); + options.preparationClasses = null; + } + if (options.activeClasses) { + element.removeClass(options.activeClasses); + options.activeClasses = null; + } +} + +function blockTransitions(node, duration) { + // we use a negative delay value since it performs blocking + // yet it doesn't kill any existing transitions running on the + // same element which makes this safe for class-based animations + var value = duration ? '-' + duration + 's' : ''; + applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]); + return [TRANSITION_DELAY_PROP, value]; +} + +function blockKeyframeAnimations(node, applyBlock) { + var value = applyBlock ? 'paused' : ''; + var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY; + applyInlineStyle(node, [key, value]); + return [key, value]; +} + +function applyInlineStyle(node, styleTuple) { + var prop = styleTuple[0]; + var value = styleTuple[1]; + node.style[prop] = value; +} + +function concatWithSpace(a,b) { + if (!a) return b; + if (!b) return a; + return a + ' ' + b; +} + +var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) { + var queue, cancelFn; + + function scheduler(tasks) { + // we make a copy since RAFScheduler mutates the state + // of the passed in array variable and this would be difficult + // to track down on the outside code + queue = queue.concat(tasks); + nextTick(); + } + + queue = scheduler.queue = []; + + /* waitUntilQuiet does two things: + * 1. It will run the FINAL `fn` value only when an uncancelled RAF has passed through + * 2. It will delay the next wave of tasks from running until the quiet `fn` has run. + * + * The motivation here is that animation code can request more time from the scheduler + * before the next wave runs. This allows for certain DOM properties such as classes to + * be resolved in time for the next animation to run. + */ + scheduler.waitUntilQuiet = function(fn) { + if (cancelFn) cancelFn(); + + cancelFn = $$rAF(function() { + cancelFn = null; + fn(); + nextTick(); + }); + }; + + return scheduler; + + function nextTick() { + if (!queue.length) return; + + var items = queue.shift(); + for (var i = 0; i < items.length; i++) { + items[i](); + } + + if (!cancelFn) { + $$rAF(function() { + if (!cancelFn) nextTick(); + }); + } + } +}]; + +var $$AnimateChildrenDirective = [function() { + return function(scope, element, attrs) { + var val = attrs.ngAnimateChildren; + if (angular.isString(val) && val.length === 0) { //empty attribute + element.data(NG_ANIMATE_CHILDREN_DATA, true); + } else { + attrs.$observe('ngAnimateChildren', function(value) { + value = value === 'on' || value === 'true'; + element.data(NG_ANIMATE_CHILDREN_DATA, value); + }); + } + }; +}]; + +var ANIMATE_TIMER_KEY = '$$animateCss'; + +/** + * @ngdoc service + * @name $animateCss + * @kind object + * + * @description + * The `$animateCss` service is a useful utility to trigger customized CSS-based transitions/keyframes + * from a JavaScript-based animation or directly from a directive. The purpose of `$animateCss` is NOT + * to side-step how `$animate` and ngAnimate work, but the goal is to allow pre-existing animations or + * directives to create more complex animations that can be purely driven using CSS code. + * + * Note that only browsers that support CSS transitions and/or keyframe animations are capable of + * rendering animations triggered via `$animateCss` (bad news for IE9 and lower). + * + * ## Usage + * Once again, `$animateCss` is designed to be used inside of a registered JavaScript animation that + * is powered by ngAnimate. It is possible to use `$animateCss` directly inside of a directive, however, + * any automatic control over cancelling animations and/or preventing animations from being run on + * child elements will not be handled by Angular. For this to work as expected, please use `$animate` to + * trigger the animation and then setup a JavaScript animation that injects `$animateCss` to trigger + * the CSS animation. + * + * The example below shows how we can create a folding animation on an element using `ng-if`: + * + * ```html + * + *
    + * This element will go BOOM + *
    + * + * ``` + * + * Now we create the **JavaScript animation** that will trigger the CSS transition: + * + * ```js + * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) { + * return { + * enter: function(element, doneFn) { + * var height = element[0].offsetHeight; + * return $animateCss(element, { + * from: { height:'0px' }, + * to: { height:height + 'px' }, + * duration: 1 // one second + * }); + * } + * } + * }]); + * ``` + * + * ## More Advanced Uses + * + * `$animateCss` is the underlying code that ngAnimate uses to power **CSS-based animations** behind the scenes. Therefore CSS hooks + * like `.ng-EVENT`, `.ng-EVENT-active`, `.ng-EVENT-stagger` are all features that can be triggered using `$animateCss` via JavaScript code. + * + * This also means that just about any combination of adding classes, removing classes, setting styles, dynamically setting a keyframe animation, + * applying a hardcoded duration or delay value, changing the animation easing or applying a stagger animation are all options that work with + * `$animateCss`. The service itself is smart enough to figure out the combination of options and examine the element styling properties in order + * to provide a working animation that will run in CSS. + * + * The example below showcases a more advanced version of the `.fold-animation` from the example above: + * + * ```js + * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) { + * return { + * enter: function(element, doneFn) { + * var height = element[0].offsetHeight; + * return $animateCss(element, { + * addClass: 'red large-text pulse-twice', + * easing: 'ease-out', + * from: { height:'0px' }, + * to: { height:height + 'px' }, + * duration: 1 // one second + * }); + * } + * } + * }]); + * ``` + * + * Since we're adding/removing CSS classes then the CSS transition will also pick those up: + * + * ```css + * /* since a hardcoded duration value of 1 was provided in the JavaScript animation code, + * the CSS classes below will be transitioned despite them being defined as regular CSS classes */ + * .red { background:red; } + * .large-text { font-size:20px; } + * + * /* we can also use a keyframe animation and $animateCss will make it work alongside the transition */ + * .pulse-twice { + * animation: 0.5s pulse linear 2; + * -webkit-animation: 0.5s pulse linear 2; + * } + * + * @keyframes pulse { + * from { transform: scale(0.5); } + * to { transform: scale(1.5); } + * } + * + * @-webkit-keyframes pulse { + * from { -webkit-transform: scale(0.5); } + * to { -webkit-transform: scale(1.5); } + * } + * ``` + * + * Given this complex combination of CSS classes, styles and options, `$animateCss` will figure everything out and make the animation happen. + * + * ## How the Options are handled + * + * `$animateCss` is very versatile and intelligent when it comes to figuring out what configurations to apply to the element to ensure the animation + * works with the options provided. Say for example we were adding a class that contained a keyframe value and we wanted to also animate some inline + * styles using the `from` and `to` properties. + * + * ```js + * var animator = $animateCss(element, { + * from: { background:'red' }, + * to: { background:'blue' } + * }); + * animator.start(); + * ``` + * + * ```css + * .rotating-animation { + * animation:0.5s rotate linear; + * -webkit-animation:0.5s rotate linear; + * } + * + * @keyframes rotate { + * from { transform: rotate(0deg); } + * to { transform: rotate(360deg); } + * } + * + * @-webkit-keyframes rotate { + * from { -webkit-transform: rotate(0deg); } + * to { -webkit-transform: rotate(360deg); } + * } + * ``` + * + * The missing pieces here are that we do not have a transition set (within the CSS code nor within the `$animateCss` options) and the duration of the animation is + * going to be detected from what the keyframe styles on the CSS class are. In this event, `$animateCss` will automatically create an inline transition + * style matching the duration detected from the keyframe style (which is present in the CSS class that is being added) and then prepare both the transition + * and keyframe animations to run in parallel on the element. Then when the animation is underway the provided `from` and `to` CSS styles will be applied + * and spread across the transition and keyframe animation. + * + * ## What is returned + * + * `$animateCss` works in two stages: a preparation phase and an animation phase. Therefore when `$animateCss` is first called it will NOT actually + * start the animation. All that is going on here is that the element is being prepared for the animation (which means that the generated CSS classes are + * added and removed on the element). Once `$animateCss` is called it will return an object with the following properties: + * + * ```js + * var animator = $animateCss(element, { ... }); + * ``` + * + * Now what do the contents of our `animator` variable look like: + * + * ```js + * { + * // starts the animation + * start: Function, + * + * // ends (aborts) the animation + * end: Function + * } + * ``` + * + * To actually start the animation we need to run `animation.start()` which will then return a promise that we can hook into to detect when the animation ends. + * If we choose not to run the animation then we MUST run `animation.end()` to perform a cleanup on the element (since some CSS classes and stlyes may have been + * applied to the element during the preparation phase). Note that all other properties such as duration, delay, transitions and keyframes are just properties + * and that changing them will not reconfigure the parameters of the animation. + * + * ### runner.done() vs runner.then() + * It is documented that `animation.start()` will return a promise object and this is true, however, there is also an additional method available on the + * runner called `.done(callbackFn)`. The done method works the same as `.finally(callbackFn)`, however, it does **not trigger a digest to occur**. + * Therefore, for performance reasons, it's always best to use `runner.done(callback)` instead of `runner.then()`, `runner.catch()` or `runner.finally()` + * unless you really need a digest to kick off afterwards. + * + * Keep in mind that, to make this easier, ngAnimate has tweaked the JS animations API to recognize when a runner instance is returned from $animateCss + * (so there is no need to call `runner.done(doneFn)` inside of your JavaScript animation code). + * Check the {@link ngAnimate.$animateCss#usage animation code above} to see how this works. + * + * @param {DOMElement} element the element that will be animated + * @param {object} options the animation-related options that will be applied during the animation + * + * * `event` - The DOM event (e.g. enter, leave, move). When used, a generated CSS class of `ng-EVENT` and `ng-EVENT-active` will be applied + * to the element during the animation. Multiple events can be provided when spaces are used as a separator. (Note that this will not perform any DOM operation.) + * * `structural` - Indicates that the `ng-` prefix will be added to the event class. Setting to `false` or omitting will turn `ng-EVENT` and + * `ng-EVENT-active` in `EVENT` and `EVENT-active`. Unused if `event` is omitted. + * * `easing` - The CSS easing value that will be applied to the transition or keyframe animation (or both). + * * `transitionStyle` - The raw CSS transition style that will be used (e.g. `1s linear all`). + * * `keyframeStyle` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`). + * * `from` - The starting CSS styles (a key/value object) that will be applied at the start of the animation. + * * `to` - The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition. + * * `addClass` - A space separated list of CSS classes that will be added to the element and spread across the animation. + * * `removeClass` - A space separated list of CSS classes that will be removed from the element and spread across the animation. + * * `duration` - A number value representing the total duration of the transition and/or keyframe (note that a value of 1 is 1000ms). If a value of `0` + * is provided then the animation will be skipped entirely. + * * `delay` - A number value representing the total delay of the transition and/or keyframe (note that a value of 1 is 1000ms). If a value of `true` is + * used then whatever delay value is detected from the CSS classes will be mirrored on the elements styles (e.g. by setting delay true then the style value + * of the element will be `transition-delay: DETECTED_VALUE`). Using `true` is useful when you want the CSS classes and inline styles to all share the same + * CSS delay value. + * * `stagger` - A numeric time value representing the delay between successively animated elements + * ({@link ngAnimate#css-staggering-animations Click here to learn how CSS-based staggering works in ngAnimate.}) + * * `staggerIndex` - The numeric index representing the stagger item (e.g. a value of 5 is equal to the sixth item in the stagger; therefore when a + * * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`) + * * `applyClassesEarly` - Whether or not the classes being added or removed will be used when detecting the animation. This is set by `$animate` when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. (Note that this will prevent any transitions from occuring on the classes being added and removed.) + * * `cleanupStyles` - Whether or not the provided `from` and `to` styles will be removed once + * the animation is closed. This is useful for when the styles are used purely for the sake of + * the animation and do not have a lasting visual effect on the element (e.g. a colapse and open animation). + * By default this value is set to `false`. + * + * @return {object} an object with start and end methods and details about the animation. + * + * * `start` - The method to start the animation. This will return a `Promise` when called. + * * `end` - This method will cancel the animation and remove all applied CSS classes and styles. + */ +var ONE_SECOND = 1000; +var BASE_TEN = 10; + +var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3; +var CLOSING_TIME_BUFFER = 1.5; + +var DETECT_CSS_PROPERTIES = { + transitionDuration: TRANSITION_DURATION_PROP, + transitionDelay: TRANSITION_DELAY_PROP, + transitionProperty: TRANSITION_PROP + PROPERTY_KEY, + animationDuration: ANIMATION_DURATION_PROP, + animationDelay: ANIMATION_DELAY_PROP, + animationIterationCount: ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY +}; + +var DETECT_STAGGER_CSS_PROPERTIES = { + transitionDuration: TRANSITION_DURATION_PROP, + transitionDelay: TRANSITION_DELAY_PROP, + animationDuration: ANIMATION_DURATION_PROP, + animationDelay: ANIMATION_DELAY_PROP +}; + +function getCssKeyframeDurationStyle(duration) { + return [ANIMATION_DURATION_PROP, duration + 's']; +} + +function getCssDelayStyle(delay, isKeyframeAnimation) { + var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP; + return [prop, delay + 's']; +} + +function computeCssStyles($window, element, properties) { + var styles = Object.create(null); + var detectedStyles = $window.getComputedStyle(element) || {}; + forEach(properties, function(formalStyleName, actualStyleName) { + var val = detectedStyles[formalStyleName]; + if (val) { + var c = val.charAt(0); + + // only numerical-based values have a negative sign or digit as the first value + if (c === '-' || c === '+' || c >= 0) { + val = parseMaxTime(val); + } + + // by setting this to null in the event that the delay is not set or is set directly as 0 + // then we can still allow for zegative values to be used later on and not mistake this + // value for being greater than any other negative value. + if (val === 0) { + val = null; + } + styles[actualStyleName] = val; + } + }); + + return styles; +} + +function parseMaxTime(str) { + var maxValue = 0; + var values = str.split(/\s*,\s*/); + forEach(values, function(value) { + // it's always safe to consider only second values and omit `ms` values since + // getComputedStyle will always handle the conversion for us + if (value.charAt(value.length - 1) == 's') { + value = value.substring(0, value.length - 1); + } + value = parseFloat(value) || 0; + maxValue = maxValue ? Math.max(value, maxValue) : value; + }); + return maxValue; +} + +function truthyTimingValue(val) { + return val === 0 || val != null; +} + +function getCssTransitionDurationStyle(duration, applyOnlyDuration) { + var style = TRANSITION_PROP; + var value = duration + 's'; + if (applyOnlyDuration) { + style += DURATION_KEY; + } else { + value += ' linear all'; + } + return [style, value]; +} + +function createLocalCacheLookup() { + var cache = Object.create(null); + return { + flush: function() { + cache = Object.create(null); + }, + + count: function(key) { + var entry = cache[key]; + return entry ? entry.total : 0; + }, + + get: function(key) { + var entry = cache[key]; + return entry && entry.value; + }, + + put: function(key, value) { + if (!cache[key]) { + cache[key] = { total: 1, value: value }; + } else { + cache[key].total++; + } + } + }; +} + +// we do not reassign an already present style value since +// if we detect the style property value again we may be +// detecting styles that were added via the `from` styles. +// We make use of `isDefined` here since an empty string +// or null value (which is what getPropertyValue will return +// for a non-existing style) will still be marked as a valid +// value for the style (a falsy value implies that the style +// is to be removed at the end of the animation). If we had a simple +// "OR" statement then it would not be enough to catch that. +function registerRestorableStyles(backup, node, properties) { + forEach(properties, function(prop) { + backup[prop] = isDefined(backup[prop]) + ? backup[prop] + : node.style.getPropertyValue(prop); + }); +} + +var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { + var gcsLookup = createLocalCacheLookup(); + var gcsStaggerLookup = createLocalCacheLookup(); + + this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout', + '$$forceReflow', '$sniffer', '$$rAFScheduler', '$animate', + function($window, $$jqLite, $$AnimateRunner, $timeout, + $$forceReflow, $sniffer, $$rAFScheduler, $animate) { + + var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); + + var parentCounter = 0; + function gcsHashFn(node, extraClasses) { + var KEY = "$$ngAnimateParentKey"; + var parentNode = node.parentNode; + var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter); + return parentID + '-' + node.getAttribute('class') + '-' + extraClasses; + } + + function computeCachedCssStyles(node, className, cacheKey, properties) { + var timings = gcsLookup.get(cacheKey); + + if (!timings) { + timings = computeCssStyles($window, node, properties); + if (timings.animationIterationCount === 'infinite') { + timings.animationIterationCount = 1; + } + } + + // we keep putting this in multiple times even though the value and the cacheKey are the same + // because we're keeping an interal tally of how many duplicate animations are detected. + gcsLookup.put(cacheKey, timings); + return timings; + } + + function computeCachedCssStaggerStyles(node, className, cacheKey, properties) { + var stagger; + + // if we have one or more existing matches of matching elements + // containing the same parent + CSS styles (which is how cacheKey works) + // then staggering is possible + if (gcsLookup.count(cacheKey) > 0) { + stagger = gcsStaggerLookup.get(cacheKey); + + if (!stagger) { + var staggerClassName = pendClasses(className, '-stagger'); + + $$jqLite.addClass(node, staggerClassName); + + stagger = computeCssStyles($window, node, properties); + + // force the conversion of a null value to zero incase not set + stagger.animationDuration = Math.max(stagger.animationDuration, 0); + stagger.transitionDuration = Math.max(stagger.transitionDuration, 0); + + $$jqLite.removeClass(node, staggerClassName); + + gcsStaggerLookup.put(cacheKey, stagger); + } + } + + return stagger || {}; + } + + var cancelLastRAFRequest; + var rafWaitQueue = []; + function waitUntilQuiet(callback) { + rafWaitQueue.push(callback); + $$rAFScheduler.waitUntilQuiet(function() { + gcsLookup.flush(); + gcsStaggerLookup.flush(); + + // DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable. + // PLEASE EXAMINE THE `$$forceReflow` service to understand why. + var pageWidth = $$forceReflow(); + + // we use a for loop to ensure that if the queue is changed + // during this looping then it will consider new requests + for (var i = 0; i < rafWaitQueue.length; i++) { + rafWaitQueue[i](pageWidth); + } + rafWaitQueue.length = 0; + }); + } + + function computeTimings(node, className, cacheKey) { + var timings = computeCachedCssStyles(node, className, cacheKey, DETECT_CSS_PROPERTIES); + var aD = timings.animationDelay; + var tD = timings.transitionDelay; + timings.maxDelay = aD && tD + ? Math.max(aD, tD) + : (aD || tD); + timings.maxDuration = Math.max( + timings.animationDuration * timings.animationIterationCount, + timings.transitionDuration); + + return timings; + } + + return function init(element, options) { + var restoreStyles = {}; + var node = getDomNode(element); + if (!node + || !node.parentNode + || !$animate.enabled()) { + return closeAndReturnNoopAnimator(); + } + + options = prepareAnimationOptions(options); + + var temporaryStyles = []; + var classes = element.attr('class'); + var styles = packageStyles(options); + var animationClosed; + var animationPaused; + var animationCompleted; + var runner; + var runnerHost; + var maxDelay; + var maxDelayTime; + var maxDuration; + var maxDurationTime; + + if (options.duration === 0 || (!$sniffer.animations && !$sniffer.transitions)) { + return closeAndReturnNoopAnimator(); + } + + var method = options.event && isArray(options.event) + ? options.event.join(' ') + : options.event; + + var isStructural = method && options.structural; + var structuralClassName = ''; + var addRemoveClassName = ''; + + if (isStructural) { + structuralClassName = pendClasses(method, EVENT_CLASS_PREFIX, true); + } else if (method) { + structuralClassName = method; + } + + if (options.addClass) { + addRemoveClassName += pendClasses(options.addClass, ADD_CLASS_SUFFIX); + } + + if (options.removeClass) { + if (addRemoveClassName.length) { + addRemoveClassName += ' '; + } + addRemoveClassName += pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX); + } + + // there may be a situation where a structural animation is combined together + // with CSS classes that need to resolve before the animation is computed. + // However this means that there is no explicit CSS code to block the animation + // from happening (by setting 0s none in the class name). If this is the case + // we need to apply the classes before the first rAF so we know to continue if + // there actually is a detected transition or keyframe animation + if (options.applyClassesEarly && addRemoveClassName.length) { + applyAnimationClasses(element, options); + } + + var preparationClasses = [structuralClassName, addRemoveClassName].join(' ').trim(); + var fullClassName = classes + ' ' + preparationClasses; + var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX); + var hasToStyles = styles.to && Object.keys(styles.to).length > 0; + var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0; + + // there is no way we can trigger an animation if no styles and + // no classes are being applied which would then trigger a transition, + // unless there a is raw keyframe value that is applied to the element. + if (!containsKeyframeAnimation + && !hasToStyles + && !preparationClasses) { + return closeAndReturnNoopAnimator(); + } + + var cacheKey, stagger; + if (options.stagger > 0) { + var staggerVal = parseFloat(options.stagger); + stagger = { + transitionDelay: staggerVal, + animationDelay: staggerVal, + transitionDuration: 0, + animationDuration: 0 + }; + } else { + cacheKey = gcsHashFn(node, fullClassName); + stagger = computeCachedCssStaggerStyles(node, preparationClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES); + } + + if (!options.$$skipPreparationClasses) { + $$jqLite.addClass(element, preparationClasses); + } + + var applyOnlyDuration; + + if (options.transitionStyle) { + var transitionStyle = [TRANSITION_PROP, options.transitionStyle]; + applyInlineStyle(node, transitionStyle); + temporaryStyles.push(transitionStyle); + } + + if (options.duration >= 0) { + applyOnlyDuration = node.style[TRANSITION_PROP].length > 0; + var durationStyle = getCssTransitionDurationStyle(options.duration, applyOnlyDuration); + + // we set the duration so that it will be picked up by getComputedStyle later + applyInlineStyle(node, durationStyle); + temporaryStyles.push(durationStyle); + } + + if (options.keyframeStyle) { + var keyframeStyle = [ANIMATION_PROP, options.keyframeStyle]; + applyInlineStyle(node, keyframeStyle); + temporaryStyles.push(keyframeStyle); + } + + var itemIndex = stagger + ? options.staggerIndex >= 0 + ? options.staggerIndex + : gcsLookup.count(cacheKey) + : 0; + + var isFirst = itemIndex === 0; + + // this is a pre-emptive way of forcing the setup classes to be added and applied INSTANTLY + // without causing any combination of transitions to kick in. By adding a negative delay value + // it forces the setup class' transition to end immediately. We later then remove the negative + // transition delay to allow for the transition to naturally do it's thing. The beauty here is + // that if there is no transition defined then nothing will happen and this will also allow + // other transitions to be stacked on top of each other without any chopping them out. + if (isFirst && !options.skipBlocking) { + blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE); + } + + var timings = computeTimings(node, fullClassName, cacheKey); + var relativeDelay = timings.maxDelay; + maxDelay = Math.max(relativeDelay, 0); + maxDuration = timings.maxDuration; + + var flags = {}; + flags.hasTransitions = timings.transitionDuration > 0; + flags.hasAnimations = timings.animationDuration > 0; + flags.hasTransitionAll = flags.hasTransitions && timings.transitionProperty == 'all'; + flags.applyTransitionDuration = hasToStyles && ( + (flags.hasTransitions && !flags.hasTransitionAll) + || (flags.hasAnimations && !flags.hasTransitions)); + flags.applyAnimationDuration = options.duration && flags.hasAnimations; + flags.applyTransitionDelay = truthyTimingValue(options.delay) && (flags.applyTransitionDuration || flags.hasTransitions); + flags.applyAnimationDelay = truthyTimingValue(options.delay) && flags.hasAnimations; + flags.recalculateTimingStyles = addRemoveClassName.length > 0; + + if (flags.applyTransitionDuration || flags.applyAnimationDuration) { + maxDuration = options.duration ? parseFloat(options.duration) : maxDuration; + + if (flags.applyTransitionDuration) { + flags.hasTransitions = true; + timings.transitionDuration = maxDuration; + applyOnlyDuration = node.style[TRANSITION_PROP + PROPERTY_KEY].length > 0; + temporaryStyles.push(getCssTransitionDurationStyle(maxDuration, applyOnlyDuration)); + } + + if (flags.applyAnimationDuration) { + flags.hasAnimations = true; + timings.animationDuration = maxDuration; + temporaryStyles.push(getCssKeyframeDurationStyle(maxDuration)); + } + } + + if (maxDuration === 0 && !flags.recalculateTimingStyles) { + return closeAndReturnNoopAnimator(); + } + + if (options.delay != null) { + var delayStyle = parseFloat(options.delay); + + if (flags.applyTransitionDelay) { + temporaryStyles.push(getCssDelayStyle(delayStyle)); + } + + if (flags.applyAnimationDelay) { + temporaryStyles.push(getCssDelayStyle(delayStyle, true)); + } + } + + // we need to recalculate the delay value since we used a pre-emptive negative + // delay value and the delay value is required for the final event checking. This + // property will ensure that this will happen after the RAF phase has passed. + if (options.duration == null && timings.transitionDuration > 0) { + flags.recalculateTimingStyles = flags.recalculateTimingStyles || isFirst; + } + + maxDelayTime = maxDelay * ONE_SECOND; + maxDurationTime = maxDuration * ONE_SECOND; + if (!options.skipBlocking) { + flags.blockTransition = timings.transitionDuration > 0; + flags.blockKeyframeAnimation = timings.animationDuration > 0 && + stagger.animationDelay > 0 && + stagger.animationDuration === 0; + } + + if (options.from) { + if (options.cleanupStyles) { + registerRestorableStyles(restoreStyles, node, Object.keys(options.from)); + } + applyAnimationFromStyles(element, options); + } + + if (flags.blockTransition || flags.blockKeyframeAnimation) { + applyBlocking(maxDuration); + } else if (!options.skipBlocking) { + blockTransitions(node, false); + } + + // TODO(matsko): for 1.5 change this code to have an animator object for better debugging + return { + $$willAnimate: true, + end: endFn, + start: function() { + if (animationClosed) return; + + runnerHost = { + end: endFn, + cancel: cancelFn, + resume: null, //this will be set during the start() phase + pause: null + }; + + runner = new $$AnimateRunner(runnerHost); + + waitUntilQuiet(start); + + // we don't have access to pause/resume the animation + // since it hasn't run yet. AnimateRunner will therefore + // set noop functions for resume and pause and they will + // later be overridden once the animation is triggered + return runner; + } + }; + + function endFn() { + close(); + } + + function cancelFn() { + close(true); + } + + function close(rejected) { // jshint ignore:line + // if the promise has been called already then we shouldn't close + // the animation again + if (animationClosed || (animationCompleted && animationPaused)) return; + animationClosed = true; + animationPaused = false; + + if (!options.$$skipPreparationClasses) { + $$jqLite.removeClass(element, preparationClasses); + } + $$jqLite.removeClass(element, activeClasses); + + blockKeyframeAnimations(node, false); + blockTransitions(node, false); + + forEach(temporaryStyles, function(entry) { + // There is only one way to remove inline style properties entirely from elements. + // By using `removeProperty` this works, but we need to convert camel-cased CSS + // styles down to hyphenated values. + node.style[entry[0]] = ''; + }); + + applyAnimationClasses(element, options); + applyAnimationStyles(element, options); + + if (Object.keys(restoreStyles).length) { + forEach(restoreStyles, function(value, prop) { + value ? node.style.setProperty(prop, value) + : node.style.removeProperty(prop); + }); + } + + // the reason why we have this option is to allow a synchronous closing callback + // that is fired as SOON as the animation ends (when the CSS is removed) or if + // the animation never takes off at all. A good example is a leave animation since + // the element must be removed just after the animation is over or else the element + // will appear on screen for one animation frame causing an overbearing flicker. + if (options.onDone) { + options.onDone(); + } + + // if the preparation function fails then the promise is not setup + if (runner) { + runner.complete(!rejected); + } + } + + function applyBlocking(duration) { + if (flags.blockTransition) { + blockTransitions(node, duration); + } + + if (flags.blockKeyframeAnimation) { + blockKeyframeAnimations(node, !!duration); + } + } + + function closeAndReturnNoopAnimator() { + runner = new $$AnimateRunner({ + end: endFn, + cancel: cancelFn + }); + + // should flush the cache animation + waitUntilQuiet(noop); + close(); + + return { + $$willAnimate: false, + start: function() { + return runner; + }, + end: endFn + }; + } + + function start() { + if (animationClosed) return; + if (!node.parentNode) { + close(); + return; + } + + var startTime, events = []; + + // even though we only pause keyframe animations here the pause flag + // will still happen when transitions are used. Only the transition will + // not be paused since that is not possible. If the animation ends when + // paused then it will not complete until unpaused or cancelled. + var playPause = function(playAnimation) { + if (!animationCompleted) { + animationPaused = !playAnimation; + if (timings.animationDuration) { + var value = blockKeyframeAnimations(node, animationPaused); + animationPaused + ? temporaryStyles.push(value) + : removeFromArray(temporaryStyles, value); + } + } else if (animationPaused && playAnimation) { + animationPaused = false; + close(); + } + }; + + // checking the stagger duration prevents an accidently cascade of the CSS delay style + // being inherited from the parent. If the transition duration is zero then we can safely + // rely that the delay value is an intential stagger delay style. + var maxStagger = itemIndex > 0 + && ((timings.transitionDuration && stagger.transitionDuration === 0) || + (timings.animationDuration && stagger.animationDuration === 0)) + && Math.max(stagger.animationDelay, stagger.transitionDelay); + if (maxStagger) { + $timeout(triggerAnimationStart, + Math.floor(maxStagger * itemIndex * ONE_SECOND), + false); + } else { + triggerAnimationStart(); + } + + // this will decorate the existing promise runner with pause/resume methods + runnerHost.resume = function() { + playPause(true); + }; + + runnerHost.pause = function() { + playPause(false); + }; + + function triggerAnimationStart() { + // just incase a stagger animation kicks in when the animation + // itself was cancelled entirely + if (animationClosed) return; + + applyBlocking(false); + + forEach(temporaryStyles, function(entry) { + var key = entry[0]; + var value = entry[1]; + node.style[key] = value; + }); + + applyAnimationClasses(element, options); + $$jqLite.addClass(element, activeClasses); + + if (flags.recalculateTimingStyles) { + fullClassName = node.className + ' ' + preparationClasses; + cacheKey = gcsHashFn(node, fullClassName); + + timings = computeTimings(node, fullClassName, cacheKey); + relativeDelay = timings.maxDelay; + maxDelay = Math.max(relativeDelay, 0); + maxDuration = timings.maxDuration; + + if (maxDuration === 0) { + close(); + return; + } + + flags.hasTransitions = timings.transitionDuration > 0; + flags.hasAnimations = timings.animationDuration > 0; + } + + if (flags.applyAnimationDelay) { + relativeDelay = typeof options.delay !== "boolean" && truthyTimingValue(options.delay) + ? parseFloat(options.delay) + : relativeDelay; + + maxDelay = Math.max(relativeDelay, 0); + timings.animationDelay = relativeDelay; + delayStyle = getCssDelayStyle(relativeDelay, true); + temporaryStyles.push(delayStyle); + node.style[delayStyle[0]] = delayStyle[1]; + } + + maxDelayTime = maxDelay * ONE_SECOND; + maxDurationTime = maxDuration * ONE_SECOND; + + if (options.easing) { + var easeProp, easeVal = options.easing; + if (flags.hasTransitions) { + easeProp = TRANSITION_PROP + TIMING_KEY; + temporaryStyles.push([easeProp, easeVal]); + node.style[easeProp] = easeVal; + } + if (flags.hasAnimations) { + easeProp = ANIMATION_PROP + TIMING_KEY; + temporaryStyles.push([easeProp, easeVal]); + node.style[easeProp] = easeVal; + } + } + + if (timings.transitionDuration) { + events.push(TRANSITIONEND_EVENT); + } + + if (timings.animationDuration) { + events.push(ANIMATIONEND_EVENT); + } + + startTime = Date.now(); + var timerTime = maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime; + var endTime = startTime + timerTime; + + var animationsData = element.data(ANIMATE_TIMER_KEY) || []; + var setupFallbackTimer = true; + if (animationsData.length) { + var currentTimerData = animationsData[0]; + setupFallbackTimer = endTime > currentTimerData.expectedEndTime; + if (setupFallbackTimer) { + $timeout.cancel(currentTimerData.timer); + } else { + animationsData.push(close); + } + } + + if (setupFallbackTimer) { + var timer = $timeout(onAnimationExpired, timerTime, false); + animationsData[0] = { + timer: timer, + expectedEndTime: endTime + }; + animationsData.push(close); + element.data(ANIMATE_TIMER_KEY, animationsData); + } + + element.on(events.join(' '), onAnimationProgress); + if (options.to) { + if (options.cleanupStyles) { + registerRestorableStyles(restoreStyles, node, Object.keys(options.to)); + } + applyAnimationToStyles(element, options); + } + } + + function onAnimationExpired() { + var animationsData = element.data(ANIMATE_TIMER_KEY); + + // this will be false in the event that the element was + // removed from the DOM (via a leave animation or something + // similar) + if (animationsData) { + for (var i = 1; i < animationsData.length; i++) { + animationsData[i](); + } + element.removeData(ANIMATE_TIMER_KEY); + } + } + + function onAnimationProgress(event) { + event.stopPropagation(); + var ev = event.originalEvent || event; + var timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now(); + + /* Firefox (or possibly just Gecko) likes to not round values up + * when a ms measurement is used for the animation */ + var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES)); + + /* $manualTimeStamp is a mocked timeStamp value which is set + * within browserTrigger(). This is only here so that tests can + * mock animations properly. Real events fallback to event.timeStamp, + * or, if they don't, then a timeStamp is automatically created for them. + * We're checking to see if the timeStamp surpasses the expected delay, + * but we're using elapsedTime instead of the timeStamp on the 2nd + * pre-condition since animations sometimes close off early */ + if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) { + // we set this flag to ensure that if the transition is paused then, when resumed, + // the animation will automatically close itself since transitions cannot be paused. + animationCompleted = true; + close(); + } + } + } + }; + }]; +}]; + +var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationProvider) { + $$animationProvider.drivers.push('$$animateCssDriver'); + + var NG_ANIMATE_SHIM_CLASS_NAME = 'ng-animate-shim'; + var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-anchor'; + + var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out'; + var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in'; + + function isDocumentFragment(node) { + return node.parentNode && node.parentNode.nodeType === 11; + } + + this.$get = ['$animateCss', '$rootScope', '$$AnimateRunner', '$rootElement', '$sniffer', '$$jqLite', '$document', + function($animateCss, $rootScope, $$AnimateRunner, $rootElement, $sniffer, $$jqLite, $document) { + + // only browsers that support these properties can render animations + if (!$sniffer.animations && !$sniffer.transitions) return noop; + + var bodyNode = $document[0].body; + var rootNode = getDomNode($rootElement); + + var rootBodyElement = jqLite( + // this is to avoid using something that exists outside of the body + // we also special case the doc fragement case because our unit test code + // appends the $rootElement to the body after the app has been bootstrapped + isDocumentFragment(rootNode) || bodyNode.contains(rootNode) ? rootNode : bodyNode + ); + + var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); + + return function initDriverFn(animationDetails) { + return animationDetails.from && animationDetails.to + ? prepareFromToAnchorAnimation(animationDetails.from, + animationDetails.to, + animationDetails.classes, + animationDetails.anchors) + : prepareRegularAnimation(animationDetails); + }; + + function filterCssClasses(classes) { + //remove all the `ng-` stuff + return classes.replace(/\bng-\S+\b/g, ''); + } + + function getUniqueValues(a, b) { + if (isString(a)) a = a.split(' '); + if (isString(b)) b = b.split(' '); + return a.filter(function(val) { + return b.indexOf(val) === -1; + }).join(' '); + } + + function prepareAnchoredAnimation(classes, outAnchor, inAnchor) { + var clone = jqLite(getDomNode(outAnchor).cloneNode(true)); + var startingClasses = filterCssClasses(getClassVal(clone)); + + outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME); + inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME); + + clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME); + + rootBodyElement.append(clone); + + var animatorIn, animatorOut = prepareOutAnimation(); + + // the user may not end up using the `out` animation and + // only making use of the `in` animation or vice-versa. + // In either case we should allow this and not assume the + // animation is over unless both animations are not used. + if (!animatorOut) { + animatorIn = prepareInAnimation(); + if (!animatorIn) { + return end(); + } + } + + var startingAnimator = animatorOut || animatorIn; + + return { + start: function() { + var runner; + + var currentAnimation = startingAnimator.start(); + currentAnimation.done(function() { + currentAnimation = null; + if (!animatorIn) { + animatorIn = prepareInAnimation(); + if (animatorIn) { + currentAnimation = animatorIn.start(); + currentAnimation.done(function() { + currentAnimation = null; + end(); + runner.complete(); + }); + return currentAnimation; + } + } + // in the event that there is no `in` animation + end(); + runner.complete(); + }); + + runner = new $$AnimateRunner({ + end: endFn, + cancel: endFn + }); + + return runner; + + function endFn() { + if (currentAnimation) { + currentAnimation.end(); + } + } + } + }; + + function calculateAnchorStyles(anchor) { + var styles = {}; + + var coords = getDomNode(anchor).getBoundingClientRect(); + + // we iterate directly since safari messes up and doesn't return + // all the keys for the coods object when iterated + forEach(['width','height','top','left'], function(key) { + var value = coords[key]; + switch (key) { + case 'top': + value += bodyNode.scrollTop; + break; + case 'left': + value += bodyNode.scrollLeft; + break; + } + styles[key] = Math.floor(value) + 'px'; + }); + return styles; + } + + function prepareOutAnimation() { + var animator = $animateCss(clone, { + addClass: NG_OUT_ANCHOR_CLASS_NAME, + delay: true, + from: calculateAnchorStyles(outAnchor) + }); + + // read the comment within `prepareRegularAnimation` to understand + // why this check is necessary + return animator.$$willAnimate ? animator : null; + } + + function getClassVal(element) { + return element.attr('class') || ''; + } + + function prepareInAnimation() { + var endingClasses = filterCssClasses(getClassVal(inAnchor)); + var toAdd = getUniqueValues(endingClasses, startingClasses); + var toRemove = getUniqueValues(startingClasses, endingClasses); + + var animator = $animateCss(clone, { + to: calculateAnchorStyles(inAnchor), + addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + toAdd, + removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + toRemove, + delay: true + }); + + // read the comment within `prepareRegularAnimation` to understand + // why this check is necessary + return animator.$$willAnimate ? animator : null; + } + + function end() { + clone.remove(); + outAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME); + inAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME); + } + } + + function prepareFromToAnchorAnimation(from, to, classes, anchors) { + var fromAnimation = prepareRegularAnimation(from, noop); + var toAnimation = prepareRegularAnimation(to, noop); + + var anchorAnimations = []; + forEach(anchors, function(anchor) { + var outElement = anchor['out']; + var inElement = anchor['in']; + var animator = prepareAnchoredAnimation(classes, outElement, inElement); + if (animator) { + anchorAnimations.push(animator); + } + }); + + // no point in doing anything when there are no elements to animate + if (!fromAnimation && !toAnimation && anchorAnimations.length === 0) return; + + return { + start: function() { + var animationRunners = []; + + if (fromAnimation) { + animationRunners.push(fromAnimation.start()); + } + + if (toAnimation) { + animationRunners.push(toAnimation.start()); + } + + forEach(anchorAnimations, function(animation) { + animationRunners.push(animation.start()); + }); + + var runner = new $$AnimateRunner({ + end: endFn, + cancel: endFn // CSS-driven animations cannot be cancelled, only ended + }); + + $$AnimateRunner.all(animationRunners, function(status) { + runner.complete(status); + }); + + return runner; + + function endFn() { + forEach(animationRunners, function(runner) { + runner.end(); + }); + } + } + }; + } + + function prepareRegularAnimation(animationDetails) { + var element = animationDetails.element; + var options = animationDetails.options || {}; + + if (animationDetails.structural) { + options.event = animationDetails.event; + options.structural = true; + options.applyClassesEarly = true; + + // we special case the leave animation since we want to ensure that + // the element is removed as soon as the animation is over. Otherwise + // a flicker might appear or the element may not be removed at all + if (animationDetails.event === 'leave') { + options.onDone = options.domOperation; + } + } + + // We assign the preparationClasses as the actual animation event since + // the internals of $animateCss will just suffix the event token values + // with `-active` to trigger the animation. + if (options.preparationClasses) { + options.event = concatWithSpace(options.event, options.preparationClasses); + } + + var animator = $animateCss(element, options); + + // the driver lookup code inside of $$animation attempts to spawn a + // driver one by one until a driver returns a.$$willAnimate animator object. + // $animateCss will always return an object, however, it will pass in + // a flag as a hint as to whether an animation was detected or not + return animator.$$willAnimate ? animator : null; + } + }]; +}]; + +// TODO(matsko): use caching here to speed things up for detection +// TODO(matsko): add documentation +// by the time... + +var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) { + this.$get = ['$injector', '$$AnimateRunner', '$$jqLite', + function($injector, $$AnimateRunner, $$jqLite) { + + var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); + // $animateJs(element, 'enter'); + return function(element, event, classes, options) { + // the `classes` argument is optional and if it is not used + // then the classes will be resolved from the element's className + // property as well as options.addClass/options.removeClass. + if (arguments.length === 3 && isObject(classes)) { + options = classes; + classes = null; + } + + options = prepareAnimationOptions(options); + if (!classes) { + classes = element.attr('class') || ''; + if (options.addClass) { + classes += ' ' + options.addClass; + } + if (options.removeClass) { + classes += ' ' + options.removeClass; + } + } + + var classesToAdd = options.addClass; + var classesToRemove = options.removeClass; + + // the lookupAnimations function returns a series of animation objects that are + // matched up with one or more of the CSS classes. These animation objects are + // defined via the module.animation factory function. If nothing is detected then + // we don't return anything which then makes $animation query the next driver. + var animations = lookupAnimations(classes); + var before, after; + if (animations.length) { + var afterFn, beforeFn; + if (event == 'leave') { + beforeFn = 'leave'; + afterFn = 'afterLeave'; // TODO(matsko): get rid of this + } else { + beforeFn = 'before' + event.charAt(0).toUpperCase() + event.substr(1); + afterFn = event; + } + + if (event !== 'enter' && event !== 'move') { + before = packageAnimations(element, event, options, animations, beforeFn); + } + after = packageAnimations(element, event, options, animations, afterFn); + } + + // no matching animations + if (!before && !after) return; + + function applyOptions() { + options.domOperation(); + applyAnimationClasses(element, options); + } + + return { + start: function() { + var closeActiveAnimations; + var chain = []; + + if (before) { + chain.push(function(fn) { + closeActiveAnimations = before(fn); + }); + } + + if (chain.length) { + chain.push(function(fn) { + applyOptions(); + fn(true); + }); + } else { + applyOptions(); + } + + if (after) { + chain.push(function(fn) { + closeActiveAnimations = after(fn); + }); + } + + var animationClosed = false; + var runner = new $$AnimateRunner({ + end: function() { + endAnimations(); + }, + cancel: function() { + endAnimations(true); + } + }); + + $$AnimateRunner.chain(chain, onComplete); + return runner; + + function onComplete(success) { + animationClosed = true; + applyOptions(); + applyAnimationStyles(element, options); + runner.complete(success); + } + + function endAnimations(cancelled) { + if (!animationClosed) { + (closeActiveAnimations || noop)(cancelled); + onComplete(cancelled); + } + } + } + }; + + function executeAnimationFn(fn, element, event, options, onDone) { + var args; + switch (event) { + case 'animate': + args = [element, options.from, options.to, onDone]; + break; + + case 'setClass': + args = [element, classesToAdd, classesToRemove, onDone]; + break; + + case 'addClass': + args = [element, classesToAdd, onDone]; + break; + + case 'removeClass': + args = [element, classesToRemove, onDone]; + break; + + default: + args = [element, onDone]; + break; + } + + args.push(options); + + var value = fn.apply(fn, args); + if (value) { + if (isFunction(value.start)) { + value = value.start(); + } + + if (value instanceof $$AnimateRunner) { + value.done(onDone); + } else if (isFunction(value)) { + // optional onEnd / onCancel callback + return value; + } + } + + return noop; + } + + function groupEventedAnimations(element, event, options, animations, fnName) { + var operations = []; + forEach(animations, function(ani) { + var animation = ani[fnName]; + if (!animation) return; + + // note that all of these animations will run in parallel + operations.push(function() { + var runner; + var endProgressCb; + + var resolved = false; + var onAnimationComplete = function(rejected) { + if (!resolved) { + resolved = true; + (endProgressCb || noop)(rejected); + runner.complete(!rejected); + } + }; + + runner = new $$AnimateRunner({ + end: function() { + onAnimationComplete(); + }, + cancel: function() { + onAnimationComplete(true); + } + }); + + endProgressCb = executeAnimationFn(animation, element, event, options, function(result) { + var cancelled = result === false; + onAnimationComplete(cancelled); + }); + + return runner; + }); + }); + + return operations; + } + + function packageAnimations(element, event, options, animations, fnName) { + var operations = groupEventedAnimations(element, event, options, animations, fnName); + if (operations.length === 0) { + var a,b; + if (fnName === 'beforeSetClass') { + a = groupEventedAnimations(element, 'removeClass', options, animations, 'beforeRemoveClass'); + b = groupEventedAnimations(element, 'addClass', options, animations, 'beforeAddClass'); + } else if (fnName === 'setClass') { + a = groupEventedAnimations(element, 'removeClass', options, animations, 'removeClass'); + b = groupEventedAnimations(element, 'addClass', options, animations, 'addClass'); + } + + if (a) { + operations = operations.concat(a); + } + if (b) { + operations = operations.concat(b); + } + } + + if (operations.length === 0) return; + + // TODO(matsko): add documentation + return function startAnimation(callback) { + var runners = []; + if (operations.length) { + forEach(operations, function(animateFn) { + runners.push(animateFn()); + }); + } + + runners.length ? $$AnimateRunner.all(runners, callback) : callback(); + + return function endFn(reject) { + forEach(runners, function(runner) { + reject ? runner.cancel() : runner.end(); + }); + }; + }; + } + }; + + function lookupAnimations(classes) { + classes = isArray(classes) ? classes : classes.split(' '); + var matches = [], flagMap = {}; + for (var i=0; i < classes.length; i++) { + var klass = classes[i], + animationFactory = $animateProvider.$$registeredAnimations[klass]; + if (animationFactory && !flagMap[klass]) { + matches.push($injector.get(animationFactory)); + flagMap[klass] = true; + } + } + return matches; + } + }]; +}]; + +var $$AnimateJsDriverProvider = ['$$animationProvider', function($$animationProvider) { + $$animationProvider.drivers.push('$$animateJsDriver'); + this.$get = ['$$animateJs', '$$AnimateRunner', function($$animateJs, $$AnimateRunner) { + return function initDriverFn(animationDetails) { + if (animationDetails.from && animationDetails.to) { + var fromAnimation = prepareAnimation(animationDetails.from); + var toAnimation = prepareAnimation(animationDetails.to); + if (!fromAnimation && !toAnimation) return; + + return { + start: function() { + var animationRunners = []; + + if (fromAnimation) { + animationRunners.push(fromAnimation.start()); + } + + if (toAnimation) { + animationRunners.push(toAnimation.start()); + } + + $$AnimateRunner.all(animationRunners, done); + + var runner = new $$AnimateRunner({ + end: endFnFactory(), + cancel: endFnFactory() + }); + + return runner; + + function endFnFactory() { + return function() { + forEach(animationRunners, function(runner) { + // at this point we cannot cancel animations for groups just yet. 1.5+ + runner.end(); + }); + }; + } + + function done(status) { + runner.complete(status); + } + } + }; + } else { + return prepareAnimation(animationDetails); + } + }; + + function prepareAnimation(animationDetails) { + // TODO(matsko): make sure to check for grouped animations and delegate down to normal animations + var element = animationDetails.element; + var event = animationDetails.event; + var options = animationDetails.options; + var classes = animationDetails.classes; + return $$animateJs(element, event, classes, options); + } + }]; +}]; + +var NG_ANIMATE_ATTR_NAME = 'data-ng-animate'; +var NG_ANIMATE_PIN_DATA = '$ngAnimatePin'; +var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { + var PRE_DIGEST_STATE = 1; + var RUNNING_STATE = 2; + + var rules = this.rules = { + skip: [], + cancel: [], + join: [] + }; + + function isAllowed(ruleType, element, currentAnimation, previousAnimation) { + return rules[ruleType].some(function(fn) { + return fn(element, currentAnimation, previousAnimation); + }); + } + + function hasAnimationClasses(options, and) { + options = options || {}; + var a = (options.addClass || '').length > 0; + var b = (options.removeClass || '').length > 0; + return and ? a && b : a || b; + } + + rules.join.push(function(element, newAnimation, currentAnimation) { + // if the new animation is class-based then we can just tack that on + return !newAnimation.structural && hasAnimationClasses(newAnimation.options); + }); + + rules.skip.push(function(element, newAnimation, currentAnimation) { + // there is no need to animate anything if no classes are being added and + // there is no structural animation that will be triggered + return !newAnimation.structural && !hasAnimationClasses(newAnimation.options); + }); + + rules.skip.push(function(element, newAnimation, currentAnimation) { + // why should we trigger a new structural animation if the element will + // be removed from the DOM anyway? + return currentAnimation.event == 'leave' && newAnimation.structural; + }); + + rules.skip.push(function(element, newAnimation, currentAnimation) { + // if there is an ongoing current animation then don't even bother running the class-based animation + return currentAnimation.structural && currentAnimation.state === RUNNING_STATE && !newAnimation.structural; + }); + + rules.cancel.push(function(element, newAnimation, currentAnimation) { + // there can never be two structural animations running at the same time + return currentAnimation.structural && newAnimation.structural; + }); + + rules.cancel.push(function(element, newAnimation, currentAnimation) { + // if the previous animation is already running, but the new animation will + // be triggered, but the new animation is structural + return currentAnimation.state === RUNNING_STATE && newAnimation.structural; + }); + + rules.cancel.push(function(element, newAnimation, currentAnimation) { + var nO = newAnimation.options; + var cO = currentAnimation.options; + + // if the exact same CSS class is added/removed then it's safe to cancel it + return (nO.addClass && nO.addClass === cO.removeClass) || (nO.removeClass && nO.removeClass === cO.addClass); + }); + + this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap', + '$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite', '$$forceReflow', + function($$rAF, $rootScope, $rootElement, $document, $$HashMap, + $$animation, $$AnimateRunner, $templateRequest, $$jqLite, $$forceReflow) { + + var activeAnimationsLookup = new $$HashMap(); + var disabledElementsLookup = new $$HashMap(); + var animationsEnabled = null; + + function postDigestTaskFactory() { + var postDigestCalled = false; + return function(fn) { + // we only issue a call to postDigest before + // it has first passed. This prevents any callbacks + // from not firing once the animation has completed + // since it will be out of the digest cycle. + if (postDigestCalled) { + fn(); + } else { + $rootScope.$$postDigest(function() { + postDigestCalled = true; + fn(); + }); + } + }; + } + + // Wait until all directive and route-related templates are downloaded and + // compiled. The $templateRequest.totalPendingRequests variable keeps track of + // all of the remote templates being currently downloaded. If there are no + // templates currently downloading then the watcher will still fire anyway. + var deregisterWatch = $rootScope.$watch( + function() { return $templateRequest.totalPendingRequests === 0; }, + function(isEmpty) { + if (!isEmpty) return; + deregisterWatch(); + + // Now that all templates have been downloaded, $animate will wait until + // the post digest queue is empty before enabling animations. By having two + // calls to $postDigest calls we can ensure that the flag is enabled at the + // very end of the post digest queue. Since all of the animations in $animate + // use $postDigest, it's important that the code below executes at the end. + // This basically means that the page is fully downloaded and compiled before + // any animations are triggered. + $rootScope.$$postDigest(function() { + $rootScope.$$postDigest(function() { + // we check for null directly in the event that the application already called + // .enabled() with whatever arguments that it provided it with + if (animationsEnabled === null) { + animationsEnabled = true; + } + }); + }); + } + ); + + var callbackRegistry = {}; + + // remember that the classNameFilter is set during the provider/config + // stage therefore we can optimize here and setup a helper function + var classNameFilter = $animateProvider.classNameFilter(); + var isAnimatableClassName = !classNameFilter + ? function() { return true; } + : function(className) { + return classNameFilter.test(className); + }; + + var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); + + function normalizeAnimationOptions(element, options) { + return mergeAnimationOptions(element, options, {}); + } + + function findCallbacks(parent, element, event) { + var targetNode = getDomNode(element); + var targetParentNode = getDomNode(parent); + + var matches = []; + var entries = callbackRegistry[event]; + if (entries) { + forEach(entries, function(entry) { + if (entry.node.contains(targetNode)) { + matches.push(entry.callback); + } else if (event === 'leave' && entry.node.contains(targetParentNode)) { + matches.push(entry.callback); + } + }); + } + + return matches; + } + + return { + on: function(event, container, callback) { + var node = extractElementNode(container); + callbackRegistry[event] = callbackRegistry[event] || []; + callbackRegistry[event].push({ + node: node, + callback: callback + }); + }, + + off: function(event, container, callback) { + var entries = callbackRegistry[event]; + if (!entries) return; + + callbackRegistry[event] = arguments.length === 1 + ? null + : filterFromRegistry(entries, container, callback); + + function filterFromRegistry(list, matchContainer, matchCallback) { + var containerNode = extractElementNode(matchContainer); + return list.filter(function(entry) { + var isMatch = entry.node === containerNode && + (!matchCallback || entry.callback === matchCallback); + return !isMatch; + }); + } + }, + + pin: function(element, parentElement) { + assertArg(isElement(element), 'element', 'not an element'); + assertArg(isElement(parentElement), 'parentElement', 'not an element'); + element.data(NG_ANIMATE_PIN_DATA, parentElement); + }, + + push: function(element, event, options, domOperation) { + options = options || {}; + options.domOperation = domOperation; + return queueAnimation(element, event, options); + }, + + // this method has four signatures: + // () - global getter + // (bool) - global setter + // (element) - element getter + // (element, bool) - element setter + enabled: function(element, bool) { + var argCount = arguments.length; + + if (argCount === 0) { + // () - Global getter + bool = !!animationsEnabled; + } else { + var hasElement = isElement(element); + + if (!hasElement) { + // (bool) - Global setter + bool = animationsEnabled = !!element; + } else { + var node = getDomNode(element); + var recordExists = disabledElementsLookup.get(node); + + if (argCount === 1) { + // (element) - Element getter + bool = !recordExists; + } else { + // (element, bool) - Element setter + bool = !!bool; + if (!bool) { + disabledElementsLookup.put(node, true); + } else if (recordExists) { + disabledElementsLookup.remove(node); + } + } + } + } + + return bool; + } + }; + + function queueAnimation(element, event, options) { + var node, parent; + element = stripCommentsFromElement(element); + if (element) { + node = getDomNode(element); + parent = element.parent(); + } + + options = prepareAnimationOptions(options); + + // we create a fake runner with a working promise. + // These methods will become available after the digest has passed + var runner = new $$AnimateRunner(); + + // this is used to trigger callbacks in postDigest mode + var runInNextPostDigestOrNow = postDigestTaskFactory(); + + if (isArray(options.addClass)) { + options.addClass = options.addClass.join(' '); + } + + if (options.addClass && !isString(options.addClass)) { + options.addClass = null; + } + + if (isArray(options.removeClass)) { + options.removeClass = options.removeClass.join(' '); + } + + if (options.removeClass && !isString(options.removeClass)) { + options.removeClass = null; + } + + if (options.from && !isObject(options.from)) { + options.from = null; + } + + if (options.to && !isObject(options.to)) { + options.to = null; + } + + // there are situations where a directive issues an animation for + // a jqLite wrapper that contains only comment nodes... If this + // happens then there is no way we can perform an animation + if (!node) { + close(); + return runner; + } + + var className = [node.className, options.addClass, options.removeClass].join(' '); + if (!isAnimatableClassName(className)) { + close(); + return runner; + } + + var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0; + + // this is a hard disable of all animations for the application or on + // the element itself, therefore there is no need to continue further + // past this point if not enabled + var skipAnimations = !animationsEnabled || disabledElementsLookup.get(node); + var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {}; + var hasExistingAnimation = !!existingAnimation.state; + + // there is no point in traversing the same collection of parent ancestors if a followup + // animation will be run on the same element that already did all that checking work + if (!skipAnimations && (!hasExistingAnimation || existingAnimation.state != PRE_DIGEST_STATE)) { + skipAnimations = !areAnimationsAllowed(element, parent, event); + } + + if (skipAnimations) { + close(); + return runner; + } + + if (isStructural) { + closeChildAnimations(element); + } + + var newAnimation = { + structural: isStructural, + element: element, + event: event, + close: close, + options: options, + runner: runner + }; + + if (hasExistingAnimation) { + var skipAnimationFlag = isAllowed('skip', element, newAnimation, existingAnimation); + if (skipAnimationFlag) { + if (existingAnimation.state === RUNNING_STATE) { + close(); + return runner; + } else { + mergeAnimationOptions(element, existingAnimation.options, options); + return existingAnimation.runner; + } + } + + var cancelAnimationFlag = isAllowed('cancel', element, newAnimation, existingAnimation); + if (cancelAnimationFlag) { + if (existingAnimation.state === RUNNING_STATE) { + // this will end the animation right away and it is safe + // to do so since the animation is already running and the + // runner callback code will run in async + existingAnimation.runner.end(); + } else if (existingAnimation.structural) { + // this means that the animation is queued into a digest, but + // hasn't started yet. Therefore it is safe to run the close + // method which will call the runner methods in async. + existingAnimation.close(); + } else { + // this will merge the new animation options into existing animation options + mergeAnimationOptions(element, existingAnimation.options, newAnimation.options); + return existingAnimation.runner; + } + } else { + // a joined animation means that this animation will take over the existing one + // so an example would involve a leave animation taking over an enter. Then when + // the postDigest kicks in the enter will be ignored. + var joinAnimationFlag = isAllowed('join', element, newAnimation, existingAnimation); + if (joinAnimationFlag) { + if (existingAnimation.state === RUNNING_STATE) { + normalizeAnimationOptions(element, options); + } else { + applyGeneratedPreparationClasses(element, isStructural ? event : null, options); + + event = newAnimation.event = existingAnimation.event; + options = mergeAnimationOptions(element, existingAnimation.options, newAnimation.options); + + //we return the same runner since only the option values of this animation will + //be fed into the `existingAnimation`. + return existingAnimation.runner; + } + } + } + } else { + // normalization in this case means that it removes redundant CSS classes that + // already exist (addClass) or do not exist (removeClass) on the element + normalizeAnimationOptions(element, options); + } + + // when the options are merged and cleaned up we may end up not having to do + // an animation at all, therefore we should check this before issuing a post + // digest callback. Structural animations will always run no matter what. + var isValidAnimation = newAnimation.structural; + if (!isValidAnimation) { + // animate (from/to) can be quickly checked first, otherwise we check if any classes are present + isValidAnimation = (newAnimation.event === 'animate' && Object.keys(newAnimation.options.to || {}).length > 0) + || hasAnimationClasses(newAnimation.options); + } + + if (!isValidAnimation) { + close(); + clearElementAnimationState(element); + return runner; + } + + // the counter keeps track of cancelled animations + var counter = (existingAnimation.counter || 0) + 1; + newAnimation.counter = counter; + + markElementAnimationState(element, PRE_DIGEST_STATE, newAnimation); + + $rootScope.$$postDigest(function() { + var animationDetails = activeAnimationsLookup.get(node); + var animationCancelled = !animationDetails; + animationDetails = animationDetails || {}; + + // if addClass/removeClass is called before something like enter then the + // registered parent element may not be present. The code below will ensure + // that a final value for parent element is obtained + var parentElement = element.parent() || []; + + // animate/structural/class-based animations all have requirements. Otherwise there + // is no point in performing an animation. The parent node must also be set. + var isValidAnimation = parentElement.length > 0 + && (animationDetails.event === 'animate' + || animationDetails.structural + || hasAnimationClasses(animationDetails.options)); + + // this means that the previous animation was cancelled + // even if the follow-up animation is the same event + if (animationCancelled || animationDetails.counter !== counter || !isValidAnimation) { + // if another animation did not take over then we need + // to make sure that the domOperation and options are + // handled accordingly + if (animationCancelled) { + applyAnimationClasses(element, options); + applyAnimationStyles(element, options); + } + + // if the event changed from something like enter to leave then we do + // it, otherwise if it's the same then the end result will be the same too + if (animationCancelled || (isStructural && animationDetails.event !== event)) { + options.domOperation(); + runner.end(); + } + + // in the event that the element animation was not cancelled or a follow-up animation + // isn't allowed to animate from here then we need to clear the state of the element + // so that any future animations won't read the expired animation data. + if (!isValidAnimation) { + clearElementAnimationState(element); + } + + return; + } + + // this combined multiple class to addClass / removeClass into a setClass event + // so long as a structural event did not take over the animation + event = !animationDetails.structural && hasAnimationClasses(animationDetails.options, true) + ? 'setClass' + : animationDetails.event; + + markElementAnimationState(element, RUNNING_STATE); + var realRunner = $$animation(element, event, animationDetails.options); + + realRunner.done(function(status) { + close(!status); + var animationDetails = activeAnimationsLookup.get(node); + if (animationDetails && animationDetails.counter === counter) { + clearElementAnimationState(getDomNode(element)); + } + notifyProgress(runner, event, 'close', {}); + }); + + // this will update the runner's flow-control events based on + // the `realRunner` object. + runner.setHost(realRunner); + notifyProgress(runner, event, 'start', {}); + }); + + return runner; + + function notifyProgress(runner, event, phase, data) { + runInNextPostDigestOrNow(function() { + var callbacks = findCallbacks(parent, element, event); + if (callbacks.length) { + // do not optimize this call here to RAF because + // we don't know how heavy the callback code here will + // be and if this code is buffered then this can + // lead to a performance regression. + $$rAF(function() { + forEach(callbacks, function(callback) { + callback(element, phase, data); + }); + }); + } + }); + runner.progress(event, phase, data); + } + + function close(reject) { // jshint ignore:line + clearGeneratedClasses(element, options); + applyAnimationClasses(element, options); + applyAnimationStyles(element, options); + options.domOperation(); + runner.complete(!reject); + } + } + + function closeChildAnimations(element) { + var node = getDomNode(element); + var children = node.querySelectorAll('[' + NG_ANIMATE_ATTR_NAME + ']'); + forEach(children, function(child) { + var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME)); + var animationDetails = activeAnimationsLookup.get(child); + switch (state) { + case RUNNING_STATE: + animationDetails.runner.end(); + /* falls through */ + case PRE_DIGEST_STATE: + if (animationDetails) { + activeAnimationsLookup.remove(child); + } + break; + } + }); + } + + function clearElementAnimationState(element) { + var node = getDomNode(element); + node.removeAttribute(NG_ANIMATE_ATTR_NAME); + activeAnimationsLookup.remove(node); + } + + function isMatchingElement(nodeOrElmA, nodeOrElmB) { + return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB); + } + + function areAnimationsAllowed(element, parentElement, event) { + var bodyElement = jqLite($document[0].body); + var bodyElementDetected = isMatchingElement(element, bodyElement) || element[0].nodeName === 'HTML'; + var rootElementDetected = isMatchingElement(element, $rootElement); + var parentAnimationDetected = false; + var animateChildren; + + var parentHost = element.data(NG_ANIMATE_PIN_DATA); + if (parentHost) { + parentElement = parentHost; + } + + while (parentElement && parentElement.length) { + if (!rootElementDetected) { + // angular doesn't want to attempt to animate elements outside of the application + // therefore we need to ensure that the rootElement is an ancestor of the current element + rootElementDetected = isMatchingElement(parentElement, $rootElement); + } + + var parentNode = parentElement[0]; + if (parentNode.nodeType !== ELEMENT_NODE) { + // no point in inspecting the #document element + break; + } + + var details = activeAnimationsLookup.get(parentNode) || {}; + // either an enter, leave or move animation will commence + // therefore we can't allow any animations to take place + // but if a parent animation is class-based then that's ok + if (!parentAnimationDetected) { + parentAnimationDetected = details.structural || disabledElementsLookup.get(parentNode); + } + + if (isUndefined(animateChildren) || animateChildren === true) { + var value = parentElement.data(NG_ANIMATE_CHILDREN_DATA); + if (isDefined(value)) { + animateChildren = value; + } + } + + // there is no need to continue traversing at this point + if (parentAnimationDetected && animateChildren === false) break; + + if (!rootElementDetected) { + // angular doesn't want to attempt to animate elements outside of the application + // therefore we need to ensure that the rootElement is an ancestor of the current element + rootElementDetected = isMatchingElement(parentElement, $rootElement); + if (!rootElementDetected) { + parentHost = parentElement.data(NG_ANIMATE_PIN_DATA); + if (parentHost) { + parentElement = parentHost; + } + } + } + + if (!bodyElementDetected) { + // we also need to ensure that the element is or will be apart of the body element + // otherwise it is pointless to even issue an animation to be rendered + bodyElementDetected = isMatchingElement(parentElement, bodyElement); + } + + parentElement = parentElement.parent(); + } + + var allowAnimation = !parentAnimationDetected || animateChildren; + return allowAnimation && rootElementDetected && bodyElementDetected; + } + + function markElementAnimationState(element, state, details) { + details = details || {}; + details.state = state; + + var node = getDomNode(element); + node.setAttribute(NG_ANIMATE_ATTR_NAME, state); + + var oldValue = activeAnimationsLookup.get(node); + var newValue = oldValue + ? extend(oldValue, details) + : details; + activeAnimationsLookup.put(node, newValue); + } + }]; +}]; + +var $$AnimateAsyncRunFactory = ['$$rAF', function($$rAF) { + var waitQueue = []; + + function waitForTick(fn) { + waitQueue.push(fn); + if (waitQueue.length > 1) return; + $$rAF(function() { + for (var i = 0; i < waitQueue.length; i++) { + waitQueue[i](); + } + waitQueue = []; + }); + } + + return function() { + var passed = false; + waitForTick(function() { + passed = true; + }); + return function(callback) { + passed ? callback() : waitForTick(callback); + }; + }; +}]; + +var $$AnimateRunnerFactory = ['$q', '$sniffer', '$$animateAsyncRun', + function($q, $sniffer, $$animateAsyncRun) { + + var INITIAL_STATE = 0; + var DONE_PENDING_STATE = 1; + var DONE_COMPLETE_STATE = 2; + + AnimateRunner.chain = function(chain, callback) { + var index = 0; + + next(); + function next() { + if (index === chain.length) { + callback(true); + return; + } + + chain[index](function(response) { + if (response === false) { + callback(false); + return; + } + index++; + next(); + }); + } + }; + + AnimateRunner.all = function(runners, callback) { + var count = 0; + var status = true; + forEach(runners, function(runner) { + runner.done(onProgress); + }); + + function onProgress(response) { + status = status && response; + if (++count === runners.length) { + callback(status); + } + } + }; + + function AnimateRunner(host) { + this.setHost(host); + + this._doneCallbacks = []; + this._runInAnimationFrame = $$animateAsyncRun(); + this._state = 0; + } + + AnimateRunner.prototype = { + setHost: function(host) { + this.host = host || {}; + }, + + done: function(fn) { + if (this._state === DONE_COMPLETE_STATE) { + fn(); + } else { + this._doneCallbacks.push(fn); + } + }, + + progress: noop, + + getPromise: function() { + if (!this.promise) { + var self = this; + this.promise = $q(function(resolve, reject) { + self.done(function(status) { + status === false ? reject() : resolve(); + }); + }); + } + return this.promise; + }, + + then: function(resolveHandler, rejectHandler) { + return this.getPromise().then(resolveHandler, rejectHandler); + }, + + 'catch': function(handler) { + return this.getPromise()['catch'](handler); + }, + + 'finally': function(handler) { + return this.getPromise()['finally'](handler); + }, + + pause: function() { + if (this.host.pause) { + this.host.pause(); + } + }, + + resume: function() { + if (this.host.resume) { + this.host.resume(); + } + }, + + end: function() { + if (this.host.end) { + this.host.end(); + } + this._resolve(true); + }, + + cancel: function() { + if (this.host.cancel) { + this.host.cancel(); + } + this._resolve(false); + }, + + complete: function(response) { + var self = this; + if (self._state === INITIAL_STATE) { + self._state = DONE_PENDING_STATE; + self._runInAnimationFrame(function() { + self._resolve(response); + }); + } + }, + + _resolve: function(response) { + if (this._state !== DONE_COMPLETE_STATE) { + forEach(this._doneCallbacks, function(fn) { + fn(response); + }); + this._doneCallbacks.length = 0; + this._state = DONE_COMPLETE_STATE; + } + } + }; + + return AnimateRunner; +}]; + +var $$AnimationProvider = ['$animateProvider', function($animateProvider) { + var NG_ANIMATE_REF_ATTR = 'ng-animate-ref'; + + var drivers = this.drivers = []; + + var RUNNER_STORAGE_KEY = '$$animationRunner'; + + function setRunner(element, runner) { + element.data(RUNNER_STORAGE_KEY, runner); + } + + function removeRunner(element) { + element.removeData(RUNNER_STORAGE_KEY); + } + + function getRunner(element) { + return element.data(RUNNER_STORAGE_KEY); + } + + this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$HashMap', '$$rAFScheduler', + function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$HashMap, $$rAFScheduler) { + + var animationQueue = []; + var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); + + function sortAnimations(animations) { + var tree = { children: [] }; + var i, lookup = new $$HashMap(); + + // this is done first beforehand so that the hashmap + // is filled with a list of the elements that will be animated + for (i = 0; i < animations.length; i++) { + var animation = animations[i]; + lookup.put(animation.domNode, animations[i] = { + domNode: animation.domNode, + fn: animation.fn, + children: [] + }); + } + + for (i = 0; i < animations.length; i++) { + processNode(animations[i]); + } + + return flatten(tree); + + function processNode(entry) { + if (entry.processed) return entry; + entry.processed = true; + + var elementNode = entry.domNode; + var parentNode = elementNode.parentNode; + lookup.put(elementNode, entry); + + var parentEntry; + while (parentNode) { + parentEntry = lookup.get(parentNode); + if (parentEntry) { + if (!parentEntry.processed) { + parentEntry = processNode(parentEntry); + } + break; + } + parentNode = parentNode.parentNode; + } + + (parentEntry || tree).children.push(entry); + return entry; + } + + function flatten(tree) { + var result = []; + var queue = []; + var i; + + for (i = 0; i < tree.children.length; i++) { + queue.push(tree.children[i]); + } + + var remainingLevelEntries = queue.length; + var nextLevelEntries = 0; + var row = []; + + for (i = 0; i < queue.length; i++) { + var entry = queue[i]; + if (remainingLevelEntries <= 0) { + remainingLevelEntries = nextLevelEntries; + nextLevelEntries = 0; + result.push(row); + row = []; + } + row.push(entry.fn); + entry.children.forEach(function(childEntry) { + nextLevelEntries++; + queue.push(childEntry); + }); + remainingLevelEntries--; + } + + if (row.length) { + result.push(row); + } + + return result; + } + } + + // TODO(matsko): document the signature in a better way + return function(element, event, options) { + options = prepareAnimationOptions(options); + var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0; + + // there is no animation at the current moment, however + // these runner methods will get later updated with the + // methods leading into the driver's end/cancel methods + // for now they just stop the animation from starting + var runner = new $$AnimateRunner({ + end: function() { close(); }, + cancel: function() { close(true); } + }); + + if (!drivers.length) { + close(); + return runner; + } + + setRunner(element, runner); + + var classes = mergeClasses(element.attr('class'), mergeClasses(options.addClass, options.removeClass)); + var tempClasses = options.tempClasses; + if (tempClasses) { + classes += ' ' + tempClasses; + options.tempClasses = null; + } + + animationQueue.push({ + // this data is used by the postDigest code and passed into + // the driver step function + element: element, + classes: classes, + event: event, + structural: isStructural, + options: options, + beforeStart: beforeStart, + close: close + }); + + element.on('$destroy', handleDestroyedElement); + + // we only want there to be one function called within the post digest + // block. This way we can group animations for all the animations that + // were apart of the same postDigest flush call. + if (animationQueue.length > 1) return runner; + + $rootScope.$$postDigest(function() { + var animations = []; + forEach(animationQueue, function(entry) { + // the element was destroyed early on which removed the runner + // form its storage. This means we can't animate this element + // at all and it already has been closed due to destruction. + if (getRunner(entry.element)) { + animations.push(entry); + } else { + entry.close(); + } + }); + + // now any future animations will be in another postDigest + animationQueue.length = 0; + + var groupedAnimations = groupAnimations(animations); + var toBeSortedAnimations = []; + + forEach(groupedAnimations, function(animationEntry) { + toBeSortedAnimations.push({ + domNode: getDomNode(animationEntry.from ? animationEntry.from.element : animationEntry.element), + fn: function triggerAnimationStart() { + // it's important that we apply the `ng-animate` CSS class and the + // temporary classes before we do any driver invoking since these + // CSS classes may be required for proper CSS detection. + animationEntry.beforeStart(); + + var startAnimationFn, closeFn = animationEntry.close; + + // in the event that the element was removed before the digest runs or + // during the RAF sequencing then we should not trigger the animation. + var targetElement = animationEntry.anchors + ? (animationEntry.from.element || animationEntry.to.element) + : animationEntry.element; + + if (getRunner(targetElement)) { + var operation = invokeFirstDriver(animationEntry); + if (operation) { + startAnimationFn = operation.start; + } + } + + if (!startAnimationFn) { + closeFn(); + } else { + var animationRunner = startAnimationFn(); + animationRunner.done(function(status) { + closeFn(!status); + }); + updateAnimationRunners(animationEntry, animationRunner); + } + } + }); + }); + + // we need to sort each of the animations in order of parent to child + // relationships. This ensures that the child classes are applied at the + // right time. + $$rAFScheduler(sortAnimations(toBeSortedAnimations)); + }); + + return runner; + + // TODO(matsko): change to reference nodes + function getAnchorNodes(node) { + var SELECTOR = '[' + NG_ANIMATE_REF_ATTR + ']'; + var items = node.hasAttribute(NG_ANIMATE_REF_ATTR) + ? [node] + : node.querySelectorAll(SELECTOR); + var anchors = []; + forEach(items, function(node) { + var attr = node.getAttribute(NG_ANIMATE_REF_ATTR); + if (attr && attr.length) { + anchors.push(node); + } + }); + return anchors; + } + + function groupAnimations(animations) { + var preparedAnimations = []; + var refLookup = {}; + forEach(animations, function(animation, index) { + var element = animation.element; + var node = getDomNode(element); + var event = animation.event; + var enterOrMove = ['enter', 'move'].indexOf(event) >= 0; + var anchorNodes = animation.structural ? getAnchorNodes(node) : []; + + if (anchorNodes.length) { + var direction = enterOrMove ? 'to' : 'from'; + + forEach(anchorNodes, function(anchor) { + var key = anchor.getAttribute(NG_ANIMATE_REF_ATTR); + refLookup[key] = refLookup[key] || {}; + refLookup[key][direction] = { + animationID: index, + element: jqLite(anchor) + }; + }); + } else { + preparedAnimations.push(animation); + } + }); + + var usedIndicesLookup = {}; + var anchorGroups = {}; + forEach(refLookup, function(operations, key) { + var from = operations.from; + var to = operations.to; + + if (!from || !to) { + // only one of these is set therefore we can't have an + // anchor animation since all three pieces are required + var index = from ? from.animationID : to.animationID; + var indexKey = index.toString(); + if (!usedIndicesLookup[indexKey]) { + usedIndicesLookup[indexKey] = true; + preparedAnimations.push(animations[index]); + } + return; + } + + var fromAnimation = animations[from.animationID]; + var toAnimation = animations[to.animationID]; + var lookupKey = from.animationID.toString(); + if (!anchorGroups[lookupKey]) { + var group = anchorGroups[lookupKey] = { + structural: true, + beforeStart: function() { + fromAnimation.beforeStart(); + toAnimation.beforeStart(); + }, + close: function() { + fromAnimation.close(); + toAnimation.close(); + }, + classes: cssClassesIntersection(fromAnimation.classes, toAnimation.classes), + from: fromAnimation, + to: toAnimation, + anchors: [] // TODO(matsko): change to reference nodes + }; + + // the anchor animations require that the from and to elements both have at least + // one shared CSS class which effictively marries the two elements together to use + // the same animation driver and to properly sequence the anchor animation. + if (group.classes.length) { + preparedAnimations.push(group); + } else { + preparedAnimations.push(fromAnimation); + preparedAnimations.push(toAnimation); + } + } + + anchorGroups[lookupKey].anchors.push({ + 'out': from.element, 'in': to.element + }); + }); + + return preparedAnimations; + } + + function cssClassesIntersection(a,b) { + a = a.split(' '); + b = b.split(' '); + var matches = []; + + for (var i = 0; i < a.length; i++) { + var aa = a[i]; + if (aa.substring(0,3) === 'ng-') continue; + + for (var j = 0; j < b.length; j++) { + if (aa === b[j]) { + matches.push(aa); + break; + } + } + } + + return matches.join(' '); + } + + function invokeFirstDriver(animationDetails) { + // we loop in reverse order since the more general drivers (like CSS and JS) + // may attempt more elements, but custom drivers are more particular + for (var i = drivers.length - 1; i >= 0; i--) { + var driverName = drivers[i]; + if (!$injector.has(driverName)) continue; // TODO(matsko): remove this check + + var factory = $injector.get(driverName); + var driver = factory(animationDetails); + if (driver) { + return driver; + } + } + } + + function beforeStart() { + element.addClass(NG_ANIMATE_CLASSNAME); + if (tempClasses) { + $$jqLite.addClass(element, tempClasses); + } + } + + function updateAnimationRunners(animation, newRunner) { + if (animation.from && animation.to) { + update(animation.from.element); + update(animation.to.element); + } else { + update(animation.element); + } + + function update(element) { + getRunner(element).setHost(newRunner); + } + } + + function handleDestroyedElement() { + var runner = getRunner(element); + if (runner && (event !== 'leave' || !options.$$domOperationFired)) { + runner.end(); + } + } + + function close(rejected) { // jshint ignore:line + element.off('$destroy', handleDestroyedElement); + removeRunner(element); + + applyAnimationClasses(element, options); + applyAnimationStyles(element, options); + options.domOperation(); + + if (tempClasses) { + $$jqLite.removeClass(element, tempClasses); + } + + element.removeClass(NG_ANIMATE_CLASSNAME); + runner.complete(!rejected); + } + }; + }]; +}]; + +/* global angularAnimateModule: true, + + $$AnimateAsyncRunFactory, + $$rAFSchedulerFactory, + $$AnimateChildrenDirective, + $$AnimateRunnerFactory, + $$AnimateQueueProvider, + $$AnimationProvider, + $AnimateCssProvider, + $$AnimateCssDriverProvider, + $$AnimateJsProvider, + $$AnimateJsDriverProvider, +*/ + +/** + * @ngdoc module + * @name ngAnimate + * @description + * + * The `ngAnimate` module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via + * callback hooks. Animations are not enabled by default, however, by including `ngAnimate` the animation hooks are enabled for an Angular app. + * + *
    + * + * # Usage + * Simply put, there are two ways to make use of animations when ngAnimate is used: by using **CSS** and **JavaScript**. The former works purely based + * using CSS (by using matching CSS selectors/styles) and the latter triggers animations that are registered via `module.animation()`. For + * both CSS and JS animations the sole requirement is to have a matching `CSS class` that exists both in the registered animation and within + * the HTML element that the animation will be triggered on. + * + * ## Directive Support + * The following directives are "animation aware": + * + * | Directive | Supported Animations | + * |----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------| + * | {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave and move | + * | {@link ngRoute.directive:ngView#animations ngView} | enter and leave | + * | {@link ng.directive:ngInclude#animations ngInclude} | enter and leave | + * | {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave | + * | {@link ng.directive:ngIf#animations ngIf} | enter and leave | + * | {@link ng.directive:ngClass#animations ngClass} | add and remove (the CSS class(es) present) | + * | {@link ng.directive:ngShow#animations ngShow} & {@link ng.directive:ngHide#animations ngHide} | add and remove (the ng-hide class value) | + * | {@link ng.directive:form#animation-hooks form} & {@link ng.directive:ngModel#animation-hooks ngModel} | add and remove (dirty, pristine, valid, invalid & all other validations) | + * | {@link module:ngMessages#animations ngMessages} | add and remove (ng-active & ng-inactive) | + * | {@link module:ngMessages#animations ngMessage} | enter and leave | + * + * (More information can be found by visiting each the documentation associated with each directive.) + * + * ## CSS-based Animations + * + * CSS-based animations with ngAnimate are unique since they require no JavaScript code at all. By using a CSS class that we reference between our HTML + * and CSS code we can create an animation that will be picked up by Angular when an the underlying directive performs an operation. + * + * The example below shows how an `enter` animation can be made possible on an element using `ng-if`: + * + * ```html + *
    + * Fade me in out + *
    + * + * + * ``` + * + * Notice the CSS class **fade**? We can now create the CSS transition code that references this class: + * + * ```css + * /* The starting CSS styles for the enter animation */ + * .fade.ng-enter { + * transition:0.5s linear all; + * opacity:0; + * } + * + * /* The finishing CSS styles for the enter animation */ + * .fade.ng-enter.ng-enter-active { + * opacity:1; + * } + * ``` + * + * The key thing to remember here is that, depending on the animation event (which each of the directives above trigger depending on what's going on) two + * generated CSS classes will be applied to the element; in the example above we have `.ng-enter` and `.ng-enter-active`. For CSS transitions, the transition + * code **must** be defined within the starting CSS class (in this case `.ng-enter`). The destination class is what the transition will animate towards. + * + * If for example we wanted to create animations for `leave` and `move` (ngRepeat triggers move) then we can do so using the same CSS naming conventions: + * + * ```css + * /* now the element will fade out before it is removed from the DOM */ + * .fade.ng-leave { + * transition:0.5s linear all; + * opacity:1; + * } + * .fade.ng-leave.ng-leave-active { + * opacity:0; + * } + * ``` + * + * We can also make use of **CSS Keyframes** by referencing the keyframe animation within the starting CSS class: + * + * ```css + * /* there is no need to define anything inside of the destination + * CSS class since the keyframe will take charge of the animation */ + * .fade.ng-leave { + * animation: my_fade_animation 0.5s linear; + * -webkit-animation: my_fade_animation 0.5s linear; + * } + * + * @keyframes my_fade_animation { + * from { opacity:1; } + * to { opacity:0; } + * } + * + * @-webkit-keyframes my_fade_animation { + * from { opacity:1; } + * to { opacity:0; } + * } + * ``` + * + * Feel free also mix transitions and keyframes together as well as any other CSS classes on the same element. + * + * ### CSS Class-based Animations + * + * Class-based animations (animations that are triggered via `ngClass`, `ngShow`, `ngHide` and some other directives) have a slightly different + * naming convention. Class-based animations are basic enough that a standard transition or keyframe can be referenced on the class being added + * and removed. + * + * For example if we wanted to do a CSS animation for `ngHide` then we place an animation on the `.ng-hide` CSS class: + * + * ```html + *
    + * Show and hide me + *
    + * + * + * + * ``` + * + * All that is going on here with ngShow/ngHide behind the scenes is the `.ng-hide` class is added/removed (when the hidden state is valid). Since + * ngShow and ngHide are animation aware then we can match up a transition and ngAnimate handles the rest. + * + * In addition the addition and removal of the CSS class, ngAnimate also provides two helper methods that we can use to further decorate the animation + * with CSS styles. + * + * ```html + *
    + * Highlight this box + *
    + * + * + * + * ``` + * + * We can also make use of CSS keyframes by placing them within the CSS classes. + * + * + * ### CSS Staggering Animations + * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a + * curtain-like effect. The ngAnimate module (versions >=1.2) supports staggering animations and the stagger effect can be + * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for + * the animation. The style property expected within the stagger class can either be a **transition-delay** or an + * **animation-delay** property (or both if your animation contains both transitions and keyframe animations). + * + * ```css + * .my-animation.ng-enter { + * /* standard transition code */ + * transition: 1s linear all; + * opacity:0; + * } + * .my-animation.ng-enter-stagger { + * /* this will have a 100ms delay between each successive leave animation */ + * transition-delay: 0.1s; + * + * /* As of 1.4.4, this must always be set: it signals ngAnimate + * to not accidentally inherit a delay property from another CSS class */ + * transition-duration: 0s; + * } + * .my-animation.ng-enter.ng-enter-active { + * /* standard transition styles */ + * opacity:1; + * } + * ``` + * + * Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations + * on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this + * are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation + * will also be reset if one or more animation frames have passed since the multiple calls to `$animate` were fired. + * + * The following code will issue the **ng-leave-stagger** event on the element provided: + * + * ```js + * var kids = parent.children(); + * + * $animate.leave(kids[0]); //stagger index=0 + * $animate.leave(kids[1]); //stagger index=1 + * $animate.leave(kids[2]); //stagger index=2 + * $animate.leave(kids[3]); //stagger index=3 + * $animate.leave(kids[4]); //stagger index=4 + * + * window.requestAnimationFrame(function() { + * //stagger has reset itself + * $animate.leave(kids[5]); //stagger index=0 + * $animate.leave(kids[6]); //stagger index=1 + * + * $scope.$digest(); + * }); + * ``` + * + * Stagger animations are currently only supported within CSS-defined animations. + * + * ### The `ng-animate` CSS class + * + * When ngAnimate is animating an element it will apply the `ng-animate` CSS class to the element for the duration of the animation. + * This is a temporary CSS class and it will be removed once the animation is over (for both JavaScript and CSS-based animations). + * + * Therefore, animations can be applied to an element using this temporary class directly via CSS. + * + * ```css + * .zipper.ng-animate { + * transition:0.5s linear all; + * } + * .zipper.ng-enter { + * opacity:0; + * } + * .zipper.ng-enter.ng-enter-active { + * opacity:1; + * } + * .zipper.ng-leave { + * opacity:1; + * } + * .zipper.ng-leave.ng-leave-active { + * opacity:0; + * } + * ``` + * + * (Note that the `ng-animate` CSS class is reserved and it cannot be applied on an element directly since ngAnimate will always remove + * the CSS class once an animation has completed.) + * + * + * ## JavaScript-based Animations + * + * ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared + * CSS class that is referenced in our HTML code) but in addition we need to register the JavaScript animation on the module. By making use of the + * `module.animation()` module function we can register the ainmation. + * + * Let's see an example of a enter/leave animation using `ngRepeat`: + * + * ```html + *
    + * {{ item }} + *
    + * ``` + * + * See the **slide** CSS class? Let's use that class to define an animation that we'll structure in our module code by using `module.animation`: + * + * ```js + * myModule.animation('.slide', [function() { + * return { + * // make note that other events (like addClass/removeClass) + * // have different function input parameters + * enter: function(element, doneFn) { + * jQuery(element).fadeIn(1000, doneFn); + * + * // remember to call doneFn so that angular + * // knows that the animation has concluded + * }, + * + * move: function(element, doneFn) { + * jQuery(element).fadeIn(1000, doneFn); + * }, + * + * leave: function(element, doneFn) { + * jQuery(element).fadeOut(1000, doneFn); + * } + * } + * }]); + * ``` + * + * The nice thing about JS-based animations is that we can inject other services and make use of advanced animation libraries such as + * greensock.js and velocity.js. + * + * If our animation code class-based (meaning that something like `ngClass`, `ngHide` and `ngShow` triggers it) then we can still define + * our animations inside of the same registered animation, however, the function input arguments are a bit different: + * + * ```html + *
    + * this box is moody + *
    + * + * + * + * ``` + * + * ```js + * myModule.animation('.colorful', [function() { + * return { + * addClass: function(element, className, doneFn) { + * // do some cool animation and call the doneFn + * }, + * removeClass: function(element, className, doneFn) { + * // do some cool animation and call the doneFn + * }, + * setClass: function(element, addedClass, removedClass, doneFn) { + * // do some cool animation and call the doneFn + * } + * } + * }]); + * ``` + * + * ## CSS + JS Animations Together + * + * AngularJS 1.4 and higher has taken steps to make the amalgamation of CSS and JS animations more flexible. However, unlike earlier versions of Angular, + * defining CSS and JS animations to work off of the same CSS class will not work anymore. Therefore the example below will only result in **JS animations taking + * charge of the animation**: + * + * ```html + *
    + * Slide in and out + *
    + * ``` + * + * ```js + * myModule.animation('.slide', [function() { + * return { + * enter: function(element, doneFn) { + * jQuery(element).slideIn(1000, doneFn); + * } + * } + * }]); + * ``` + * + * ```css + * .slide.ng-enter { + * transition:0.5s linear all; + * transform:translateY(-100px); + * } + * .slide.ng-enter.ng-enter-active { + * transform:translateY(0); + * } + * ``` + * + * Does this mean that CSS and JS animations cannot be used together? Do JS-based animations always have higher priority? We can make up for the + * lack of CSS animations by using the `$animateCss` service to trigger our own tweaked-out, CSS-based animations directly from + * our own JS-based animation code: + * + * ```js + * myModule.animation('.slide', ['$animateCss', function($animateCss) { + * return { + * enter: function(element) { +* // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`. + * return $animateCss(element, { + * event: 'enter', + * structural: true + * }); + * } + * } + * }]); + * ``` + * + * The nice thing here is that we can save bandwidth by sticking to our CSS-based animation code and we don't need to rely on a 3rd-party animation framework. + * + * The `$animateCss` service is very powerful since we can feed in all kinds of extra properties that will be evaluated and fed into a CSS transition or + * keyframe animation. For example if we wanted to animate the height of an element while adding and removing classes then we can do so by providing that + * data into `$animateCss` directly: + * + * ```js + * myModule.animation('.slide', ['$animateCss', function($animateCss) { + * return { + * enter: function(element) { + * return $animateCss(element, { + * event: 'enter', + * structural: true, + * addClass: 'maroon-setting', + * from: { height:0 }, + * to: { height: 200 } + * }); + * } + * } + * }]); + * ``` + * + * Now we can fill in the rest via our transition CSS code: + * + * ```css + * /* the transition tells ngAnimate to make the animation happen */ + * .slide.ng-enter { transition:0.5s linear all; } + * + * /* this extra CSS class will be absorbed into the transition + * since the $animateCss code is adding the class */ + * .maroon-setting { background:red; } + * ``` + * + * And `$animateCss` will figure out the rest. Just make sure to have the `done()` callback fire the `doneFn` function to signal when the animation is over. + * + * To learn more about what's possible be sure to visit the {@link ngAnimate.$animateCss $animateCss service}. + * + * ## Animation Anchoring (via `ng-animate-ref`) + * + * ngAnimate in AngularJS 1.4 comes packed with the ability to cross-animate elements between + * structural areas of an application (like views) by pairing up elements using an attribute + * called `ng-animate-ref`. + * + * Let's say for example we have two views that are managed by `ng-view` and we want to show + * that there is a relationship between two components situated in within these views. By using the + * `ng-animate-ref` attribute we can identify that the two components are paired together and we + * can then attach an animation, which is triggered when the view changes. + * + * Say for example we have the following template code: + * + * ```html + * + *
    + *
    + * + * + * + * + * + * + * + * + * ``` + * + * Now, when the view changes (once the link is clicked), ngAnimate will examine the + * HTML contents to see if there is a match reference between any components in the view + * that is leaving and the view that is entering. It will scan both the view which is being + * removed (leave) and inserted (enter) to see if there are any paired DOM elements that + * contain a matching ref value. + * + * The two images match since they share the same ref value. ngAnimate will now create a + * transport element (which is a clone of the first image element) and it will then attempt + * to animate to the position of the second image element in the next view. For the animation to + * work a special CSS class called `ng-anchor` will be added to the transported element. + * + * We can now attach a transition onto the `.banner.ng-anchor` CSS class and then + * ngAnimate will handle the entire transition for us as well as the addition and removal of + * any changes of CSS classes between the elements: + * + * ```css + * .banner.ng-anchor { + * /* this animation will last for 1 second since there are + * two phases to the animation (an `in` and an `out` phase) */ + * transition:0.5s linear all; + * } + * ``` + * + * We also **must** include animations for the views that are being entered and removed + * (otherwise anchoring wouldn't be possible since the new view would be inserted right away). + * + * ```css + * .view-animation.ng-enter, .view-animation.ng-leave { + * transition:0.5s linear all; + * position:fixed; + * left:0; + * top:0; + * width:100%; + * } + * .view-animation.ng-enter { + * transform:translateX(100%); + * } + * .view-animation.ng-leave, + * .view-animation.ng-enter.ng-enter-active { + * transform:translateX(0%); + * } + * .view-animation.ng-leave.ng-leave-active { + * transform:translateX(-100%); + * } + * ``` + * + * Now we can jump back to the anchor animation. When the animation happens, there are two stages that occur: + * an `out` and an `in` stage. The `out` stage happens first and that is when the element is animated away + * from its origin. Once that animation is over then the `in` stage occurs which animates the + * element to its destination. The reason why there are two animations is to give enough time + * for the enter animation on the new element to be ready. + * + * The example above sets up a transition for both the in and out phases, but we can also target the out or + * in phases directly via `ng-anchor-out` and `ng-anchor-in`. + * + * ```css + * .banner.ng-anchor-out { + * transition: 0.5s linear all; + * + * /* the scale will be applied during the out animation, + * but will be animated away when the in animation runs */ + * transform: scale(1.2); + * } + * + * .banner.ng-anchor-in { + * transition: 1s linear all; + * } + * ``` + * + * + * + * + * ### Anchoring Demo + * + + + Home +
    +
    +
    +
    +
    + + angular.module('anchoringExample', ['ngAnimate', 'ngRoute']) + .config(['$routeProvider', function($routeProvider) { + $routeProvider.when('/', { + templateUrl: 'home.html', + controller: 'HomeController as home' + }); + $routeProvider.when('/profile/:id', { + templateUrl: 'profile.html', + controller: 'ProfileController as profile' + }); + }]) + .run(['$rootScope', function($rootScope) { + $rootScope.records = [ + { id:1, title: "Miss Beulah Roob" }, + { id:2, title: "Trent Morissette" }, + { id:3, title: "Miss Ava Pouros" }, + { id:4, title: "Rod Pouros" }, + { id:5, title: "Abdul Rice" }, + { id:6, title: "Laurie Rutherford Sr." }, + { id:7, title: "Nakia McLaughlin" }, + { id:8, title: "Jordon Blanda DVM" }, + { id:9, title: "Rhoda Hand" }, + { id:10, title: "Alexandrea Sauer" } + ]; + }]) + .controller('HomeController', [function() { + //empty + }]) + .controller('ProfileController', ['$rootScope', '$routeParams', function($rootScope, $routeParams) { + var index = parseInt($routeParams.id, 10); + var record = $rootScope.records[index - 1]; + + this.title = record.title; + this.id = record.id; + }]); + + +

    Welcome to the home page

    +

    Please click on an element

    + + {{ record.title }} + +
    + +
    + {{ profile.title }} +
    +
    + + .record { + display:block; + font-size:20px; + } + .profile { + background:black; + color:white; + font-size:100px; + } + .view-container { + position:relative; + } + .view-container > .view.ng-animate { + position:absolute; + top:0; + left:0; + width:100%; + min-height:500px; + } + .view.ng-enter, .view.ng-leave, + .record.ng-anchor { + transition:0.5s linear all; + } + .view.ng-enter { + transform:translateX(100%); + } + .view.ng-enter.ng-enter-active, .view.ng-leave { + transform:translateX(0%); + } + .view.ng-leave.ng-leave-active { + transform:translateX(-100%); + } + .record.ng-anchor-out { + background:red; + } + +
    + * + * ### How is the element transported? + * + * When an anchor animation occurs, ngAnimate will clone the starting element and position it exactly where the starting + * element is located on screen via absolute positioning. The cloned element will be placed inside of the root element + * of the application (where ng-app was defined) and all of the CSS classes of the starting element will be applied. The + * element will then animate into the `out` and `in` animations and will eventually reach the coordinates and match + * the dimensions of the destination element. During the entire animation a CSS class of `.ng-animate-shim` will be applied + * to both the starting and destination elements in order to hide them from being visible (the CSS styling for the class + * is: `visibility:hidden`). Once the anchor reaches its destination then it will be removed and the destination element + * will become visible since the shim class will be removed. + * + * ### How is the morphing handled? + * + * CSS Anchoring relies on transitions and keyframes and the internal code is intelligent enough to figure out + * what CSS classes differ between the starting element and the destination element. These different CSS classes + * will be added/removed on the anchor element and a transition will be applied (the transition that is provided + * in the anchor class). Long story short, ngAnimate will figure out what classes to add and remove which will + * make the transition of the element as smooth and automatic as possible. Be sure to use simple CSS classes that + * do not rely on DOM nesting structure so that the anchor element appears the same as the starting element (since + * the cloned element is placed inside of root element which is likely close to the body element). + * + * Note that if the root element is on the `` element then the cloned node will be placed inside of body. + * + * + * ## Using $animate in your directive code + * + * So far we've explored how to feed in animations into an Angular application, but how do we trigger animations within our own directives in our application? + * By injecting the `$animate` service into our directive code, we can trigger structural and class-based hooks which can then be consumed by animations. Let's + * imagine we have a greeting box that shows and hides itself when the data changes + * + * ```html + * Hi there + * ``` + * + * ```js + * ngModule.directive('greetingBox', ['$animate', function($animate) { + * return function(scope, element, attrs) { + * attrs.$observe('active', function(value) { + * value ? $animate.addClass(element, 'on') : $animate.removeClass(element, 'on'); + * }); + * }); + * }]); + * ``` + * + * Now the `on` CSS class is added and removed on the greeting box component. Now if we add a CSS class on top of the greeting box element + * in our HTML code then we can trigger a CSS or JS animation to happen. + * + * ```css + * /* normally we would create a CSS class to reference on the element */ + * greeting-box.on { transition:0.5s linear all; background:green; color:white; } + * ``` + * + * The `$animate` service contains a variety of other methods like `enter`, `leave`, `animate` and `setClass`. To learn more about what's + * possible be sure to visit the {@link ng.$animate $animate service API page}. + * + * + * ### Preventing Collisions With Third Party Libraries + * + * Some third-party frameworks place animation duration defaults across many element or className + * selectors in order to make their code small and reuseable. This can lead to issues with ngAnimate, which + * is expecting actual animations on these elements and has to wait for their completion. + * + * You can prevent this unwanted behavior by using a prefix on all your animation classes: + * + * ```css + * /* prefixed with animate- */ + * .animate-fade-add.animate-fade-add-active { + * transition:1s linear all; + * opacity:0; + * } + * ``` + * + * You then configure `$animate` to enforce this prefix: + * + * ```js + * $animateProvider.classNameFilter(/animate-/); + * ``` + * + * This also may provide your application with a speed boost since only specific elements containing CSS class prefix + * will be evaluated for animation when any DOM changes occur in the application. + * + * ## Callbacks and Promises + * + * When `$animate` is called it returns a promise that can be used to capture when the animation has ended. Therefore if we were to trigger + * an animation (within our directive code) then we can continue performing directive and scope related activities after the animation has + * ended by chaining onto the returned promise that animation method returns. + * + * ```js + * // somewhere within the depths of the directive + * $animate.enter(element, parent).then(function() { + * //the animation has completed + * }); + * ``` + * + * (Note that earlier versions of Angular prior to v1.4 required the promise code to be wrapped using `$scope.$apply(...)`. This is not the case + * anymore.) + * + * In addition to the animation promise, we can also make use of animation-related callbacks within our directives and controller code by registering + * an event listener using the `$animate` service. Let's say for example that an animation was triggered on our view + * routing controller to hook into that: + * + * ```js + * ngModule.controller('HomePageController', ['$animate', function($animate) { + * $animate.on('enter', ngViewElement, function(element) { + * // the animation for this route has completed + * }]); + * }]) + * ``` + * + * (Note that you will need to trigger a digest within the callback to get angular to notice any scope-related changes.) + */ + +/** + * @ngdoc service + * @name $animate + * @kind object + * + * @description + * The ngAnimate `$animate` service documentation is the same for the core `$animate` service. + * + * Click here {@link ng.$animate to learn more about animations with `$animate`}. + */ +angular.module('ngAnimate', []) + .directive('ngAnimateChildren', $$AnimateChildrenDirective) + .factory('$$rAFScheduler', $$rAFSchedulerFactory) + + .factory('$$AnimateRunner', $$AnimateRunnerFactory) + .factory('$$animateAsyncRun', $$AnimateAsyncRunFactory) + + .provider('$$animateQueue', $$AnimateQueueProvider) + .provider('$$animation', $$AnimationProvider) + + .provider('$animateCss', $AnimateCssProvider) + .provider('$$animateCssDriver', $$AnimateCssDriverProvider) + + .provider('$$animateJs', $$AnimateJsProvider) + .provider('$$animateJsDriver', $$AnimateJsDriverProvider); + + +})(window, window.angular); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-animate.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-animate.min.js new file mode 100644 index 00000000..9461603d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-animate.min.js @@ -0,0 +1,56 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(H,u,Sa){'use strict';function wa(a,b,c){if(!a)throw ngMinErr("areq",b||"?",c||"required");return a}function xa(a,b){if(!a&&!b)return"";if(!a)return b;if(!b)return a;X(a)&&(a=a.join(" "));X(b)&&(b=b.join(" "));return a+" "+b}function Ia(a){var b={};a&&(a.to||a.from)&&(b.to=a.to,b.from=a.from);return b}function T(a,b,c){var d="";a=X(a)?a:a&&I(a)&&a.length?a.split(/\s+/):[];q(a,function(a,s){a&&0=a&&(a=m,m=0,b.push(e),e=[]);e.push(h.fn);h.children.forEach(function(a){m++;c.push(a)});a--}e.length&&b.push(e);return b}(c)}var $=[],u=N(a);return function(g,C,D){function K(a){a=a.hasAttribute("ng-animate-ref")?[a]:a.querySelectorAll("[ng-animate-ref]");var b=[];q(a,function(a){var c=a.getAttribute("ng-animate-ref");c&&c.length&&b.push(a)});return b} +function l(a){var b=[],c={};q(a,function(a,f){var d=B(a.element),t=0<=["enter","move"].indexOf(a.event),d=a.structural?K(d):[];if(d.length){var m=t?"to":"from";q(d,function(a){var b=a.getAttribute("ng-animate-ref");c[b]=c[b]||{};c[b][m]={animationID:f,element:L(a)}})}else b.push(a)});var f={},d={};q(c,function(c,m){var w=c.from,e=c.to;if(w&&e){var h=a[w.animationID],g=a[e.animationID],x=w.animationID.toString();if(!d[x]){var A=d[x]={structural:!0,beforeStart:function(){h.beforeStart();g.beforeStart()}, +close:function(){h.close();g.close()},classes:y(h.classes,g.classes),from:h,to:g,anchors:[]};A.classes.length?b.push(A):(b.push(h),b.push(g))}d[x].anchors.push({out:w.element,"in":e.element})}else w=w?w.animationID:e.animationID,e=w.toString(),f[e]||(f[e]=!0,b.push(a[w]))});return b}function y(a,b){a=a.split(" ");b=b.split(" ");for(var c=[],f=0;fG.expectedEndTime)?h.cancel(G.timer):l.push(m)}r&&(v=h(d,v,!1),l[0]={timer:v,expectedEndTime:k},l.push(m),a.data("$$animateCss",l));a.on(x.join(" "),g);c.to&&(c.cleanupStyles&&Ea(t,n,Object.keys(c.to)),za(a,c))}}function d(){var b=a.data("$$animateCss");if(b){for(var c=1;c=N&&b>=J&&(va=!0,m())}if(!ga)if(n.parentNode){var A,x=[],l=function(a){if(va)k&&a&&(k=!1,m());else if(k=!a,E.animationDuration)if(a=na(n,k),k)y.push(a);else{var b=y,c=b.indexOf(a);0<=a&&b.splice(c,1)}},v=0ARIA](http://www.w3.org/TR/wai-aria/) + * attributes that convey state or semantic information about the application for users + * of assistive technologies, such as screen readers. + * + *
    + * + * ## Usage + * + * For ngAria to do its magic, simply include the module `ngAria` as a dependency. The following + * directives are supported: + * `ngModel`, `ngDisabled`, `ngShow`, `ngHide`, `ngClick`, `ngDblClick`, and `ngMessages`. + * + * Below is a more detailed breakdown of the attributes handled by ngAria: + * + * | Directive | Supported Attributes | + * |---------------------------------------------|----------------------------------------------------------------------------------------| + * | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled | + * | {@link ng.directive:ngShow ngShow} | aria-hidden | + * | {@link ng.directive:ngHide ngHide} | aria-hidden | + * | {@link ng.directive:ngDblclick ngDblclick} | tabindex | + * | {@link module:ngMessages ngMessages} | aria-live | + * | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles | + * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role | + * + * Find out more information about each directive by reading the + * {@link guide/accessibility ngAria Developer Guide}. + * + * ##Example + * Using ngDisabled with ngAria: + * ```html + * + * ``` + * Becomes: + * ```html + * + * ``` + * + * ##Disabling Attributes + * It's possible to disable individual attributes added by ngAria with the + * {@link ngAria.$ariaProvider#config config} method. For more details, see the + * {@link guide/accessibility Developer Guide}. + */ + /* global -ngAriaModule */ +var ngAriaModule = angular.module('ngAria', ['ng']). + provider('$aria', $AriaProvider); + +/** +* Internal Utilities +*/ +var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA', 'SELECT', 'DETAILS', 'SUMMARY']; + +var isNodeOneOf = function(elem, nodeTypeArray) { + if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) { + return true; + } +}; +/** + * @ngdoc provider + * @name $ariaProvider + * + * @description + * + * Used for configuring the ARIA attributes injected and managed by ngAria. + * + * ```js + * angular.module('myApp', ['ngAria'], function config($ariaProvider) { + * $ariaProvider.config({ + * ariaValue: true, + * tabindex: false + * }); + * }); + *``` + * + * ## Dependencies + * Requires the {@link ngAria} module to be installed. + * + */ +function $AriaProvider() { + var config = { + ariaHidden: true, + ariaChecked: true, + ariaDisabled: true, + ariaRequired: true, + ariaInvalid: true, + ariaMultiline: true, + ariaValue: true, + tabindex: true, + bindKeypress: true, + bindRoleForClick: true + }; + + /** + * @ngdoc method + * @name $ariaProvider#config + * + * @param {object} config object to enable/disable specific ARIA attributes + * + * - **ariaHidden** – `{boolean}` – Enables/disables aria-hidden tags + * - **ariaChecked** – `{boolean}` – Enables/disables aria-checked tags + * - **ariaDisabled** – `{boolean}` – Enables/disables aria-disabled tags + * - **ariaRequired** – `{boolean}` – Enables/disables aria-required tags + * - **ariaInvalid** – `{boolean}` – Enables/disables aria-invalid tags + * - **ariaMultiline** – `{boolean}` – Enables/disables aria-multiline tags + * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags + * - **tabindex** – `{boolean}` – Enables/disables tabindex tags + * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on `<div>` and + * `<li>` elements with ng-click + * - **bindRoleForClick** – `{boolean}` – Adds role=button to non-interactive elements like `div` + * using ng-click, making them more accessible to users of assistive technologies + * + * @description + * Enables/disables various ARIA attributes + */ + this.config = function(newConfig) { + config = angular.extend(config, newConfig); + }; + + function watchExpr(attrName, ariaAttr, nodeBlackList, negate) { + return function(scope, elem, attr) { + var ariaCamelName = attr.$normalize(ariaAttr); + if (config[ariaCamelName] && !isNodeOneOf(elem, nodeBlackList) && !attr[ariaCamelName]) { + scope.$watch(attr[attrName], function(boolVal) { + // ensure boolean value + boolVal = negate ? !boolVal : !!boolVal; + elem.attr(ariaAttr, boolVal); + }); + } + }; + } + /** + * @ngdoc service + * @name $aria + * + * @description + * @priority 200 + * + * The $aria service contains helper methods for applying common + * [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives. + * + * ngAria injects common accessibility attributes that tell assistive technologies when HTML + * elements are enabled, selected, hidden, and more. To see how this is performed with ngAria, + * let's review a code snippet from ngAria itself: + * + *```js + * ngAriaModule.directive('ngDisabled', ['$aria', function($aria) { + * return $aria.$$watchExpr('ngDisabled', 'aria-disabled'); + * }]) + *``` + * Shown above, the ngAria module creates a directive with the same signature as the + * traditional `ng-disabled` directive. But this ngAria version is dedicated to + * solely managing accessibility attributes. The internal `$aria` service is used to watch the + * boolean attribute `ngDisabled`. If it has not been explicitly set by the developer, + * `aria-disabled` is injected as an attribute with its value synchronized to the value in + * `ngDisabled`. + * + * Because ngAria hooks into the `ng-disabled` directive, developers do not have to do + * anything to enable this feature. The `aria-disabled` attribute is automatically managed + * simply as a silent side-effect of using `ng-disabled` with the ngAria module. + * + * The full list of directives that interface with ngAria: + * * **ngModel** + * * **ngShow** + * * **ngHide** + * * **ngClick** + * * **ngDblclick** + * * **ngMessages** + * * **ngDisabled** + * + * Read the {@link guide/accessibility ngAria Developer Guide} for a thorough explanation of each + * directive. + * + * + * ## Dependencies + * Requires the {@link ngAria} module to be installed. + */ + this.$get = function() { + return { + config: function(key) { + return config[key]; + }, + $$watchExpr: watchExpr + }; + }; +} + + +ngAriaModule.directive('ngShow', ['$aria', function($aria) { + return $aria.$$watchExpr('ngShow', 'aria-hidden', [], true); +}]) +.directive('ngHide', ['$aria', function($aria) { + return $aria.$$watchExpr('ngHide', 'aria-hidden', [], false); +}]) +.directive('ngModel', ['$aria', function($aria) { + + function shouldAttachAttr(attr, normalizedAttr, elem) { + return $aria.config(normalizedAttr) && !elem.attr(attr); + } + + function shouldAttachRole(role, elem) { + return !elem.attr('role') && (elem.attr('type') === role) && (elem[0].nodeName !== 'INPUT'); + } + + function getShape(attr, elem) { + var type = attr.type, + role = attr.role; + + return ((type || role) === 'checkbox' || role === 'menuitemcheckbox') ? 'checkbox' : + ((type || role) === 'radio' || role === 'menuitemradio') ? 'radio' : + (type === 'range' || role === 'progressbar' || role === 'slider') ? 'range' : + (type || role) === 'textbox' || elem[0].nodeName === 'TEXTAREA' ? 'multiline' : ''; + } + + return { + restrict: 'A', + require: '?ngModel', + priority: 200, //Make sure watches are fired after any other directives that affect the ngModel value + compile: function(elem, attr) { + var shape = getShape(attr, elem); + + return { + pre: function(scope, elem, attr, ngModel) { + if (shape === 'checkbox' && attr.type !== 'checkbox') { + //Use the input[checkbox] $isEmpty implementation for elements with checkbox roles + ngModel.$isEmpty = function(value) { + return value === false; + }; + } + }, + post: function(scope, elem, attr, ngModel) { + var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem) + && !isNodeOneOf(elem, nodeBlackList); + + function ngAriaWatchModelValue() { + return ngModel.$modelValue; + } + + function getRadioReaction() { + if (needsTabIndex) { + needsTabIndex = false; + return function ngAriaRadioReaction(newVal) { + var boolVal = (attr.value == ngModel.$viewValue); + elem.attr('aria-checked', boolVal); + elem.attr('tabindex', 0 - !boolVal); + }; + } else { + return function ngAriaRadioReaction(newVal) { + elem.attr('aria-checked', (attr.value == ngModel.$viewValue)); + }; + } + } + + function ngAriaCheckboxReaction() { + elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue)); + } + + switch (shape) { + case 'radio': + case 'checkbox': + if (shouldAttachRole(shape, elem)) { + elem.attr('role', shape); + } + if (shouldAttachAttr('aria-checked', 'ariaChecked', elem)) { + scope.$watch(ngAriaWatchModelValue, shape === 'radio' ? + getRadioReaction() : ngAriaCheckboxReaction); + } + if (needsTabIndex) { + elem.attr('tabindex', 0); + } + break; + case 'range': + if (shouldAttachRole(shape, elem)) { + elem.attr('role', 'slider'); + } + if ($aria.config('ariaValue')) { + var needsAriaValuemin = !elem.attr('aria-valuemin') && + (attr.hasOwnProperty('min') || attr.hasOwnProperty('ngMin')); + var needsAriaValuemax = !elem.attr('aria-valuemax') && + (attr.hasOwnProperty('max') || attr.hasOwnProperty('ngMax')); + var needsAriaValuenow = !elem.attr('aria-valuenow'); + + if (needsAriaValuemin) { + attr.$observe('min', function ngAriaValueMinReaction(newVal) { + elem.attr('aria-valuemin', newVal); + }); + } + if (needsAriaValuemax) { + attr.$observe('max', function ngAriaValueMinReaction(newVal) { + elem.attr('aria-valuemax', newVal); + }); + } + if (needsAriaValuenow) { + scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) { + elem.attr('aria-valuenow', newVal); + }); + } + } + if (needsTabIndex) { + elem.attr('tabindex', 0); + } + break; + case 'multiline': + if (shouldAttachAttr('aria-multiline', 'ariaMultiline', elem)) { + elem.attr('aria-multiline', true); + } + break; + } + + if (ngModel.$validators.required && shouldAttachAttr('aria-required', 'ariaRequired', elem)) { + scope.$watch(function ngAriaRequiredWatch() { + return ngModel.$error.required; + }, function ngAriaRequiredReaction(newVal) { + elem.attr('aria-required', !!newVal); + }); + } + + if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem)) { + scope.$watch(function ngAriaInvalidWatch() { + return ngModel.$invalid; + }, function ngAriaInvalidReaction(newVal) { + elem.attr('aria-invalid', !!newVal); + }); + } + } + }; + } + }; +}]) +.directive('ngDisabled', ['$aria', function($aria) { + return $aria.$$watchExpr('ngDisabled', 'aria-disabled', []); +}]) +.directive('ngMessages', function() { + return { + restrict: 'A', + require: '?ngMessages', + link: function(scope, elem, attr, ngMessages) { + if (!elem.attr('aria-live')) { + elem.attr('aria-live', 'assertive'); + } + } + }; +}) +.directive('ngClick',['$aria', '$parse', function($aria, $parse) { + return { + restrict: 'A', + compile: function(elem, attr) { + var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true); + return function(scope, elem, attr) { + + if (!isNodeOneOf(elem, nodeBlackList)) { + + if ($aria.config('bindRoleForClick') && !elem.attr('role')) { + elem.attr('role', 'button'); + } + + if ($aria.config('tabindex') && !elem.attr('tabindex')) { + elem.attr('tabindex', 0); + } + + if ($aria.config('bindKeypress') && !attr.ngKeypress) { + elem.on('keypress', function(event) { + var keyCode = event.which || event.keyCode; + if (keyCode === 32 || keyCode === 13) { + scope.$apply(callback); + } + + function callback() { + fn(scope, { $event: event }); + } + }); + } + } + }; + } + }; +}]) +.directive('ngDblclick', ['$aria', function($aria) { + return function(scope, elem, attr) { + if ($aria.config('tabindex') && !elem.attr('tabindex') && !isNodeOneOf(elem, nodeBlackList)) { + elem.attr('tabindex', 0); + } + }; +}]); + + +})(window, window.angular); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-aria.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-aria.min.js new file mode 100644 index 00000000..4e6fb7c7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-aria.min.js @@ -0,0 +1,14 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(u,n,v){'use strict';var r="BUTTON A INPUT TEXTAREA SELECT DETAILS SUMMARY".split(" "),p=function(a,c){if(-1!==c.indexOf(a[0].nodeName))return!0};n.module("ngAria",["ng"]).provider("$aria",function(){function a(a,f,l,m){return function(d,e,b){var g=b.$normalize(f);!c[g]||p(e,l)||b[g]||d.$watch(b[a],function(b){b=m?!b:!!b;e.attr(f,b)})}}var c={ariaHidden:!0,ariaChecked:!0,ariaDisabled:!0,ariaRequired:!0,ariaInvalid:!0,ariaMultiline:!0,ariaValue:!0,tabindex:!0,bindKeypress:!0,bindRoleForClick:!0}; +this.config=function(a){c=n.extend(c,a)};this.$get=function(){return{config:function(a){return c[a]},$$watchExpr:a}}}).directive("ngShow",["$aria",function(a){return a.$$watchExpr("ngShow","aria-hidden",[],!0)}]).directive("ngHide",["$aria",function(a){return a.$$watchExpr("ngHide","aria-hidden",[],!1)}]).directive("ngModel",["$aria",function(a){function c(c,m,d){return a.config(m)&&!d.attr(c)}function k(a,c){return!c.attr("role")&&c.attr("type")===a&&"INPUT"!==c[0].nodeName}function f(a,c){var d= +a.type,e=a.role;return"checkbox"===(d||e)||"menuitemcheckbox"===e?"checkbox":"radio"===(d||e)||"menuitemradio"===e?"radio":"range"===d||"progressbar"===e||"slider"===e?"range":"textbox"===(d||e)||"TEXTAREA"===c[0].nodeName?"multiline":""}return{restrict:"A",require:"?ngModel",priority:200,compile:function(l,m){var d=f(m,l);return{pre:function(a,b,c,h){"checkbox"===d&&"checkbox"!==c.type&&(h.$isEmpty=function(b){return!1===b})},post:function(e,b,g,h){function f(){return h.$modelValue}function m(){return q? +(q=!1,function(a){a=g.value==h.$viewValue;b.attr("aria-checked",a);b.attr("tabindex",0-!a)}):function(a){b.attr("aria-checked",g.value==h.$viewValue)}}function l(){b.attr("aria-checked",!h.$isEmpty(h.$viewValue))}var q=c("tabindex","tabindex",b)&&!p(b,r);switch(d){case "radio":case "checkbox":k(d,b)&&b.attr("role",d);c("aria-checked","ariaChecked",b)&&e.$watch(f,"radio"===d?m():l);q&&b.attr("tabindex",0);break;case "range":k(d,b)&&b.attr("role","slider");if(a.config("ariaValue")){var n=!b.attr("aria-valuemin")&& +(g.hasOwnProperty("min")||g.hasOwnProperty("ngMin")),s=!b.attr("aria-valuemax")&&(g.hasOwnProperty("max")||g.hasOwnProperty("ngMax")),t=!b.attr("aria-valuenow");n&&g.$observe("min",function(a){b.attr("aria-valuemin",a)});s&&g.$observe("max",function(a){b.attr("aria-valuemax",a)});t&&e.$watch(f,function(a){b.attr("aria-valuenow",a)})}q&&b.attr("tabindex",0);break;case "multiline":c("aria-multiline","ariaMultiline",b)&&b.attr("aria-multiline",!0)}h.$validators.required&&c("aria-required","ariaRequired", +b)&&e.$watch(function(){return h.$error.required},function(a){b.attr("aria-required",!!a)});c("aria-invalid","ariaInvalid",b)&&e.$watch(function(){return h.$invalid},function(a){b.attr("aria-invalid",!!a)})}}}}}]).directive("ngDisabled",["$aria",function(a){return a.$$watchExpr("ngDisabled","aria-disabled",[])}]).directive("ngMessages",function(){return{restrict:"A",require:"?ngMessages",link:function(a,c,k,f){c.attr("aria-live")||c.attr("aria-live","assertive")}}}).directive("ngClick",["$aria","$parse", +function(a,c){return{restrict:"A",compile:function(k,f){var l=c(f.ngClick,null,!0);return function(c,d,e){if(!p(d,r)&&(a.config("bindRoleForClick")&&!d.attr("role")&&d.attr("role","button"),a.config("tabindex")&&!d.attr("tabindex")&&d.attr("tabindex",0),a.config("bindKeypress")&&!e.ngKeypress))d.on("keypress",function(a){function d(){l(c,{$event:a})}var e=a.which||a.keyCode;32!==e&&13!==e||c.$apply(d)})}}}}]).directive("ngDblclick",["$aria",function(a){return function(c,k,f){!a.config("tabindex")|| +k.attr("tabindex")||p(k,r)||k.attr("tabindex",0)}}])})(window,window.angular); +//# sourceMappingURL=angular-aria.min.js.map diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-aria.min.js.map b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-aria.min.js.map new file mode 100644 index 00000000..13000e15 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-aria.min.js.map @@ -0,0 +1,8 @@ +{ +"version":3, +"file":"angular-aria.min.js", +"lineCount":13, +"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAyDtC,IAAIC,EAAgB,gDAAA,MAAA,CAAA,GAAA,CAApB,CAEIC,EAAcA,QAAQ,CAACC,CAAD,CAAOC,CAAP,CAAsB,CAC9C,GAAiD,EAAjD,GAAIA,CAAAC,QAAA,CAAsBF,CAAA,CAAK,CAAL,CAAAG,SAAtB,CAAJ,CACE,MAAO,CAAA,CAFqC,CAR7BP,EAAAQ,OAAA,CAAe,QAAf,CAAyB,CAAC,IAAD,CAAzB,CAAAC,SAAAC,CACc,OADdA,CAkCnBC,QAAsB,EAAG,CAwCvBC,QAASA,EAAS,CAACC,CAAD,CAAWC,CAAX,CAAqBZ,CAArB,CAAoCa,CAApC,CAA4C,CAC5D,MAAO,SAAQ,CAACC,CAAD,CAAQZ,CAAR,CAAca,CAAd,CAAoB,CACjC,IAAIC,EAAgBD,CAAAE,WAAA,CAAgBL,CAAhB,CAChB,EAAAM,CAAA,CAAOF,CAAP,CAAJ,EAA8Bf,CAAA,CAAYC,CAAZ,CAAkBF,CAAlB,CAA9B,EAAmEe,CAAA,CAAKC,CAAL,CAAnE,EACEF,CAAAK,OAAA,CAAaJ,CAAA,CAAKJ,CAAL,CAAb,CAA6B,QAAQ,CAACS,CAAD,CAAU,CAE7CA,CAAA,CAAUP,CAAA,CAAS,CAACO,CAAV,CAAoB,CAAEA,CAAAA,CAChClB,EAAAa,KAAA,CAAUH,CAAV,CAAoBQ,CAApB,CAH6C,CAA/C,CAH+B,CADyB,CAvC9D,IAAIF,EAAS,CACXG,WAAY,CAAA,CADD,CAEXC,YAAa,CAAA,CAFF,CAGXC,aAAc,CAAA,CAHH,CAIXC,aAAc,CAAA,CAJH,CAKXC,YAAa,CAAA,CALF,CAMXC,cAAe,CAAA,CANJ,CAOXC,UAAW,CAAA,CAPA,CAQXC,SAAU,CAAA,CARC,CASXC,aAAc,CAAA,CATH,CAUXC,iBAAkB,CAAA,CAVP,CAmCb;IAAAZ,OAAA,CAAca,QAAQ,CAACC,CAAD,CAAY,CAChCd,CAAA,CAASpB,CAAAmC,OAAA,CAAef,CAAf,CAAuBc,CAAvB,CADuB,CA8DlC,KAAAE,KAAA,CAAYC,QAAQ,EAAG,CACrB,MAAO,CACLjB,OAAQA,QAAQ,CAACkB,CAAD,CAAM,CACpB,MAAOlB,EAAA,CAAOkB,CAAP,CADa,CADjB,CAILC,YAAa3B,CAJR,CADc,CAlGA,CAlCNF,CA+InB8B,UAAA,CAAuB,QAAvB,CAAiC,CAAC,OAAD,CAAU,QAAQ,CAACC,CAAD,CAAQ,CACzD,MAAOA,EAAAF,YAAA,CAAkB,QAAlB,CAA4B,aAA5B,CAA2C,EAA3C,CAA+C,CAAA,CAA/C,CADkD,CAA1B,CAAjC,CAAAC,UAAA,CAGW,QAHX,CAGqB,CAAC,OAAD,CAAU,QAAQ,CAACC,CAAD,CAAQ,CAC7C,MAAOA,EAAAF,YAAA,CAAkB,QAAlB,CAA4B,aAA5B,CAA2C,EAA3C,CAA+C,CAAA,CAA/C,CADsC,CAA1B,CAHrB,CAAAC,UAAA,CAMW,SANX,CAMsB,CAAC,OAAD,CAAU,QAAQ,CAACC,CAAD,CAAQ,CAE9CC,QAASA,EAAgB,CAACzB,CAAD,CAAO0B,CAAP,CAAuBvC,CAAvB,CAA6B,CACpD,MAAOqC,EAAArB,OAAA,CAAauB,CAAb,CAAP,EAAuC,CAACvC,CAAAa,KAAA,CAAUA,CAAV,CADY,CAItD2B,QAASA,EAAgB,CAACC,CAAD,CAAOzC,CAAP,CAAa,CACpC,MAAO,CAACA,CAAAa,KAAA,CAAU,MAAV,CAAR,EAA8Bb,CAAAa,KAAA,CAAU,MAAV,CAA9B,GAAoD4B,CAApD,EAAmF,OAAnF,GAA8DzC,CAAA,CAAK,CAAL,CAAAG,SAD1B,CAItCuC,QAASA,EAAQ,CAAC7B,CAAD,CAAOb,CAAP,CAAa,CAAA,IACxB2C;AAAO9B,CAAA8B,KADiB,CAExBF,EAAO5B,CAAA4B,KAEX,OAA2B,UAApB,IAAEE,CAAF,EAAUF,CAAV,GAA2C,kBAA3C,GAAkCA,CAAlC,CAAiE,UAAjE,CACoB,OAApB,IAAEE,CAAF,EAAUF,CAAV,GAA2C,eAA3C,GAAkCA,CAAlC,CAA8D,OAA9D,CACU,OAAV,GAACE,CAAD,EAA2C,aAA3C,GAAkCF,CAAlC,EAAqE,QAArE,GAA4DA,CAA5D,CAAiF,OAAjF,CACmB,SAAnB,IAACE,CAAD,EAASF,CAAT,GAAuD,UAAvD,GAAkCzC,CAAA,CAAK,CAAL,CAAAG,SAAlC,CAAoE,WAApE,CAAkF,EAP7D,CAU9B,MAAO,CACLyC,SAAU,GADL,CAELC,QAAS,UAFJ,CAGLC,SAAU,GAHL,CAILC,QAASA,QAAQ,CAAC/C,CAAD,CAAOa,CAAP,CAAa,CAC5B,IAAImC,EAAQN,CAAA,CAAS7B,CAAT,CAAeb,CAAf,CAEZ,OAAO,CACLiD,IAAKA,QAAQ,CAACrC,CAAD,CAAQZ,CAAR,CAAca,CAAd,CAAoBqC,CAApB,CAA6B,CAC1B,UAAd,GAAIF,CAAJ,EAA0C,UAA1C,GAA4BnC,CAAA8B,KAA5B,GAEEO,CAAAC,SAFF,CAEqBC,QAAQ,CAACC,CAAD,CAAQ,CACjC,MAAiB,CAAA,CAAjB,GAAOA,CAD0B,CAFrC,CADwC,CADrC,CASLC,KAAMA,QAAQ,CAAC1C,CAAD,CAAQZ,CAAR,CAAca,CAAd,CAAoBqC,CAApB,CAA6B,CAIzCK,QAASA,EAAqB,EAAG,CAC/B,MAAOL,EAAAM,YADwB,CAIjCC,QAASA,EAAgB,EAAG,CAC1B,MAAIC,EAAJ;CACEA,CACOC,CADS,CAAA,CACTA,CAAAA,QAA4B,CAACC,CAAD,CAAS,CACtC1C,CAAAA,CAAWL,CAAAwC,MAAXnC,EAAyBgC,CAAAW,WAC7B7D,EAAAa,KAAA,CAAU,cAAV,CAA0BK,CAA1B,CACAlB,EAAAa,KAAA,CAAU,UAAV,CAAsB,CAAtB,CAA0B,CAACK,CAA3B,CAH0C,CAF9C,EAQSyC,QAA4B,CAACC,CAAD,CAAS,CAC1C5D,CAAAa,KAAA,CAAU,cAAV,CAA2BA,CAAAwC,MAA3B,EAAyCH,CAAAW,WAAzC,CAD0C,CATpB,CAe5BC,QAASA,EAAsB,EAAG,CAChC9D,CAAAa,KAAA,CAAU,cAAV,CAA0B,CAACqC,CAAAC,SAAA,CAAiBD,CAAAW,WAAjB,CAA3B,CADgC,CAtBlC,IAAIH,EAAgBpB,CAAA,CAAiB,UAAjB,CAA6B,UAA7B,CAAyCtC,CAAzC,CAAhB0D,EACqB,CAAC3D,CAAA,CAAYC,CAAZ,CAAkBF,CAAlB,CAyB1B,QAAQkD,CAAR,EACE,KAAK,OAAL,CACA,KAAK,UAAL,CACMR,CAAA,CAAiBQ,CAAjB,CAAwBhD,CAAxB,CAAJ,EACEA,CAAAa,KAAA,CAAU,MAAV,CAAkBmC,CAAlB,CAEEV,EAAA,CAAiB,cAAjB,CAAiC,aAAjC,CAAgDtC,CAAhD,CAAJ,EACEY,CAAAK,OAAA,CAAasC,CAAb,CAA8C,OAAV,GAAAP,CAAA,CAChCS,CAAA,EADgC,CACXK,CADzB,CAGEJ,EAAJ,EACE1D,CAAAa,KAAA,CAAU,UAAV,CAAsB,CAAtB,CAEF,MACF,MAAK,OAAL,CACM2B,CAAA,CAAiBQ,CAAjB,CAAwBhD,CAAxB,CAAJ,EACEA,CAAAa,KAAA,CAAU,MAAV,CAAkB,QAAlB,CAEF,IAAIwB,CAAArB,OAAA,CAAa,WAAb,CAAJ,CAA+B,CAC7B,IAAI+C,EAAoB,CAAC/D,CAAAa,KAAA,CAAU,eAAV,CAArBkD;CACClD,CAAAmD,eAAA,CAAoB,KAApB,CADDD,EAC+BlD,CAAAmD,eAAA,CAAoB,OAApB,CAD/BD,CAAJ,CAEIE,EAAoB,CAACjE,CAAAa,KAAA,CAAU,eAAV,CAArBoD,GACCpD,CAAAmD,eAAA,CAAoB,KAApB,CADDC,EAC+BpD,CAAAmD,eAAA,CAAoB,OAApB,CAD/BC,CAFJ,CAIIC,EAAoB,CAAClE,CAAAa,KAAA,CAAU,eAAV,CAErBkD,EAAJ,EACElD,CAAAsD,SAAA,CAAc,KAAd,CAAqBC,QAA+B,CAACR,CAAD,CAAS,CAC3D5D,CAAAa,KAAA,CAAU,eAAV,CAA2B+C,CAA3B,CAD2D,CAA7D,CAIEK,EAAJ,EACEpD,CAAAsD,SAAA,CAAc,KAAd,CAAqBC,QAA+B,CAACR,CAAD,CAAS,CAC3D5D,CAAAa,KAAA,CAAU,eAAV,CAA2B+C,CAA3B,CAD2D,CAA7D,CAIEM,EAAJ,EACEtD,CAAAK,OAAA,CAAasC,CAAb,CAAoCc,QAA+B,CAACT,CAAD,CAAS,CAC1E5D,CAAAa,KAAA,CAAU,eAAV,CAA2B+C,CAA3B,CAD0E,CAA5E,CAlB2B,CAuB3BF,CAAJ,EACE1D,CAAAa,KAAA,CAAU,UAAV,CAAsB,CAAtB,CAEF,MACF,MAAK,WAAL,CACMyB,CAAA,CAAiB,gBAAjB,CAAmC,eAAnC,CAAoDtC,CAApD,CAAJ,EACEA,CAAAa,KAAA,CAAU,gBAAV,CAA4B,CAAA,CAA5B,CA/CN,CAoDIqC,CAAAoB,YAAAC,SAAJ,EAAoCjC,CAAA,CAAiB,eAAjB,CAAkC,cAAlC;AAAkDtC,CAAlD,CAApC,EACEY,CAAAK,OAAA,CAAauD,QAA4B,EAAG,CAC1C,MAAOtB,EAAAuB,OAAAF,SADmC,CAA5C,CAEGG,QAA+B,CAACd,CAAD,CAAS,CACzC5D,CAAAa,KAAA,CAAU,eAAV,CAA2B,CAAE+C,CAAAA,CAA7B,CADyC,CAF3C,CAOEtB,EAAA,CAAiB,cAAjB,CAAiC,aAAjC,CAAgDtC,CAAhD,CAAJ,EACEY,CAAAK,OAAA,CAAa0D,QAA2B,EAAG,CACzC,MAAOzB,EAAA0B,SADkC,CAA3C,CAEGC,QAA8B,CAACjB,CAAD,CAAS,CACxC5D,CAAAa,KAAA,CAAU,cAAV,CAA0B,CAAE+C,CAAAA,CAA5B,CADwC,CAF1C,CAxFuC,CATtC,CAHqB,CAJzB,CApBuC,CAA1B,CANtB,CAAAxB,UAAA,CA6IW,YA7IX,CA6IyB,CAAC,OAAD,CAAU,QAAQ,CAACC,CAAD,CAAQ,CACjD,MAAOA,EAAAF,YAAA,CAAkB,YAAlB,CAAgC,eAAhC,CAAiD,EAAjD,CAD0C,CAA1B,CA7IzB,CAAAC,UAAA,CAgJW,YAhJX,CAgJyB,QAAQ,EAAG,CAClC,MAAO,CACLQ,SAAU,GADL,CAELC,QAAS,aAFJ,CAGLiC,KAAMA,QAAQ,CAAClE,CAAD,CAAQZ,CAAR,CAAca,CAAd,CAAoBkE,CAApB,CAAgC,CACvC/E,CAAAa,KAAA,CAAU,WAAV,CAAL,EACEb,CAAAa,KAAA,CAAU,WAAV,CAAuB,WAAvB,CAF0C,CAHzC,CAD2B,CAhJpC,CAAAuB,UAAA,CA2JW,SA3JX,CA2JqB,CAAC,OAAD,CAAU,QAAV;AAAoB,QAAQ,CAACC,CAAD,CAAQ2C,CAAR,CAAgB,CAC/D,MAAO,CACLpC,SAAU,GADL,CAELG,QAASA,QAAQ,CAAC/C,CAAD,CAAOa,CAAP,CAAa,CAC5B,IAAIoE,EAAKD,CAAA,CAAOnE,CAAAqE,QAAP,CAAyC,IAAzC,CAAqE,CAAA,CAArE,CACT,OAAO,SAAQ,CAACtE,CAAD,CAAQZ,CAAR,CAAca,CAAd,CAAoB,CAEjC,GAAK,CAAAd,CAAA,CAAYC,CAAZ,CAAkBF,CAAlB,CAAL,GAEMuC,CAAArB,OAAA,CAAa,kBAAb,CAQA,EARqC,CAAAhB,CAAAa,KAAA,CAAU,MAAV,CAQrC,EAPFb,CAAAa,KAAA,CAAU,MAAV,CAAkB,QAAlB,CAOE,CAJAwB,CAAArB,OAAA,CAAa,UAAb,CAIA,EAJ6B,CAAAhB,CAAAa,KAAA,CAAU,UAAV,CAI7B,EAHFb,CAAAa,KAAA,CAAU,UAAV,CAAsB,CAAtB,CAGE,CAAAwB,CAAArB,OAAA,CAAa,cAAb,CAAA,EAAiCmE,CAAAtE,CAAAsE,WAVvC,EAWInF,CAAAoF,GAAA,CAAQ,UAAR,CAAoB,QAAQ,CAACC,CAAD,CAAQ,CAMlCC,QAASA,EAAQ,EAAG,CAClBL,CAAA,CAAGrE,CAAH,CAAU,CAAE2E,OAAQF,CAAV,CAAV,CADkB,CALpB,IAAIG,EAAUH,CAAAI,MAAVD,EAAyBH,CAAAG,QACb,GAAhB,GAAIA,CAAJ,EAAkC,EAAlC,GAAsBA,CAAtB,EACE5E,CAAA8E,OAAA,CAAaJ,CAAb,CAHgC,CAApC,CAb6B,CAFP,CAFzB,CADwD,CAA5C,CA3JrB,CAAAlD,UAAA,CA6LW,YA7LX,CA6LyB,CAAC,OAAD,CAAU,QAAQ,CAACC,CAAD,CAAQ,CACjD,MAAO,SAAQ,CAACzB,CAAD,CAAQZ,CAAR,CAAca,CAAd,CAAoB,CAC7B,CAAAwB,CAAArB,OAAA,CAAa,UAAb,CAAJ;AAAiChB,CAAAa,KAAA,CAAU,UAAV,CAAjC,EAA2Dd,CAAA,CAAYC,CAAZ,CAAkBF,CAAlB,CAA3D,EACEE,CAAAa,KAAA,CAAU,UAAV,CAAsB,CAAtB,CAF+B,CADc,CAA1B,CA7LzB,CAlMsC,CAArC,CAAD,CAwYGlB,MAxYH,CAwYWA,MAAAC,QAxYX;", +"sources":["angular-aria.js"], +"names":["window","angular","undefined","nodeBlackList","isNodeOneOf","elem","nodeTypeArray","indexOf","nodeName","module","provider","ngAriaModule","$AriaProvider","watchExpr","attrName","ariaAttr","negate","scope","attr","ariaCamelName","$normalize","config","$watch","boolVal","ariaHidden","ariaChecked","ariaDisabled","ariaRequired","ariaInvalid","ariaMultiline","ariaValue","tabindex","bindKeypress","bindRoleForClick","this.config","newConfig","extend","$get","this.$get","key","$$watchExpr","directive","$aria","shouldAttachAttr","normalizedAttr","shouldAttachRole","role","getShape","type","restrict","require","priority","compile","shape","pre","ngModel","$isEmpty","ngModel.$isEmpty","value","post","ngAriaWatchModelValue","$modelValue","getRadioReaction","needsTabIndex","ngAriaRadioReaction","newVal","$viewValue","ngAriaCheckboxReaction","needsAriaValuemin","hasOwnProperty","needsAriaValuemax","needsAriaValuenow","$observe","ngAriaValueMinReaction","ngAriaValueNowReaction","$validators","required","ngAriaRequiredWatch","$error","ngAriaRequiredReaction","ngAriaInvalidWatch","$invalid","ngAriaInvalidReaction","link","ngMessages","$parse","fn","ngClick","ngKeypress","on","event","callback","$event","keyCode","which","$apply"] +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.js new file mode 100644 index 00000000..8a04e120 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.js @@ -0,0 +1,321 @@ +/** + * @license AngularJS v1.4.8 + * (c) 2010-2015 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +/** + * @ngdoc module + * @name ngCookies + * @description + * + * # ngCookies + * + * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies. + * + * + *
    + * + * See {@link ngCookies.$cookies `$cookies`} for usage. + */ + + +angular.module('ngCookies', ['ng']). + /** + * @ngdoc provider + * @name $cookiesProvider + * @description + * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service. + * */ + provider('$cookies', [function $CookiesProvider() { + /** + * @ngdoc property + * @name $cookiesProvider#defaults + * @description + * + * Object containing default options to pass when setting cookies. + * + * The object may have following properties: + * + * - **path** - `{string}` - The cookie will be available only for this path and its + * sub-paths. By default, this would be the URL that appears in your base tag. + * - **domain** - `{string}` - The cookie will be available only for this domain and + * its sub-domains. For obvious security reasons the user agent will not accept the + * cookie if the current domain is not a sub domain or equals to the requested domain. + * - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT" + * or a Date object indicating the exact date/time this cookie will expire. + * - **secure** - `{boolean}` - The cookie will be available only in secured connection. + * + * Note: by default the address that appears in your `` tag will be used as path. + * This is important so that cookies will be visible for all routes in case html5mode is enabled + * + **/ + var defaults = this.defaults = {}; + + function calcOptions(options) { + return options ? angular.extend({}, defaults, options) : defaults; + } + + /** + * @ngdoc service + * @name $cookies + * + * @description + * Provides read/write access to browser's cookies. + * + *
    + * Up until Angular 1.3, `$cookies` exposed properties that represented the + * current browser cookie values. In version 1.4, this behavior has changed, and + * `$cookies` now provides a standard api of getters, setters etc. + *
    + * + * Requires the {@link ngCookies `ngCookies`} module to be installed. + * + * @example + * + * ```js + * angular.module('cookiesExample', ['ngCookies']) + * .controller('ExampleController', ['$cookies', function($cookies) { + * // Retrieving a cookie + * var favoriteCookie = $cookies.get('myFavorite'); + * // Setting a cookie + * $cookies.put('myFavorite', 'oatmeal'); + * }]); + * ``` + */ + this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) { + return { + /** + * @ngdoc method + * @name $cookies#get + * + * @description + * Returns the value of given cookie key + * + * @param {string} key Id to use for lookup. + * @returns {string} Raw cookie value. + */ + get: function(key) { + return $$cookieReader()[key]; + }, + + /** + * @ngdoc method + * @name $cookies#getObject + * + * @description + * Returns the deserialized value of given cookie key + * + * @param {string} key Id to use for lookup. + * @returns {Object} Deserialized cookie value. + */ + getObject: function(key) { + var value = this.get(key); + return value ? angular.fromJson(value) : value; + }, + + /** + * @ngdoc method + * @name $cookies#getAll + * + * @description + * Returns a key value object with all the cookies + * + * @returns {Object} All cookies + */ + getAll: function() { + return $$cookieReader(); + }, + + /** + * @ngdoc method + * @name $cookies#put + * + * @description + * Sets a value for given cookie key + * + * @param {string} key Id for the `value`. + * @param {string} value Raw value to be stored. + * @param {Object=} options Options object. + * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults} + */ + put: function(key, value, options) { + $$cookieWriter(key, value, calcOptions(options)); + }, + + /** + * @ngdoc method + * @name $cookies#putObject + * + * @description + * Serializes and sets a value for given cookie key + * + * @param {string} key Id for the `value`. + * @param {Object} value Value to be stored. + * @param {Object=} options Options object. + * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults} + */ + putObject: function(key, value, options) { + this.put(key, angular.toJson(value), options); + }, + + /** + * @ngdoc method + * @name $cookies#remove + * + * @description + * Remove given cookie + * + * @param {string} key Id of the key-value pair to delete. + * @param {Object=} options Options object. + * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults} + */ + remove: function(key, options) { + $$cookieWriter(key, undefined, calcOptions(options)); + } + }; + }]; + }]); + +angular.module('ngCookies'). +/** + * @ngdoc service + * @name $cookieStore + * @deprecated + * @requires $cookies + * + * @description + * Provides a key-value (string-object) storage, that is backed by session cookies. + * Objects put or retrieved from this storage are automatically serialized or + * deserialized by angular's toJson/fromJson. + * + * Requires the {@link ngCookies `ngCookies`} module to be installed. + * + *
    + * **Note:** The $cookieStore service is **deprecated**. + * Please use the {@link ngCookies.$cookies `$cookies`} service instead. + *
    + * + * @example + * + * ```js + * angular.module('cookieStoreExample', ['ngCookies']) + * .controller('ExampleController', ['$cookieStore', function($cookieStore) { + * // Put cookie + * $cookieStore.put('myFavorite','oatmeal'); + * // Get cookie + * var favoriteCookie = $cookieStore.get('myFavorite'); + * // Removing a cookie + * $cookieStore.remove('myFavorite'); + * }]); + * ``` + */ + factory('$cookieStore', ['$cookies', function($cookies) { + + return { + /** + * @ngdoc method + * @name $cookieStore#get + * + * @description + * Returns the value of given cookie key + * + * @param {string} key Id to use for lookup. + * @returns {Object} Deserialized cookie value, undefined if the cookie does not exist. + */ + get: function(key) { + return $cookies.getObject(key); + }, + + /** + * @ngdoc method + * @name $cookieStore#put + * + * @description + * Sets a value for given cookie key + * + * @param {string} key Id for the `value`. + * @param {Object} value Value to be stored. + */ + put: function(key, value) { + $cookies.putObject(key, value); + }, + + /** + * @ngdoc method + * @name $cookieStore#remove + * + * @description + * Remove given cookie + * + * @param {string} key Id of the key-value pair to delete. + */ + remove: function(key) { + $cookies.remove(key); + } + }; + + }]); + +/** + * @name $$cookieWriter + * @requires $document + * + * @description + * This is a private service for writing cookies + * + * @param {string} name Cookie name + * @param {string=} value Cookie value (if undefined, cookie will be deleted) + * @param {Object=} options Object with options that need to be stored for the cookie. + */ +function $$CookieWriter($document, $log, $browser) { + var cookiePath = $browser.baseHref(); + var rawDocument = $document[0]; + + function buildCookieString(name, value, options) { + var path, expires; + options = options || {}; + expires = options.expires; + path = angular.isDefined(options.path) ? options.path : cookiePath; + if (angular.isUndefined(value)) { + expires = 'Thu, 01 Jan 1970 00:00:00 GMT'; + value = ''; + } + if (angular.isString(expires)) { + expires = new Date(expires); + } + + var str = encodeURIComponent(name) + '=' + encodeURIComponent(value); + str += path ? ';path=' + path : ''; + str += options.domain ? ';domain=' + options.domain : ''; + str += expires ? ';expires=' + expires.toUTCString() : ''; + str += options.secure ? ';secure' : ''; + + // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum: + // - 300 cookies + // - 20 cookies per unique domain + // - 4096 bytes per cookie + var cookieLength = str.length + 1; + if (cookieLength > 4096) { + $log.warn("Cookie '" + name + + "' possibly not set or overflowed because it was too large (" + + cookieLength + " > 4096 bytes)!"); + } + + return str; + } + + return function(name, value, options) { + rawDocument.cookie = buildCookieString(name, value, options); + }; +} + +$$CookieWriter.$inject = ['$document', '$log', '$browser']; + +angular.module('ngCookies').provider('$$cookieWriter', function $$CookieWriterProvider() { + this.$get = $$CookieWriter; +}); + + +})(window, window.angular); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.min.js new file mode 100644 index 00000000..6a1bab08 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.min.js @@ -0,0 +1,9 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(p,c,n){'use strict';function l(b,a,g){var d=g.baseHref(),k=b[0];return function(b,e,f){var g,h;f=f||{};h=f.expires;g=c.isDefined(f.path)?f.path:d;c.isUndefined(e)&&(h="Thu, 01 Jan 1970 00:00:00 GMT",e="");c.isString(h)&&(h=new Date(h));e=encodeURIComponent(b)+"="+encodeURIComponent(e);e=e+(g?";path="+g:"")+(f.domain?";domain="+f.domain:"");e+=h?";expires="+h.toUTCString():"";e+=f.secure?";secure":"";f=e.length+1;4096 4096 bytes)!");k.cookie=e}}c.module("ngCookies",["ng"]).provider("$cookies",[function(){var b=this.defaults={};this.$get=["$$cookieReader","$$cookieWriter",function(a,g){return{get:function(d){return a()[d]},getObject:function(d){return(d=this.get(d))?c.fromJson(d):d},getAll:function(){return a()},put:function(d,a,m){g(d,a,m?c.extend({},b,m):b)},putObject:function(d,b,a){this.put(d,c.toJson(b),a)},remove:function(a,k){g(a,n,k?c.extend({},b,k):b)}}}]}]);c.module("ngCookies").factory("$cookieStore", +["$cookies",function(b){return{get:function(a){return b.getObject(a)},put:function(a,c){b.putObject(a,c)},remove:function(a){b.remove(a)}}}]);l.$inject=["$document","$log","$browser"];c.module("ngCookies").provider("$$cookieWriter",function(){this.$get=l})})(window,window.angular); +//# sourceMappingURL=angular-cookies.min.js.map diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.min.js.map b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.min.js.map new file mode 100644 index 00000000..d269e1f2 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-cookies.min.js.map @@ -0,0 +1,8 @@ +{ +"version":3, +"file":"angular-cookies.min.js", +"lineCount":8, +"mappings":"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", +"sources":["angular-cookies.js"], +"names":["window","angular","undefined","$$CookieWriter","$document","$log","$browser","cookiePath","baseHref","rawDocument","name","value","options","path","expires","isDefined","isUndefined","isString","Date","str","encodeURIComponent","domain","toUTCString","secure","cookieLength","length","warn","cookie","module","provider","$CookiesProvider","defaults","$get","$$cookieReader","$$cookieWriter","get","key","getObject","fromJson","getAll","put","extend","putObject","toJson","remove","factory","$cookies","$inject","$$CookieWriterProvider"] +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-csp.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-csp.css new file mode 100644 index 00000000..f3cd926c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-csp.css @@ -0,0 +1,21 @@ +/* Include this file in your html if you are using the CSP mode. */ + +@charset "UTF-8"; + +[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], +.ng-cloak, .x-ng-cloak, +.ng-hide:not(.ng-hide-animate) { + display: none !important; +} + +ng\:form { + display: block; +} + +.ng-animate-shim { + visibility:hidden; +} + +.ng-anchor { + position:absolute; +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-loader.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-loader.js new file mode 100644 index 00000000..992b129b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-loader.js @@ -0,0 +1,443 @@ +/** + * @license AngularJS v1.4.8 + * (c) 2010-2015 Google, Inc. http://angularjs.org + * License: MIT + */ + +(function() {'use strict'; + function isFunction(value) {return typeof value === 'function';}; + +/** + * @description + * + * This object provides a utility for producing rich Error messages within + * Angular. It can be called as follows: + * + * var exampleMinErr = minErr('example'); + * throw exampleMinErr('one', 'This {0} is {1}', foo, bar); + * + * The above creates an instance of minErr in the example namespace. The + * resulting error will have a namespaced error code of example.one. The + * resulting error will replace {0} with the value of foo, and {1} with the + * value of bar. The object is not restricted in the number of arguments it can + * take. + * + * If fewer arguments are specified than necessary for interpolation, the extra + * interpolation markers will be preserved in the final string. + * + * Since data will be parsed statically during a build step, some restrictions + * are applied with respect to how minErr instances are created and called. + * Instances should have names of the form namespaceMinErr for a minErr created + * using minErr('namespace') . Error codes, namespaces and template strings + * should all be static strings, not variables or general expressions. + * + * @param {string} module The namespace to use for the new minErr instance. + * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning + * error from returned function, for cases when a particular type of error is useful. + * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance + */ + +function minErr(module, ErrorConstructor) { + ErrorConstructor = ErrorConstructor || Error; + return function() { + var SKIP_INDEXES = 2; + + var templateArgs = arguments, + code = templateArgs[0], + message = '[' + (module ? module + ':' : '') + code + '] ', + template = templateArgs[1], + paramPrefix, i; + + message += template.replace(/\{\d+\}/g, function(match) { + var index = +match.slice(1, -1), + shiftedIndex = index + SKIP_INDEXES; + + if (shiftedIndex < templateArgs.length) { + return toDebugString(templateArgs[shiftedIndex]); + } + + return match; + }); + + message += '\nhttp://errors.angularjs.org/1.4.8/' + + (module ? module + '/' : '') + code; + + for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') { + message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' + + encodeURIComponent(toDebugString(templateArgs[i])); + } + + return new ErrorConstructor(message); + }; +} + +/** + * @ngdoc type + * @name angular.Module + * @module ng + * @description + * + * Interface for configuring angular {@link angular.module modules}. + */ + +function setupModuleLoader(window) { + + var $injectorMinErr = minErr('$injector'); + var ngMinErr = minErr('ng'); + + function ensure(obj, name, factory) { + return obj[name] || (obj[name] = factory()); + } + + var angular = ensure(window, 'angular', Object); + + // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap + angular.$$minErr = angular.$$minErr || minErr; + + return ensure(angular, 'module', function() { + /** @type {Object.} */ + var modules = {}; + + /** + * @ngdoc function + * @name angular.module + * @module ng + * @description + * + * The `angular.module` is a global place for creating, registering and retrieving Angular + * modules. + * All modules (angular core or 3rd party) that should be available to an application must be + * registered using this mechanism. + * + * Passing one argument retrieves an existing {@link angular.Module}, + * whereas passing more than one argument creates a new {@link angular.Module} + * + * + * # Module + * + * A module is a collection of services, directives, controllers, filters, and configuration information. + * `angular.module` is used to configure the {@link auto.$injector $injector}. + * + * ```js + * // Create a new module + * var myModule = angular.module('myModule', []); + * + * // register a new service + * myModule.value('appName', 'MyCoolApp'); + * + * // configure existing services inside initialization blocks. + * myModule.config(['$locationProvider', function($locationProvider) { + * // Configure existing providers + * $locationProvider.hashPrefix('!'); + * }]); + * ``` + * + * Then you can create an injector and load your modules like this: + * + * ```js + * var injector = angular.injector(['ng', 'myModule']) + * ``` + * + * However it's more likely that you'll just use + * {@link ng.directive:ngApp ngApp} or + * {@link angular.bootstrap} to simplify this process for you. + * + * @param {!string} name The name of the module to create or retrieve. + * @param {!Array.=} requires If specified then new module is being created. If + * unspecified then the module is being retrieved for further configuration. + * @param {Function=} configFn Optional configuration function for the module. Same as + * {@link angular.Module#config Module#config()}. + * @returns {module} new module with the {@link angular.Module} api. + */ + return function module(name, requires, configFn) { + var assertNotHasOwnProperty = function(name, context) { + if (name === 'hasOwnProperty') { + throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); + } + }; + + assertNotHasOwnProperty(name, 'module'); + if (requires && modules.hasOwnProperty(name)) { + modules[name] = null; + } + return ensure(modules, name, function() { + if (!requires) { + throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " + + "the module name or forgot to load it. If registering a module ensure that you " + + "specify the dependencies as the second argument.", name); + } + + /** @type {!Array.>} */ + var invokeQueue = []; + + /** @type {!Array.} */ + var configBlocks = []; + + /** @type {!Array.} */ + var runBlocks = []; + + var config = invokeLater('$injector', 'invoke', 'push', configBlocks); + + /** @type {angular.Module} */ + var moduleInstance = { + // Private state + _invokeQueue: invokeQueue, + _configBlocks: configBlocks, + _runBlocks: runBlocks, + + /** + * @ngdoc property + * @name angular.Module#requires + * @module ng + * + * @description + * Holds the list of modules which the injector will load before the current module is + * loaded. + */ + requires: requires, + + /** + * @ngdoc property + * @name angular.Module#name + * @module ng + * + * @description + * Name of the module. + */ + name: name, + + + /** + * @ngdoc method + * @name angular.Module#provider + * @module ng + * @param {string} name service name + * @param {Function} providerType Construction function for creating new instance of the + * service. + * @description + * See {@link auto.$provide#provider $provide.provider()}. + */ + provider: invokeLaterAndSetModuleName('$provide', 'provider'), + + /** + * @ngdoc method + * @name angular.Module#factory + * @module ng + * @param {string} name service name + * @param {Function} providerFunction Function for creating new instance of the service. + * @description + * See {@link auto.$provide#factory $provide.factory()}. + */ + factory: invokeLaterAndSetModuleName('$provide', 'factory'), + + /** + * @ngdoc method + * @name angular.Module#service + * @module ng + * @param {string} name service name + * @param {Function} constructor A constructor function that will be instantiated. + * @description + * See {@link auto.$provide#service $provide.service()}. + */ + service: invokeLaterAndSetModuleName('$provide', 'service'), + + /** + * @ngdoc method + * @name angular.Module#value + * @module ng + * @param {string} name service name + * @param {*} object Service instance object. + * @description + * See {@link auto.$provide#value $provide.value()}. + */ + value: invokeLater('$provide', 'value'), + + /** + * @ngdoc method + * @name angular.Module#constant + * @module ng + * @param {string} name constant name + * @param {*} object Constant value. + * @description + * Because the constants are fixed, they get applied before other provide methods. + * See {@link auto.$provide#constant $provide.constant()}. + */ + constant: invokeLater('$provide', 'constant', 'unshift'), + + /** + * @ngdoc method + * @name angular.Module#decorator + * @module ng + * @param {string} The name of the service to decorate. + * @param {Function} This function will be invoked when the service needs to be + * instantiated and should return the decorated service instance. + * @description + * See {@link auto.$provide#decorator $provide.decorator()}. + */ + decorator: invokeLaterAndSetModuleName('$provide', 'decorator'), + + /** + * @ngdoc method + * @name angular.Module#animation + * @module ng + * @param {string} name animation name + * @param {Function} animationFactory Factory function for creating new instance of an + * animation. + * @description + * + * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. + * + * + * Defines an animation hook that can be later used with + * {@link $animate $animate} service and directives that use this service. + * + * ```js + * module.animation('.animation-name', function($inject1, $inject2) { + * return { + * eventName : function(element, done) { + * //code to run the animation + * //once complete, then run done() + * return function cancellationFunction(element) { + * //code to cancel the animation + * } + * } + * } + * }) + * ``` + * + * See {@link ng.$animateProvider#register $animateProvider.register()} and + * {@link ngAnimate ngAnimate module} for more information. + */ + animation: invokeLaterAndSetModuleName('$animateProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#filter + * @module ng + * @param {string} name Filter name - this must be a valid angular expression identifier + * @param {Function} filterFactory Factory function for creating new instance of filter. + * @description + * See {@link ng.$filterProvider#register $filterProvider.register()}. + * + *
    + * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`. + * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace + * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores + * (`myapp_subsection_filterx`). + *
    + */ + filter: invokeLaterAndSetModuleName('$filterProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#controller + * @module ng + * @param {string|Object} name Controller name, or an object map of controllers where the + * keys are the names and the values are the constructors. + * @param {Function} constructor Controller constructor function. + * @description + * See {@link ng.$controllerProvider#register $controllerProvider.register()}. + */ + controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#directive + * @module ng + * @param {string|Object} name Directive name, or an object map of directives where the + * keys are the names and the values are the factories. + * @param {Function} directiveFactory Factory function for creating new instance of + * directives. + * @description + * See {@link ng.$compileProvider#directive $compileProvider.directive()}. + */ + directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'), + + /** + * @ngdoc method + * @name angular.Module#config + * @module ng + * @param {Function} configFn Execute this function on module load. Useful for service + * configuration. + * @description + * Use this method to register work which needs to be performed on module loading. + * For more about how to configure services, see + * {@link providers#provider-recipe Provider Recipe}. + */ + config: config, + + /** + * @ngdoc method + * @name angular.Module#run + * @module ng + * @param {Function} initializationFn Execute this function after injector creation. + * Useful for application initialization. + * @description + * Use this method to register work which should be performed when the injector is done + * loading all modules. + */ + run: function(block) { + runBlocks.push(block); + return this; + } + }; + + if (configFn) { + config(configFn); + } + + return moduleInstance; + + /** + * @param {string} provider + * @param {string} method + * @param {String=} insertMethod + * @returns {angular.Module} + */ + function invokeLater(provider, method, insertMethod, queue) { + if (!queue) queue = invokeQueue; + return function() { + queue[insertMethod || 'push']([provider, method, arguments]); + return moduleInstance; + }; + } + + /** + * @param {string} provider + * @param {string} method + * @returns {angular.Module} + */ + function invokeLaterAndSetModuleName(provider, method) { + return function(recipeName, factoryFunction) { + if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name; + invokeQueue.push([provider, method, arguments]); + return moduleInstance; + }; + } + }); + }; + }); + +} + +setupModuleLoader(window); +})(window); + +/** + * Closure compiler type information + * + * @typedef { { + * requires: !Array., + * invokeQueue: !Array.>, + * + * service: function(string, Function):angular.Module, + * factory: function(string, Function):angular.Module, + * value: function(string, *):angular.Module, + * + * filter: function(string, Function):angular.Module, + * + * init: function(Function):angular.Module + * } } + */ +angular.Module; + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-loader.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-loader.min.js new file mode 100644 index 00000000..67d08168 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-loader.min.js @@ -0,0 +1,10 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(){'use strict';function d(b){return function(){var a=arguments[0],e;e="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.4.8/"+(b?b+"/":"")+a;for(a=1;a= line.length) { + index -= line.length; + } else { + return { line: i + 1, column: index + 1 }; + } + } +} +var PARSE_CACHE_FOR_TEXT_LITERALS = Object.create(null); + +function parseTextLiteral(text) { + var cachedFn = PARSE_CACHE_FOR_TEXT_LITERALS[text]; + if (cachedFn != null) { + return cachedFn; + } + function parsedFn(context) { return text; } + parsedFn['$$watchDelegate'] = function watchDelegate(scope, listener, objectEquality) { + var unwatch = scope['$watch'](noop, + function textLiteralWatcher() { + if (isFunction(listener)) { listener.call(null, text, text, scope); } + unwatch(); + }, + objectEquality); + return unwatch; + }; + PARSE_CACHE_FOR_TEXT_LITERALS[text] = parsedFn; + parsedFn['exp'] = text; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js + parsedFn['expressions'] = []; // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. + return parsedFn; +} + +function subtractOffset(expressionFn, offset) { + if (offset === 0) { + return expressionFn; + } + function minusOffset(value) { + return (value == void 0) ? value : value - offset; + } + function parsedFn(context) { return minusOffset(expressionFn(context)); } + var unwatch; + parsedFn['$$watchDelegate'] = function watchDelegate(scope, listener, objectEquality) { + unwatch = scope['$watch'](expressionFn, + function pluralExpressionWatchListener(newValue, oldValue) { + if (isFunction(listener)) { listener.call(null, minusOffset(newValue), minusOffset(oldValue), scope); } + }, + objectEquality); + return unwatch; + }; + return parsedFn; +} + +// NOTE: ADVANCED_OPTIMIZATIONS mode. +// +// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using +// constructs incompatible with that mode. + +/* global $interpolateMinErr: false */ +/* global isFunction: false */ +/* global noop: false */ + +/** + * @constructor + * @private + */ +function MessageSelectorBase(expressionFn, choices) { + var self = this; + this.expressionFn = expressionFn; + this.choices = choices; + if (choices["other"] === void 0) { + throw $interpolateMinErr('reqother', '“other” is a required option.'); + } + this.parsedFn = function(context) { return self.getResult(context); }; + this.parsedFn['$$watchDelegate'] = function $$watchDelegate(scope, listener, objectEquality) { + return self.watchDelegate(scope, listener, objectEquality); + }; + this.parsedFn['exp'] = expressionFn['exp']; + this.parsedFn['expressions'] = expressionFn['expressions']; +} + +MessageSelectorBase.prototype.getMessageFn = function getMessageFn(value) { + return this.choices[this.categorizeValue(value)]; +}; + +MessageSelectorBase.prototype.getResult = function getResult(context) { + return this.getMessageFn(this.expressionFn(context))(context); +}; + +MessageSelectorBase.prototype.watchDelegate = function watchDelegate(scope, listener, objectEquality) { + var watchers = new MessageSelectorWatchers(this, scope, listener, objectEquality); + return function() { watchers.cancelWatch(); }; +}; + +/** + * @constructor + * @private + */ +function MessageSelectorWatchers(msgSelector, scope, listener, objectEquality) { + var self = this; + this.scope = scope; + this.msgSelector = msgSelector; + this.listener = listener; + this.objectEquality = objectEquality; + this.lastMessage = void 0; + this.messageFnWatcher = noop; + var expressionFnListener = function(newValue, oldValue) { return self.expressionFnListener(newValue, oldValue); }; + this.expressionFnWatcher = scope['$watch'](msgSelector.expressionFn, expressionFnListener, objectEquality); +} + +MessageSelectorWatchers.prototype.expressionFnListener = function expressionFnListener(newValue, oldValue) { + var self = this; + this.messageFnWatcher(); + var messageFnListener = function(newMessage, oldMessage) { return self.messageFnListener(newMessage, oldMessage); }; + var messageFn = this.msgSelector.getMessageFn(newValue); + this.messageFnWatcher = this.scope['$watch'](messageFn, messageFnListener, this.objectEquality); +}; + +MessageSelectorWatchers.prototype.messageFnListener = function messageFnListener(newMessage, oldMessage) { + if (isFunction(this.listener)) { + this.listener.call(null, newMessage, newMessage === oldMessage ? newMessage : this.lastMessage, this.scope); + } + this.lastMessage = newMessage; +}; + +MessageSelectorWatchers.prototype.cancelWatch = function cancelWatch() { + this.expressionFnWatcher(); + this.messageFnWatcher(); +}; + +/** + * @constructor + * @extends MessageSelectorBase + * @private + */ +function SelectMessage(expressionFn, choices) { + MessageSelectorBase.call(this, expressionFn, choices); +} + +function SelectMessageProto() {} +SelectMessageProto.prototype = MessageSelectorBase.prototype; + +SelectMessage.prototype = new SelectMessageProto(); +SelectMessage.prototype.categorizeValue = function categorizeSelectValue(value) { + return (this.choices[value] !== void 0) ? value : "other"; +}; + +/** + * @constructor + * @extends MessageSelectorBase + * @private + */ +function PluralMessage(expressionFn, choices, offset, pluralCat) { + MessageSelectorBase.call(this, expressionFn, choices); + this.offset = offset; + this.pluralCat = pluralCat; +} + +function PluralMessageProto() {} +PluralMessageProto.prototype = MessageSelectorBase.prototype; + +PluralMessage.prototype = new PluralMessageProto(); +PluralMessage.prototype.categorizeValue = function categorizePluralValue(value) { + if (isNaN(value)) { + return "other"; + } else if (this.choices[value] !== void 0) { + return value; + } else { + var category = this.pluralCat(value - this.offset); + return (this.choices[category] !== void 0) ? category : "other"; + } +}; + +// NOTE: ADVANCED_OPTIMIZATIONS mode. +// +// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using +// constructs incompatible with that mode. + +/* global $interpolateMinErr: false */ +/* global isFunction: false */ +/* global parseTextLiteral: false */ + +/** + * @constructor + * @private + */ +function InterpolationParts(trustedContext, allOrNothing) { + this.trustedContext = trustedContext; + this.allOrNothing = allOrNothing; + this.textParts = []; + this.expressionFns = []; + this.expressionIndices = []; + this.partialText = ''; + this.concatParts = null; +} + +InterpolationParts.prototype.flushPartialText = function flushPartialText() { + if (this.partialText) { + if (this.concatParts == null) { + this.textParts.push(this.partialText); + } else { + this.textParts.push(this.concatParts.join('')); + this.concatParts = null; + } + this.partialText = ''; + } +}; + +InterpolationParts.prototype.addText = function addText(text) { + if (text.length) { + if (!this.partialText) { + this.partialText = text; + } else if (this.concatParts) { + this.concatParts.push(text); + } else { + this.concatParts = [this.partialText, text]; + } + } +}; + +InterpolationParts.prototype.addExpressionFn = function addExpressionFn(expressionFn) { + this.flushPartialText(); + this.expressionIndices.push(this.textParts.length); + this.expressionFns.push(expressionFn); + this.textParts.push(''); +}; + +InterpolationParts.prototype.getExpressionValues = function getExpressionValues(context) { + var expressionValues = new Array(this.expressionFns.length); + for (var i = 0; i < this.expressionFns.length; i++) { + expressionValues[i] = this.expressionFns[i](context); + } + return expressionValues; +}; + +InterpolationParts.prototype.getResult = function getResult(expressionValues) { + for (var i = 0; i < this.expressionIndices.length; i++) { + var expressionValue = expressionValues[i]; + if (this.allOrNothing && expressionValue === void 0) return; + this.textParts[this.expressionIndices[i]] = expressionValue; + } + return this.textParts.join(''); +}; + + +InterpolationParts.prototype.toParsedFn = function toParsedFn(mustHaveExpression, originalText) { + var self = this; + this.flushPartialText(); + if (mustHaveExpression && this.expressionFns.length === 0) { + return void 0; + } + if (this.textParts.length === 0) { + return parseTextLiteral(''); + } + if (this.trustedContext && this.textParts.length > 1) { + $interpolateMinErr['throwNoconcat'](originalText); + } + if (this.expressionFns.length === 0) { + if (this.textParts.length != 1) { this.errorInParseLogic(); } + return parseTextLiteral(this.textParts[0]); + } + var parsedFn = function(context) { + return self.getResult(self.getExpressionValues(context)); + }; + parsedFn['$$watchDelegate'] = function $$watchDelegate(scope, listener, objectEquality) { + return self.watchDelegate(scope, listener, objectEquality); + }; + + parsedFn['exp'] = originalText; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js + parsedFn['expressions'] = new Array(this.expressionFns.length); // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. + for (var i = 0; i < this.expressionFns.length; i++) { + parsedFn['expressions'][i] = this.expressionFns[i]['exp']; + } + + return parsedFn; +}; + +InterpolationParts.prototype.watchDelegate = function watchDelegate(scope, listener, objectEquality) { + var watcher = new InterpolationPartsWatcher(this, scope, listener, objectEquality); + return function() { watcher.cancelWatch(); }; +}; + +function InterpolationPartsWatcher(interpolationParts, scope, listener, objectEquality) { + this.interpolationParts = interpolationParts; + this.scope = scope; + this.previousResult = (void 0); + this.listener = listener; + var self = this; + this.expressionFnsWatcher = scope['$watchGroup'](interpolationParts.expressionFns, function(newExpressionValues, oldExpressionValues) { + self.watchListener(newExpressionValues, oldExpressionValues); + }); +} + +InterpolationPartsWatcher.prototype.watchListener = function watchListener(newExpressionValues, oldExpressionValues) { + var result = this.interpolationParts.getResult(newExpressionValues); + if (isFunction(this.listener)) { + this.listener.call(null, result, newExpressionValues === oldExpressionValues ? result : this.previousResult, this.scope); + } + this.previousResult = result; +}; + +InterpolationPartsWatcher.prototype.cancelWatch = function cancelWatch() { + this.expressionFnsWatcher(); +}; + +// NOTE: ADVANCED_OPTIMIZATIONS mode. +// +// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using +// constructs incompatible with that mode. + +/* global $interpolateMinErr: false */ +/* global indexToLineAndColumn: false */ +/* global InterpolationParts: false */ +/* global PluralMessage: false */ +/* global SelectMessage: false */ +/* global subtractOffset: false */ + +// The params src and dst are exactly one of two types: NestedParserState or MessageFormatParser. +// This function is fully optimized by V8. (inspect via IRHydra or --trace-deopt.) +// The idea behind writing it this way is to avoid repeating oneself. This is the ONE place where +// the parser state that is saved/restored when parsing nested mustaches is specified. +function copyNestedParserState(src, dst) { + dst.expressionFn = src.expressionFn; + dst.expressionMinusOffsetFn = src.expressionMinusOffsetFn; + dst.pluralOffset = src.pluralOffset; + dst.choices = src.choices; + dst.choiceKey = src.choiceKey; + dst.interpolationParts = src.interpolationParts; + dst.ruleChoiceKeyword = src.ruleChoiceKeyword; + dst.msgStartIndex = src.msgStartIndex; + dst.expressionStartIndex = src.expressionStartIndex; +} + +function NestedParserState(parser) { + copyNestedParserState(parser, this); +} + +/** + * @constructor + * @private + */ +function MessageFormatParser(text, startIndex, $parse, pluralCat, stringifier, + mustHaveExpression, trustedContext, allOrNothing) { + this.text = text; + this.index = startIndex || 0; + this.$parse = $parse; + this.pluralCat = pluralCat; + this.stringifier = stringifier; + this.mustHaveExpression = !!mustHaveExpression; + this.trustedContext = trustedContext; + this.allOrNothing = !!allOrNothing; + this.expressionFn = null; + this.expressionMinusOffsetFn = null; + this.pluralOffset = null; + this.choices = null; + this.choiceKey = null; + this.interpolationParts = null; + this.msgStartIndex = null; + this.nestedStateStack = []; + this.parsedFn = null; + this.rule = null; + this.ruleStack = null; + this.ruleChoiceKeyword = null; + this.interpNestLevel = null; + this.expressionStartIndex = null; + this.stringStartIndex = null; + this.stringQuote = null; + this.stringInterestsRe = null; + this.angularOperatorStack = null; + this.textPart = null; +} + +// preserve v8 optimization. +var EMPTY_STATE = new NestedParserState(new MessageFormatParser( + /* text= */ '', /* startIndex= */ 0, /* $parse= */ null, /* pluralCat= */ null, /* stringifier= */ null, + /* mustHaveExpression= */ false, /* trustedContext= */ null, /* allOrNothing */ false)); + +MessageFormatParser.prototype.pushState = function pushState() { + this.nestedStateStack.push(new NestedParserState(this)); + copyNestedParserState(EMPTY_STATE, this); +}; + +MessageFormatParser.prototype.popState = function popState() { + if (this.nestedStateStack.length === 0) { + this.errorInParseLogic(); + } + var previousState = this.nestedStateStack.pop(); + copyNestedParserState(previousState, this); +}; + +// Oh my JavaScript! Who knew you couldn't match a regex at a specific +// location in a string but will always search forward?! +// Apparently you'll be growing this ability via the sticky flag (y) in +// ES6. I'll just to work around you for now. +MessageFormatParser.prototype.matchRe = function matchRe(re, search) { + re.lastIndex = this.index; + var match = re.exec(this.text); + if (match != null && (search === true || (match.index == this.index))) { + this.index = re.lastIndex; + return match; + } + return null; +}; + +MessageFormatParser.prototype.searchRe = function searchRe(re) { + return this.matchRe(re, true); +}; + + +MessageFormatParser.prototype.consumeRe = function consumeRe(re) { + // Without the sticky flag, we can't use the .test() method to consume a + // match at the current index. Instead, we'll use the slower .exec() method + // and verify match.index. + return !!this.matchRe(re); +}; + +// Run through our grammar avoiding deeply nested function call chains. +MessageFormatParser.prototype.run = function run(initialRule) { + this.ruleStack = [initialRule]; + do { + this.rule = this.ruleStack.pop(); + while (this.rule) { + this.rule(); + } + this.assertRuleOrNull(this.rule); + } while (this.ruleStack.length > 0); +}; + +MessageFormatParser.prototype.errorInParseLogic = function errorInParseLogic() { + throw $interpolateMinErr('logicbug', + 'The messageformat parser has encountered an internal error. Please file a github issue against the AngularJS project and provide this message text that triggers the bug. Text: “{0}”', + this.text); +}; + +MessageFormatParser.prototype.assertRuleOrNull = function assertRuleOrNull(rule) { + if (rule === void 0) { + this.errorInParseLogic(); + } +}; + +var NEXT_WORD_RE = /\s*(\w+)\s*/g; +MessageFormatParser.prototype.errorExpecting = function errorExpecting() { + // What was wrong with the syntax? Unsupported type, missing comma, or something else? + var match = this.matchRe(NEXT_WORD_RE), position; + if (match == null) { + position = indexToLineAndColumn(this.text, this.index); + throw $interpolateMinErr('reqarg', + 'Expected one of “plural” or “select” at line {0}, column {1} of text “{2}”', + position.line, position.column, this.text); + } + var word = match[1]; + if (word == "select" || word == "plural") { + position = indexToLineAndColumn(this.text, this.index); + throw $interpolateMinErr('reqcomma', + 'Expected a comma after the keyword “{0}” at line {1}, column {2} of text “{3}”', + word, position.line, position.column, this.text); + } else { + position = indexToLineAndColumn(this.text, this.index); + throw $interpolateMinErr('unknarg', + 'Unsupported keyword “{0}” at line {0}, column {1}. Only “plural” and “select” are currently supported. Text: “{3}”', + word, position.line, position.column, this.text); + } +}; + +var STRING_START_RE = /['"]/g; +MessageFormatParser.prototype.ruleString = function ruleString() { + var match = this.matchRe(STRING_START_RE); + if (match == null) { + var position = indexToLineAndColumn(this.text, this.index); + throw $interpolateMinErr('wantstring', + 'Expected the beginning of a string at line {0}, column {1} in text “{2}”', + position.line, position.column, this.text); + } + this.startStringAtMatch(match); +}; + +MessageFormatParser.prototype.startStringAtMatch = function startStringAtMatch(match) { + this.stringStartIndex = match.index; + this.stringQuote = match[0]; + this.stringInterestsRe = this.stringQuote == "'" ? SQUOTED_STRING_INTEREST_RE : DQUOTED_STRING_INTEREST_RE; + this.rule = this.ruleInsideString; +}; + +var SQUOTED_STRING_INTEREST_RE = /\\(?:\\|'|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}|[0-7]{3}|\r\n|\n|[\s\S])|'/g; +var DQUOTED_STRING_INTEREST_RE = /\\(?:\\|"|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}|[0-7]{3}|\r\n|\n|[\s\S])|"/g; +MessageFormatParser.prototype.ruleInsideString = function ruleInsideString() { + var match = this.searchRe(this.stringInterestsRe); + if (match == null) { + var position = indexToLineAndColumn(this.text, this.stringStartIndex); + throw $interpolateMinErr('untermstr', + 'The string beginning at line {0}, column {1} is unterminated in text “{2}”', + position.line, position.column, this.text); + } + var chars = match[0]; + if (match == this.stringQuote) { + this.rule = null; + } +}; + +var PLURAL_OR_SELECT_ARG_TYPE_RE = /\s*(plural|select)\s*,\s*/g; +MessageFormatParser.prototype.rulePluralOrSelect = function rulePluralOrSelect() { + var match = this.searchRe(PLURAL_OR_SELECT_ARG_TYPE_RE); + if (match == null) { + this.errorExpecting(); + } + var argType = match[1]; + switch (argType) { + case "plural": this.rule = this.rulePluralStyle; break; + case "select": this.rule = this.ruleSelectStyle; break; + default: this.errorInParseLogic(); + } +}; + +MessageFormatParser.prototype.rulePluralStyle = function rulePluralStyle() { + this.choices = Object.create(null); + this.ruleChoiceKeyword = this.rulePluralValueOrKeyword; + this.rule = this.rulePluralOffset; +}; + +MessageFormatParser.prototype.ruleSelectStyle = function ruleSelectStyle() { + this.choices = Object.create(null); + this.ruleChoiceKeyword = this.ruleSelectKeyword; + this.rule = this.ruleSelectKeyword; +}; + +var NUMBER_RE = /[0]|(?:[1-9][0-9]*)/g; +var PLURAL_OFFSET_RE = new RegExp("\\s*offset\\s*:\\s*(" + NUMBER_RE.source + ")", "g"); + +MessageFormatParser.prototype.rulePluralOffset = function rulePluralOffset() { + var match = this.matchRe(PLURAL_OFFSET_RE); + this.pluralOffset = (match == null) ? 0 : parseInt(match[1], 10); + this.expressionMinusOffsetFn = subtractOffset(this.expressionFn, this.pluralOffset); + this.rule = this.rulePluralValueOrKeyword; +}; + +MessageFormatParser.prototype.assertChoiceKeyIsNew = function assertChoiceKeyIsNew(choiceKey, index) { + if (this.choices[choiceKey] !== void 0) { + var position = indexToLineAndColumn(this.text, index); + throw $interpolateMinErr('dupvalue', + 'The choice “{0}” is specified more than once. Duplicate key is at line {1}, column {2} in text “{3}”', + choiceKey, position.line, position.column, this.text); + } +}; + +var SELECT_KEYWORD = /\s*(\w+)/g; +MessageFormatParser.prototype.ruleSelectKeyword = function ruleSelectKeyword() { + var match = this.matchRe(SELECT_KEYWORD); + if (match == null) { + this.parsedFn = new SelectMessage(this.expressionFn, this.choices).parsedFn; + this.rule = null; + return; + } + this.choiceKey = match[1]; + this.assertChoiceKeyIsNew(this.choiceKey, match.index); + this.rule = this.ruleMessageText; +}; + +var EXPLICIT_VALUE_OR_KEYWORD_RE = new RegExp("\\s*(?:(?:=(" + NUMBER_RE.source + "))|(\\w+))", "g"); +MessageFormatParser.prototype.rulePluralValueOrKeyword = function rulePluralValueOrKeyword() { + var match = this.matchRe(EXPLICIT_VALUE_OR_KEYWORD_RE); + if (match == null) { + this.parsedFn = new PluralMessage(this.expressionFn, this.choices, this.pluralOffset, this.pluralCat).parsedFn; + this.rule = null; + return; + } + if (match[1] != null) { + this.choiceKey = parseInt(match[1], 10); + } else { + this.choiceKey = match[2]; + } + this.assertChoiceKeyIsNew(this.choiceKey, match.index); + this.rule = this.ruleMessageText; +}; + +var BRACE_OPEN_RE = /\s*{/g; +var BRACE_CLOSE_RE = /}/g; +MessageFormatParser.prototype.ruleMessageText = function ruleMessageText() { + if (!this.consumeRe(BRACE_OPEN_RE)) { + var position = indexToLineAndColumn(this.text, this.index); + throw $interpolateMinErr('reqopenbrace', + 'The plural choice “{0}” must be followed by a message in braces at line {1}, column {2} in text “{3}”', + this.choiceKey, position.line, position.column, this.text); + } + this.msgStartIndex = this.index; + this.interpolationParts = new InterpolationParts(this.trustedContext, this.allOrNothing); + this.rule = this.ruleInInterpolationOrMessageText; +}; + +// Note: Since "\" is used as an escape character, don't allow it to be part of the +// startSymbol/endSymbol when I add the feature to allow them to be redefined. +var INTERP_OR_END_MESSAGE_RE = /\\.|{{|}/g; +var INTERP_OR_PLURALVALUE_OR_END_MESSAGE_RE = /\\.|{{|#|}/g; +var ESCAPE_OR_MUSTACHE_BEGIN_RE = /\\.|{{/g; +MessageFormatParser.prototype.advanceInInterpolationOrMessageText = function advanceInInterpolationOrMessageText() { + var currentIndex = this.index, match, re; + if (this.ruleChoiceKeyword == null) { // interpolation + match = this.searchRe(ESCAPE_OR_MUSTACHE_BEGIN_RE); + if (match == null) { // End of interpolation text. Nothing more to process. + this.textPart = this.text.substring(currentIndex); + this.index = this.text.length; + return null; + } + } else { + match = this.searchRe(this.ruleChoiceKeyword == this.rulePluralValueOrKeyword ? + INTERP_OR_PLURALVALUE_OR_END_MESSAGE_RE : INTERP_OR_END_MESSAGE_RE); + if (match == null) { + var position = indexToLineAndColumn(this.text, this.msgStartIndex); + throw $interpolateMinErr('reqendbrace', + 'The plural/select choice “{0}” message starting at line {1}, column {2} does not have an ending closing brace. Text “{3}”', + this.choiceKey, position.line, position.column, this.text); + } + } + // match is non-null. + var token = match[0]; + this.textPart = this.text.substring(currentIndex, match.index); + return token; +}; + +MessageFormatParser.prototype.ruleInInterpolationOrMessageText = function ruleInInterpolationOrMessageText() { + var currentIndex = this.index; + var token = this.advanceInInterpolationOrMessageText(); + if (token == null) { + // End of interpolation text. Nothing more to process. + this.index = this.text.length; + this.interpolationParts.addText(this.text.substring(currentIndex)); + this.rule = null; + return; + } + if (token[0] == "\\") { + // unescape next character and continue + this.interpolationParts.addText(this.textPart + token[1]); + return; + } + this.interpolationParts.addText(this.textPart); + if (token == "{{") { + this.pushState(); + this.ruleStack.push(this.ruleEndMustacheInInterpolationOrMessage); + this.rule = this.ruleEnteredMustache; + } else if (token == "}") { + this.choices[this.choiceKey] = this.interpolationParts.toParsedFn(/*mustHaveExpression=*/false, this.text); + this.rule = this.ruleChoiceKeyword; + } else if (token == "#") { + this.interpolationParts.addExpressionFn(this.expressionMinusOffsetFn); + } else { + this.errorInParseLogic(); + } +}; + +MessageFormatParser.prototype.ruleInterpolate = function ruleInterpolate() { + this.interpolationParts = new InterpolationParts(this.trustedContext, this.allOrNothing); + this.rule = this.ruleInInterpolation; +}; + +MessageFormatParser.prototype.ruleInInterpolation = function ruleInInterpolation() { + var currentIndex = this.index; + var match = this.searchRe(ESCAPE_OR_MUSTACHE_BEGIN_RE); + if (match == null) { + // End of interpolation text. Nothing more to process. + this.index = this.text.length; + this.interpolationParts.addText(this.text.substring(currentIndex)); + this.parsedFn = this.interpolationParts.toParsedFn(this.mustHaveExpression, this.text); + this.rule = null; + return; + } + var token = match[0]; + if (token[0] == "\\") { + // unescape next character and continue + this.interpolationParts.addText(this.text.substring(currentIndex, match.index) + token[1]); + return; + } + this.interpolationParts.addText(this.text.substring(currentIndex, match.index)); + this.pushState(); + this.ruleStack.push(this.ruleInterpolationEndMustache); + this.rule = this.ruleEnteredMustache; +}; + +MessageFormatParser.prototype.ruleInterpolationEndMustache = function ruleInterpolationEndMustache() { + var expressionFn = this.parsedFn; + this.popState(); + this.interpolationParts.addExpressionFn(expressionFn); + this.rule = this.ruleInInterpolation; +}; + +MessageFormatParser.prototype.ruleEnteredMustache = function ruleEnteredMustache() { + this.parsedFn = null; + this.ruleStack.push(this.ruleEndMustache); + this.rule = this.ruleAngularExpression; +}; + +MessageFormatParser.prototype.ruleEndMustacheInInterpolationOrMessage = function ruleEndMustacheInInterpolationOrMessage() { + var expressionFn = this.parsedFn; + this.popState(); + this.interpolationParts.addExpressionFn(expressionFn); + this.rule = this.ruleInInterpolationOrMessageText; +}; + + + +var INTERP_END_RE = /\s*}}/g; +MessageFormatParser.prototype.ruleEndMustache = function ruleEndMustache() { + var match = this.matchRe(INTERP_END_RE); + if (match == null) { + var position = indexToLineAndColumn(this.text, this.index); + throw $interpolateMinErr('reqendinterp', + 'Expecting end of interpolation symbol, “{0}”, at line {1}, column {2} in text “{3}”', + '}}', position.line, position.column, this.text); + } + if (this.parsedFn == null) { + // If we parsed a MessageFormat extension, (e.g. select/plural today, maybe more some other + // day), then the result *has* to be a string and those rules would have already set + // this.parsedFn. If there was no MessageFormat extension, then there is no requirement to + // stringify the result and parsedFn isn't set. We set it here. While we could have set it + // unconditionally when exiting the Angular expression, I intend for us to not just replace + // $interpolate, but also to replace $parse in a future version (so ng-bind can work), and in + // such a case we do not want to unnecessarily stringify something if it's not going to be used + // in a string context. + this.parsedFn = this.$parse(this.expressionFn, this.stringifier); + this.parsedFn['exp'] = this.expressionFn['exp']; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js + this.parsedFn['expressions'] = this.expressionFn['expressions']; // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. + } + this.rule = null; +}; + +MessageFormatParser.prototype.ruleAngularExpression = function ruleAngularExpression() { + this.angularOperatorStack = []; + this.expressionStartIndex = this.index; + this.rule = this.ruleInAngularExpression; +}; + +function getEndOperator(opBegin) { + switch (opBegin) { + case "{": return "}"; + case "[": return "]"; + case "(": return ")"; + default: return null; + } +} + +function getBeginOperator(opEnd) { + switch (opEnd) { + case "}": return "{"; + case "]": return "["; + case ")": return "("; + default: return null; + } +} + +// TODO(chirayu): The interpolation endSymbol must also be accounted for. It +// just so happens that "}" is an operator so it's in the list below. But we +// should support any other type of start/end interpolation symbol. +var INTERESTING_OPERATORS_RE = /[[\]{}()'",]/g; +MessageFormatParser.prototype.ruleInAngularExpression = function ruleInAngularExpression() { + var startIndex = this.index; + var match = this.searchRe(INTERESTING_OPERATORS_RE); + var position; + if (match == null) { + if (this.angularOperatorStack.length === 0) { + // This is the end of the Angular expression so this is actually a + // success. Note that when inside an interpolation, this means we even + // consumed the closing interpolation symbols if they were curlies. This + // is NOT an error at this point but will become an error further up the + // stack when the part that saw the opening curlies is unable to find the + // closing ones. + this.index = this.text.length; + this.expressionFn = this.$parse(this.text.substring(this.expressionStartIndex, this.index)); + // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js + this.expressionFn['exp'] = this.text.substring(this.expressionStartIndex, this.index); + this.expressionFn['expressions'] = this.expressionFn['expressions']; + this.rule = null; + return; + } + var innermostOperator = this.angularOperatorStack[0]; + throw $interpolateMinErr('badexpr', + 'Unexpected end of Angular expression. Expecting operator “{0}” at the end of the text “{1}”', + this.getEndOperator(innermostOperator), this.text); + } + var operator = match[0]; + if (operator == "'" || operator == '"') { + this.ruleStack.push(this.ruleInAngularExpression); + this.startStringAtMatch(match); + return; + } + if (operator == ",") { + if (this.trustedContext) { + position = indexToLineAndColumn(this.text, this.index); + throw $interpolateMinErr('unsafe', + 'Use of select/plural MessageFormat syntax is currently disallowed in a secure context ({0}). At line {1}, column {2} of text “{3}”', + this.trustedContext, position.line, position.column, this.text); + } + // only the top level comma has relevance. + if (this.angularOperatorStack.length === 0) { + // todo: does this need to be trimmed? + this.expressionFn = this.$parse(this.text.substring(this.expressionStartIndex, match.index)); + // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js + this.expressionFn['exp'] = this.text.substring(this.expressionStartIndex, match.index); + this.expressionFn['expressions'] = this.expressionFn['expressions']; + this.rule = null; + this.rule = this.rulePluralOrSelect; + } + return; + } + if (getEndOperator(operator) != null) { + this.angularOperatorStack.unshift(operator); + return; + } + var beginOperator = getBeginOperator(operator); + if (beginOperator == null) { + this.errorInParseLogic(); + } + if (this.angularOperatorStack.length > 0) { + if (beginOperator == this.angularOperatorStack[0]) { + this.angularOperatorStack.shift(); + return; + } + position = indexToLineAndColumn(this.text, this.index); + throw $interpolateMinErr('badexpr', + 'Unexpected operator “{0}” at line {1}, column {2} in text. Was expecting “{3}”. Text: “{4}”', + operator, position.line, position.column, getEndOperator(this.angularOperatorStack[0]), this.text); + } + // We are trying to pop off the operator stack but there really isn't anything to pop off. + this.index = match.index; + this.expressionFn = this.$parse(this.text.substring(this.expressionStartIndex, this.index)); + // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js + this.expressionFn['exp'] = this.text.substring(this.expressionStartIndex, this.index); + this.expressionFn['expressions'] = this.expressionFn['expressions']; + this.rule = null; +}; + +// NOTE: ADVANCED_OPTIMIZATIONS mode. +// +// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using +// constructs incompatible with that mode. + +/* global $interpolateMinErr: false */ +/* global MessageFormatParser: false */ +/* global stringify: false */ + +/** + * @ngdoc service + * @name $$messageFormat + * + * @description + * Angular internal service to recognize MessageFormat extensions in interpolation expressions. + * For more information, see: + * https://docs.google.com/a/google.com/document/d/1pbtW2yvtmFBikfRrJd8VAsabiFkKezmYZ_PbgdjQOVU/edit + * + * ## Example + * + * + * + *
    + *
    + * {{recipients.length, plural, offset:1 + * =0 {{{sender.name}} gave no gifts (\#=#)} + * =1 {{{sender.name}} gave one gift to {{recipients[0].name}} (\#=#)} + * one {{{sender.name}} gave {{recipients[0].name}} and one other person a gift (\#=#)} + * other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\#=#)} + * }} + *
    + *
    + * + * + * function Person(name, gender) { + * this.name = name; + * this.gender = gender; + * } + * + * var alice = new Person("Alice", "female"), + * bob = new Person("Bob", "male"), + * charlie = new Person("Charlie", "male"), + * harry = new Person("Harry Potter", "male"); + * + * angular.module('msgFmtExample', ['ngMessageFormat']) + * .controller('AppController', ['$scope', function($scope) { + * $scope.recipients = [alice, bob, charlie]; + * $scope.sender = harry; + * $scope.decreaseRecipients = function() { + * --$scope.recipients.length; + * }; + * }]); + * + * + * + * describe('MessageFormat plural', function() { + * it('should pluralize initial values', function() { + * var messageElem = element(by.binding('recipients.length')), decreaseRecipientsBtn = element(by.id('decreaseRecipients')); + * expect(messageElem.getText()).toEqual('Harry Potter gave Alice and 2 other people a gift (#=2)'); + * decreaseRecipientsBtn.click(); + * expect(messageElem.getText()).toEqual('Harry Potter gave Alice and one other person a gift (#=1)'); + * decreaseRecipientsBtn.click(); + * expect(messageElem.getText()).toEqual('Harry Potter gave one gift to Alice (#=0)'); + * decreaseRecipientsBtn.click(); + * expect(messageElem.getText()).toEqual('Harry Potter gave no gifts (#=-1)'); + * }); + * }); + * + *
    + */ +var $$MessageFormatFactory = ['$parse', '$locale', '$sce', '$exceptionHandler', function $$messageFormat( + $parse, $locale, $sce, $exceptionHandler) { + + function getStringifier(trustedContext, allOrNothing, text) { + return function stringifier(value) { + try { + value = trustedContext ? $sce['getTrusted'](trustedContext, value) : $sce['valueOf'](value); + return allOrNothing && (value === void 0) ? value : stringify(value); + } catch (err) { + $exceptionHandler($interpolateMinErr['interr'](text, err)); + } + }; + } + + function interpolate(text, mustHaveExpression, trustedContext, allOrNothing) { + var stringifier = getStringifier(trustedContext, allOrNothing, text); + var parser = new MessageFormatParser(text, 0, $parse, $locale['pluralCat'], stringifier, + mustHaveExpression, trustedContext, allOrNothing); + parser.run(parser.ruleInterpolate); + return parser.parsedFn; + } + + return { + 'interpolate': interpolate + }; +}]; + +var $$interpolateDecorator = ['$$messageFormat', '$delegate', function $$interpolateDecorator($$messageFormat, $interpolate) { + if ($interpolate['startSymbol']() != "{{" || $interpolate['endSymbol']() != "}}") { + throw $interpolateMinErr('nochgmustache', 'angular-message-format.js currently does not allow you to use custom start and end symbols for interpolation.'); + } + var interpolate = $$messageFormat['interpolate']; + interpolate['startSymbol'] = $interpolate['startSymbol']; + interpolate['endSymbol'] = $interpolate['endSymbol']; + return interpolate; +}]; + + +/** + * @ngdoc module + * @name ngMessageFormat + * @packageName angular-message-format + * @description + */ +var module = window['angular']['module']('ngMessageFormat', ['ng']); +module['factory']('$$messageFormat', $$MessageFormatFactory); +module['config'](['$provide', function($provide) { + $provide['decorator']('$interpolate', $$interpolateDecorator); +}]); + + +})(window, window.angular); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-message-format.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-message-format.min.js new file mode 100644 index 00000000..3d69b5ac --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-message-format.min.js @@ -0,0 +1,26 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(h){'use strict';function C(a){if(null==a)return"";switch(typeof a){case "string":return a;case "number":return""+a;default:return D(a)}}function f(a,b){for(var d=a.split(/\n/g),k=0;k=c.length)b-=c.length;else return{h:k+1,f:b+1}}}function t(a){function b(){return a}var d=u[a];if(null!=d)return d;b.$$watchDelegate=function(b,d,c){var e=b.$watch(v,function(){m(d)&&d.call(null,a,a,b);e()},c);return e};u[a]=b;b.exp=a;b.expressions=[];return b}function F(a,b){function d(a){return void 0== +a?a:a-b}function c(b){return d(a(b))}if(0===b)return a;var e;c.$$watchDelegate=function(b,c,k){return e=b.$watch(a,function(a,k){m(c)&&c.call(null,d(a),d(k),b)},k)};return c}function l(a,b){var d=this;this.b=a;this.e=b;if(void 0===b.other)throw e("reqother");this.d=function(a){return d.D(a)};this.d.$$watchDelegate=function(a,b,c){return d.P(a,b,c)};this.d.exp=a.exp;this.d.expressions=a.expressions}function n(a,b,d,c){var e=this;this.scope=b;this.oa=a;this.v=d;this.qa=c;this.U=void 0;this.K=v;this.ka= +b.$watch(a.b,function(a){return e.ja(a)},c)}function p(a,b){l.call(this,a,b)}function w(){}function q(a,b,d,c){l.call(this,a,b);this.offset=d;this.M=c}function x(){}function g(a,b){this.u=a;this.B=b;this.i=[];this.g=[];this.J=[];this.s="";this.q=null}function r(a,b,d){this.c=a;this.scope=b;this.W=void 0;this.v=d;var c=this;this.la=b.$watchGroup(a.g,function(a,b){c.Ea(a,b)})}function s(a,b){b.b=a.b;b.C=a.C;b.w=a.w;b.e=a.e;b.k=a.k;b.c=a.c;b.n=a.n;b.F=a.F;b.l=a.l}function y(a){s(a,this)}function c(a, +b,d,c,e,E,f,g){this.text=a;this.index=b||0;this.A=d;this.M=c;this.Da=e;this.pa=!!E;this.u=f;this.B=!!g;this.F=this.c=this.k=this.e=this.w=this.C=this.b=null;this.L=[];this.G=this.j=this.ca=this.O=this.da=this.l=this.n=this.o=this.a=this.d=null}function z(a){switch(a){case "{":return"}";case "[":return"]";case "(":return")";default:return null}}function G(a){switch(a){case "}":return"{";case "]":return"[";case ")":return"(";default:return null}}var e=h.angular.$interpolateMinErr,v=h.angular.noop,m= +h.angular.isFunction,D=h.angular.toJson,u=Object.create(null);l.prototype.T=function(a){return this.e[this.R(a)]};l.prototype.D=function(a){return this.T(this.b(a))(a)};l.prototype.P=function(a,b,d){var c=new n(this,a,b,d);return function(){c.I()}};n.prototype.ja=function(a){var b=this;this.K();a=this.oa.T(a);this.K=this.scope.$watch(a,function(a,c){return b.na(a,c)},this.qa)};n.prototype.na=function(a,b){m(this.v)&&this.v.call(null,a,a===b?a:this.U,this.scope);this.U=a};n.prototype.I=function(){this.ka(); +this.K()};w.prototype=l.prototype;p.prototype=new w;p.prototype.R=function(a){return void 0!==this.e[a]?a:"other"};x.prototype=l.prototype;q.prototype=new x;q.prototype.R=function(a){if(isNaN(a))return"other";if(void 0!==this.e[a])return a;a=this.M(a-this.offset);return void 0!==this.e[a]?a:"other"};g.prototype.S=function(){this.s&&(null==this.q?this.i.push(this.s):(this.i.push(this.q.join("")),this.q=null),this.s="")};g.prototype.p=function(a){a.length&&(this.s?this.q?this.q.push(a):this.q=[this.s, +a]:this.s=a)};g.prototype.H=function(a){this.S();this.J.push(this.i.length);this.g.push(a);this.i.push("")};g.prototype.ma=function(a){for(var b=Array(this.g.length),d=0;d + * + *
    + *
    You did not enter a field
    + *
    + * Your email must be between 5 and 100 characters long + *
    + *
    + * + * ``` + * + * Now whatever key/value entries are present within the provided object (in this case `$error`) then + * the ngMessages directive will render the inner first ngMessage directive (depending if the key values + * match the attribute value present on each ngMessage directive). In other words, if your errors + * object contains the following data: + * + * ```javascript + * + * myField.$error = { minlength : true, required : true }; + * ``` + * + * Then the `required` message will be displayed first. When required is false then the `minlength` message + * will be displayed right after (since these messages are ordered this way in the template HTML code). + * The prioritization of each message is determined by what order they're present in the DOM. + * Therefore, instead of having custom JavaScript code determine the priority of what errors are + * present before others, the presentation of the errors are handled within the template. + * + * By default, ngMessages will only display one error at a time. However, if you wish to display all + * messages then the `ng-messages-multiple` attribute flag can be used on the element containing the + * ngMessages directive to make this happen. + * + * ```html + * + *
    ...
    + * + * + * ... + * ``` + * + * ## Reusing and Overriding Messages + * In addition to prioritization, ngMessages also allows for including messages from a remote or an inline + * template. This allows for generic collection of messages to be reused across multiple parts of an + * application. + * + * ```html + * + * + *
    + *
    + *
    + * ``` + * + * However, including generic messages may not be useful enough to match all input fields, therefore, + * `ngMessages` provides the ability to override messages defined in the remote template by redefining + * them within the directive container. + * + * ```html + * + * + * + *
    + * + * + *
    + * + *
    You did not enter your email address
    + * + * + *
    Your email address is invalid
    + * + * + *
    + *
    + *
    + * ``` + * + * In the example HTML code above the message that is set on required will override the corresponding + * required message defined within the remote template. Therefore, with particular input fields (such + * email addresses, date fields, autocomplete inputs, etc...), specialized error messages can be applied + * while more generic messages can be used to handle other, more general input errors. + * + * ## Dynamic Messaging + * ngMessages also supports using expressions to dynamically change key values. Using arrays and + * repeaters to list messages is also supported. This means that the code below will be able to + * fully adapt itself and display the appropriate message when any of the expression data changes: + * + * ```html + *
    + * + *
    + *
    You did not enter your email address
    + *
    + * + *
    {{ errorMessage.text }}
    + *
    + *
    + *
    + * ``` + * + * The `errorMessage.type` expression can be a string value or it can be an array so + * that multiple errors can be associated with a single error message: + * + * ```html + * + *
    + *
    You did not enter your email address
    + *
    + * Your email must be between 5 and 100 characters long + *
    + *
    + * ``` + * + * Feel free to use other structural directives such as ng-if and ng-switch to further control + * what messages are active and when. Be careful, if you place ng-message on the same element + * as these structural directives, Angular may not be able to determine if a message is active + * or not. Therefore it is best to place the ng-message on a child element of the structural + * directive. + * + * ```html + *
    + *
    + *
    Please enter something
    + *
    + *
    + * ``` + * + * ## Animations + * If the `ngAnimate` module is active within the application then the `ngMessages`, `ngMessage` and + * `ngMessageExp` directives will trigger animations whenever any messages are added and removed from + * the DOM by the `ngMessages` directive. + * + * Whenever the `ngMessages` directive contains one or more visible messages then the `.ng-active` CSS + * class will be added to the element. The `.ng-inactive` CSS class will be applied when there are no + * messages present. Therefore, CSS transitions and keyframes as well as JavaScript animations can + * hook into the animations whenever these classes are added/removed. + * + * Let's say that our HTML code for our messages container looks like so: + * + * ```html + * + * ``` + * + * Then the CSS animation code for the message container looks like so: + * + * ```css + * .my-messages { + * transition:1s linear all; + * } + * .my-messages.ng-active { + * // messages are visible + * } + * .my-messages.ng-inactive { + * // messages are hidden + * } + * ``` + * + * Whenever an inner message is attached (becomes visible) or removed (becomes hidden) then the enter + * and leave animation is triggered for each particular element bound to the `ngMessage` directive. + * + * Therefore, the CSS code for the inner messages looks like so: + * + * ```css + * .some-message { + * transition:1s linear all; + * } + * + * .some-message.ng-enter {} + * .some-message.ng-enter.ng-enter-active {} + * + * .some-message.ng-leave {} + * .some-message.ng-leave.ng-leave-active {} + * ``` + * + * {@link ngAnimate Click here} to learn how to use JavaScript animations or to learn more about ngAnimate. + */ +angular.module('ngMessages', []) + + /** + * @ngdoc directive + * @module ngMessages + * @name ngMessages + * @restrict AE + * + * @description + * `ngMessages` is a directive that is designed to show and hide messages based on the state + * of a key/value object that it listens on. The directive itself complements error message + * reporting with the `ngModel` $error object (which stores a key/value state of validation errors). + * + * `ngMessages` manages the state of internal messages within its container element. The internal + * messages use the `ngMessage` directive and will be inserted/removed from the page depending + * on if they're present within the key/value object. By default, only one message will be displayed + * at a time and this depends on the prioritization of the messages within the template. (This can + * be changed by using the `ng-messages-multiple` or `multiple` attribute on the directive container.) + * + * A remote template can also be used to promote message reusability and messages can also be + * overridden. + * + * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`. + * + * @usage + * ```html + * + * + * ... + * ... + * ... + * + * + * + * + * ... + * ... + * ... + * + * ``` + * + * @param {string} ngMessages an angular expression evaluating to a key/value object + * (this is typically the $error object on an ngModel instance). + * @param {string=} ngMessagesMultiple|multiple when set, all messages will be displayed with true + * + * @example + * + * + *
    + * + *
    myForm.myName.$error = {{ myForm.myName.$error | json }}
    + * + *
    + *
    You did not enter a field
    + *
    Your field is too short
    + *
    Your field is too long
    + *
    + *
    + *
    + * + * angular.module('ngMessagesExample', ['ngMessages']); + * + *
    + */ + .directive('ngMessages', ['$animate', function($animate) { + var ACTIVE_CLASS = 'ng-active'; + var INACTIVE_CLASS = 'ng-inactive'; + + return { + require: 'ngMessages', + restrict: 'AE', + controller: ['$element', '$scope', '$attrs', function($element, $scope, $attrs) { + var ctrl = this; + var latestKey = 0; + var nextAttachId = 0; + + this.getAttachId = function getAttachId() { return nextAttachId++; }; + + var messages = this.messages = {}; + var renderLater, cachedCollection; + + this.render = function(collection) { + collection = collection || {}; + + renderLater = false; + cachedCollection = collection; + + // this is true if the attribute is empty or if the attribute value is truthy + var multiple = isAttrTruthy($scope, $attrs.ngMessagesMultiple) || + isAttrTruthy($scope, $attrs.multiple); + + var unmatchedMessages = []; + var matchedKeys = {}; + var messageItem = ctrl.head; + var messageFound = false; + var totalMessages = 0; + + // we use != instead of !== to allow for both undefined and null values + while (messageItem != null) { + totalMessages++; + var messageCtrl = messageItem.message; + + var messageUsed = false; + if (!messageFound) { + forEach(collection, function(value, key) { + if (!messageUsed && truthy(value) && messageCtrl.test(key)) { + // this is to prevent the same error name from showing up twice + if (matchedKeys[key]) return; + matchedKeys[key] = true; + + messageUsed = true; + messageCtrl.attach(); + } + }); + } + + if (messageUsed) { + // unless we want to display multiple messages then we should + // set a flag here to avoid displaying the next message in the list + messageFound = !multiple; + } else { + unmatchedMessages.push(messageCtrl); + } + + messageItem = messageItem.next; + } + + forEach(unmatchedMessages, function(messageCtrl) { + messageCtrl.detach(); + }); + + unmatchedMessages.length !== totalMessages + ? $animate.setClass($element, ACTIVE_CLASS, INACTIVE_CLASS) + : $animate.setClass($element, INACTIVE_CLASS, ACTIVE_CLASS); + }; + + $scope.$watchCollection($attrs.ngMessages || $attrs['for'], ctrl.render); + + this.reRender = function() { + if (!renderLater) { + renderLater = true; + $scope.$evalAsync(function() { + if (renderLater) { + cachedCollection && ctrl.render(cachedCollection); + } + }); + } + }; + + this.register = function(comment, messageCtrl) { + var nextKey = latestKey.toString(); + messages[nextKey] = { + message: messageCtrl + }; + insertMessageNode($element[0], comment, nextKey); + comment.$$ngMessageNode = nextKey; + latestKey++; + + ctrl.reRender(); + }; + + this.deregister = function(comment) { + var key = comment.$$ngMessageNode; + delete comment.$$ngMessageNode; + removeMessageNode($element[0], comment, key); + delete messages[key]; + ctrl.reRender(); + }; + + function findPreviousMessage(parent, comment) { + var prevNode = comment; + var parentLookup = []; + while (prevNode && prevNode !== parent) { + var prevKey = prevNode.$$ngMessageNode; + if (prevKey && prevKey.length) { + return messages[prevKey]; + } + + // dive deeper into the DOM and examine its children for any ngMessage + // comments that may be in an element that appears deeper in the list + if (prevNode.childNodes.length && parentLookup.indexOf(prevNode) == -1) { + parentLookup.push(prevNode); + prevNode = prevNode.childNodes[prevNode.childNodes.length - 1]; + } else { + prevNode = prevNode.previousSibling || prevNode.parentNode; + } + } + } + + function insertMessageNode(parent, comment, key) { + var messageNode = messages[key]; + if (!ctrl.head) { + ctrl.head = messageNode; + } else { + var match = findPreviousMessage(parent, comment); + if (match) { + messageNode.next = match.next; + match.next = messageNode; + } else { + messageNode.next = ctrl.head; + ctrl.head = messageNode; + } + } + } + + function removeMessageNode(parent, comment, key) { + var messageNode = messages[key]; + + var match = findPreviousMessage(parent, comment); + if (match) { + match.next = messageNode.next; + } else { + ctrl.head = messageNode.next; + } + } + }] + }; + + function isAttrTruthy(scope, attr) { + return (isString(attr) && attr.length === 0) || //empty attribute + truthy(scope.$eval(attr)); + } + + function truthy(val) { + return isString(val) ? val.length : !!val; + } + }]) + + /** + * @ngdoc directive + * @name ngMessagesInclude + * @restrict AE + * @scope + * + * @description + * `ngMessagesInclude` is a directive with the purpose to import existing ngMessage template + * code from a remote template and place the downloaded template code into the exact spot + * that the ngMessagesInclude directive is placed within the ngMessages container. This allows + * for a series of pre-defined messages to be reused and also allows for the developer to + * determine what messages are overridden due to the placement of the ngMessagesInclude directive. + * + * @usage + * ```html + * + * + * ... + * + * + * + * + * ... + * + * ``` + * + * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`. + * + * @param {string} ngMessagesInclude|src a string value corresponding to the remote template. + */ + .directive('ngMessagesInclude', + ['$templateRequest', '$document', '$compile', function($templateRequest, $document, $compile) { + + return { + restrict: 'AE', + require: '^^ngMessages', // we only require this for validation sake + link: function($scope, element, attrs) { + var src = attrs.ngMessagesInclude || attrs.src; + $templateRequest(src).then(function(html) { + $compile(html)($scope, function(contents) { + element.after(contents); + + // the anchor is placed for debugging purposes + var anchor = jqLite($document[0].createComment(' ngMessagesInclude: ' + src + ' ')); + element.after(anchor); + + // we don't want to pollute the DOM anymore by keeping an empty directive element + element.remove(); + }); + }); + } + }; + }]) + + /** + * @ngdoc directive + * @name ngMessage + * @restrict AE + * @scope + * + * @description + * `ngMessage` is a directive with the purpose to show and hide a particular message. + * For `ngMessage` to operate, a parent `ngMessages` directive on a parent DOM element + * must be situated since it determines which messages are visible based on the state + * of the provided key/value map that `ngMessages` listens on. + * + * More information about using `ngMessage` can be found in the + * {@link module:ngMessages `ngMessages` module documentation}. + * + * @usage + * ```html + * + * + * ... + * ... + * + * + * + * + * ... + * ... + * + * ``` + * + * @param {expression} ngMessage|when a string value corresponding to the message key. + */ + .directive('ngMessage', ngMessageDirectiveFactory('AE')) + + + /** + * @ngdoc directive + * @name ngMessageExp + * @restrict AE + * @scope + * + * @description + * `ngMessageExp` is a directive with the purpose to show and hide a particular message. + * For `ngMessageExp` to operate, a parent `ngMessages` directive on a parent DOM element + * must be situated since it determines which messages are visible based on the state + * of the provided key/value map that `ngMessages` listens on. + * + * @usage + * ```html + * + * + * ... + * + * + * + * + * ... + * + * ``` + * + * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`. + * + * @param {expression} ngMessageExp|whenExp an expression value corresponding to the message key. + */ + .directive('ngMessageExp', ngMessageDirectiveFactory('A')); + +function ngMessageDirectiveFactory(restrict) { + return ['$animate', function($animate) { + return { + restrict: 'AE', + transclude: 'element', + terminal: true, + require: '^^ngMessages', + link: function(scope, element, attrs, ngMessagesCtrl, $transclude) { + var commentNode = element[0]; + + var records; + var staticExp = attrs.ngMessage || attrs.when; + var dynamicExp = attrs.ngMessageExp || attrs.whenExp; + var assignRecords = function(items) { + records = items + ? (isArray(items) + ? items + : items.split(/[\s,]+/)) + : null; + ngMessagesCtrl.reRender(); + }; + + if (dynamicExp) { + assignRecords(scope.$eval(dynamicExp)); + scope.$watchCollection(dynamicExp, assignRecords); + } else { + assignRecords(staticExp); + } + + var currentElement, messageCtrl; + ngMessagesCtrl.register(commentNode, messageCtrl = { + test: function(name) { + return contains(records, name); + }, + attach: function() { + if (!currentElement) { + $transclude(scope, function(elm) { + $animate.enter(elm, null, element); + currentElement = elm; + + // Each time we attach this node to a message we get a new id that we can match + // when we are destroying the node later. + var $$attachId = currentElement.$$attachId = ngMessagesCtrl.getAttachId(); + + // in the event that the parent element is destroyed + // by any other structural directive then it's time + // to deregister the message from the controller + currentElement.on('$destroy', function() { + if (currentElement && currentElement.$$attachId === $$attachId) { + ngMessagesCtrl.deregister(commentNode); + messageCtrl.detach(); + } + }); + }); + } + }, + detach: function() { + if (currentElement) { + var elm = currentElement; + currentElement = null; + $animate.leave(elm); + } + } + }); + } + }; + }]; + + function contains(collection, key) { + if (collection) { + return isArray(collection) + ? collection.indexOf(key) >= 0 + : collection.hasOwnProperty(key); + } + } +} + + +})(window, window.angular); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-messages.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-messages.min.js new file mode 100644 index 00000000..e7f8119d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-messages.min.js @@ -0,0 +1,12 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(z,h,A){'use strict';function m(h){return["$animate",function(r){return{restrict:"AE",transclude:"element",terminal:!0,require:"^^ngMessages",link:function(n,f,a,g,l){var c=f[0],p,h=a.ngMessage||a.when;a=a.ngMessageExp||a.whenExp;var k=function(b){p=b?v(b)?b:b.split(/[\s,]+/):null;g.reRender()};a?(k(n.$eval(a)),n.$watchCollection(a,k)):k(h);var e,q;g.register(c,q={test:function(b){var a=p;b=a?v(a)?0<=a.indexOf(b):a.hasOwnProperty(b):void 0;return b},attach:function(){e||l(n,function(b){r.enter(b, +null,f);e=b;var a=e.$$attachId=g.getAttachId();e.on("$destroy",function(){e&&e.$$attachId===a&&(g.deregister(c),q.detach())})})},detach:function(){if(e){var b=e;e=null;r.leave(b)}}})}}}]}var v=h.isArray,w=h.forEach,x=h.isString,y=h.element;h.module("ngMessages",[]).directive("ngMessages",["$animate",function(h){function r(f,a){return x(a)&&0===a.length||n(f.$eval(a))}function n(f){return x(f)?f.length:!!f}return{require:"ngMessages",restrict:"AE",controller:["$element","$scope","$attrs",function(f, +a,g){function l(b,a){for(var d=a,f=[];d&&d!==b;){var c=d.$$ngMessageNode;if(c&&c.length)return k[c];d.childNodes.length&&-1==f.indexOf(d)?(f.push(d),d=d.childNodes[d.childNodes.length-1]):d=d.previousSibling||d.parentNode}}var c=this,p=0,m=0;this.getAttachId=function(){return m++};var k=this.messages={},e,q;this.render=function(b){b=b||{};e=!1;q=b;for(var p=r(a,g.ngMessagesMultiple)||r(a,g.multiple),d=[],k={},s=c.head,l=!1,m=0;null!=s;){m++;var t=s.message,u=!1;l||w(b,function(a,b){!u&&n(a)&&t.test(b)&& +!k[b]&&(u=k[b]=!0,t.attach())});u?l=!p:d.push(t);s=s.next}w(d,function(b){b.detach()});d.length!==m?h.setClass(f,"ng-active","ng-inactive"):h.setClass(f,"ng-inactive","ng-active")};a.$watchCollection(g.ngMessages||g["for"],c.render);this.reRender=function(){e||(e=!0,a.$evalAsync(function(){e&&q&&c.render(q)}))};this.register=function(b,a){var d=p.toString();k[d]={message:a};var e=f[0],g=k[d];c.head?(e=l(e,b))?(g.next=e.next,e.next=g):(g.next=c.head,c.head=g):c.head=g;b.$$ngMessageNode=d;p++;c.reRender()}; +this.deregister=function(b){var a=b.$$ngMessageNode;delete b.$$ngMessageNode;var d=k[a];(b=l(f[0],b))?b.next=d.next:c.head=d.next;delete k[a];c.reRender()}}]}}]).directive("ngMessagesInclude",["$templateRequest","$document","$compile",function(h,m,n){return{restrict:"AE",require:"^^ngMessages",link:function(f,a,g){var l=g.ngMessagesInclude||g.src;h(l).then(function(c){n(c)(f,function(c){a.after(c);c=y(m[0].createComment(" ngMessagesInclude: "+l+" "));a.after(c);a.remove()})})}}}]).directive("ngMessage", +m("AE")).directive("ngMessageExp",m("A"))})(window,window.angular); +//# sourceMappingURL=angular-messages.min.js.map diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-messages.min.js.map b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-messages.min.js.map new file mode 100644 index 00000000..506e76c0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-messages.min.js.map @@ -0,0 +1,8 @@ +{ +"version":3, +"file":"angular-messages.min.js", +"lineCount":11, +"mappings":"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", +"sources":["angular-messages.js"], +"names":["window","angular","undefined","ngMessageDirectiveFactory","restrict","$animate","transclude","terminal","require","link","scope","element","attrs","ngMessagesCtrl","$transclude","commentNode","records","staticExp","ngMessage","when","dynamicExp","ngMessageExp","whenExp","assignRecords","items","isArray","split","reRender","$eval","$watchCollection","currentElement","messageCtrl","register","test","name","collection","indexOf","hasOwnProperty","attach","elm","enter","$$attachId","getAttachId","on","deregister","detach","leave","forEach","isString","jqLite","module","directive","isAttrTruthy","attr","length","truthy","val","controller","$element","$scope","$attrs","findPreviousMessage","parent","comment","prevNode","parentLookup","prevKey","$$ngMessageNode","messages","childNodes","push","previousSibling","parentNode","ctrl","latestKey","nextAttachId","this.getAttachId","renderLater","cachedCollection","render","this.render","multiple","ngMessagesMultiple","unmatchedMessages","matchedKeys","messageItem","head","messageFound","totalMessages","message","messageUsed","value","key","next","setClass","ACTIVE_CLASS","INACTIVE_CLASS","ngMessages","this.reRender","$evalAsync","this.register","nextKey","toString","messageNode","match","this.deregister","$templateRequest","$document","$compile","src","ngMessagesInclude","then","html","contents","after","anchor","createComment","remove"] +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-mocks.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-mocks.js new file mode 100644 index 00000000..917d8427 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-mocks.js @@ -0,0 +1,2471 @@ +/** + * @license AngularJS v1.4.8 + * (c) 2010-2015 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) { + +'use strict'; + +/** + * @ngdoc object + * @name angular.mock + * @description + * + * Namespace from 'angular-mocks.js' which contains testing related code. + */ +angular.mock = {}; + +/** + * ! This is a private undocumented service ! + * + * @name $browser + * + * @description + * This service is a mock implementation of {@link ng.$browser}. It provides fake + * implementation for commonly used browser apis that are hard to test, e.g. setTimeout, xhr, + * cookies, etc... + * + * The api of this service is the same as that of the real {@link ng.$browser $browser}, except + * that there are several helper methods available which can be used in tests. + */ +angular.mock.$BrowserProvider = function() { + this.$get = function() { + return new angular.mock.$Browser(); + }; +}; + +angular.mock.$Browser = function() { + var self = this; + + this.isMock = true; + self.$$url = "http://server/"; + self.$$lastUrl = self.$$url; // used by url polling fn + self.pollFns = []; + + // TODO(vojta): remove this temporary api + self.$$completeOutstandingRequest = angular.noop; + self.$$incOutstandingRequestCount = angular.noop; + + + // register url polling fn + + self.onUrlChange = function(listener) { + self.pollFns.push( + function() { + if (self.$$lastUrl !== self.$$url || self.$$state !== self.$$lastState) { + self.$$lastUrl = self.$$url; + self.$$lastState = self.$$state; + listener(self.$$url, self.$$state); + } + } + ); + + return listener; + }; + + self.$$applicationDestroyed = angular.noop; + self.$$checkUrlChange = angular.noop; + + self.deferredFns = []; + self.deferredNextId = 0; + + self.defer = function(fn, delay) { + delay = delay || 0; + self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId}); + self.deferredFns.sort(function(a, b) { return a.time - b.time;}); + return self.deferredNextId++; + }; + + + /** + * @name $browser#defer.now + * + * @description + * Current milliseconds mock time. + */ + self.defer.now = 0; + + + self.defer.cancel = function(deferId) { + var fnIndex; + + angular.forEach(self.deferredFns, function(fn, index) { + if (fn.id === deferId) fnIndex = index; + }); + + if (angular.isDefined(fnIndex)) { + self.deferredFns.splice(fnIndex, 1); + return true; + } + + return false; + }; + + + /** + * @name $browser#defer.flush + * + * @description + * Flushes all pending requests and executes the defer callbacks. + * + * @param {number=} number of milliseconds to flush. See {@link #defer.now} + */ + self.defer.flush = function(delay) { + if (angular.isDefined(delay)) { + self.defer.now += delay; + } else { + if (self.deferredFns.length) { + self.defer.now = self.deferredFns[self.deferredFns.length - 1].time; + } else { + throw new Error('No deferred tasks to be flushed'); + } + } + + while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) { + self.deferredFns.shift().fn(); + } + }; + + self.$$baseHref = '/'; + self.baseHref = function() { + return this.$$baseHref; + }; +}; +angular.mock.$Browser.prototype = { + +/** + * @name $browser#poll + * + * @description + * run all fns in pollFns + */ + poll: function poll() { + angular.forEach(this.pollFns, function(pollFn) { + pollFn(); + }); + }, + + url: function(url, replace, state) { + if (angular.isUndefined(state)) { + state = null; + } + if (url) { + this.$$url = url; + // Native pushState serializes & copies the object; simulate it. + this.$$state = angular.copy(state); + return this; + } + + return this.$$url; + }, + + state: function() { + return this.$$state; + }, + + notifyWhenNoOutstandingRequests: function(fn) { + fn(); + } +}; + + +/** + * @ngdoc provider + * @name $exceptionHandlerProvider + * + * @description + * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors + * passed to the `$exceptionHandler`. + */ + +/** + * @ngdoc service + * @name $exceptionHandler + * + * @description + * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed + * to it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration + * information. + * + * + * ```js + * describe('$exceptionHandlerProvider', function() { + * + * it('should capture log messages and exceptions', function() { + * + * module(function($exceptionHandlerProvider) { + * $exceptionHandlerProvider.mode('log'); + * }); + * + * inject(function($log, $exceptionHandler, $timeout) { + * $timeout(function() { $log.log(1); }); + * $timeout(function() { $log.log(2); throw 'banana peel'; }); + * $timeout(function() { $log.log(3); }); + * expect($exceptionHandler.errors).toEqual([]); + * expect($log.assertEmpty()); + * $timeout.flush(); + * expect($exceptionHandler.errors).toEqual(['banana peel']); + * expect($log.log.logs).toEqual([[1], [2], [3]]); + * }); + * }); + * }); + * ``` + */ + +angular.mock.$ExceptionHandlerProvider = function() { + var handler; + + /** + * @ngdoc method + * @name $exceptionHandlerProvider#mode + * + * @description + * Sets the logging mode. + * + * @param {string} mode Mode of operation, defaults to `rethrow`. + * + * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log` + * mode stores an array of errors in `$exceptionHandler.errors`, to allow later + * assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and + * {@link ngMock.$log#reset reset()} + * - `rethrow`: If any errors are passed to the handler in tests, it typically means that there + * is a bug in the application or test, so this mock will make these tests fail. + * For any implementations that expect exceptions to be thrown, the `rethrow` mode + * will also maintain a log of thrown errors. + */ + this.mode = function(mode) { + + switch (mode) { + case 'log': + case 'rethrow': + var errors = []; + handler = function(e) { + if (arguments.length == 1) { + errors.push(e); + } else { + errors.push([].slice.call(arguments, 0)); + } + if (mode === "rethrow") { + throw e; + } + }; + handler.errors = errors; + break; + default: + throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!"); + } + }; + + this.$get = function() { + return handler; + }; + + this.mode('rethrow'); +}; + + +/** + * @ngdoc service + * @name $log + * + * @description + * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays + * (one array per logging level). These arrays are exposed as `logs` property of each of the + * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`. + * + */ +angular.mock.$LogProvider = function() { + var debug = true; + + function concat(array1, array2, index) { + return array1.concat(Array.prototype.slice.call(array2, index)); + } + + this.debugEnabled = function(flag) { + if (angular.isDefined(flag)) { + debug = flag; + return this; + } else { + return debug; + } + }; + + this.$get = function() { + var $log = { + log: function() { $log.log.logs.push(concat([], arguments, 0)); }, + warn: function() { $log.warn.logs.push(concat([], arguments, 0)); }, + info: function() { $log.info.logs.push(concat([], arguments, 0)); }, + error: function() { $log.error.logs.push(concat([], arguments, 0)); }, + debug: function() { + if (debug) { + $log.debug.logs.push(concat([], arguments, 0)); + } + } + }; + + /** + * @ngdoc method + * @name $log#reset + * + * @description + * Reset all of the logging arrays to empty. + */ + $log.reset = function() { + /** + * @ngdoc property + * @name $log#log.logs + * + * @description + * Array of messages logged using {@link ng.$log#log `log()`}. + * + * @example + * ```js + * $log.log('Some Log'); + * var first = $log.log.logs.unshift(); + * ``` + */ + $log.log.logs = []; + /** + * @ngdoc property + * @name $log#info.logs + * + * @description + * Array of messages logged using {@link ng.$log#info `info()`}. + * + * @example + * ```js + * $log.info('Some Info'); + * var first = $log.info.logs.unshift(); + * ``` + */ + $log.info.logs = []; + /** + * @ngdoc property + * @name $log#warn.logs + * + * @description + * Array of messages logged using {@link ng.$log#warn `warn()`}. + * + * @example + * ```js + * $log.warn('Some Warning'); + * var first = $log.warn.logs.unshift(); + * ``` + */ + $log.warn.logs = []; + /** + * @ngdoc property + * @name $log#error.logs + * + * @description + * Array of messages logged using {@link ng.$log#error `error()`}. + * + * @example + * ```js + * $log.error('Some Error'); + * var first = $log.error.logs.unshift(); + * ``` + */ + $log.error.logs = []; + /** + * @ngdoc property + * @name $log#debug.logs + * + * @description + * Array of messages logged using {@link ng.$log#debug `debug()`}. + * + * @example + * ```js + * $log.debug('Some Error'); + * var first = $log.debug.logs.unshift(); + * ``` + */ + $log.debug.logs = []; + }; + + /** + * @ngdoc method + * @name $log#assertEmpty + * + * @description + * Assert that all of the logging methods have no logged messages. If any messages are present, + * an exception is thrown. + */ + $log.assertEmpty = function() { + var errors = []; + angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) { + angular.forEach($log[logLevel].logs, function(log) { + angular.forEach(log, function(logItem) { + errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' + + (logItem.stack || '')); + }); + }); + }); + if (errors.length) { + errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or " + + "an expected log message was not checked and removed:"); + errors.push(''); + throw new Error(errors.join('\n---------\n')); + } + }; + + $log.reset(); + return $log; + }; +}; + + +/** + * @ngdoc service + * @name $interval + * + * @description + * Mock implementation of the $interval service. + * + * Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to + * move forward by `millis` milliseconds and trigger any functions scheduled to run in that + * time. + * + * @param {function()} fn A function that should be called repeatedly. + * @param {number} delay Number of milliseconds between each function call. + * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat + * indefinitely. + * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise + * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. + * @param {...*=} Pass additional parameters to the executed function. + * @returns {promise} A promise which will be notified on each iteration. + */ +angular.mock.$IntervalProvider = function() { + this.$get = ['$browser', '$rootScope', '$q', '$$q', + function($browser, $rootScope, $q, $$q) { + var repeatFns = [], + nextRepeatId = 0, + now = 0; + + var $interval = function(fn, delay, count, invokeApply) { + var hasParams = arguments.length > 4, + args = hasParams ? Array.prototype.slice.call(arguments, 4) : [], + iteration = 0, + skipApply = (angular.isDefined(invokeApply) && !invokeApply), + deferred = (skipApply ? $$q : $q).defer(), + promise = deferred.promise; + + count = (angular.isDefined(count)) ? count : 0; + promise.then(null, null, (!hasParams) ? fn : function() { + fn.apply(null, args); + }); + + promise.$$intervalId = nextRepeatId; + + function tick() { + deferred.notify(iteration++); + + if (count > 0 && iteration >= count) { + var fnIndex; + deferred.resolve(iteration); + + angular.forEach(repeatFns, function(fn, index) { + if (fn.id === promise.$$intervalId) fnIndex = index; + }); + + if (angular.isDefined(fnIndex)) { + repeatFns.splice(fnIndex, 1); + } + } + + if (skipApply) { + $browser.defer.flush(); + } else { + $rootScope.$apply(); + } + } + + repeatFns.push({ + nextTime:(now + delay), + delay: delay, + fn: tick, + id: nextRepeatId, + deferred: deferred + }); + repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;}); + + nextRepeatId++; + return promise; + }; + /** + * @ngdoc method + * @name $interval#cancel + * + * @description + * Cancels a task associated with the `promise`. + * + * @param {promise} promise A promise from calling the `$interval` function. + * @returns {boolean} Returns `true` if the task was successfully cancelled. + */ + $interval.cancel = function(promise) { + if (!promise) return false; + var fnIndex; + + angular.forEach(repeatFns, function(fn, index) { + if (fn.id === promise.$$intervalId) fnIndex = index; + }); + + if (angular.isDefined(fnIndex)) { + repeatFns[fnIndex].deferred.reject('canceled'); + repeatFns.splice(fnIndex, 1); + return true; + } + + return false; + }; + + /** + * @ngdoc method + * @name $interval#flush + * @description + * + * Runs interval tasks scheduled to be run in the next `millis` milliseconds. + * + * @param {number=} millis maximum timeout amount to flush up until. + * + * @return {number} The amount of time moved forward. + */ + $interval.flush = function(millis) { + now += millis; + while (repeatFns.length && repeatFns[0].nextTime <= now) { + var task = repeatFns[0]; + task.fn(); + task.nextTime += task.delay; + repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;}); + } + return millis; + }; + + return $interval; + }]; +}; + + +/* jshint -W101 */ +/* The R_ISO8061_STR regex is never going to fit into the 100 char limit! + * This directive should go inside the anonymous function but a bug in JSHint means that it would + * not be enacted early enough to prevent the warning. + */ +var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; + +function jsonStringToDate(string) { + var match; + if (match = string.match(R_ISO8061_STR)) { + var date = new Date(0), + tzHour = 0, + tzMin = 0; + if (match[9]) { + tzHour = toInt(match[9] + match[10]); + tzMin = toInt(match[9] + match[11]); + } + date.setUTCFullYear(toInt(match[1]), toInt(match[2]) - 1, toInt(match[3])); + date.setUTCHours(toInt(match[4] || 0) - tzHour, + toInt(match[5] || 0) - tzMin, + toInt(match[6] || 0), + toInt(match[7] || 0)); + return date; + } + return string; +} + +function toInt(str) { + return parseInt(str, 10); +} + +function padNumber(num, digits, trim) { + var neg = ''; + if (num < 0) { + neg = '-'; + num = -num; + } + num = '' + num; + while (num.length < digits) num = '0' + num; + if (trim) { + num = num.substr(num.length - digits); + } + return neg + num; +} + + +/** + * @ngdoc type + * @name angular.mock.TzDate + * @description + * + * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`. + * + * Mock of the Date type which has its timezone specified via constructor arg. + * + * The main purpose is to create Date-like instances with timezone fixed to the specified timezone + * offset, so that we can test code that depends on local timezone settings without dependency on + * the time zone settings of the machine where the code is running. + * + * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored) + * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC* + * + * @example + * !!!! WARNING !!!!! + * This is not a complete Date object so only methods that were implemented can be called safely. + * To make matters worse, TzDate instances inherit stuff from Date via a prototype. + * + * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is + * incomplete we might be missing some non-standard methods. This can result in errors like: + * "Date.prototype.foo called on incompatible Object". + * + * ```js + * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z'); + * newYearInBratislava.getTimezoneOffset() => -60; + * newYearInBratislava.getFullYear() => 2010; + * newYearInBratislava.getMonth() => 0; + * newYearInBratislava.getDate() => 1; + * newYearInBratislava.getHours() => 0; + * newYearInBratislava.getMinutes() => 0; + * newYearInBratislava.getSeconds() => 0; + * ``` + * + */ +angular.mock.TzDate = function(offset, timestamp) { + var self = new Date(0); + if (angular.isString(timestamp)) { + var tsStr = timestamp; + + self.origDate = jsonStringToDate(timestamp); + + timestamp = self.origDate.getTime(); + if (isNaN(timestamp)) { + throw { + name: "Illegal Argument", + message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string" + }; + } + } else { + self.origDate = new Date(timestamp); + } + + var localOffset = new Date(timestamp).getTimezoneOffset(); + self.offsetDiff = localOffset * 60 * 1000 - offset * 1000 * 60 * 60; + self.date = new Date(timestamp + self.offsetDiff); + + self.getTime = function() { + return self.date.getTime() - self.offsetDiff; + }; + + self.toLocaleDateString = function() { + return self.date.toLocaleDateString(); + }; + + self.getFullYear = function() { + return self.date.getFullYear(); + }; + + self.getMonth = function() { + return self.date.getMonth(); + }; + + self.getDate = function() { + return self.date.getDate(); + }; + + self.getHours = function() { + return self.date.getHours(); + }; + + self.getMinutes = function() { + return self.date.getMinutes(); + }; + + self.getSeconds = function() { + return self.date.getSeconds(); + }; + + self.getMilliseconds = function() { + return self.date.getMilliseconds(); + }; + + self.getTimezoneOffset = function() { + return offset * 60; + }; + + self.getUTCFullYear = function() { + return self.origDate.getUTCFullYear(); + }; + + self.getUTCMonth = function() { + return self.origDate.getUTCMonth(); + }; + + self.getUTCDate = function() { + return self.origDate.getUTCDate(); + }; + + self.getUTCHours = function() { + return self.origDate.getUTCHours(); + }; + + self.getUTCMinutes = function() { + return self.origDate.getUTCMinutes(); + }; + + self.getUTCSeconds = function() { + return self.origDate.getUTCSeconds(); + }; + + self.getUTCMilliseconds = function() { + return self.origDate.getUTCMilliseconds(); + }; + + self.getDay = function() { + return self.date.getDay(); + }; + + // provide this method only on browsers that already have it + if (self.toISOString) { + self.toISOString = function() { + return padNumber(self.origDate.getUTCFullYear(), 4) + '-' + + padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' + + padNumber(self.origDate.getUTCDate(), 2) + 'T' + + padNumber(self.origDate.getUTCHours(), 2) + ':' + + padNumber(self.origDate.getUTCMinutes(), 2) + ':' + + padNumber(self.origDate.getUTCSeconds(), 2) + '.' + + padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'; + }; + } + + //hide all methods not implemented in this mock that the Date prototype exposes + var unimplementedMethods = ['getUTCDay', + 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', + 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', + 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', + 'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString', + 'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf']; + + angular.forEach(unimplementedMethods, function(methodName) { + self[methodName] = function() { + throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock"); + }; + }); + + return self; +}; + +//make "tzDateInstance instanceof Date" return true +angular.mock.TzDate.prototype = Date.prototype; +/* jshint +W101 */ + +angular.mock.animate = angular.module('ngAnimateMock', ['ng']) + + .config(['$provide', function($provide) { + + $provide.factory('$$forceReflow', function() { + function reflowFn() { + reflowFn.totalReflows++; + } + reflowFn.totalReflows = 0; + return reflowFn; + }); + + $provide.factory('$$animateAsyncRun', function() { + var queue = []; + var queueFn = function() { + return function(fn) { + queue.push(fn); + }; + }; + queueFn.flush = function() { + if (queue.length === 0) return false; + + for (var i = 0; i < queue.length; i++) { + queue[i](); + } + queue = []; + + return true; + }; + return queueFn; + }); + + $provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF', + '$$forceReflow', '$$animateAsyncRun', '$rootScope', + function($delegate, $timeout, $browser, $$rAF, + $$forceReflow, $$animateAsyncRun, $rootScope) { + var animate = { + queue: [], + cancel: $delegate.cancel, + on: $delegate.on, + off: $delegate.off, + pin: $delegate.pin, + get reflows() { + return $$forceReflow.totalReflows; + }, + enabled: $delegate.enabled, + flush: function() { + $rootScope.$digest(); + + var doNextRun, somethingFlushed = false; + do { + doNextRun = false; + + if ($$rAF.queue.length) { + $$rAF.flush(); + doNextRun = somethingFlushed = true; + } + + if ($$animateAsyncRun.flush()) { + doNextRun = somethingFlushed = true; + } + } while (doNextRun); + + if (!somethingFlushed) { + throw new Error('No pending animations ready to be closed or flushed'); + } + + $rootScope.$digest(); + } + }; + + angular.forEach( + ['animate','enter','leave','move','addClass','removeClass','setClass'], function(method) { + animate[method] = function() { + animate.queue.push({ + event: method, + element: arguments[0], + options: arguments[arguments.length - 1], + args: arguments + }); + return $delegate[method].apply($delegate, arguments); + }; + }); + + return animate; + }]); + + }]); + + +/** + * @ngdoc function + * @name angular.mock.dump + * @description + * + * *NOTE*: this is not an injectable instance, just a globally available function. + * + * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for + * debugging. + * + * This method is also available on window, where it can be used to display objects on debug + * console. + * + * @param {*} object - any object to turn into string. + * @return {string} a serialized string of the argument + */ +angular.mock.dump = function(object) { + return serialize(object); + + function serialize(object) { + var out; + + if (angular.isElement(object)) { + object = angular.element(object); + out = angular.element('
    '); + angular.forEach(object, function(element) { + out.append(angular.element(element).clone()); + }); + out = out.html(); + } else if (angular.isArray(object)) { + out = []; + angular.forEach(object, function(o) { + out.push(serialize(o)); + }); + out = '[ ' + out.join(', ') + ' ]'; + } else if (angular.isObject(object)) { + if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) { + out = serializeScope(object); + } else if (object instanceof Error) { + out = object.stack || ('' + object.name + ': ' + object.message); + } else { + // TODO(i): this prevents methods being logged, + // we should have a better way to serialize objects + out = angular.toJson(object, true); + } + } else { + out = String(object); + } + + return out; + } + + function serializeScope(scope, offset) { + offset = offset || ' '; + var log = [offset + 'Scope(' + scope.$id + '): {']; + for (var key in scope) { + if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) { + log.push(' ' + key + ': ' + angular.toJson(scope[key])); + } + } + var child = scope.$$childHead; + while (child) { + log.push(serializeScope(child, offset + ' ')); + child = child.$$nextSibling; + } + log.push('}'); + return log.join('\n' + offset); + } +}; + +/** + * @ngdoc service + * @name $httpBackend + * @description + * Fake HTTP backend implementation suitable for unit testing applications that use the + * {@link ng.$http $http service}. + * + * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less + * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}. + * + * During unit testing, we want our unit tests to run quickly and have no external dependencies so + * we don’t want to send [XHR](https://developer.mozilla.org/en/xmlhttprequest) or + * [JSONP](http://en.wikipedia.org/wiki/JSONP) requests to a real server. All we really need is + * to verify whether a certain request has been sent or not, or alternatively just let the + * application make requests, respond with pre-trained responses and assert that the end result is + * what we expect it to be. + * + * This mock implementation can be used to respond with static or dynamic responses via the + * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc). + * + * When an Angular application needs some data from a server, it calls the $http service, which + * sends the request to a real server using $httpBackend service. With dependency injection, it is + * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify + * the requests and respond with some testing data without sending a request to a real server. + * + * There are two ways to specify what test data should be returned as http responses by the mock + * backend when the code under test makes http requests: + * + * - `$httpBackend.expect` - specifies a request expectation + * - `$httpBackend.when` - specifies a backend definition + * + * + * # Request Expectations vs Backend Definitions + * + * Request expectations provide a way to make assertions about requests made by the application and + * to define responses for those requests. The test will fail if the expected requests are not made + * or they are made in the wrong order. + * + * Backend definitions allow you to define a fake backend for your application which doesn't assert + * if a particular request was made or not, it just returns a trained response if a request is made. + * The test will pass whether or not the request gets made during testing. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Request expectationsBackend definitions
    Syntax.expect(...).respond(...).when(...).respond(...)
    Typical usagestrict unit testsloose (black-box) unit testing
    Fulfills multiple requestsNOYES
    Order of requests mattersYESNO
    Request requiredYESNO
    Response requiredoptional (see below)YES
    + * + * In cases where both backend definitions and request expectations are specified during unit + * testing, the request expectations are evaluated first. + * + * If a request expectation has no response specified, the algorithm will search your backend + * definitions for an appropriate response. + * + * If a request didn't match any expectation or if the expectation doesn't have the response + * defined, the backend definitions are evaluated in sequential order to see if any of them match + * the request. The response from the first matched definition is returned. + * + * + * # Flushing HTTP requests + * + * The $httpBackend used in production always responds to requests asynchronously. If we preserved + * this behavior in unit testing, we'd have to create async unit tests, which are hard to write, + * to follow and to maintain. But neither can the testing mock respond synchronously; that would + * change the execution of the code under test. For this reason, the mock $httpBackend has a + * `flush()` method, which allows the test to explicitly flush pending requests. This preserves + * the async api of the backend, while allowing the test to execute synchronously. + * + * + * # Unit testing with mock $httpBackend + * The following code shows how to setup and use the mock backend when unit testing a controller. + * First we create the controller under test: + * + ```js + // The module code + angular + .module('MyApp', []) + .controller('MyController', MyController); + + // The controller code + function MyController($scope, $http) { + var authToken; + + $http.get('/auth.py').success(function(data, status, headers) { + authToken = headers('A-Token'); + $scope.user = data; + }); + + $scope.saveMessage = function(message) { + var headers = { 'Authorization': authToken }; + $scope.status = 'Saving...'; + + $http.post('/add-msg.py', message, { headers: headers } ).success(function(response) { + $scope.status = ''; + }).error(function() { + $scope.status = 'Failed...'; + }); + }; + } + ``` + * + * Now we setup the mock backend and create the test specs: + * + ```js + // testing controller + describe('MyController', function() { + var $httpBackend, $rootScope, createController, authRequestHandler; + + // Set up the module + beforeEach(module('MyApp')); + + beforeEach(inject(function($injector) { + // Set up the mock http service responses + $httpBackend = $injector.get('$httpBackend'); + // backend definition common for all tests + authRequestHandler = $httpBackend.when('GET', '/auth.py') + .respond({userId: 'userX'}, {'A-Token': 'xxx'}); + + // Get hold of a scope (i.e. the root scope) + $rootScope = $injector.get('$rootScope'); + // The $controller service is used to create instances of controllers + var $controller = $injector.get('$controller'); + + createController = function() { + return $controller('MyController', {'$scope' : $rootScope }); + }; + })); + + + afterEach(function() { + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + + it('should fetch authentication token', function() { + $httpBackend.expectGET('/auth.py'); + var controller = createController(); + $httpBackend.flush(); + }); + + + it('should fail authentication', function() { + + // Notice how you can change the response even after it was set + authRequestHandler.respond(401, ''); + + $httpBackend.expectGET('/auth.py'); + var controller = createController(); + $httpBackend.flush(); + expect($rootScope.status).toBe('Failed...'); + }); + + + it('should send msg to server', function() { + var controller = createController(); + $httpBackend.flush(); + + // now you don’t care about the authentication, but + // the controller will still send the request and + // $httpBackend will respond without you having to + // specify the expectation and response for this request + + $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, ''); + $rootScope.saveMessage('message content'); + expect($rootScope.status).toBe('Saving...'); + $httpBackend.flush(); + expect($rootScope.status).toBe(''); + }); + + + it('should send auth header', function() { + var controller = createController(); + $httpBackend.flush(); + + $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) { + // check if the header was sent, if it wasn't the expectation won't + // match the request and the test will fail + return headers['Authorization'] == 'xxx'; + }).respond(201, ''); + + $rootScope.saveMessage('whatever'); + $httpBackend.flush(); + }); + }); + ``` + */ +angular.mock.$HttpBackendProvider = function() { + this.$get = ['$rootScope', '$timeout', createHttpBackendMock]; +}; + +/** + * General factory function for $httpBackend mock. + * Returns instance for unit testing (when no arguments specified): + * - passing through is disabled + * - auto flushing is disabled + * + * Returns instance for e2e testing (when `$delegate` and `$browser` specified): + * - passing through (delegating request to real backend) is enabled + * - auto flushing is enabled + * + * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified) + * @param {Object=} $browser Auto-flushing enabled if specified + * @return {Object} Instance of $httpBackend mock + */ +function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { + var definitions = [], + expectations = [], + responses = [], + responsesPush = angular.bind(responses, responses.push), + copy = angular.copy; + + function createResponse(status, data, headers, statusText) { + if (angular.isFunction(status)) return status; + + return function() { + return angular.isNumber(status) + ? [status, data, headers, statusText] + : [200, status, data, headers]; + }; + } + + // TODO(vojta): change params to: method, url, data, headers, callback + function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) { + var xhr = new MockXhr(), + expectation = expectations[0], + wasExpected = false; + + function prettyPrint(data) { + return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp) + ? data + : angular.toJson(data); + } + + function wrapResponse(wrapped) { + if (!$browser && timeout) { + timeout.then ? timeout.then(handleTimeout) : $timeout(handleTimeout, timeout); + } + + return handleResponse; + + function handleResponse() { + var response = wrapped.response(method, url, data, headers); + xhr.$$respHeaders = response[2]; + callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(), + copy(response[3] || '')); + } + + function handleTimeout() { + for (var i = 0, ii = responses.length; i < ii; i++) { + if (responses[i] === handleResponse) { + responses.splice(i, 1); + callback(-1, undefined, ''); + break; + } + } + } + } + + if (expectation && expectation.match(method, url)) { + if (!expectation.matchData(data)) { + throw new Error('Expected ' + expectation + ' with different data\n' + + 'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data); + } + + if (!expectation.matchHeaders(headers)) { + throw new Error('Expected ' + expectation + ' with different headers\n' + + 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' + + prettyPrint(headers)); + } + + expectations.shift(); + + if (expectation.response) { + responses.push(wrapResponse(expectation)); + return; + } + wasExpected = true; + } + + var i = -1, definition; + while ((definition = definitions[++i])) { + if (definition.match(method, url, data, headers || {})) { + if (definition.response) { + // if $browser specified, we do auto flush all requests + ($browser ? $browser.defer : responsesPush)(wrapResponse(definition)); + } else if (definition.passThrough) { + $delegate(method, url, data, callback, headers, timeout, withCredentials); + } else throw new Error('No response defined !'); + return; + } + } + throw wasExpected ? + new Error('No response defined !') : + new Error('Unexpected request: ' + method + ' ' + url + '\n' + + (expectation ? 'Expected ' + expectation : 'No more request expected')); + } + + /** + * @ngdoc method + * @name $httpBackend#when + * @description + * Creates a new backend definition. + * + * @param {string} method HTTP method. + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives + * data string and returns true if the data is as expected. + * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header + * object and returns true if the headers match the current definition. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + * + * - respond – + * `{function([status,] data[, headers, statusText]) + * | function(function(method, url, data, headers)}` + * – The respond method takes a set of static data to be returned or a function that can + * return an array containing response status (number), response data (string), response + * headers (Object), and the text for the status (string). The respond method returns the + * `requestHandler` object for possible overrides. + */ + $httpBackend.when = function(method, url, data, headers) { + var definition = new MockHttpExpectation(method, url, data, headers), + chain = { + respond: function(status, data, headers, statusText) { + definition.passThrough = undefined; + definition.response = createResponse(status, data, headers, statusText); + return chain; + } + }; + + if ($browser) { + chain.passThrough = function() { + definition.response = undefined; + definition.passThrough = true; + return chain; + }; + } + + definitions.push(definition); + return chain; + }; + + /** + * @ngdoc method + * @name $httpBackend#whenGET + * @description + * Creates a new backend definition for GET requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#whenHEAD + * @description + * Creates a new backend definition for HEAD requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#whenDELETE + * @description + * Creates a new backend definition for DELETE requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#whenPOST + * @description + * Creates a new backend definition for POST requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives + * data string and returns true if the data is as expected. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#whenPUT + * @description + * Creates a new backend definition for PUT requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives + * data string and returns true if the data is as expected. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#whenJSONP + * @description + * Creates a new backend definition for JSONP requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + createShortMethods('when'); + + + /** + * @ngdoc method + * @name $httpBackend#expect + * @description + * Creates a new request expectation. + * + * @param {string} method HTTP method. + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that + * receives data string and returns true if the data is as expected, or Object if request body + * is in JSON format. + * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header + * object and returns true if the headers match the current expectation. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + * + * - respond – + * `{function([status,] data[, headers, statusText]) + * | function(function(method, url, data, headers)}` + * – The respond method takes a set of static data to be returned or a function that can + * return an array containing response status (number), response data (string), response + * headers (Object), and the text for the status (string). The respond method returns the + * `requestHandler` object for possible overrides. + */ + $httpBackend.expect = function(method, url, data, headers) { + var expectation = new MockHttpExpectation(method, url, data, headers), + chain = { + respond: function(status, data, headers, statusText) { + expectation.response = createResponse(status, data, headers, statusText); + return chain; + } + }; + + expectations.push(expectation); + return chain; + }; + + + /** + * @ngdoc method + * @name $httpBackend#expectGET + * @description + * Creates a new request expectation for GET requests. For more info see `expect()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. See #expect for more info. + */ + + /** + * @ngdoc method + * @name $httpBackend#expectHEAD + * @description + * Creates a new request expectation for HEAD requests. For more info see `expect()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#expectDELETE + * @description + * Creates a new request expectation for DELETE requests. For more info see `expect()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#expectPOST + * @description + * Creates a new request expectation for POST requests. For more info see `expect()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that + * receives data string and returns true if the data is as expected, or Object if request body + * is in JSON format. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#expectPUT + * @description + * Creates a new request expectation for PUT requests. For more info see `expect()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that + * receives data string and returns true if the data is as expected, or Object if request body + * is in JSON format. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#expectPATCH + * @description + * Creates a new request expectation for PATCH requests. For more info see `expect()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that + * receives data string and returns true if the data is as expected, or Object if request body + * is in JSON format. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + + /** + * @ngdoc method + * @name $httpBackend#expectJSONP + * @description + * Creates a new request expectation for JSONP requests. For more info see `expect()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives an url + * and returns true if the url matches the current definition. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. + */ + createShortMethods('expect'); + + + /** + * @ngdoc method + * @name $httpBackend#flush + * @description + * Flushes all pending requests using the trained responses. + * + * @param {number=} count Number of responses to flush (in the order they arrived). If undefined, + * all pending requests will be flushed. If there are no pending requests when the flush method + * is called an exception is thrown (as this typically a sign of programming error). + */ + $httpBackend.flush = function(count, digest) { + if (digest !== false) $rootScope.$digest(); + if (!responses.length) throw new Error('No pending request to flush !'); + + if (angular.isDefined(count) && count !== null) { + while (count--) { + if (!responses.length) throw new Error('No more pending request to flush !'); + responses.shift()(); + } + } else { + while (responses.length) { + responses.shift()(); + } + } + $httpBackend.verifyNoOutstandingExpectation(digest); + }; + + + /** + * @ngdoc method + * @name $httpBackend#verifyNoOutstandingExpectation + * @description + * Verifies that all of the requests defined via the `expect` api were made. If any of the + * requests were not made, verifyNoOutstandingExpectation throws an exception. + * + * Typically, you would call this method following each test case that asserts requests using an + * "afterEach" clause. + * + * ```js + * afterEach($httpBackend.verifyNoOutstandingExpectation); + * ``` + */ + $httpBackend.verifyNoOutstandingExpectation = function(digest) { + if (digest !== false) $rootScope.$digest(); + if (expectations.length) { + throw new Error('Unsatisfied requests: ' + expectations.join(', ')); + } + }; + + + /** + * @ngdoc method + * @name $httpBackend#verifyNoOutstandingRequest + * @description + * Verifies that there are no outstanding requests that need to be flushed. + * + * Typically, you would call this method following each test case that asserts requests using an + * "afterEach" clause. + * + * ```js + * afterEach($httpBackend.verifyNoOutstandingRequest); + * ``` + */ + $httpBackend.verifyNoOutstandingRequest = function() { + if (responses.length) { + throw new Error('Unflushed requests: ' + responses.length); + } + }; + + + /** + * @ngdoc method + * @name $httpBackend#resetExpectations + * @description + * Resets all request expectations, but preserves all backend definitions. Typically, you would + * call resetExpectations during a multiple-phase test when you want to reuse the same instance of + * $httpBackend mock. + */ + $httpBackend.resetExpectations = function() { + expectations.length = 0; + responses.length = 0; + }; + + return $httpBackend; + + + function createShortMethods(prefix) { + angular.forEach(['GET', 'DELETE', 'JSONP', 'HEAD'], function(method) { + $httpBackend[prefix + method] = function(url, headers) { + return $httpBackend[prefix](method, url, undefined, headers); + }; + }); + + angular.forEach(['PUT', 'POST', 'PATCH'], function(method) { + $httpBackend[prefix + method] = function(url, data, headers) { + return $httpBackend[prefix](method, url, data, headers); + }; + }); + } +} + +function MockHttpExpectation(method, url, data, headers) { + + this.data = data; + this.headers = headers; + + this.match = function(m, u, d, h) { + if (method != m) return false; + if (!this.matchUrl(u)) return false; + if (angular.isDefined(d) && !this.matchData(d)) return false; + if (angular.isDefined(h) && !this.matchHeaders(h)) return false; + return true; + }; + + this.matchUrl = function(u) { + if (!url) return true; + if (angular.isFunction(url.test)) return url.test(u); + if (angular.isFunction(url)) return url(u); + return url == u; + }; + + this.matchHeaders = function(h) { + if (angular.isUndefined(headers)) return true; + if (angular.isFunction(headers)) return headers(h); + return angular.equals(headers, h); + }; + + this.matchData = function(d) { + if (angular.isUndefined(data)) return true; + if (data && angular.isFunction(data.test)) return data.test(d); + if (data && angular.isFunction(data)) return data(d); + if (data && !angular.isString(data)) { + return angular.equals(angular.fromJson(angular.toJson(data)), angular.fromJson(d)); + } + return data == d; + }; + + this.toString = function() { + return method + ' ' + url; + }; +} + +function createMockXhr() { + return new MockXhr(); +} + +function MockXhr() { + + // hack for testing $http, $httpBackend + MockXhr.$$lastInstance = this; + + this.open = function(method, url, async) { + this.$$method = method; + this.$$url = url; + this.$$async = async; + this.$$reqHeaders = {}; + this.$$respHeaders = {}; + }; + + this.send = function(data) { + this.$$data = data; + }; + + this.setRequestHeader = function(key, value) { + this.$$reqHeaders[key] = value; + }; + + this.getResponseHeader = function(name) { + // the lookup must be case insensitive, + // that's why we try two quick lookups first and full scan last + var header = this.$$respHeaders[name]; + if (header) return header; + + name = angular.lowercase(name); + header = this.$$respHeaders[name]; + if (header) return header; + + header = undefined; + angular.forEach(this.$$respHeaders, function(headerVal, headerName) { + if (!header && angular.lowercase(headerName) == name) header = headerVal; + }); + return header; + }; + + this.getAllResponseHeaders = function() { + var lines = []; + + angular.forEach(this.$$respHeaders, function(value, key) { + lines.push(key + ': ' + value); + }); + return lines.join('\n'); + }; + + this.abort = angular.noop; +} + + +/** + * @ngdoc service + * @name $timeout + * @description + * + * This service is just a simple decorator for {@link ng.$timeout $timeout} service + * that adds a "flush" and "verifyNoPendingTasks" methods. + */ + +angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $browser) { + + /** + * @ngdoc method + * @name $timeout#flush + * @description + * + * Flushes the queue of pending tasks. + * + * @param {number=} delay maximum timeout amount to flush up until + */ + $delegate.flush = function(delay) { + $browser.defer.flush(delay); + }; + + /** + * @ngdoc method + * @name $timeout#verifyNoPendingTasks + * @description + * + * Verifies that there are no pending tasks that need to be flushed. + */ + $delegate.verifyNoPendingTasks = function() { + if ($browser.deferredFns.length) { + throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' + + formatPendingTasksAsString($browser.deferredFns)); + } + }; + + function formatPendingTasksAsString(tasks) { + var result = []; + angular.forEach(tasks, function(task) { + result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}'); + }); + + return result.join(', '); + } + + return $delegate; +}]; + +angular.mock.$RAFDecorator = ['$delegate', function($delegate) { + var rafFn = function(fn) { + var index = rafFn.queue.length; + rafFn.queue.push(fn); + return function() { + rafFn.queue.splice(index, 1); + }; + }; + + rafFn.queue = []; + rafFn.supported = $delegate.supported; + + rafFn.flush = function() { + if (rafFn.queue.length === 0) { + throw new Error('No rAF callbacks present'); + } + + var length = rafFn.queue.length; + for (var i = 0; i < length; i++) { + rafFn.queue[i](); + } + + rafFn.queue = rafFn.queue.slice(i); + }; + + return rafFn; +}]; + +/** + * + */ +angular.mock.$RootElementProvider = function() { + this.$get = function() { + return angular.element('
    '); + }; +}; + +/** + * @ngdoc service + * @name $controller + * @description + * A decorator for {@link ng.$controller} with additional `bindings` parameter, useful when testing + * controllers of directives that use {@link $compile#-bindtocontroller- `bindToController`}. + * + * + * ## Example + * + * ```js + * + * // Directive definition ... + * + * myMod.directive('myDirective', { + * controller: 'MyDirectiveController', + * bindToController: { + * name: '@' + * } + * }); + * + * + * // Controller definition ... + * + * myMod.controller('MyDirectiveController', ['log', function($log) { + * $log.info(this.name); + * })]; + * + * + * // In a test ... + * + * describe('myDirectiveController', function() { + * it('should write the bound name to the log', inject(function($controller, $log) { + * var ctrl = $controller('MyDirectiveController', { /* no locals */ }, { name: 'Clark Kent' }); + * expect(ctrl.name).toEqual('Clark Kent'); + * expect($log.info.logs).toEqual(['Clark Kent']); + * }); + * }); + * + * ``` + * + * @param {Function|string} constructor If called with a function then it's considered to be the + * controller constructor function. Otherwise it's considered to be a string which is used + * to retrieve the controller constructor using the following steps: + * + * * check if a controller with given name is registered via `$controllerProvider` + * * check if evaluating the string on the current scope returns a constructor + * * if $controllerProvider#allowGlobals, check `window[constructor]` on the global + * `window` object (not recommended) + * + * The string can use the `controller as property` syntax, where the controller instance is published + * as the specified property on the `scope`; the `scope` must be injected into `locals` param for this + * to work correctly. + * + * @param {Object} locals Injection locals for Controller. + * @param {Object=} bindings Properties to add to the controller before invoking the constructor. This is used + * to simulate the `bindToController` feature and simplify certain kinds of tests. + * @return {Object} Instance of given controller. + */ +angular.mock.$ControllerDecorator = ['$delegate', function($delegate) { + return function(expression, locals, later, ident) { + if (later && typeof later === 'object') { + var create = $delegate(expression, locals, true, ident); + angular.extend(create.instance, later); + return create(); + } + return $delegate(expression, locals, later, ident); + }; +}]; + + +/** + * @ngdoc module + * @name ngMock + * @packageName angular-mocks + * @description + * + * # ngMock + * + * The `ngMock` module provides support to inject and mock Angular services into unit tests. + * In addition, ngMock also extends various core ng services such that they can be + * inspected and controlled in a synchronous manner within test code. + * + * + *
    + * + */ +angular.module('ngMock', ['ng']).provider({ + $browser: angular.mock.$BrowserProvider, + $exceptionHandler: angular.mock.$ExceptionHandlerProvider, + $log: angular.mock.$LogProvider, + $interval: angular.mock.$IntervalProvider, + $httpBackend: angular.mock.$HttpBackendProvider, + $rootElement: angular.mock.$RootElementProvider +}).config(['$provide', function($provide) { + $provide.decorator('$timeout', angular.mock.$TimeoutDecorator); + $provide.decorator('$$rAF', angular.mock.$RAFDecorator); + $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator); + $provide.decorator('$controller', angular.mock.$ControllerDecorator); +}]); + +/** + * @ngdoc module + * @name ngMockE2E + * @module ngMockE2E + * @packageName angular-mocks + * @description + * + * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing. + * Currently there is only one mock present in this module - + * the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock. + */ +angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { + $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator); +}]); + +/** + * @ngdoc service + * @name $httpBackend + * @module ngMockE2E + * @description + * Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of + * applications that use the {@link ng.$http $http service}. + * + * *Note*: For fake http backend implementation suitable for unit testing please see + * {@link ngMock.$httpBackend unit-testing $httpBackend mock}. + * + * This implementation can be used to respond with static or dynamic responses via the `when` api + * and its shortcuts (`whenGET`, `whenPOST`, etc) and optionally pass through requests to the + * real $httpBackend for specific requests (e.g. to interact with certain remote apis or to fetch + * templates from a webserver). + * + * As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application + * is being developed with the real backend api replaced with a mock, it is often desirable for + * certain category of requests to bypass the mock and issue a real http request (e.g. to fetch + * templates or static files from the webserver). To configure the backend with this behavior + * use the `passThrough` request handler of `when` instead of `respond`. + * + * Additionally, we don't want to manually have to flush mocked out requests like we do during unit + * testing. For this reason the e2e $httpBackend flushes mocked out requests + * automatically, closely simulating the behavior of the XMLHttpRequest object. + * + * To setup the application to run with this http backend, you have to create a module that depends + * on the `ngMockE2E` and your application modules and defines the fake backend: + * + * ```js + * myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']); + * myAppDev.run(function($httpBackend) { + * phones = [{name: 'phone1'}, {name: 'phone2'}]; + * + * // returns the current list of phones + * $httpBackend.whenGET('/phones').respond(phones); + * + * // adds a new phone to the phones array + * $httpBackend.whenPOST('/phones').respond(function(method, url, data) { + * var phone = angular.fromJson(data); + * phones.push(phone); + * return [200, phone, {}]; + * }); + * $httpBackend.whenGET(/^\/templates\//).passThrough(); + * //... + * }); + * ``` + * + * Afterwards, bootstrap your app with this new module. + */ + +/** + * @ngdoc method + * @name $httpBackend#when + * @module ngMockE2E + * @description + * Creates a new backend definition. + * + * @param {string} method HTTP method. + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp)=} data HTTP request body. + * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header + * object and returns true if the headers match the current definition. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. + * + * - respond – + * `{function([status,] data[, headers, statusText]) + * | function(function(method, url, data, headers)}` + * – The respond method takes a set of static data to be returned or a function that can return + * an array containing response status (number), response data (string), response headers + * (Object), and the text for the status (string). + * - passThrough – `{function()}` – Any request matching a backend definition with + * `passThrough` handler will be passed through to the real backend (an XHR request will be made + * to the server.) + * - Both methods return the `requestHandler` object for possible overrides. + */ + +/** + * @ngdoc method + * @name $httpBackend#whenGET + * @module ngMockE2E + * @description + * Creates a new backend definition for GET requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. + */ + +/** + * @ngdoc method + * @name $httpBackend#whenHEAD + * @module ngMockE2E + * @description + * Creates a new backend definition for HEAD requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. + */ + +/** + * @ngdoc method + * @name $httpBackend#whenDELETE + * @module ngMockE2E + * @description + * Creates a new backend definition for DELETE requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. + */ + +/** + * @ngdoc method + * @name $httpBackend#whenPOST + * @module ngMockE2E + * @description + * Creates a new backend definition for POST requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp)=} data HTTP request body. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. + */ + +/** + * @ngdoc method + * @name $httpBackend#whenPUT + * @module ngMockE2E + * @description + * Creates a new backend definition for PUT requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp)=} data HTTP request body. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. + */ + +/** + * @ngdoc method + * @name $httpBackend#whenPATCH + * @module ngMockE2E + * @description + * Creates a new backend definition for PATCH requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @param {(string|RegExp)=} data HTTP request body. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. + */ + +/** + * @ngdoc method + * @name $httpBackend#whenJSONP + * @module ngMockE2E + * @description + * Creates a new backend definition for JSONP requests. For more info see `when()`. + * + * @param {string|RegExp|function(string)} url HTTP url or function that receives a url + * and returns true if the url matches the current definition. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. + */ +angular.mock.e2e = {}; +angular.mock.e2e.$httpBackendDecorator = + ['$rootScope', '$timeout', '$delegate', '$browser', createHttpBackendMock]; + + +/** + * @ngdoc type + * @name $rootScope.Scope + * @module ngMock + * @description + * {@link ng.$rootScope.Scope Scope} type decorated with helper methods useful for testing. These + * methods are automatically available on any {@link ng.$rootScope.Scope Scope} instance when + * `ngMock` module is loaded. + * + * In addition to all the regular `Scope` methods, the following helper methods are available: + */ +angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) { + + var $rootScopePrototype = Object.getPrototypeOf($delegate); + + $rootScopePrototype.$countChildScopes = countChildScopes; + $rootScopePrototype.$countWatchers = countWatchers; + + return $delegate; + + // ------------------------------------------------------------------------------------------ // + + /** + * @ngdoc method + * @name $rootScope.Scope#$countChildScopes + * @module ngMock + * @description + * Counts all the direct and indirect child scopes of the current scope. + * + * The current scope is excluded from the count. The count includes all isolate child scopes. + * + * @returns {number} Total number of child scopes. + */ + function countChildScopes() { + // jshint validthis: true + var count = 0; // exclude the current scope + var pendingChildHeads = [this.$$childHead]; + var currentScope; + + while (pendingChildHeads.length) { + currentScope = pendingChildHeads.shift(); + + while (currentScope) { + count += 1; + pendingChildHeads.push(currentScope.$$childHead); + currentScope = currentScope.$$nextSibling; + } + } + + return count; + } + + + /** + * @ngdoc method + * @name $rootScope.Scope#$countWatchers + * @module ngMock + * @description + * Counts all the watchers of direct and indirect child scopes of the current scope. + * + * The watchers of the current scope are included in the count and so are all the watchers of + * isolate child scopes. + * + * @returns {number} Total number of watchers. + */ + function countWatchers() { + // jshint validthis: true + var count = this.$$watchers ? this.$$watchers.length : 0; // include the current scope + var pendingChildHeads = [this.$$childHead]; + var currentScope; + + while (pendingChildHeads.length) { + currentScope = pendingChildHeads.shift(); + + while (currentScope) { + count += currentScope.$$watchers ? currentScope.$$watchers.length : 0; + pendingChildHeads.push(currentScope.$$childHead); + currentScope = currentScope.$$nextSibling; + } + } + + return count; + } +}]; + + +if (window.jasmine || window.mocha) { + + var currentSpec = null, + annotatedFunctions = [], + isSpecRunning = function() { + return !!currentSpec; + }; + + angular.mock.$$annotate = angular.injector.$$annotate; + angular.injector.$$annotate = function(fn) { + if (typeof fn === 'function' && !fn.$inject) { + annotatedFunctions.push(fn); + } + return angular.mock.$$annotate.apply(this, arguments); + }; + + + (window.beforeEach || window.setup)(function() { + annotatedFunctions = []; + currentSpec = this; + }); + + (window.afterEach || window.teardown)(function() { + var injector = currentSpec.$injector; + + annotatedFunctions.forEach(function(fn) { + delete fn.$inject; + }); + + angular.forEach(currentSpec.$modules, function(module) { + if (module && module.$$hashKey) { + module.$$hashKey = undefined; + } + }); + + currentSpec.$injector = null; + currentSpec.$modules = null; + currentSpec = null; + + if (injector) { + injector.get('$rootElement').off(); + } + + // clean up jquery's fragment cache + angular.forEach(angular.element.fragments, function(val, key) { + delete angular.element.fragments[key]; + }); + + MockXhr.$$lastInstance = null; + + angular.forEach(angular.callbacks, function(val, key) { + delete angular.callbacks[key]; + }); + angular.callbacks.counter = 0; + }); + + /** + * @ngdoc function + * @name angular.mock.module + * @description + * + * *NOTE*: This function is also published on window for easy access.
    + * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha + * + * This function registers a module configuration code. It collects the configuration information + * which will be used when the injector is created by {@link angular.mock.inject inject}. + * + * See {@link angular.mock.inject inject} for usage example + * + * @param {...(string|Function|Object)} fns any number of modules which are represented as string + * aliases or as anonymous module initialization functions. The modules are used to + * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an + * object literal is passed each key-value pair will be registered on the module via + * {@link auto.$provide $provide}.value, the key being the string name (or token) to associate + * with the value on the injector. + */ + window.module = angular.mock.module = function() { + var moduleFns = Array.prototype.slice.call(arguments, 0); + return isSpecRunning() ? workFn() : workFn; + ///////////////////// + function workFn() { + if (currentSpec.$injector) { + throw new Error('Injector already created, can not register a module!'); + } else { + var modules = currentSpec.$modules || (currentSpec.$modules = []); + angular.forEach(moduleFns, function(module) { + if (angular.isObject(module) && !angular.isArray(module)) { + modules.push(function($provide) { + angular.forEach(module, function(value, key) { + $provide.value(key, value); + }); + }); + } else { + modules.push(module); + } + }); + } + } + }; + + /** + * @ngdoc function + * @name angular.mock.inject + * @description + * + * *NOTE*: This function is also published on window for easy access.
    + * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha + * + * The inject function wraps a function into an injectable function. The inject() creates new + * instance of {@link auto.$injector $injector} per test, which is then used for + * resolving references. + * + * + * ## Resolving References (Underscore Wrapping) + * Often, we would like to inject a reference once, in a `beforeEach()` block and reuse this + * in multiple `it()` clauses. To be able to do this we must assign the reference to a variable + * that is declared in the scope of the `describe()` block. Since we would, most likely, want + * the variable to have the same name of the reference we have a problem, since the parameter + * to the `inject()` function would hide the outer variable. + * + * To help with this, the injected parameters can, optionally, be enclosed with underscores. + * These are ignored by the injector when the reference name is resolved. + * + * For example, the parameter `_myService_` would be resolved as the reference `myService`. + * Since it is available in the function body as _myService_, we can then assign it to a variable + * defined in an outer scope. + * + * ``` + * // Defined out reference variable outside + * var myService; + * + * // Wrap the parameter in underscores + * beforeEach( inject( function(_myService_){ + * myService = _myService_; + * })); + * + * // Use myService in a series of tests. + * it('makes use of myService', function() { + * myService.doStuff(); + * }); + * + * ``` + * + * See also {@link angular.mock.module angular.mock.module} + * + * ## Example + * Example of what a typical jasmine tests looks like with the inject method. + * ```js + * + * angular.module('myApplicationModule', []) + * .value('mode', 'app') + * .value('version', 'v1.0.1'); + * + * + * describe('MyApp', function() { + * + * // You need to load modules that you want to test, + * // it loads only the "ng" module by default. + * beforeEach(module('myApplicationModule')); + * + * + * // inject() is used to inject arguments of all given functions + * it('should provide a version', inject(function(mode, version) { + * expect(version).toEqual('v1.0.1'); + * expect(mode).toEqual('app'); + * })); + * + * + * // The inject and module method can also be used inside of the it or beforeEach + * it('should override a version and test the new version is injected', function() { + * // module() takes functions or strings (module aliases) + * module(function($provide) { + * $provide.value('version', 'overridden'); // override version here + * }); + * + * inject(function(version) { + * expect(version).toEqual('overridden'); + * }); + * }); + * }); + * + * ``` + * + * @param {...Function} fns any number of functions which will be injected using the injector. + */ + + + + var ErrorAddingDeclarationLocationStack = function(e, errorForStack) { + this.message = e.message; + this.name = e.name; + if (e.line) this.line = e.line; + if (e.sourceId) this.sourceId = e.sourceId; + if (e.stack && errorForStack) + this.stack = e.stack + '\n' + errorForStack.stack; + if (e.stackArray) this.stackArray = e.stackArray; + }; + ErrorAddingDeclarationLocationStack.prototype.toString = Error.prototype.toString; + + window.inject = angular.mock.inject = function() { + var blockFns = Array.prototype.slice.call(arguments, 0); + var errorForStack = new Error('Declaration Location'); + return isSpecRunning() ? workFn.call(currentSpec) : workFn; + ///////////////////// + function workFn() { + var modules = currentSpec.$modules || []; + var strictDi = !!currentSpec.$injectorStrict; + modules.unshift('ngMock'); + modules.unshift('ng'); + var injector = currentSpec.$injector; + if (!injector) { + if (strictDi) { + // If strictDi is enabled, annotate the providerInjector blocks + angular.forEach(modules, function(moduleFn) { + if (typeof moduleFn === "function") { + angular.injector.$$annotate(moduleFn); + } + }); + } + injector = currentSpec.$injector = angular.injector(modules, strictDi); + currentSpec.$injectorStrict = strictDi; + } + for (var i = 0, ii = blockFns.length; i < ii; i++) { + if (currentSpec.$injectorStrict) { + // If the injector is strict / strictDi, and the spec wants to inject using automatic + // annotation, then annotate the function here. + injector.annotate(blockFns[i]); + } + try { + /* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */ + injector.invoke(blockFns[i] || angular.noop, this); + /* jshint +W040 */ + } catch (e) { + if (e.stack && errorForStack) { + throw new ErrorAddingDeclarationLocationStack(e, errorForStack); + } + throw e; + } finally { + errorForStack = null; + } + } + } + }; + + + angular.mock.inject.strictDi = function(value) { + value = arguments.length ? !!value : true; + return isSpecRunning() ? workFn() : workFn; + + function workFn() { + if (value !== currentSpec.$injectorStrict) { + if (currentSpec.$injector) { + throw new Error('Injector already created, can not modify strict annotations'); + } else { + currentSpec.$injectorStrict = value; + } + } + } + }; +} + + +})(window, window.angular); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-resource.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-resource.js new file mode 100644 index 00000000..335859f7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-resource.js @@ -0,0 +1,684 @@ +/** + * @license AngularJS v1.4.8 + * (c) 2010-2015 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +var $resourceMinErr = angular.$$minErr('$resource'); + +// Helper functions and regex to lookup a dotted path on an object +// stopping at undefined/null. The path must be composed of ASCII +// identifiers (just like $parse) +var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/; + +function isValidDottedPath(path) { + return (path != null && path !== '' && path !== 'hasOwnProperty' && + MEMBER_NAME_REGEX.test('.' + path)); +} + +function lookupDottedPath(obj, path) { + if (!isValidDottedPath(path)) { + throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path); + } + var keys = path.split('.'); + for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) { + var key = keys[i]; + obj = (obj !== null) ? obj[key] : undefined; + } + return obj; +} + +/** + * Create a shallow copy of an object and clear other fields from the destination + */ +function shallowClearAndCopy(src, dst) { + dst = dst || {}; + + angular.forEach(dst, function(value, key) { + delete dst[key]; + }); + + for (var key in src) { + if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { + dst[key] = src[key]; + } + } + + return dst; +} + +/** + * @ngdoc module + * @name ngResource + * @description + * + * # ngResource + * + * The `ngResource` module provides interaction support with RESTful services + * via the $resource service. + * + * + *
    + * + * See {@link ngResource.$resource `$resource`} for usage. + */ + +/** + * @ngdoc service + * @name $resource + * @requires $http + * + * @description + * A factory which creates a resource object that lets you interact with + * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources. + * + * The returned resource object has action methods which provide high-level behaviors without + * the need to interact with the low level {@link ng.$http $http} service. + * + * Requires the {@link ngResource `ngResource`} module to be installed. + * + * By default, trailing slashes will be stripped from the calculated URLs, + * which can pose problems with server backends that do not expect that + * behavior. This can be disabled by configuring the `$resourceProvider` like + * this: + * + * ```js + app.config(['$resourceProvider', function($resourceProvider) { + // Don't strip trailing slashes from calculated URLs + $resourceProvider.defaults.stripTrailingSlashes = false; + }]); + * ``` + * + * @param {string} url A parameterized URL template with parameters prefixed by `:` as in + * `/user/:username`. If you are using a URL with a port number (e.g. + * `http://example.com:8080/api`), it will be respected. + * + * If you are using a url with a suffix, just add the suffix, like this: + * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')` + * or even `$resource('http://example.com/resource/:resource_id.:format')` + * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be + * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you + * can escape it with `/\.`. + * + * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in + * `actions` methods. If any of the parameter value is a function, it will be executed every time + * when a param value needs to be obtained for a request (unless the param was overridden). + * + * Each key value in the parameter object is first bound to url template if present and then any + * excess keys are appended to the url search query after the `?`. + * + * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in + * URL `/path/greet?salutation=Hello`. + * + * If the parameter value is prefixed with `@` then the value for that parameter will be extracted + * from the corresponding property on the `data` object (provided when calling an action method). For + * example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of `someParam` + * will be `data.someProp`. + * + * @param {Object.=} actions Hash with declaration of custom actions that should extend + * the default set of resource actions. The declaration should be created in the format of {@link + * ng.$http#usage $http.config}: + * + * {action1: {method:?, params:?, isArray:?, headers:?, ...}, + * action2: {method:?, params:?, isArray:?, headers:?, ...}, + * ...} + * + * Where: + * + * - **`action`** – {string} – The name of action. This name becomes the name of the method on + * your resource object. + * - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`, + * `DELETE`, `JSONP`, etc). + * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of + * the parameter value is a function, it will be executed every time when a param value needs to + * be obtained for a request (unless the param was overridden). + * - **`url`** – {string} – action specific `url` override. The url templating is supported just + * like for the resource-level urls. + * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, + * see `returns` section. + * - **`transformRequest`** – + * `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * request body and headers and returns its transformed (typically serialized) version. + * By default, transformRequest will contain one function that checks if the request data is + * an object and serializes to using `angular.toJson`. To prevent this behavior, set + * `transformRequest` to an empty array: `transformRequest: []` + * - **`transformResponse`** – + * `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * response body and headers and returns its transformed (typically deserialized) version. + * By default, transformResponse will contain one function that checks if the response looks like + * a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior, set + * `transformResponse` to an empty array: `transformResponse: []` + * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the + * GET request, otherwise if a cache instance built with + * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for + * caching. + * - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that + * should abort the request when resolved. + * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the + * XHR object. See + * [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5) + * for more information. + * - **`responseType`** - `{string}` - see + * [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType). + * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods - + * `response` and `responseError`. Both `response` and `responseError` interceptors get called + * with `http response` object. See {@link ng.$http $http interceptors}. + * + * @param {Object} options Hash with custom settings that should extend the + * default `$resourceProvider` behavior. The only supported option is + * + * Where: + * + * - **`stripTrailingSlashes`** – {boolean} – If true then the trailing + * slashes from any calculated URL will be stripped. (Defaults to true.) + * + * @returns {Object} A resource "class" object with methods for the default set of resource actions + * optionally extended with custom `actions`. The default set contains these actions: + * ```js + * { 'get': {method:'GET'}, + * 'save': {method:'POST'}, + * 'query': {method:'GET', isArray:true}, + * 'remove': {method:'DELETE'}, + * 'delete': {method:'DELETE'} }; + * ``` + * + * Calling these methods invoke an {@link ng.$http} with the specified http method, + * destination and parameters. When the data is returned from the server then the object is an + * instance of the resource class. The actions `save`, `remove` and `delete` are available on it + * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create, + * read, update, delete) on server-side data like this: + * ```js + * var User = $resource('/user/:userId', {userId:'@id'}); + * var user = User.get({userId:123}, function() { + * user.abc = true; + * user.$save(); + * }); + * ``` + * + * It is important to realize that invoking a $resource object method immediately returns an + * empty reference (object or array depending on `isArray`). Once the data is returned from the + * server the existing reference is populated with the actual data. This is a useful trick since + * usually the resource is assigned to a model which is then rendered by the view. Having an empty + * object results in no rendering, once the data arrives from the server then the object is + * populated with the data and the view automatically re-renders itself showing the new data. This + * means that in most cases one never has to write a callback function for the action methods. + * + * The action methods on the class object or instance object can be invoked with the following + * parameters: + * + * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])` + * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])` + * - non-GET instance actions: `instance.$action([parameters], [success], [error])` + * + * + * Success callback is called with (value, responseHeaders) arguments, where the value is + * the populated resource instance or collection object. The error callback is called + * with (httpResponse) argument. + * + * Class actions return empty instance (with additional properties below). + * Instance actions return promise of the action. + * + * The Resource instances and collection have these additional properties: + * + * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this + * instance or collection. + * + * On success, the promise is resolved with the same resource instance or collection object, + * updated with data from server. This makes it easy to use in + * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view + * rendering until the resource(s) are loaded. + * + * On failure, the promise is resolved with the {@link ng.$http http response} object, without + * the `resource` property. + * + * If an interceptor object was provided, the promise will instead be resolved with the value + * returned by the interceptor. + * + * - `$resolved`: `true` after first server interaction is completed (either with success or + * rejection), `false` before that. Knowing if the Resource has been resolved is useful in + * data-binding. + * + * @example + * + * # Credit card resource + * + * ```js + // Define CreditCard class + var CreditCard = $resource('/user/:userId/card/:cardId', + {userId:123, cardId:'@id'}, { + charge: {method:'POST', params:{charge:true}} + }); + + // We can retrieve a collection from the server + var cards = CreditCard.query(function() { + // GET: /user/123/card + // server returns: [ {id:456, number:'1234', name:'Smith'} ]; + + var card = cards[0]; + // each item is an instance of CreditCard + expect(card instanceof CreditCard).toEqual(true); + card.name = "J. Smith"; + // non GET methods are mapped onto the instances + card.$save(); + // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'} + // server returns: {id:456, number:'1234', name: 'J. Smith'}; + + // our custom method is mapped as well. + card.$charge({amount:9.99}); + // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'} + }); + + // we can create an instance as well + var newCard = new CreditCard({number:'0123'}); + newCard.name = "Mike Smith"; + newCard.$save(); + // POST: /user/123/card {number:'0123', name:'Mike Smith'} + // server returns: {id:789, number:'0123', name: 'Mike Smith'}; + expect(newCard.id).toEqual(789); + * ``` + * + * The object returned from this function execution is a resource "class" which has "static" method + * for each action in the definition. + * + * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and + * `headers`. + * When the data is returned from the server then the object is an instance of the resource type and + * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD + * operations (create, read, update, delete) on server-side data. + + ```js + var User = $resource('/user/:userId', {userId:'@id'}); + User.get({userId:123}, function(user) { + user.abc = true; + user.$save(); + }); + ``` + * + * It's worth noting that the success callback for `get`, `query` and other methods gets passed + * in the response that came from the server as well as $http header getter function, so one + * could rewrite the above example and get access to http headers as: + * + ```js + var User = $resource('/user/:userId', {userId:'@id'}); + User.get({userId:123}, function(u, getResponseHeaders){ + u.abc = true; + u.$save(function(u, putResponseHeaders) { + //u => saved user object + //putResponseHeaders => $http header getter + }); + }); + ``` + * + * You can also access the raw `$http` promise via the `$promise` property on the object returned + * + ``` + var User = $resource('/user/:userId', {userId:'@id'}); + User.get({userId:123}) + .$promise.then(function(user) { + $scope.user = user; + }); + ``` + + * # Creating a custom 'PUT' request + * In this example we create a custom method on our resource to make a PUT request + * ```js + * var app = angular.module('app', ['ngResource', 'ngRoute']); + * + * // Some APIs expect a PUT request in the format URL/object/ID + * // Here we are creating an 'update' method + * app.factory('Notes', ['$resource', function($resource) { + * return $resource('/notes/:id', null, + * { + * 'update': { method:'PUT' } + * }); + * }]); + * + * // In our controller we get the ID from the URL using ngRoute and $routeParams + * // We pass in $routeParams and our Notes factory along with $scope + * app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes', + function($scope, $routeParams, Notes) { + * // First get a note object from the factory + * var note = Notes.get({ id:$routeParams.id }); + * $id = note.id; + * + * // Now call update passing in the ID first then the object you are updating + * Notes.update({ id:$id }, note); + * + * // This will PUT /notes/ID with the note object in the request payload + * }]); + * ``` + */ +angular.module('ngResource', ['ng']). + provider('$resource', function() { + var PROTOCOL_AND_DOMAIN_REGEX = /^https?:\/\/[^\/]*/; + var provider = this; + + this.defaults = { + // Strip slashes by default + stripTrailingSlashes: true, + + // Default actions configuration + actions: { + 'get': {method: 'GET'}, + 'save': {method: 'POST'}, + 'query': {method: 'GET', isArray: true}, + 'remove': {method: 'DELETE'}, + 'delete': {method: 'DELETE'} + } + }; + + this.$get = ['$http', '$q', function($http, $q) { + + var noop = angular.noop, + forEach = angular.forEach, + extend = angular.extend, + copy = angular.copy, + isFunction = angular.isFunction; + + /** + * We need our custom method because encodeURIComponent is too aggressive and doesn't follow + * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set + * (pchar) allowed in path segments: + * segment = *pchar + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * pct-encoded = "%" HEXDIG HEXDIG + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ + function encodeUriSegment(val) { + return encodeUriQuery(val, true). + replace(/%26/gi, '&'). + replace(/%3D/gi, '='). + replace(/%2B/gi, '+'); + } + + + /** + * This method is intended for encoding *key* or *value* parts of query component. We need a + * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't + * have to be encoded per http://tools.ietf.org/html/rfc3986: + * query = *( pchar / "/" / "?" ) + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * pct-encoded = "%" HEXDIG HEXDIG + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ + function encodeUriQuery(val, pctEncodeSpaces) { + return encodeURIComponent(val). + replace(/%40/gi, '@'). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); + } + + function Route(template, defaults) { + this.template = template; + this.defaults = extend({}, provider.defaults, defaults); + this.urlParams = {}; + } + + Route.prototype = { + setUrlParams: function(config, params, actionUrl) { + var self = this, + url = actionUrl || self.template, + val, + encodedVal, + protocolAndDomain = ''; + + var urlParams = self.urlParams = {}; + forEach(url.split(/\W/), function(param) { + if (param === 'hasOwnProperty') { + throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name."); + } + if (!(new RegExp("^\\d+$").test(param)) && param && + (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) { + urlParams[param] = true; + } + }); + url = url.replace(/\\:/g, ':'); + url = url.replace(PROTOCOL_AND_DOMAIN_REGEX, function(match) { + protocolAndDomain = match; + return ''; + }); + + params = params || {}; + forEach(self.urlParams, function(_, urlParam) { + val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam]; + if (angular.isDefined(val) && val !== null) { + encodedVal = encodeUriSegment(val); + url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) { + return encodedVal + p1; + }); + } else { + url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match, + leadingSlashes, tail) { + if (tail.charAt(0) == '/') { + return tail; + } else { + return leadingSlashes + tail; + } + }); + } + }); + + // strip trailing slashes and set the url (unless this behavior is specifically disabled) + if (self.defaults.stripTrailingSlashes) { + url = url.replace(/\/+$/, '') || '/'; + } + + // then replace collapse `/.` if found in the last URL path segment before the query + // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x` + url = url.replace(/\/\.(?=\w+($|\?))/, '.'); + // replace escaped `/\.` with `/.` + config.url = protocolAndDomain + url.replace(/\/\\\./, '/.'); + + + // set params - delegate param encoding to $http + forEach(params, function(value, key) { + if (!self.urlParams[key]) { + config.params = config.params || {}; + config.params[key] = value; + } + }); + } + }; + + + function resourceFactory(url, paramDefaults, actions, options) { + var route = new Route(url, options); + + actions = extend({}, provider.defaults.actions, actions); + + function extractParams(data, actionParams) { + var ids = {}; + actionParams = extend({}, paramDefaults, actionParams); + forEach(actionParams, function(value, key) { + if (isFunction(value)) { value = value(); } + ids[key] = value && value.charAt && value.charAt(0) == '@' ? + lookupDottedPath(data, value.substr(1)) : value; + }); + return ids; + } + + function defaultResponseInterceptor(response) { + return response.resource; + } + + function Resource(value) { + shallowClearAndCopy(value || {}, this); + } + + Resource.prototype.toJSON = function() { + var data = extend({}, this); + delete data.$promise; + delete data.$resolved; + return data; + }; + + forEach(actions, function(action, name) { + var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method); + + Resource[name] = function(a1, a2, a3, a4) { + var params = {}, data, success, error; + + /* jshint -W086 */ /* (purposefully fall through case statements) */ + switch (arguments.length) { + case 4: + error = a4; + success = a3; + //fallthrough + case 3: + case 2: + if (isFunction(a2)) { + if (isFunction(a1)) { + success = a1; + error = a2; + break; + } + + success = a2; + error = a3; + //fallthrough + } else { + params = a1; + data = a2; + success = a3; + break; + } + case 1: + if (isFunction(a1)) success = a1; + else if (hasBody) data = a1; + else params = a1; + break; + case 0: break; + default: + throw $resourceMinErr('badargs', + "Expected up to 4 arguments [params, data, success, error], got {0} arguments", + arguments.length); + } + /* jshint +W086 */ /* (purposefully fall through case statements) */ + + var isInstanceCall = this instanceof Resource; + var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data)); + var httpConfig = {}; + var responseInterceptor = action.interceptor && action.interceptor.response || + defaultResponseInterceptor; + var responseErrorInterceptor = action.interceptor && action.interceptor.responseError || + undefined; + + forEach(action, function(value, key) { + switch (key) { + default: + httpConfig[key] = copy(value); + break; + case 'params': + case 'isArray': + case 'interceptor': + break; + case 'timeout': + httpConfig[key] = value; + break; + } + }); + + if (hasBody) httpConfig.data = data; + route.setUrlParams(httpConfig, + extend({}, extractParams(data, action.params || {}), params), + action.url); + + var promise = $http(httpConfig).then(function(response) { + var data = response.data, + promise = value.$promise; + + if (data) { + // Need to convert action.isArray to boolean in case it is undefined + // jshint -W018 + if (angular.isArray(data) !== (!!action.isArray)) { + throw $resourceMinErr('badcfg', + 'Error in resource configuration for action `{0}`. Expected response to ' + + 'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object', + angular.isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url); + } + // jshint +W018 + if (action.isArray) { + value.length = 0; + forEach(data, function(item) { + if (typeof item === "object") { + value.push(new Resource(item)); + } else { + // Valid JSON values may be string literals, and these should not be converted + // into objects. These items will not have access to the Resource prototype + // methods, but unfortunately there + value.push(item); + } + }); + } else { + shallowClearAndCopy(data, value); + value.$promise = promise; + } + } + + value.$resolved = true; + + response.resource = value; + + return response; + }, function(response) { + value.$resolved = true; + + (error || noop)(response); + + return $q.reject(response); + }); + + promise = promise.then( + function(response) { + var value = responseInterceptor(response); + (success || noop)(value, response.headers); + return value; + }, + responseErrorInterceptor); + + if (!isInstanceCall) { + // we are creating instance / collection + // - set the initial promise + // - return the instance / collection + value.$promise = promise; + value.$resolved = false; + + return value; + } + + // instance call + return promise; + }; + + + Resource.prototype['$' + name] = function(params, success, error) { + if (isFunction(params)) { + error = success; success = params; params = {}; + } + var result = Resource[name].call(this, params, this, success, error); + return result.$promise || result; + }; + }); + + Resource.bind = function(additionalParamDefaults) { + return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions); + }; + + return Resource; + } + + return resourceFactory; + }]; + }); + + +})(window, window.angular); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-resource.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-resource.min.js new file mode 100644 index 00000000..c3fb7aab --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-resource.min.js @@ -0,0 +1,14 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(I,f,C){'use strict';function D(t,e){e=e||{};f.forEach(e,function(f,k){delete e[k]});for(var k in t)!t.hasOwnProperty(k)||"$"===k.charAt(0)&&"$"===k.charAt(1)||(e[k]=t[k]);return e}var y=f.$$minErr("$resource"),B=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;f.module("ngResource",["ng"]).provider("$resource",function(){var t=/^https?:\/\/[^\/]*/,e=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}}; +this.$get=["$http","$q",function(k,F){function w(f,g){this.template=f;this.defaults=r({},e.defaults,g);this.urlParams={}}function z(l,g,s,h){function c(a,q){var c={};q=r({},g,q);u(q,function(b,q){x(b)&&(b=b());var m;if(b&&b.charAt&&"@"==b.charAt(0)){m=a;var d=b.substr(1);if(null==d||""===d||"hasOwnProperty"===d||!B.test("."+d))throw y("badmember",d);for(var d=d.split("."),n=0,g=d.length;n + */ + /* global -ngRouteModule */ +var ngRouteModule = angular.module('ngRoute', ['ng']). + provider('$route', $RouteProvider), + $routeMinErr = angular.$$minErr('ngRoute'); + +/** + * @ngdoc provider + * @name $routeProvider + * + * @description + * + * Used for configuring routes. + * + * ## Example + * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`. + * + * ## Dependencies + * Requires the {@link ngRoute `ngRoute`} module to be installed. + */ +function $RouteProvider() { + function inherit(parent, extra) { + return angular.extend(Object.create(parent), extra); + } + + var routes = {}; + + /** + * @ngdoc method + * @name $routeProvider#when + * + * @param {string} path Route path (matched against `$location.path`). If `$location.path` + * contains redundant trailing slash or is missing one, the route will still match and the + * `$location.path` will be updated to add or drop the trailing slash to exactly match the + * route definition. + * + * * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up + * to the next slash are matched and stored in `$routeParams` under the given `name` + * when the route matches. + * * `path` can contain named groups starting with a colon and ending with a star: + * e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name` + * when the route matches. + * * `path` can contain optional named groups with a question mark: e.g.`:name?`. + * + * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match + * `/color/brown/largecode/code/with/slashes/edit` and extract: + * + * * `color: brown` + * * `largecode: code/with/slashes`. + * + * + * @param {Object} route Mapping information to be assigned to `$route.current` on route + * match. + * + * Object properties: + * + * - `controller` – `{(string|function()=}` – Controller fn that should be associated with + * newly created scope or the name of a {@link angular.Module#controller registered + * controller} if passed as a string. + * - `controllerAs` – `{string=}` – An identifier name for a reference to the controller. + * If present, the controller will be published to scope under the `controllerAs` name. + * - `template` – `{string=|function()=}` – html template as a string or a function that + * returns an html template as a string which should be used by {@link + * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives. + * This property takes precedence over `templateUrl`. + * + * If `template` is a function, it will be called with the following parameters: + * + * - `{Array.}` - route parameters extracted from the current + * `$location.path()` by applying the current route + * + * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html + * template that should be used by {@link ngRoute.directive:ngView ngView}. + * + * If `templateUrl` is a function, it will be called with the following parameters: + * + * - `{Array.}` - route parameters extracted from the current + * `$location.path()` by applying the current route + * + * - `resolve` - `{Object.=}` - An optional map of dependencies which should + * be injected into the controller. If any of these dependencies are promises, the router + * will wait for them all to be resolved or one to be rejected before the controller is + * instantiated. + * If all the promises are resolved successfully, the values of the resolved promises are + * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is + * fired. If any of the promises are rejected the + * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object + * is: + * + * - `key` – `{string}`: a name of a dependency to be injected into the controller. + * - `factory` - `{string|function}`: If `string` then it is an alias for a service. + * Otherwise if function, then it is {@link auto.$injector#invoke injected} + * and the return value is treated as the dependency. If the result is a promise, it is + * resolved before its value is injected into the controller. Be aware that + * `ngRoute.$routeParams` will still refer to the previous route within these resolve + * functions. Use `$route.current.params` to access the new route parameters, instead. + * + * - `redirectTo` – {(string|function())=} – value to update + * {@link ng.$location $location} path with and trigger route redirection. + * + * If `redirectTo` is a function, it will be called with the following parameters: + * + * - `{Object.}` - route parameters extracted from the current + * `$location.path()` by applying the current route templateUrl. + * - `{string}` - current `$location.path()` + * - `{Object}` - current `$location.search()` + * + * The custom `redirectTo` function is expected to return a string which will be used + * to update `$location.path()` and `$location.search()`. + * + * - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()` + * or `$location.hash()` changes. + * + * If the option is set to `false` and url in the browser changes, then + * `$routeUpdate` event is broadcasted on the root scope. + * + * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive + * + * If the option is set to `true`, then the particular route can be matched without being + * case sensitive + * + * @returns {Object} self + * + * @description + * Adds a new route definition to the `$route` service. + */ + this.when = function(path, route) { + //copy original route object to preserve params inherited from proto chain + var routeCopy = angular.copy(route); + if (angular.isUndefined(routeCopy.reloadOnSearch)) { + routeCopy.reloadOnSearch = true; + } + if (angular.isUndefined(routeCopy.caseInsensitiveMatch)) { + routeCopy.caseInsensitiveMatch = this.caseInsensitiveMatch; + } + routes[path] = angular.extend( + routeCopy, + path && pathRegExp(path, routeCopy) + ); + + // create redirection for trailing slashes + if (path) { + var redirectPath = (path[path.length - 1] == '/') + ? path.substr(0, path.length - 1) + : path + '/'; + + routes[redirectPath] = angular.extend( + {redirectTo: path}, + pathRegExp(redirectPath, routeCopy) + ); + } + + return this; + }; + + /** + * @ngdoc property + * @name $routeProvider#caseInsensitiveMatch + * @description + * + * A boolean property indicating if routes defined + * using this provider should be matched using a case insensitive + * algorithm. Defaults to `false`. + */ + this.caseInsensitiveMatch = false; + + /** + * @param path {string} path + * @param opts {Object} options + * @return {?Object} + * + * @description + * Normalizes the given path, returning a regular expression + * and the original path. + * + * Inspired by pathRexp in visionmedia/express/lib/utils.js. + */ + function pathRegExp(path, opts) { + var insensitive = opts.caseInsensitiveMatch, + ret = { + originalPath: path, + regexp: path + }, + keys = ret.keys = []; + + path = path + .replace(/([().])/g, '\\$1') + .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) { + var optional = option === '?' ? option : null; + var star = option === '*' ? option : null; + keys.push({ name: key, optional: !!optional }); + slash = slash || ''; + return '' + + (optional ? '' : slash) + + '(?:' + + (optional ? slash : '') + + (star && '(.+?)' || '([^/]+)') + + (optional || '') + + ')' + + (optional || ''); + }) + .replace(/([\/$\*])/g, '\\$1'); + + ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : ''); + return ret; + } + + /** + * @ngdoc method + * @name $routeProvider#otherwise + * + * @description + * Sets route definition that will be used on route change when no other route definition + * is matched. + * + * @param {Object|string} params Mapping information to be assigned to `$route.current`. + * If called with a string, the value maps to `redirectTo`. + * @returns {Object} self + */ + this.otherwise = function(params) { + if (typeof params === 'string') { + params = {redirectTo: params}; + } + this.when(null, params); + return this; + }; + + + this.$get = ['$rootScope', + '$location', + '$routeParams', + '$q', + '$injector', + '$templateRequest', + '$sce', + function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) { + + /** + * @ngdoc service + * @name $route + * @requires $location + * @requires $routeParams + * + * @property {Object} current Reference to the current route definition. + * The route definition contains: + * + * - `controller`: The controller constructor as define in route definition. + * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for + * controller instantiation. The `locals` contain + * the resolved values of the `resolve` map. Additionally the `locals` also contain: + * + * - `$scope` - The current route scope. + * - `$template` - The current route template HTML. + * + * @property {Object} routes Object with all route configuration Objects as its properties. + * + * @description + * `$route` is used for deep-linking URLs to controllers and views (HTML partials). + * It watches `$location.url()` and tries to map the path to an existing route definition. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API. + * + * The `$route` service is typically used in conjunction with the + * {@link ngRoute.directive:ngView `ngView`} directive and the + * {@link ngRoute.$routeParams `$routeParams`} service. + * + * @example + * This example shows how changing the URL hash causes the `$route` to match a route against the + * URL, and the `ngView` pulls in the partial. + * + * + * + *
    + * Choose: + * Moby | + * Moby: Ch1 | + * Gatsby | + * Gatsby: Ch4 | + * Scarlet Letter
    + * + *
    + * + *
    + * + *
    $location.path() = {{$location.path()}}
    + *
    $route.current.templateUrl = {{$route.current.templateUrl}}
    + *
    $route.current.params = {{$route.current.params}}
    + *
    $route.current.scope.name = {{$route.current.scope.name}}
    + *
    $routeParams = {{$routeParams}}
    + *
    + *
    + * + * + * controller: {{name}}
    + * Book Id: {{params.bookId}}
    + *
    + * + * + * controller: {{name}}
    + * Book Id: {{params.bookId}}
    + * Chapter Id: {{params.chapterId}} + *
    + * + * + * angular.module('ngRouteExample', ['ngRoute']) + * + * .controller('MainController', function($scope, $route, $routeParams, $location) { + * $scope.$route = $route; + * $scope.$location = $location; + * $scope.$routeParams = $routeParams; + * }) + * + * .controller('BookController', function($scope, $routeParams) { + * $scope.name = "BookController"; + * $scope.params = $routeParams; + * }) + * + * .controller('ChapterController', function($scope, $routeParams) { + * $scope.name = "ChapterController"; + * $scope.params = $routeParams; + * }) + * + * .config(function($routeProvider, $locationProvider) { + * $routeProvider + * .when('/Book/:bookId', { + * templateUrl: 'book.html', + * controller: 'BookController', + * resolve: { + * // I will cause a 1 second delay + * delay: function($q, $timeout) { + * var delay = $q.defer(); + * $timeout(delay.resolve, 1000); + * return delay.promise; + * } + * } + * }) + * .when('/Book/:bookId/ch/:chapterId', { + * templateUrl: 'chapter.html', + * controller: 'ChapterController' + * }); + * + * // configure html5 to get links working on jsfiddle + * $locationProvider.html5Mode(true); + * }); + * + * + * + * + * it('should load and compile correct template', function() { + * element(by.linkText('Moby: Ch1')).click(); + * var content = element(by.css('[ng-view]')).getText(); + * expect(content).toMatch(/controller\: ChapterController/); + * expect(content).toMatch(/Book Id\: Moby/); + * expect(content).toMatch(/Chapter Id\: 1/); + * + * element(by.partialLinkText('Scarlet')).click(); + * + * content = element(by.css('[ng-view]')).getText(); + * expect(content).toMatch(/controller\: BookController/); + * expect(content).toMatch(/Book Id\: Scarlet/); + * }); + * + *
    + */ + + /** + * @ngdoc event + * @name $route#$routeChangeStart + * @eventType broadcast on root scope + * @description + * Broadcasted before a route change. At this point the route services starts + * resolving all of the dependencies needed for the route change to occur. + * Typically this involves fetching the view template as well as any dependencies + * defined in `resolve` route property. Once all of the dependencies are resolved + * `$routeChangeSuccess` is fired. + * + * The route change (and the `$location` change that triggered it) can be prevented + * by calling `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} + * for more details about event object. + * + * @param {Object} angularEvent Synthetic event object. + * @param {Route} next Future route information. + * @param {Route} current Current route information. + */ + + /** + * @ngdoc event + * @name $route#$routeChangeSuccess + * @eventType broadcast on root scope + * @description + * Broadcasted after a route change has happened successfully. + * The `resolve` dependencies are now available in the `current.locals` property. + * + * {@link ngRoute.directive:ngView ngView} listens for the directive + * to instantiate the controller and render the view. + * + * @param {Object} angularEvent Synthetic event object. + * @param {Route} current Current route information. + * @param {Route|Undefined} previous Previous route information, or undefined if current is + * first route entered. + */ + + /** + * @ngdoc event + * @name $route#$routeChangeError + * @eventType broadcast on root scope + * @description + * Broadcasted if any of the resolve promises are rejected. + * + * @param {Object} angularEvent Synthetic event object + * @param {Route} current Current route information. + * @param {Route} previous Previous route information. + * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise. + */ + + /** + * @ngdoc event + * @name $route#$routeUpdate + * @eventType broadcast on root scope + * @description + * The `reloadOnSearch` property has been set to false, and we are reusing the same + * instance of the Controller. + * + * @param {Object} angularEvent Synthetic event object + * @param {Route} current Current/previous route information. + */ + + var forceReload = false, + preparedRoute, + preparedRouteIsUpdateOnly, + $route = { + routes: routes, + + /** + * @ngdoc method + * @name $route#reload + * + * @description + * Causes `$route` service to reload the current route even if + * {@link ng.$location $location} hasn't changed. + * + * As a result of that, {@link ngRoute.directive:ngView ngView} + * creates new scope and reinstantiates the controller. + */ + reload: function() { + forceReload = true; + $rootScope.$evalAsync(function() { + // Don't support cancellation of a reload for now... + prepareRoute(); + commitRoute(); + }); + }, + + /** + * @ngdoc method + * @name $route#updateParams + * + * @description + * Causes `$route` service to update the current URL, replacing + * current route parameters with those specified in `newParams`. + * Provided property names that match the route's path segment + * definitions will be interpolated into the location's path, while + * remaining properties will be treated as query params. + * + * @param {!Object} newParams mapping of URL parameter names to values + */ + updateParams: function(newParams) { + if (this.current && this.current.$$route) { + newParams = angular.extend({}, this.current.params, newParams); + $location.path(interpolate(this.current.$$route.originalPath, newParams)); + // interpolate modifies newParams, only query params are left + $location.search(newParams); + } else { + throw $routeMinErr('norout', 'Tried updating route when with no current route'); + } + } + }; + + $rootScope.$on('$locationChangeStart', prepareRoute); + $rootScope.$on('$locationChangeSuccess', commitRoute); + + return $route; + + ///////////////////////////////////////////////////// + + /** + * @param on {string} current url + * @param route {Object} route regexp to match the url against + * @return {?Object} + * + * @description + * Check if the route matches the current url. + * + * Inspired by match in + * visionmedia/express/lib/router/router.js. + */ + function switchRouteMatcher(on, route) { + var keys = route.keys, + params = {}; + + if (!route.regexp) return null; + + var m = route.regexp.exec(on); + if (!m) return null; + + for (var i = 1, len = m.length; i < len; ++i) { + var key = keys[i - 1]; + + var val = m[i]; + + if (key && val) { + params[key.name] = val; + } + } + return params; + } + + function prepareRoute($locationEvent) { + var lastRoute = $route.current; + + preparedRoute = parseRoute(); + preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route + && angular.equals(preparedRoute.pathParams, lastRoute.pathParams) + && !preparedRoute.reloadOnSearch && !forceReload; + + if (!preparedRouteIsUpdateOnly && (lastRoute || preparedRoute)) { + if ($rootScope.$broadcast('$routeChangeStart', preparedRoute, lastRoute).defaultPrevented) { + if ($locationEvent) { + $locationEvent.preventDefault(); + } + } + } + } + + function commitRoute() { + var lastRoute = $route.current; + var nextRoute = preparedRoute; + + if (preparedRouteIsUpdateOnly) { + lastRoute.params = nextRoute.params; + angular.copy(lastRoute.params, $routeParams); + $rootScope.$broadcast('$routeUpdate', lastRoute); + } else if (nextRoute || lastRoute) { + forceReload = false; + $route.current = nextRoute; + if (nextRoute) { + if (nextRoute.redirectTo) { + if (angular.isString(nextRoute.redirectTo)) { + $location.path(interpolate(nextRoute.redirectTo, nextRoute.params)).search(nextRoute.params) + .replace(); + } else { + $location.url(nextRoute.redirectTo(nextRoute.pathParams, $location.path(), $location.search())) + .replace(); + } + } + } + + $q.when(nextRoute). + then(function() { + if (nextRoute) { + var locals = angular.extend({}, nextRoute.resolve), + template, templateUrl; + + angular.forEach(locals, function(value, key) { + locals[key] = angular.isString(value) ? + $injector.get(value) : $injector.invoke(value, null, null, key); + }); + + if (angular.isDefined(template = nextRoute.template)) { + if (angular.isFunction(template)) { + template = template(nextRoute.params); + } + } else if (angular.isDefined(templateUrl = nextRoute.templateUrl)) { + if (angular.isFunction(templateUrl)) { + templateUrl = templateUrl(nextRoute.params); + } + if (angular.isDefined(templateUrl)) { + nextRoute.loadedTemplateUrl = $sce.valueOf(templateUrl); + template = $templateRequest(templateUrl); + } + } + if (angular.isDefined(template)) { + locals['$template'] = template; + } + return $q.all(locals); + } + }). + then(function(locals) { + // after route change + if (nextRoute == $route.current) { + if (nextRoute) { + nextRoute.locals = locals; + angular.copy(nextRoute.params, $routeParams); + } + $rootScope.$broadcast('$routeChangeSuccess', nextRoute, lastRoute); + } + }, function(error) { + if (nextRoute == $route.current) { + $rootScope.$broadcast('$routeChangeError', nextRoute, lastRoute, error); + } + }); + } + } + + + /** + * @returns {Object} the current active route, by matching it against the URL + */ + function parseRoute() { + // Match a route + var params, match; + angular.forEach(routes, function(route, path) { + if (!match && (params = switchRouteMatcher($location.path(), route))) { + match = inherit(route, { + params: angular.extend({}, $location.search(), params), + pathParams: params}); + match.$$route = route; + } + }); + // No route matched; fallback to "otherwise" route + return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}}); + } + + /** + * @returns {string} interpolation of the redirect path with the parameters + */ + function interpolate(string, params) { + var result = []; + angular.forEach((string || '').split(':'), function(segment, i) { + if (i === 0) { + result.push(segment); + } else { + var segmentMatch = segment.match(/(\w+)(?:[?*])?(.*)/); + var key = segmentMatch[1]; + result.push(params[key]); + result.push(segmentMatch[2] || ''); + delete params[key]; + } + }); + return result.join(''); + } + }]; +} + +ngRouteModule.provider('$routeParams', $RouteParamsProvider); + + +/** + * @ngdoc service + * @name $routeParams + * @requires $route + * + * @description + * The `$routeParams` service allows you to retrieve the current set of route parameters. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * The route parameters are a combination of {@link ng.$location `$location`}'s + * {@link ng.$location#search `search()`} and {@link ng.$location#path `path()`}. + * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched. + * + * In case of parameter name collision, `path` params take precedence over `search` params. + * + * The service guarantees that the identity of the `$routeParams` object will remain unchanged + * (but its properties will likely change) even when a route change occurs. + * + * Note that the `$routeParams` are only updated *after* a route change completes successfully. + * This means that you cannot rely on `$routeParams` being correct in route resolve functions. + * Instead you can use `$route.current.params` to access the new route's parameters. + * + * @example + * ```js + * // Given: + * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby + * // Route: /Chapter/:chapterId/Section/:sectionId + * // + * // Then + * $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'} + * ``` + */ +function $RouteParamsProvider() { + this.$get = function() { return {}; }; +} + +ngRouteModule.directive('ngView', ngViewFactory); +ngRouteModule.directive('ngView', ngViewFillContentFactory); + + +/** + * @ngdoc directive + * @name ngView + * @restrict ECA + * + * @description + * # Overview + * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by + * including the rendered template of the current route into the main layout (`index.html`) file. + * Every time the current route changes, the included view changes with it according to the + * configuration of the `$route` service. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * @animations + * enter - animation is used to bring new content into the browser. + * leave - animation is used to animate existing content away. + * + * The enter and leave animation occur concurrently. + * + * @scope + * @priority 400 + * @param {string=} onload Expression to evaluate whenever the view updates. + * + * @param {string=} autoscroll Whether `ngView` should call {@link ng.$anchorScroll + * $anchorScroll} to scroll the viewport after the view is updated. + * + * - If the attribute is not set, disable scrolling. + * - If the attribute is set without value, enable scrolling. + * - Otherwise enable scrolling only if the `autoscroll` attribute value evaluated + * as an expression yields a truthy value. + * @example + + +
    + Choose: + Moby | + Moby: Ch1 | + Gatsby | + Gatsby: Ch4 | + Scarlet Letter
    + +
    +
    +
    +
    + +
    $location.path() = {{main.$location.path()}}
    +
    $route.current.templateUrl = {{main.$route.current.templateUrl}}
    +
    $route.current.params = {{main.$route.current.params}}
    +
    $routeParams = {{main.$routeParams}}
    +
    +
    + + +
    + controller: {{book.name}}
    + Book Id: {{book.params.bookId}}
    +
    +
    + + +
    + controller: {{chapter.name}}
    + Book Id: {{chapter.params.bookId}}
    + Chapter Id: {{chapter.params.chapterId}} +
    +
    + + + .view-animate-container { + position:relative; + height:100px!important; + background:white; + border:1px solid black; + height:40px; + overflow:hidden; + } + + .view-animate { + padding:10px; + } + + .view-animate.ng-enter, .view-animate.ng-leave { + transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + + display:block; + width:100%; + border-left:1px solid black; + + position:absolute; + top:0; + left:0; + right:0; + bottom:0; + padding:10px; + } + + .view-animate.ng-enter { + left:100%; + } + .view-animate.ng-enter.ng-enter-active { + left:0; + } + .view-animate.ng-leave.ng-leave-active { + left:-100%; + } + + + + angular.module('ngViewExample', ['ngRoute', 'ngAnimate']) + .config(['$routeProvider', '$locationProvider', + function($routeProvider, $locationProvider) { + $routeProvider + .when('/Book/:bookId', { + templateUrl: 'book.html', + controller: 'BookCtrl', + controllerAs: 'book' + }) + .when('/Book/:bookId/ch/:chapterId', { + templateUrl: 'chapter.html', + controller: 'ChapterCtrl', + controllerAs: 'chapter' + }); + + $locationProvider.html5Mode(true); + }]) + .controller('MainCtrl', ['$route', '$routeParams', '$location', + function($route, $routeParams, $location) { + this.$route = $route; + this.$location = $location; + this.$routeParams = $routeParams; + }]) + .controller('BookCtrl', ['$routeParams', function($routeParams) { + this.name = "BookCtrl"; + this.params = $routeParams; + }]) + .controller('ChapterCtrl', ['$routeParams', function($routeParams) { + this.name = "ChapterCtrl"; + this.params = $routeParams; + }]); + + + + + it('should load and compile correct template', function() { + element(by.linkText('Moby: Ch1')).click(); + var content = element(by.css('[ng-view]')).getText(); + expect(content).toMatch(/controller\: ChapterCtrl/); + expect(content).toMatch(/Book Id\: Moby/); + expect(content).toMatch(/Chapter Id\: 1/); + + element(by.partialLinkText('Scarlet')).click(); + + content = element(by.css('[ng-view]')).getText(); + expect(content).toMatch(/controller\: BookCtrl/); + expect(content).toMatch(/Book Id\: Scarlet/); + }); + +
    + */ + + +/** + * @ngdoc event + * @name ngView#$viewContentLoaded + * @eventType emit on the current ngView scope + * @description + * Emitted every time the ngView content is reloaded. + */ +ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate']; +function ngViewFactory($route, $anchorScroll, $animate) { + return { + restrict: 'ECA', + terminal: true, + priority: 400, + transclude: 'element', + link: function(scope, $element, attr, ctrl, $transclude) { + var currentScope, + currentElement, + previousLeaveAnimation, + autoScrollExp = attr.autoscroll, + onloadExp = attr.onload || ''; + + scope.$on('$routeChangeSuccess', update); + update(); + + function cleanupLastView() { + if (previousLeaveAnimation) { + $animate.cancel(previousLeaveAnimation); + previousLeaveAnimation = null; + } + + if (currentScope) { + currentScope.$destroy(); + currentScope = null; + } + if (currentElement) { + previousLeaveAnimation = $animate.leave(currentElement); + previousLeaveAnimation.then(function() { + previousLeaveAnimation = null; + }); + currentElement = null; + } + } + + function update() { + var locals = $route.current && $route.current.locals, + template = locals && locals.$template; + + if (angular.isDefined(template)) { + var newScope = scope.$new(); + var current = $route.current; + + // Note: This will also link all children of ng-view that were contained in the original + // html. If that content contains controllers, ... they could pollute/change the scope. + // However, using ng-view on an element with additional content does not make sense... + // Note: We can't remove them in the cloneAttchFn of $transclude as that + // function is called before linking the content, which would apply child + // directives to non existing elements. + var clone = $transclude(newScope, function(clone) { + $animate.enter(clone, null, currentElement || $element).then(function onNgViewEnter() { + if (angular.isDefined(autoScrollExp) + && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } + }); + cleanupLastView(); + }); + + currentElement = clone; + currentScope = current.scope = newScope; + currentScope.$emit('$viewContentLoaded'); + currentScope.$eval(onloadExp); + } else { + cleanupLastView(); + } + } + } + }; +} + +// This directive is called during the $transclude call of the first `ngView` directive. +// It will replace and compile the content of the element with the loaded template. +// We need this directive so that the element content is already filled when +// the link function of another directive on the same element as ngView +// is called. +ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route']; +function ngViewFillContentFactory($compile, $controller, $route) { + return { + restrict: 'ECA', + priority: -400, + link: function(scope, $element) { + var current = $route.current, + locals = current.locals; + + $element.html(locals.$template); + + var link = $compile($element.contents()); + + if (current.controller) { + locals.$scope = scope; + var controller = $controller(current.controller, locals); + if (current.controllerAs) { + scope[current.controllerAs] = controller; + } + $element.data('$ngControllerController', controller); + $element.children().data('$ngControllerController', controller); + } + + link(scope); + } + }; +} + + +})(window, window.angular); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-route.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-route.min.js new file mode 100644 index 00000000..3c5fd343 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-route.min.js @@ -0,0 +1,15 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(p,c,C){'use strict';function v(r,h,g){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,f,b,d,y){function z(){k&&(g.cancel(k),k=null);l&&(l.$destroy(),l=null);m&&(k=g.leave(m),k.then(function(){k=null}),m=null)}function x(){var b=r.current&&r.current.locals;if(c.isDefined(b&&b.$template)){var b=a.$new(),d=r.current;m=y(b,function(b){g.enter(b,null,m||f).then(function(){!c.isDefined(t)||t&&!a.$eval(t)||h()});z()});l=d.scope=b;l.$emit("$viewContentLoaded"); +l.$eval(w)}else z()}var l,m,k,t=b.autoscroll,w=b.onload||"";a.$on("$routeChangeSuccess",x);x()}}}function A(c,h,g){return{restrict:"ECA",priority:-400,link:function(a,f){var b=g.current,d=b.locals;f.html(d.$template);var y=c(f.contents());b.controller&&(d.$scope=a,d=h(b.controller,d),b.controllerAs&&(a[b.controllerAs]=d),f.data("$ngControllerController",d),f.children().data("$ngControllerController",d));y(a)}}}p=c.module("ngRoute",["ng"]).provider("$route",function(){function r(a,f){return c.extend(Object.create(a), +f)}function h(a,c){var b=c.caseInsensitiveMatch,d={originalPath:a,regexp:a},g=d.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,c,b,d){a="?"===d?d:null;d="*"===d?d:null;g.push({name:b,optional:!!a});c=c||"";return""+(a?"":c)+"(?:"+(a?c:"")+(d&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");d.regexp=new RegExp("^"+a+"$",b?"i":"");return d}var g={};this.when=function(a,f){var b=c.copy(f);c.isUndefined(b.reloadOnSearch)&&(b.reloadOnSearch=!0); +c.isUndefined(b.caseInsensitiveMatch)&&(b.caseInsensitiveMatch=this.caseInsensitiveMatch);g[a]=c.extend(b,a&&h(a,b));if(a){var d="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";g[d]=c.extend({redirectTo:a},h(d,b))}return this};this.caseInsensitiveMatch=!1;this.otherwise=function(a){"string"===typeof a&&(a={redirectTo:a});this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function(a,f,b,d,h,p,x){function l(b){var e=s.current; +(v=(n=k())&&e&&n.$$route===e.$$route&&c.equals(n.pathParams,e.pathParams)&&!n.reloadOnSearch&&!w)||!e&&!n||a.$broadcast("$routeChangeStart",n,e).defaultPrevented&&b&&b.preventDefault()}function m(){var u=s.current,e=n;if(v)u.params=e.params,c.copy(u.params,b),a.$broadcast("$routeUpdate",u);else if(e||u)w=!1,(s.current=e)&&e.redirectTo&&(c.isString(e.redirectTo)?f.path(t(e.redirectTo,e.params)).search(e.params).replace():f.url(e.redirectTo(e.pathParams,f.path(),f.search())).replace()),d.when(e).then(function(){if(e){var a= +c.extend({},e.resolve),b,f;c.forEach(a,function(b,e){a[e]=c.isString(b)?h.get(b):h.invoke(b,null,null,e)});c.isDefined(b=e.template)?c.isFunction(b)&&(b=b(e.params)):c.isDefined(f=e.templateUrl)&&(c.isFunction(f)&&(f=f(e.params)),c.isDefined(f)&&(e.loadedTemplateUrl=x.valueOf(f),b=p(f)));c.isDefined(b)&&(a.$template=b);return d.all(a)}}).then(function(f){e==s.current&&(e&&(e.locals=f,c.copy(e.params,b)),a.$broadcast("$routeChangeSuccess",e,u))},function(b){e==s.current&&a.$broadcast("$routeChangeError", +e,u,b)})}function k(){var a,b;c.forEach(g,function(d,g){var q;if(q=!b){var h=f.path();q=d.keys;var l={};if(d.regexp)if(h=d.regexp.exec(h)){for(var k=1,m=h.length;k + * + * See {@link ngSanitize.$sanitize `$sanitize`} for usage. + */ + +/* + * HTML Parser By Misko Hevery (misko@hevery.com) + * based on: HTML Parser By John Resig (ejohn.org) + * Original code by Erik Arvidsson, Mozilla Public License + * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js + * + * // Use like so: + * htmlParser(htmlString, { + * start: function(tag, attrs, unary) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * }); + * + */ + + +/** + * @ngdoc service + * @name $sanitize + * @kind function + * + * @description + * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are + * then serialized back to properly escaped html string. This means that no unsafe input can make + * it into the returned string, however, since our parser is more strict than a typical browser + * parser, it's possible that some obscure input, which would be recognized as valid HTML by a + * browser, won't make it through the sanitizer. The input may also contain SVG markup. + * The whitelist is configured using the functions `aHrefSanitizationWhitelist` and + * `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}. + * + * @param {string} html HTML input. + * @returns {string} Sanitized HTML. + * + * @example + + + +
    + Snippet: + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectiveHowSourceRendered
    ng-bind-htmlAutomatically uses $sanitize
    <div ng-bind-html="snippet">
    </div>
    ng-bind-htmlBypass $sanitize by explicitly trusting the dangerous value +
    <div ng-bind-html="deliberatelyTrustDangerousSnippet()">
    +</div>
    +
    ng-bindAutomatically escapes
    <div ng-bind="snippet">
    </div>
    +
    +
    + + it('should sanitize the html snippet by default', function() { + expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). + toBe('

    an html\nclick here\nsnippet

    '); + }); + + it('should inline raw snippet if bound to a trusted value', function() { + expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()). + toBe("

    an html\n" + + "click here\n" + + "snippet

    "); + }); + + it('should escape snippet without any filter', function() { + expect(element(by.css('#bind-default div')).getInnerHtml()). + toBe("<p style=\"color:blue\">an html\n" + + "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + + "snippet</p>"); + }); + + it('should update', function() { + element(by.model('snippet')).clear(); + element(by.model('snippet')).sendKeys('new text'); + expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). + toBe('new text'); + expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe( + 'new text'); + expect(element(by.css('#bind-default div')).getInnerHtml()).toBe( + "new <b onclick=\"alert(1)\">text</b>"); + }); +
    +
    + */ +function $SanitizeProvider() { + this.$get = ['$$sanitizeUri', function($$sanitizeUri) { + return function(html) { + var buf = []; + htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) { + return !/^unsafe/.test($$sanitizeUri(uri, isImage)); + })); + return buf.join(''); + }; + }]; +} + +function sanitizeText(chars) { + var buf = []; + var writer = htmlSanitizeWriter(buf, angular.noop); + writer.chars(chars); + return buf.join(''); +} + + +// Regular Expressions for parsing tags and attributes +var START_TAG_REGEXP = + /^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/, + END_TAG_REGEXP = /^<\/\s*([\w:-]+)[^>]*>/, + ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, + BEGIN_TAG_REGEXP = /^/g, + DOCTYPE_REGEXP = /]*?)>/i, + CDATA_REGEXP = //g, + SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + // Match everything outside of normal chars and " (quote character) + NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; + + +// Good source of info about elements and attributes +// http://dev.w3.org/html5/spec/Overview.html#semantics +// http://simon.html5.org/html-elements + +// Safe Void Elements - HTML5 +// http://dev.w3.org/html5/spec/Overview.html#void-elements +var voidElements = makeMap("area,br,col,hr,img,wbr"); + +// Elements that you can, intentionally, leave open (and which close themselves) +// http://dev.w3.org/html5/spec/Overview.html#optional-tags +var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"), + optionalEndTagInlineElements = makeMap("rp,rt"), + optionalEndTagElements = angular.extend({}, + optionalEndTagInlineElements, + optionalEndTagBlockElements); + +// Safe Block Elements - HTML5 +var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," + + "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," + + "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")); + +// Inline Elements - HTML5 +var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," + + "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," + + "samp,small,span,strike,strong,sub,sup,time,tt,u,var")); + +// SVG Elements +// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements +// Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted. +// They can potentially allow for arbitrary javascript to be executed. See #11290 +var svgElements = makeMap("circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph," + + "hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline," + + "radialGradient,rect,stop,svg,switch,text,title,tspan,use"); + +// Special Elements (can contain anything) +var specialElements = makeMap("script,style"); + +var validElements = angular.extend({}, + voidElements, + blockElements, + inlineElements, + optionalEndTagElements, + svgElements); + +//Attributes that have href and hence need to be sanitized +var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap,xlink:href"); + +var htmlAttrs = makeMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' + + 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' + + 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' + + 'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' + + 'valign,value,vspace,width'); + +// SVG attributes (without "id" and "name" attributes) +// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes +var svgAttrs = makeMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' + + 'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' + + 'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' + + 'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' + + 'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' + + 'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' + + 'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' + + 'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' + + 'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' + + 'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' + + 'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' + + 'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' + + 'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' + + 'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' + + 'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true); + +var validAttrs = angular.extend({}, + uriAttrs, + svgAttrs, + htmlAttrs); + +function makeMap(str, lowercaseKeys) { + var obj = {}, items = str.split(','), i; + for (i = 0; i < items.length; i++) { + obj[lowercaseKeys ? angular.lowercase(items[i]) : items[i]] = true; + } + return obj; +} + + +/** + * @example + * htmlParser(htmlString, { + * start: function(tag, attrs, unary) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * }); + * + * @param {string} html string + * @param {object} handler + */ +function htmlParser(html, handler) { + if (typeof html !== 'string') { + if (html === null || typeof html === 'undefined') { + html = ''; + } else { + html = '' + html; + } + } + var index, chars, match, stack = [], last = html, text; + stack.last = function() { return stack[stack.length - 1]; }; + + while (html) { + text = ''; + chars = true; + + // Make sure we're not in a script or style element + if (!stack.last() || !specialElements[stack.last()]) { + + // Comment + if (html.indexOf("", index) === index) { + if (handler.comment) handler.comment(html.substring(4, index)); + html = html.substring(index + 3); + chars = false; + } + // DOCTYPE + } else if (DOCTYPE_REGEXP.test(html)) { + match = html.match(DOCTYPE_REGEXP); + + if (match) { + html = html.replace(match[0], ''); + chars = false; + } + // end tag + } else if (BEGING_END_TAGE_REGEXP.test(html)) { + match = html.match(END_TAG_REGEXP); + + if (match) { + html = html.substring(match[0].length); + match[0].replace(END_TAG_REGEXP, parseEndTag); + chars = false; + } + + // start tag + } else if (BEGIN_TAG_REGEXP.test(html)) { + match = html.match(START_TAG_REGEXP); + + if (match) { + // We only have a valid start-tag if there is a '>'. + if (match[4]) { + html = html.substring(match[0].length); + match[0].replace(START_TAG_REGEXP, parseStartTag); + } + chars = false; + } else { + // no ending tag found --- this piece should be encoded as an entity. + text += '<'; + html = html.substring(1); + } + } + + if (chars) { + index = html.indexOf("<"); + + text += index < 0 ? html : html.substring(0, index); + html = index < 0 ? "" : html.substring(index); + + if (handler.chars) handler.chars(decodeEntities(text)); + } + + } else { + // IE versions 9 and 10 do not understand the regex '[^]', so using a workaround with [\W\w]. + html = html.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'), + function(all, text) { + text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1"); + + if (handler.chars) handler.chars(decodeEntities(text)); + + return ""; + }); + + parseEndTag("", stack.last()); + } + + if (html == last) { + throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " + + "of html: {0}", html); + } + last = html; + } + + // Clean up any remaining tags + parseEndTag(); + + function parseStartTag(tag, tagName, rest, unary) { + tagName = angular.lowercase(tagName); + if (blockElements[tagName]) { + while (stack.last() && inlineElements[stack.last()]) { + parseEndTag("", stack.last()); + } + } + + if (optionalEndTagElements[tagName] && stack.last() == tagName) { + parseEndTag("", tagName); + } + + unary = voidElements[tagName] || !!unary; + + if (!unary) { + stack.push(tagName); + } + + var attrs = {}; + + rest.replace(ATTR_REGEXP, + function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) { + var value = doubleQuotedValue + || singleQuotedValue + || unquotedValue + || ''; + + attrs[name] = decodeEntities(value); + }); + if (handler.start) handler.start(tagName, attrs, unary); + } + + function parseEndTag(tag, tagName) { + var pos = 0, i; + tagName = angular.lowercase(tagName); + if (tagName) { + // Find the closest opened tag of the same type + for (pos = stack.length - 1; pos >= 0; pos--) { + if (stack[pos] == tagName) break; + } + } + + if (pos >= 0) { + // Close all the open elements, up the stack + for (i = stack.length - 1; i >= pos; i--) + if (handler.end) handler.end(stack[i]); + + // Remove the open elements from the stack + stack.length = pos; + } + } +} + +var hiddenPre=document.createElement("pre"); +/** + * decodes all entities into regular string + * @param value + * @returns {string} A string with decoded entities. + */ +function decodeEntities(value) { + if (!value) { return ''; } + + hiddenPre.innerHTML = value.replace(//g, '>'); +} + +/** + * create an HTML/XML writer which writes to buffer + * @param {Array} buf use buf.jain('') to get out sanitized html string + * @returns {object} in the form of { + * start: function(tag, attrs, unary) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * } + */ +function htmlSanitizeWriter(buf, uriValidator) { + var ignore = false; + var out = angular.bind(buf, buf.push); + return { + start: function(tag, attrs, unary) { + tag = angular.lowercase(tag); + if (!ignore && specialElements[tag]) { + ignore = tag; + } + if (!ignore && validElements[tag] === true) { + out('<'); + out(tag); + angular.forEach(attrs, function(value, key) { + var lkey=angular.lowercase(key); + var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background'); + if (validAttrs[lkey] === true && + (uriAttrs[lkey] !== true || uriValidator(value, isImage))) { + out(' '); + out(key); + out('="'); + out(encodeEntities(value)); + out('"'); + } + }); + out(unary ? '/>' : '>'); + } + }, + end: function(tag) { + tag = angular.lowercase(tag); + if (!ignore && validElements[tag] === true) { + out(''); + } + if (tag == ignore) { + ignore = false; + } + }, + chars: function(chars) { + if (!ignore) { + out(encodeEntities(chars)); + } + } + }; +} + + +// define ngSanitize module and register $sanitize service +angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider); + +/* global sanitizeText: false */ + +/** + * @ngdoc filter + * @name linky + * @kind function + * + * @description + * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and + * plain email address links. + * + * Requires the {@link ngSanitize `ngSanitize`} module to be installed. + * + * @param {string} text Input text. + * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in. + * @returns {string} Html-linkified text. + * + * @usage + + * + * @example + + + +
    + Snippet: + + + + + + + + + + + + + + + + + + + + + +
    FilterSourceRendered
    linky filter +
    <div ng-bind-html="snippet | linky">
    </div>
    +
    +
    +
    linky target +
    <div ng-bind-html="snippetWithTarget | linky:'_blank'">
    </div>
    +
    +
    +
    no filter
    <div ng-bind="snippet">
    </div>
    + + + it('should linkify the snippet with urls', function() { + expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). + toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' + + 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); + expect(element.all(by.css('#linky-filter a')).count()).toEqual(4); + }); + + it('should not linkify snippet without the linky filter', function() { + expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()). + toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' + + 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); + expect(element.all(by.css('#escaped-html a')).count()).toEqual(0); + }); + + it('should update', function() { + element(by.model('snippet')).clear(); + element(by.model('snippet')).sendKeys('new http://link.'); + expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). + toBe('new http://link.'); + expect(element.all(by.css('#linky-filter a')).count()).toEqual(1); + expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()) + .toBe('new http://link.'); + }); + + it('should work with the target property', function() { + expect(element(by.id('linky-target')). + element(by.binding("snippetWithTarget | linky:'_blank'")).getText()). + toBe('http://angularjs.org/'); + expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank'); + }); + + + */ +angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { + var LINKY_URL_REGEXP = + /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i, + MAILTO_REGEXP = /^mailto:/i; + + return function(text, target) { + if (!text) return text; + var match; + var raw = text; + var html = []; + var url; + var i; + while ((match = raw.match(LINKY_URL_REGEXP))) { + // We can not end in these as they are sometimes found at the end of the sentence + url = match[0]; + // if we did not match ftp/http/www/mailto then assume mailto + if (!match[2] && !match[4]) { + url = (match[3] ? 'http://' : 'mailto:') + url; + } + i = match.index; + addText(raw.substr(0, i)); + addLink(url, match[0].replace(MAILTO_REGEXP, '')); + raw = raw.substring(i + match[0].length); + } + addText(raw); + return $sanitize(html.join('')); + + function addText(text) { + if (!text) { + return; + } + html.push(sanitizeText(text)); + } + + function addLink(url, text) { + html.push(''); + addText(text); + html.push(''); + } + }; +}]); + + +})(window, window.angular); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-sanitize.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-sanitize.min.js new file mode 100644 index 00000000..a1e654ce --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-sanitize.min.js @@ -0,0 +1,16 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(n,h,p){'use strict';function E(a){var f=[];r(f,h.noop).chars(a);return f.join("")}function g(a,f){var d={},c=a.split(","),b;for(b=0;b=c;d--)f.end&&f.end(e[d]);e.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,k,e=[],m=a,l;for(e.last=function(){return e[e.length-1]};a;){l="";k=!0;if(e.last()&&w[e.last()])a=a.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*"+e.last()+"[^>]*>","i"),function(a,b){b=b.replace(H,"$1").replace(I,"$1");f.chars&&f.chars(q(b));return""}),c("",e.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e", +b)===b&&(f.comment&&f.comment(a.substring(4,b)),a=a.substring(b+3),k=!1);else if(x.test(a)){if(b=a.match(x))a=a.replace(b[0],""),k=!1}else if(J.test(a)){if(b=a.match(y))a=a.substring(b[0].length),b[0].replace(y,c),k=!1}else K.test(a)&&((b=a.match(z))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(z,d)),k=!1):(l+="<",a=a.substring(1)));k&&(b=a.indexOf("<"),l+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),f.chars&&f.chars(q(l)))}if(a==m)throw L("badparse",a);m=a}c()}function q(a){if(!a)return"";A.innerHTML= +a.replace(//g,">")}function r(a,f){var d=!1,c=h.bind(a,a.push);return{start:function(a,k,e){a=h.lowercase(a);!d&&w[a]&&(d=a);d||!0!==C[a]||(c("<"),c(a),h.forEach(k,function(d,e){var k=h.lowercase(e),g="img"===a&&"src"===k|| +"background"===k;!0!==O[k]||!0===D[k]&&!f(d,g)||(c(" "),c(e),c('="'),c(B(d)),c('"'))}),c(e?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==C[a]||(c(""));a==d&&(d=!1)},chars:function(a){d||c(B(a))}}}var L=h.$$minErr("$sanitize"),z=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,y=/^<\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^]*?)>/i, +I=/"\u201d\u2019]/i,d=/^mailto:/i;return function(c,b){function k(a){a&&g.push(E(a))}function e(a, +c){g.push("');k(c);g.push("")}if(!c)return c;for(var m,l=c,g=[],n,p;m=l.match(f);)n=m[0],m[2]||m[4]||(n=(m[3]?"http://":"mailto:")+n),p=m.index,k(l.substr(0,p)),e(n,m[0].replace(d,"")),l=l.substring(p+m[0].length);k(l);return a(g.join(""))}}])})(window,window.angular); +//# sourceMappingURL=angular-sanitize.min.js.map diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-sanitize.min.js.map b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-sanitize.min.js.map new file mode 100644 index 00000000..2f360f4d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-sanitize.min.js.map @@ -0,0 +1,8 @@ +{ +"version":3, +"file":"angular-sanitize.min.js", +"lineCount":15, +"mappings":"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", +"sources":["angular-sanitize.js"], +"names":["window","angular","undefined","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","makeMap","str","lowercaseKeys","obj","items","split","i","length","lowercase","htmlParser","html","handler","parseStartTag","tag","tagName","rest","unary","blockElements","stack","last","inlineElements","parseEndTag","optionalEndTagElements","voidElements","push","attrs","replace","ATTR_REGEXP","match","name","doubleQuotedValue","singleQuotedValue","unquotedValue","decodeEntities","start","pos","end","index","text","stack.last","specialElements","RegExp","all","COMMENT_REGEXP","CDATA_REGEXP","indexOf","lastIndexOf","comment","substring","DOCTYPE_REGEXP","test","BEGING_END_TAGE_REGEXP","END_TAG_REGEXP","BEGIN_TAG_REGEXP","START_TAG_REGEXP","$sanitizeMinErr","value","hiddenPre","innerHTML","textContent","encodeEntities","SURROGATE_PAIR_REGEXP","hi","charCodeAt","low","NON_ALPHANUMERIC_REGEXP","uriValidator","ignore","out","bind","validElements","forEach","key","lkey","isImage","validAttrs","uriAttrs","$$minErr","optionalEndTagBlockElements","optionalEndTagInlineElements","extend","svgElements","htmlAttrs","svgAttrs","document","createElement","module","provider","$SanitizeProvider","$get","$$sanitizeUri","uri","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","target","addText","addLink","url","isDefined","raw","substr"] +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-scenario.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-scenario.js new file mode 100644 index 00000000..78dd37d0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/external/angular-1.4.8/angular-scenario.js @@ -0,0 +1,40439 @@ +/*! + * jQuery JavaScript Library v2.1.1 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-05-01T17:11Z + */ + +(function( global, factory ) {'use strict'; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var arr = []; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + version = "2.1.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; + }, + + isPlainObject: function( obj ) { + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + // Support: Android < 4.0, iOS < 6 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf("use strict") === 1 ) { + script = document.createElement("script"); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v1.10.19 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-04-18 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { + div.innerHTML = "
    "; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowclip^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + len = this.length, + ret = [], + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; + }, + + sibling: function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter(function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.unique( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * The ready event handler and self cleanup method + */ +function completed() { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + jQuery.ready(); +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[0], key ) : emptyGet; +}; + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( owner ) { + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + +function Data() { + // Support: Android < 4, + // Old WebKit does not have Object.preventExtensions/freeze method, + // return new empty object instead with no [[set]] accessor + Object.defineProperty( this.cache = {}, 0, { + get: function() { + return {}; + } + }); + + this.expando = jQuery.expando + Math.random(); +} + +Data.uid = 1; +Data.accepts = jQuery.acceptData; + +Data.prototype = { + key: function( owner ) { + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return the key for a frozen object. + if ( !Data.accepts( owner ) ) { + return 0; + } + + var descriptor = {}, + // Check if the owner object already has a cache key + unlock = owner[ this.expando ]; + + // If not, create one + if ( !unlock ) { + unlock = Data.uid++; + + // Secure it in a non-enumerable, non-writable property + try { + descriptor[ this.expando ] = { value: unlock }; + Object.defineProperties( owner, descriptor ); + + // Support: Android < 4 + // Fallback to a less secure definition + } catch ( e ) { + descriptor[ this.expando ] = unlock; + jQuery.extend( owner, descriptor ); + } + } + + // Ensure the cache object + if ( !this.cache[ unlock ] ) { + this.cache[ unlock ] = {}; + } + + return unlock; + }, + set: function( owner, data, value ) { + var prop, + // There may be an unlock assigned to this node, + // if there is no entry for this "owner", create one inline + // and set the unlock as though an owner entry had always existed + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + // Fresh assignments by object are shallow copied + if ( jQuery.isEmptyObject( cache ) ) { + jQuery.extend( this.cache[ unlock ], data ); + // Otherwise, copy the properties one-by-one to the cache object + } else { + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + } + return cache; + }, + get: function( owner, key ) { + // Either a valid cache is found, or will be created. + // New caches will be created and the unlock returned, + // allowing direct access to the newly created + // empty data object. A valid owner object must be provided. + var cache = this.cache[ this.key( owner ) ]; + + return key === undefined ? + cache : cache[ key ]; + }, + access: function( owner, key, value ) { + var stored; + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ((key && typeof key === "string") && value === undefined) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase(key) ); + } + + // [*]When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + if ( key === undefined ) { + this.cache[ unlock ] = {}; + + } else { + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + }, + hasData: function( owner ) { + return !jQuery.isEmptyObject( + this.cache[ owner[ this.expando ] ] || {} + ); + }, + discard: function( owner ) { + if ( owner[ this.expando ] ) { + delete this.cache[ owner[ this.expando ] ]; + } + } +}; +var data_priv = new Data(); + +var data_user = new Data(); + + + +/* + Implementation Summary + + 1. Enforce API surface and semantic compatibility with 1.9.x branch + 2. Improve the module's maintainability by reducing the storage + paths to a single mechanism. + 3. Use the same single mechanism to support "private" and "user" data. + 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) + 5. Avoid exposing implementation details on user objects (eg. expando properties) + 6. Provide a clear path for implementation upgrade to WeakMap in 2014 +*/ +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + data_user.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend({ + hasData: function( elem ) { + return data_user.hasData( elem ) || data_priv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return data_user.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + data_user.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to data_priv methods, these can be deprecated. + _data: function( elem, name, data ) { + return data_priv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + data_priv.remove( elem, name ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = data_user.get( elem ); + + if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + data_priv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + data_user.set( this, key ); + }); + } + + return access( this, function( value ) { + var data, + camelKey = jQuery.camelCase( key ); + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + // Attempt to get data from the cache + // with the key as-is + data = data_user.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to get data from the cache + // with the key camelized + data = data_user.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each(function() { + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = data_user.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + data_user.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf("-") !== -1 && data !== undefined ) { + data_user.set( this, key, value ); + } + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + data_user.remove( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = data_priv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = data_priv.access( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return data_priv.get( elem, key ) || data_priv.access( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + data_priv.remove( elem, [ type + "queue", key ] ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = data_priv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + // Support: Windows Web Apps (WWA) + // `name` and `type` need .setAttribute for WWA + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE9-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +})(); +var strundefined = typeof undefined; + + + +support.focusinBubbles = "onfocusin" in window; + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.hasData( elem ) && data_priv.get( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + data_priv.remove( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome < 28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } +}; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && e.preventDefault ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && e.stopPropagation ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// Support: Chrome 15+ +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// Create "bubbling" focus and blur events +// Support: Firefox, Chrome, Safari +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + data_priv.remove( doc, fix ); + + } else { + data_priv.access( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +var + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + + // Support: IE 9 + option: [ 1, "" ], + + thead: [ 1, "", "
    " ], + col: [ 2, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + _default: [ 0, "", "" ] + }; + +// Support: IE 9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: 1.x compatibility +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute("type"); + } + + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + data_priv.set( + elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) + ); + } +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( data_priv.hasData( src ) ) { + pdataOld = data_priv.access( src ); + pdataCur = data_priv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( data_user.hasData( src ) ) { + udataOld = data_user.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + data_user.set( dest, udataCur ); + } +} + +function getAll( context, tag ) { + var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : + context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + +// Support: IE >= 9 +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Support: IE >= 9 + // Fix Cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Fixes #12346 + // Support: Webkit, IE + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; + }, + + cleanData: function( elems ) { + var data, elem, type, key, + special = jQuery.event.special, + i = 0; + + for ( ; (elem = elems[ i ]) !== undefined; i++ ) { + if ( jQuery.acceptData( elem ) ) { + key = elem[ data_priv.expando ]; + + if ( key && (data = data_priv.cache[ key ]) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + if ( data_priv.cache[ key ] ) { + // Discard any remaining `private` data + delete data_priv.cache[ key ]; + } + } + } + // Discard any remaining `user` data + delete data_user.cache[ elem[ data_user.expando ] ]; + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each(function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + }); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: QtWebKit + // .get() because push.apply(_, arraylike) throws + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "
    + + + + + + --> + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-viz.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-viz.html new file mode 100644 index 00000000..252b51ec --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-viz.html @@ -0,0 +1,7 @@ +
    + + +
    + + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook.htm b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook.htm new file mode 100644 index 00000000..71aca7ab --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook.htm @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebookInputs.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebookInputs.html new file mode 100644 index 00000000..0969aa2f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebookInputs.html @@ -0,0 +1,70 @@ + + + + + + + + +
    +
    +
    +
    + +
    +
    + + + + + + +
    +
    +
    + +
    + +
    + +
    + +
    +
    + +
    + +
    + + + Remove +
    +
    +
    +
    + + + + +
    + +
    + Submit +
    + + + +
    + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-closed-cloop.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-closed-cloop.js new file mode 100644 index 00000000..94169ff4 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-closed-cloop.js @@ -0,0 +1,28 @@ +appDS2.controller('adminClosedLoopController', ['$scope','$http','$q','$log',function ($scope, $http,$q, $log){ + $scope.camunda_cockpit_url = ''; + var deferred = $q.defer(); + $http({ + method: "GET", + url: "get_camunda_cockpit_link", + }).success( function(res) { + // if the returned response is error HTML page in string format + if(res.link_defined=='false'){ + $log.error('Retrieval of camunda cockpit link failed. Please make sure the variable "camunda_cockpit_url" is defined in the system.properties file.'); + deferred.reject(status); + } + // valid cockpit url + else if(res.camunda_cockpit_link!=null & res.camunda_cockpit_link!= '') { + $scope.camunda_cockpit_url = res.camunda_cockpit_link; + deferred.resolve(res); + // if the defined url is empty; + } else { + $log.error('Please ensure the variable "camunda_cockpit_url" is properly defined in system.properties file (i.e., neither null nor empty).'); + deferred.reject(status); + } + // API call fails + }).error( function(status) { + $log.error('get_camunda_cockpit_link RestAPI call failed.'); + deferred.reject(status); + }); + return deferred.promise; +}]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-controller.js new file mode 100644 index 00000000..8d664fcb --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-controller.js @@ -0,0 +1,940 @@ +appDS2.controller('adminController', function($scope, $http,AdminService, $modal, $routeParams, $rootScope){ + + $scope.totalPages = 5; + $scope.viewPerPage = 8; + $scope.searchString = ""; + $scope.currentPage = 1; + $scope.nextSort=""; + $scope.showLoader = false; + $scope.tableData=[]; + $scope.routeRoleId = $routeParams.roleId; + $scope.regions = []; + /*function*/ + $scope.getFunctionList = function(){ + $scope.tableData.length=0; + AdminService.getRoleFunctionList().then(function(data){ + var j = data; + $scope.data = JSON.parse(j.data); + $scope.tableData =JSON.parse($scope.data.availableRoleFunctions); + },function(error){ + console.log("failed"); + }); + } + + $scope.getCacheRegionsList = function(){ + // $scope.regions.length=0; + AdminService.getCacheRegions().then(function(data){ + var j = data; + $scope.data = JSON.parse(j.data); + /* for(var i = 0; i< $scope.data.length; i++){ + if($scope.data[i].cacheName !== '[object Object]'){ + $scope.regions.push($scope.data[i]); + } + }*/ + $scope.regions =$scope.data; + },function(error){ + console.log("failed"); + //reloadPageOnce(); + }); + } + + + $scope.delRoleFunc = function(roleData){ + AdminService.delRoleFunctionList(roleData).then(function(msg){ + var message = msg; + if(message.data!=null && message.data!=''){ + var status = message.data; + if(status=='"success"'){ + $scope.successPopUp(); + $scope.getFunctionList(); + }else{ + $scope.errorPopUp(''); + } + } + + },function(error){ + + }); + } + + $scope.saveRoleFunction = function(roleData){ + AdminService.saveRoleFunctionList(roleData).then(function(msg){ + var message = msg; + if(message.data!=null && message.data!=''){ + var status = message.data; + if(status=='"success"'){ + $scope.successPopUp(); + $scope.getFunctionList(); + }else{ + $scope.errorPopUp(''); + } + } + + },function(error){ + + }); + } + + $scope.addRoleFunction = function(roleData){ + AdminService.addRoleFunctionList(roleData).then(function(msg){ + var message = msg; + if(message.data!=null && message.data!=''){ + var status = message.data; + if(status=='"success"'){ + $scope.successPopUp(); + $scope.getFunctionList(); + }else if(status=='"code exists"'){ + $scope.errorPopUp('Code already exists'); + $scope.getFunctionList(); + }else{ + $scope.errorPopUp(''); + } + } + + },function(error){ + + }); + } + /*init*/ + $scope.getFunctionList(); + $scope.getCacheRegionsList(); + /*popup*/ + var ModalInstanceCtrl = function ($scope, $modalInstance, items, AdminService,$rootScope) { + $scope.roleFun=items; + $scope.msg=items; + + // remove role function associated to a role on Role Edit page + $scope.roleFunRemoveRole = function (roleFunction) { + AdminService.removeRoleFunction(roleFunction, $routeParams.roleId).then(function(msg){ + var message = msg; + $scope.cancel(); + if(message.role){ + $rootScope.$broadcast('updateRoleFunctions',{data:message.role}); + /*$modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + sizeClass: 'modal-small', + })*/ + }else{ + $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return msg; + } + } + }) + } + + },function(error){ + console.log("error"); + }); + } + + //role activation for selected child role + $scope.activateRoleChildConfirmPopUp = function (selected, availableRole) { + $scope.msg.roleFun = availableRole.name; + $scope.msg.selected = selected; + $scope.msg.availableRole = availableRole; + var toggleType = null; + if(selected) { + toggleType = "activate"; + } else { + toggleType = "inactivate"; + } + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-child-add-confirm.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return $scope.msg; + } + } + }); + } + + // confirm Child Role Add + $scope.confirmRoleChildAdd = function(selected,availableRole,id){ + AdminService.confirmRoleChildAdd(selected,availableRole,id).then(function(msg){ + var message = msg; + $scope.cancel(); + if(message.role){ + //$rootScope.$broadcast('updateAvailbleRoles',{data:message.availableRoles}); + /*$modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + sizeClass: 'modal-small', + })*/ + }else{ + $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return msg; + } + } + }) + } + + },function(error){ + console.log("error"); + }); + } + + // confirm Child Role Remove + $scope.confirmRoleChildRemove = function(selected,availableRole,id){ + AdminService.confirmRoleChildRemove(selected,availableRole,id).then(function(msg){ + var message = msg; + $scope.cancel(); + if(message.role){ + //$rootScope.$broadcast('updateAvailbleRoles',{data:message.availableRoles}); + /*$modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + sizeClass: 'modal-small', + })*/ + }else{ + $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return msg; + } + } + }) + } + + },function(error){ + console.log("error"); + }); + } + + //role activation for role function + $scope.activateRoleConfirmPopUp = function (selected, availableRole) { + $scope.msg.roleFun = availableRole.name; + $scope.msg.selected = selected; + $scope.msg.availableRole = availableRole; + var toggleType = null; + if(selected) { + toggleType = "activate"; + } else { + toggleType = "inactivate"; + } + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-add-confirm.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return $scope.msg; + } + } + }); + } + + // confirm Role Function Add + $scope.confirmRoleFunAdd = function(selected,availableRole,id){ + AdminService.confirmRoleFunAdd(selected,availableRole,id).then(function(msg){ + var message = msg; + $scope.cancel(); + if(message.role){ + $rootScope.$broadcast('updateRoleFunctions',{data:message.role}); + /*$modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + sizeClass: 'modal-small', + })*/ + }else{ + $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return msg; + } + } + }) + } + + },function(error){ + console.log("error"); + }); + } + + // confirm Role Function Remove + $scope.confirmRoleFunRemove = function(selected,availableRole,id){ + AdminService.confirmRoleFunRemove(selected,availableRole,id).then(function(msg){ + var message = msg; + $scope.cancel(); + if(message.role){ + $rootScope.$broadcast('updateRoleFunctions',{data:message.role}); + /*$modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + sizeClass: 'modal-small', + })*/ + }else{ + $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return msg; + } + } + }) + } + + },function(error){ + console.log("error"); + }); + } + + //role activation + $scope.roleActivate = function(selected,availableRole){ + AdminService.activateRole(selected,availableRole).then(function(msg){ + var message = msg; + $scope.cancel(); + if(message.availableRoles){ + $rootScope.$broadcast('updateAvailbleRoles',{data:message.availableRoles}); + /*$modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + sizeClass: 'modal-small', + })*/ + }else{ + $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return msg; + } + } + }) + } + + },function(error){ + console.log("error"); + }); + } + + //role deletion + $scope.delRole = function(roleData){ + AdminService.delRoleList(roleData).then(function(msg){ + var message = msg; + $scope.cancel(); + if(message.availableRoles){ + $rootScope.$broadcast('updateAvailbleRoles',{data:message.availableRoles}); + /*$modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + sizeClass: 'modal-small', + })*/ + }else{ + $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return msg; + } + } + }) + } + + },function(error){ + + }); + } + + $scope.save = function (data) { + $modalInstance.close(data); + }; + + // Cancel for toggle switch on Role Fn + $scope.cancelRoleFunSwitch = function (msg) { + $scope.msg.availableRole.selected = !$scope.msg.availableRole.selected; + //$scope.msg.availableRoleFunctions[$scope.msg.availableRoleFunctions.indexOf($scope.msg.availableRole)] = $scope.selectedRoleFun; + $modalInstance.dismiss('cancel'); + }; + + // Cancel for toggle switch on Role List + $scope.cancelRoleSwitch = function (msg) { + $scope.msg.availableRole.active = !$scope.msg.availableRole.active; + $modalInstance.dismiss('cancel'); + }; + + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; + + $scope.deleteFun = function(data){ + $modalInstance.close(data); + } + }; + + $scope.successPopUp = function () { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return ''; + } + } + }); + }; + + $scope.successTestModelPopUp = function (response) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modalpopup.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-large', + resolve: { + items: function () { + var message = { + title: '', + text: response + }; + return message; + } + } + }); + }; + $scope.errorPopUp = function (msg) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return msg; + } + } + }); + }; + $scope.saveRoleFuncPopUp = function (availableRoleFunction) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-edit.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return availableRoleFunction; + } + } + }); + + modalInstance.result.then(function (data) { + $scope.saveRoleFunction(data); + }); + } + + $scope.addRoleFuncPopUp = function (availableRoleFunction) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-add.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return availableRoleFunction; + } + } + }); + + modalInstance.result.then(function (data) { + $scope.addRoleFunction(data); + }); + } + + $scope.delRoleFuncConfirmPopUp = function (availableRoleFunction) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-del-confirm.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + var message = { + title: '', + text: availableRoleFunction.name, + content: availableRoleFunction + }; + return message; + } + } + }); + + modalInstance.result.then(function (data) { + $scope.delRoleFunc(data.content); + }); + } + $scope.clearAllFuncPopUp = function () { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-confirm.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + // return availableRoleFunction; + } + } + }); + + modalInstance.result.then(function () { + $scope.clearAll(); + }); + } + + $scope.clearAll = function(){ + AdminService.clearAdminRegions().then(function(msg){ + var message = msg; + if(message.data!=null && message.data!=''){ + var status = message.data; + if(status=='"success"'){ + $scope.successTestModelPopUp(''); + $scope.getCacheRegionsList(); + }else{ + $scope.errorPopUp(); + } + } + + },function(error){ + + }); + } + $scope.showRegionDetailsFuncPopUp = function (response) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/success_modalpopup.html', + controller: ModalInstanceCtrl, + //sizeClass: 'modal-small', + resolve: { + items: function () { + var message = { + title: '', + text: response, + }; + return message; + } + } + }); + + modalInstance.result.then(function (response) { + $scope.showRegionDetails(response); + }); + } + + $scope.showRegionDetails = function(cacheName) { + AdminService.showRegionDetails(cacheName).then(function(res){ + + var message = res.data; + var msgParsed = JSON.stringify(message); + // alert('1 : '+msgParsed); + + var messaged = message.data; + var msgParsedd = JSON.stringify(messaged); + //alert('2 : '+msgParsedd); + //console.log('2 '+msgParsedd); + //console.log('4 '+msgParsedd.substr(3,msgParsedd.length -2).split('\\n')); + + + if(message.data!=null && message.data!=''){ + var status = res.status; + + + if(status==200){ + + + + var htmlstring = message.data.toString(); + var htmlStrReplace = htmlstring.replace(/['"]+/g, ''); + var htmlStrReplaceSplit = htmlStrReplace.split('\n'); + var dataStr = htmlStrReplace.replace(/\\n/g, "\n"); //htmlstring.replace(/\n/g, " "); + $scope.successTestModelPopUp(dataStr); + }else{ + $scope.errorPopUp(''); + } + } + + },function(error){ + + }); + } + + $scope.clearRegionFuncPopUp = function (cacheName) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-region-confirm.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + var message = { + title: '', + text: cacheName + }; + return message; + } + } + }); + + modalInstance.result.then(function (cacheName) { + $scope.clearRegionFunction(cacheName); + }); + } + + $scope.clearRegionFunction = function(cacheName){ + AdminService.clearRegionFunction(cacheName).then(function(msg){ + var message = msg; + if(message.data!=null && message.data!=''){ + var status = message.data; + if(status=='"success"'){ + $scope.successPopUp(); + $scope.getCacheRegionsList()(); + }else{ + $scope.errorPopUp(''); + } + } + + },function(error){ + + }); + } + + $scope.clearItemFuncPopUp = function (cacheName, key) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/clearItem-region-confirm.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + var message = { + title: '', + text: cacheName + }; + return message; + } + } + }); + + modalInstance.result.then(function (cacheName, key) { + $scope.clearItemFunction(cacheName, key); + }); + } + + $scope.clearItemFunction = function(cacheName, key){ + AdminService.clearItemnFunction(cacheName, key).then(function(msg){ + var message = msg; + if(message.data!=null && message.data!=''){ + var status = message.data; + if(status=='"success"'){ + $scope.successPopUp(); + $scope.getCacheRegionsList()(); + }else{ + $scope.errorPopUp(''); + } + } + + },function(error){ + + }); + } + + + /*$scope.showItemDetails = function(cacheName,key) { + $http.get("jcs_admin/showItemDetails?keyName="+key+"&cacheName="+cacheName).success(function(response){ + var message = "CacheName: "+ response.cacheName + +"\nkey: "+response.key + +"\nIS_SPOOL: "+response.attr.IS_SPOOL + +"\nIS_LATERAL: "+response.attr.IS_LATERAL + +"\nIS_REMOTE: "+response.attr.IS_REMOTE + +"\nIS_ETERNAL: "+response.attr.IS_ETERNAL + +"\nversion: "+response.attr.version + +"\nmaxLifeSeconds: "+response.attr.maxLifeSeconds + +"\nmaxIdleTimeSeconds: "+response.attr.maxIdleTimeSeconds + +"\nsize: "+response.attr.size + +"\ncreateTime: "+response.attr.createTime + +"\nlastAccessTime: "+response.attr.lastAccessTime + +"\nidleTime: "+response.attr.idleTime + +"\ntimeToLiveSeconds: "+response.attr.timeToLiveSeconds + +"\nisSpool: "+response.attr.isSpool + +"\nisLateral: "+response.attr.isLateral + +"\nisRemote: "+response.attr.isRemote + +"\nisEternal: "+response.attr.isEternal; + modalService.showSuccess('',message);}); + };*/ + + + $scope.showItemDetails = function(cacheName, key){ + AdminService.showItemDetails(cacheName, key).then(function(msg){ + var message = msg; + if(message.data!=null && message.data!=''){ + var status = message.data; + if(status=='"success"'){ + + $scope.successPopUp(); + $scope.getCacheRegionsList()(); + }else{ + $scope.errorPopUp(''); + } + } + + },function(error){ + + }); + } + + + //role deletion pop up + $scope.delRoleConfirmPopUp = function (availableRole) { + + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-delete-confirm.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + var message = { + availableRole:availableRole, + roleName: availableRole.name + }; + return message; + } + } + }); + + /*modalInstance.result.then(function (data) { + $scope.delRole(data); + });*/ + } + + // role activation + $scope.activateRoleConfirmPopUp = function (selected, availableRole) { + var toggleType = null; + if(selected) { + toggleType = "activate"; + } else { + toggleType = "inactivate"; + } + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-confirm-activation.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + var message = { + //availableRole: $scope.msg.availableRole, + text: toggleType, + selected:selected, + availableRole:availableRole, + roleName:availableRole.name + }; + return message; + } + } + }); + + /*modalInstance.result.then(function (data) { + $scope.activateRole(data); + });*/ + } + + $scope.roleFnInit = function(){ + AdminService.getRole($routeParams.roleId).then(function(data){ + + var j = data; + $scope.data = JSON.parse(j.data); + + $scope.role =JSON.parse($scope.data.role); + // console.log($scope.role); + + $scope.ociavailableRoleFunctions =JSON.parse($scope.data.availableRoleFunctions); + // console.log($scope.ociavailableRoleFunctions); + $scope.availableRoleFunctions=[]; + + if($scope.ociavailableRoleFunctions) + angular.forEach($scope.ociavailableRoleFunctions, function(a,i){ + var availableRoleFunction = a; + availableRoleFunction.selected = false; + angular.forEach($scope.role.roleFunctions, function(b,j){ + if(a.code === b.code) { + availableRoleFunction.selected = true; + } + }); + $scope.availableRoleFunctions.push(availableRoleFunction); + }); + + + $scope.ociavailableRoles=JSON.parse($scope.data.availableRoles); + // console.log($scope.ociavailableRoles); + //console.log("testing roles if exist"); + $scope.availableRoles=[]; + + if($scope.ociavailableRoles) + angular.forEach($scope.ociavailableRoles, function(a,i){ + var availableRole = a; + availableRole.selected = false; + if($scope.role.childRoles){ + angular.forEach($scope.role.childRoles, function(b,j){ + if(a.id === b.id) { + availableRole.selected = true; + } + }); + }; + $scope.availableRoles.push(availableRole); + }); + + + },function(error){ + console.log("roleControllerDS2 failed: " + error); + reloadPageOnce(); + }); + } + + // updating roles on role list page after deletion of a role + $rootScope.$on('updateAvailbleRoles', function(e,d){ + $scope.ociavailableRoles = d.data; + }) + + // updating role functions on roles page after deletion of a role function + $rootScope.$on('updateRoleFunctions',function(e,d){ + $scope.role = d.data; + }) + + $scope.roleFnInit(); + + $scope.saveRole = function() { + var errorMsg; + // Validate non-empty priority as integer + if ($scope.role.priority && $scope.role.priority != '' && isNaN(parseInt($scope.role.priority))) { + errorMsg = 'Priority must be an integer.'; + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return errorMsg; + } + } + }); + return; + } + for (x in $scope.availableRoles){ + // console.log($scope.availableRoles[x].name); + if ($scope.availableRoles[x].name==$scope.role.name){ + errorMsg = 'Role already exists.'; + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return errorMsg; + } + } + }); + return; + } + } + if(!errorMsg){ + var postData={ + role: $scope.role, + childRoles: $scope.role.childRoles, + roleFunctions : $scope.role.roleFunctions + }; + AdminService.saveRole(postData, $routeParams.roleId).then(function(msg){ + if(msg.role){ + //$scope.role = msg.role; + sessionStorage.setItem('addCall', true); + location.href='admin#/role/'+msg.role.id; + $scope.availableRoles.push(msg); + $scope.routeRoleId = msg.role.id; + $rootScope.$broadcast('updateAvailbleRoles',{data:$scope.availableRoles}); + //saving the addCall variable in sessionStorage to change the url from AddRole to Edit Role on success of Save and displaying the success pop up + if(sessionStorage.addCall){ + $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + sizeClass: 'modal-small' + }); + sessionStorage.removeItem('addCall'); + } + } else{ + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + msg = 'Error saving Role. Please retry'; + return msg; + } + } + }); + } + },function(error){ + console.log("error msg"); + }) + + } + } + + $scope.addNewRoleFunctionModalPopup = function(data, role,info) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-large', + resolve: { + items: function () { + var message = { + roleFunctions:data, + role:role, + roleId:info.id, + availableRoleFunctions:$scope.ociavailableRoleFunctions + }; + return message; + } + } + }); + } + + $scope.addNewChildRoleFunctionModalPopup = function(data, role,info) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-child-roles-modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-large', + resolve: { + items: function () { + var message = { + roleChildFunctions:data, + role:role, + roleId:info.id + }; + return message; + } + } + }); + } + + // remove role function associated to a role on Role Edit page + $scope.removeRoleFunction= function(roleFunction){ + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-role-del-confirm.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + var message = { + roleFunction:roleFunction + }; + return message; + } + } + }); + } + +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-menu-edit.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-menu-edit.js new file mode 100644 index 00000000..00cd92d7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-menu-edit.js @@ -0,0 +1,184 @@ +appDS2.controller('AdminMenuEditController', function ($scope, AdminMenuService, $modal, $route,AdminService){ + + $scope.showInput = true; + $scope.totalPages1 = 5; + $scope.viewPerPage1 = 8; + $scope.currentPage1 = 1; + $scope.showLoader = false; + $scope.firstPlay = true; + $scope.tableFnMenuItems = []; + $scope.$watch('viewPerPage1', function(val) { + $scope.showLoader = true; + AdminMenuService.getFnMenuItems($scope.currentPage1, val).then(function(data){ + var j = data; + $scope.data = JSON.parse(j.data); + $scope.fnMenuItems = $scope.data.fnMenuItems; + var totalItems = $scope.fnMenuItems.length; + $scope.totalPages1 = Math.ceil(totalItems / $scope.viewPerPage1); + for (x in $scope.fnMenuItems) { + if ($scope.fnMenuItems[x].active_yn=='Y') + $scope.fnMenuItems[x].active_yn=true; + else + $scope.fnMenuItems[x].active_yn=false; + } + $scope.showLoader = false; + $scope.currentPage1=1; + var endIndex = 1 * $scope.viewPerPage1; + var startIndex = endIndex - $scope.viewPerPage1; + $scope.tableFnMenuItems = $scope.fnMenuItems.slice(startIndex, endIndex); + },function(error){ + console.log('AdminMenuEditControler::$watch viewPerPage1 failed', error); + reloadPageOnce(); + }); + + }); + + $scope.customHandler1 = function(num) { + $scope.currentPage1=num; + var endIndex = num * $scope.viewPerPage1; + var startIndex = endIndex - $scope.viewPerPage1; + $scope.tableFnMenuItems = $scope.fnMenuItems.slice(startIndex, endIndex); + }; + + $scope.init = function () { + $scope.numberOfRecordstoShow=20; + AdminMenuService.getFnMenuItems().then(function(data){ + var j = data; + $scope.data =JSON.parse(j.data); + $scope.fnMenuItems =($scope.data.fnMenuItems); + },function(error){ + console.log('AdminMenuEditControler::init failed'); + }); + } + + $scope.init(); + + $scope.mapActiveStatus = function(status){ + if(status) + status = "Y"; + else + status = "N"; + return status; + }; + + $scope.addNewFnMenuItemModalPopup = function(availableFnMenuItem) { + $scope.editFnMenuItem = null; + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fnmenu-add.html', + controller: fn_menu_popupController, + resolve: { + message: function () { + var message = { + availableFnMenuItem: $scope.editFnMenuItem + }; + return message; + } + } + }); + + modalInstance.result.then(function(response){ + // console.log('response', response); + $scope.availableFnMenuItems=response.availableFnMenuItems; + $route.reload(); + }); + + }; + + $scope.removeMenuItem = function (fnMenuItem) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/admin-menu-del-confirm.html', + controller: deletefn_menu_popupController, + sizeClass: 'modal-small', + resolve: { + items: function () { + var message = { + title: '', + text: fnMenuItem.label + }; + return fnMenuItem; + } + } + }); + }; + + + $scope.editRoleFunction = null; + var dialog = null; + $scope.editRoleFunctionPopup = function(availableRoleFunction) { + $scope.editRoleFunction = availableRoleFunction; + $( "#dialog" ).dialog({ + modal: true + }); + }; + + $scope.editMenuItemModalPopup = function(availableFnMenuItem) { + $scope.editFnMenuItem = availableFnMenuItem; + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fnmenu-add.html', + controller: fn_menu_popupController, + resolve: { + message: function () { + var message = { + availableFnMenuItem: $scope.editFnMenuItem + }; + return message; + } + } + }); + + modalInstance.result.then(function(response){ + $scope.availableFnMenuItems=response.availableFnMenuItems; + $route.reload(); + }); + }; + + $scope.editRoleFunctionModalPopup = function(availableRoleFunction) { + $scope.editRoleFunction = availableRoleFunction; + var modalInstance = $modal.open({ + templateUrl: 'edit_role_function_popup.html', + controller: 'rolefunctionpopupController', + resolve: { + message: function () { + var message = { + availableRoleFunction: $scope.editRoleFunction + }; + return message; + } + } + }); + modalInstance.result.then(function(response){ + // console.log('response', response); + $scope.availableRoleFunctions=response.availableRoleFunctions; + }); + }; + + $scope.addNewRoleFunctionModalPopup = function(availableRoleFunction) { + $scope.editRoleFunction = null; + var modalInstance = $modal.open({ + templateUrl: 'edit_role_function_popup.html', + controller: 'rolefunctionpopupController', + resolve: { + message: function () { + var message = { + availableRoleFunction: $scope.editRoleFunction + }; + return message; + } + } + }); + + modalInstance.result.then(function(response){ + $scope.availableRoleFunctions=response.availableRoleFunctions; + }); + }; + + $scope.addNewRoleFunctionPopup = function() { + $scope.editRoleFunction = null; + $( "#dialog" ).dialog({ + modal: true + }); + }; + + + +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-route.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-route.js new file mode 100644 index 00000000..c7c06a7e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-route.js @@ -0,0 +1,43 @@ +appDS2.config(function($routeProvider) { + $routeProvider + .when('/net_map', { + templateUrl: 'app/fusion/scripts/DS2-view-models/DS2-sample-page/net_map.html', + controller: "netMapController" + }) + .when('/jcs_admin', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/jcs_admin.html', + controller: 'adminController' + }) + .when('/admin_menu_edit', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/admin-menu-edit.html', + controller: 'AdminMenuEditController' + }) + .when('/usage_list', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/usage.html', + controller: 'usageListControllerDS2' + }) + .when('/role_function_list', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/role-function.html', + controller : "adminController" + }) + .when('/role/:roleId', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/role.html', + controller: 'adminController' + }) + .when('/collaborate_list', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/collaborate-list.html', + controller: 'collaborateListControllerDS2' + }) + .when('/adminClosedLoop', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/admin_closed_loop.html', + controller: 'adminClosedLoopController' + }) + .when('/all', { + templateUrl: 'app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-listing.html', + controller: 'workflowsController' + }) + .otherwise({ + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/role_list.html', + controller : 'adminController' + }); +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-whitelist.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-whitelist.js new file mode 100644 index 00000000..3e82df8e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/admin-whitelist.js @@ -0,0 +1,3 @@ +appDS2.config(function ($sceDelegateProvider) { + $sceDelegateProvider.resourceUrlWhitelist(['self','**']); +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate-list-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate-list-controller.js new file mode 100644 index 00000000..670e8fc1 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate-list-controller.js @@ -0,0 +1,71 @@ +appDS2.controller("collaborateListControllerDS2", function ($scope,$http, $modal,AdminService) { + + $scope.showInput = true; + $scope.totalPages1 = 5; + $scope.viewPerPage1 = 8; + $scope.currentPage1 = 1; + $scope.showLoader = false; + $scope.firstPlay = true; + // Start with empty list to silence error in console + $scope.tableData = []; + $scope.tableCollbItems = []; + // $scope.totalPages1 = 20; + $scope.$watch('viewPerPage1', function(val) { + $scope.showLoader = true; + AdminService.getCollaborateList($scope.currentPage1, val).then(function(data){ + var j = data; + $scope.data = JSON.parse(j.data); + $scope.tableData = $scope.data; + var totalItems = $scope.tableData.length; + //console.log(totalItems); + $scope.totalPages1 = Math.ceil(totalItems / $scope.viewPerPage1); + $scope.showLoader = false; + $scope.currentPage1=1; + var endIndex = 1 * $scope.viewPerPage1; + var startIndex = endIndex - $scope.viewPerPage1; + $scope.tableCollbItems = $scope.tableData.slice(startIndex, endIndex); + },function(error){ + console.log("failed"); + reloadPageOnce(); + }); + }); + + $scope.customHandler1 = function(num) { + $scope.currentPage1=num; + var endIndex = num * $scope.viewPerPage1; + var startIndex = endIndex - $scope.viewPerPage1; + $scope.tableCollbItems = $scope.tableData.slice(startIndex, endIndex); + }; + + $scope.openCollaboration = function(chatId){ + openInNewTab('openCollaboration?chat_id=' + chatId); + } + + $scope.toggleProfileActive = function(profileId) { + modalService.popupConfirmWin("Confirm","You are about to change user's active status. Do you want to continue?", + function(){ + $http.get("profile/toggleProfileActive?profile_id="+profileId).success(function(){}); + }) + }; + +}); + +function openInNewTab(url) { + var win = window.open(url, '_blank'); + win.focus(); +}; + +function downloadScreenCaptureExtenstion() { + + var chromeURL = 'https://chrome.google.com/webstore/detail/icgmlogfeajbfdffajhoebcfbibfhaen'; + var firefoxURL = 'https://addons.mozilla.org/en-US/firefox/addon/screen-capturing-capability'; + var url; + + if(isChrome) + url = chromeURL; + else if(isFirefox) + url = firefoxURL; + + var win = window.open(url); + win.focus(); +}; diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate/collaborate.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate/collaborate.js new file mode 100644 index 00000000..fa9af088 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate/collaborate.js @@ -0,0 +1,7 @@ +app.config(function($routeProvider) { + $routeProvider + .when('/collaborate_list', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/collaborate-list.html', + controller: 'collaborateListControllerDS2' + }) +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate/workflowController.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate/workflowController.js new file mode 100644 index 00000000..c43ad8b7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborate/workflowController.js @@ -0,0 +1,490 @@ +app.controller('workflowsController', function($scope, $http, $uibModal, $log, modalService, $modal) { + + $scope.viewPerPage = 5; + $scope.scrollViewsPerPage = 20; + $scope.currentPage = 2; + $scope.totalPage; + $scope.searchCategory = ""; + $scope.searchString = ""; + $scope.radio = { + value: "" + }; + + + $scope.showModal = false; + $scope.toggleModal = function(){ + $scope.showModal = !$scope.showModal; + }; + + $scope.workflow = {}; + $scope.workflow.active = "true"; + + $scope.updateAllWorkflowStatus = function() { + angular.forEach($scope.workflows,function(value){ + $scope.checkWorkflowStatus(value); + }) + } + + $scope.fetchWorkflowsList = function() { + $http.get('workflows/list').then(function(workflowList){ + console.log('Got new list from server = ' + workflowList.data); + $scope.workflows = workflowList.data; + $scope.updateAllWorkflowStatus(); + }); + }; + + $scope.addNewWorkflow = function(newWorkflow) { + $http.post('workflows/addWorkflow/', JSON.stringify(newWorkflow)).success(function() { + $scope.fetchWorkflowsList(); + }); + + $scope.workflow.name = ''; + + }; + + $scope.updateWorkflow = function (workflowToEdit) { + //workflowToEdit.active='true'; + var modalInstance = $uibModal.open({ + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-new.html', + //size : modalSize, + controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { + $scope.workflow = workflowToEdit; + $scope.ok = function() { + console.log('Updating existing workflow ... ' + JSON.stringify($scope.workflow)); + $http.post('workflows/editWorkflow/', JSON.stringify($scope.workflow)).then(function(returnedWorkflow){ + console.log('Returned Workflow = ' + JSON.stringify(returnedWorkflow)); + $uibModalInstance.close($scope.workflow); + }); + }; + + $scope.cancel = function() { + $uibModalInstance.dismiss(); + }; + }], + //End of inner controller + resolve: { + workflow: function() { + console.log('Passing ' + JSON.stringify($scope.workflow)); + return $scope.workflow; + } + } + }); + + modalInstance.result.then(function (editedWorkFlow) { + //Need to convert to proper date - later + delete editedWorkFlow.created; + delete editedWorkFlow.updated; + + delete editedWorkFlow.createdBy; + delete editedWorkFlow.modifiedBy; + + console.log('selected Item ' + JSON.stringify(editedWorkFlow)); + $scope.$emit('workflowAdded', editedWorkFlow); + + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + }; + + $scope.reset = function(){ + console.log("Resetting ...."); + }; + + $scope.update = function(){ + console.log("updating ...."); + }; + + $scope.createWorkflow = function (modalSize) { + + var modalInstance = $uibModal.open({ + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-new.html', + size : modalSize, + controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { + $scope.workflow = {}; + $scope.workflow.active = 'true'; + $scope.ok = function() { + console.log('Saving new workflow ... ' + JSON.stringify($scope.workflow)); + $http.post('workflows/addWorkflow/', JSON.stringify($scope.workflow)).then(function(returnedWorkflow){ + console.log('Returned Workflow = ' + JSON.stringify(returnedWorkflow)); + $uibModalInstance.close($scope.workflow); + }); + }; +/* console.log(size);*/ + $scope.cancel = function() { + $uibModalInstance.dismiss(); + }; + }], + //End of inner controller + resolve: { + workflow: function() { + console.log('Passing ' + JSON.stringify($scope.workflow)); + return $scope.workflow; + } + } + }); + + modalInstance.result.then(function (newWorkflow) { + console.log('selected Item ' + JSON.stringify(newWorkflow)); + $scope.$emit('workflowAdded', newWorkflow); + + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + };//End of createWorkflow function + + + $scope.removeWorkflow = function(workflowToRemove){ + var modalInstance = $uibModal.open({ + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-remove.html', + controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { + $scope.workflowToRemove = workflowToRemove; + $scope.ok = function() { + console.log('Removing workflow ... ' + JSON.stringify($scope.workflowToRemove) + ' on client request.'); + $http.post('workflows/removeWorkflow/', JSON.stringify($scope.workflowToRemove.id)).then(function(){ + console.log('Workflow successfully removed !!!'); + $uibModalInstance.close(); + }); + }; + + $scope.cancel = function() { + $uibModalInstance.dismiss(); + }; + }] + }); + + modalInstance.result.then(function () { + $scope.$emit('workflowRemoved'); + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + + }; + + + + $scope.scheduleWorkflow = function(workflowToSchedule){ + var modalInstance = $uibModal.open({ + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-schedule.html', + size:'lg', + + controller: ['$scope', '$uibModalInstance', '$http','dateFilter', function ($scope, $uibModalInstance, $http,dateFilter) { + + $scope.workflowToSchedule = workflowToSchedule; + $scope.dt = new Date(); + $scope.dt2 = new Date(); + $scope.dateformat = 'MM/dd/yyyy', + $scope.datetimeformat = "hh:mm a"; + + $scope.recurrenceOptions =[{ + index:0, value:'One-Time', title:'One-Time' + },{ + index:1, value: 'Hourly',title:'Hourly' + },{ + index:2, value: 'Daily',title:'Daily' + },{ + index:3, value: 'Weekly',title:'Weekly' + }] + $scope.selectRecurrenceOpt = $scope.recurrenceOptions[0]; + + $scope.hours = []; + for (var i=0; i<24; i++){ + var newObj={} + newObj.index = i; + newObj.value = ""+i; + newObj.title = ""+i; + $scope.hours.push(newObj); + } + + $scope.minutes = []; + for (var i=0; i<60; i++){ + var newObj={} + newObj.index = i; + newObj.value = ""+i; + newObj.title = ""+i; + $scope.minutes.push(newObj); + } + + $scope.AMPMOptions =[ + { + index:0, value:'AM', title:'AM' + },{ + index:1, value: 'PM',title:'PM' + }] + + $scope.selectFirstHour =$scope.hours[0]; + $scope.selectFirstMinute =$scope.minutes[0]; + + $scope.selectLastHour =$scope.hours[0]; + $scope.selectLastMinute =$scope.minutes[0]; + + $scope.selectStartAMPMOption=$scope.AMPMOptions[0]; + $scope.selectLastAMPMOption=$scope.AMPMOptions[0]; + + var GenerateCronExpression = function(trigger_dt, RecurrenceOpt) { + var CRON_sec = trigger_dt.getSeconds(); + var CRON_min = trigger_dt.getMinutes(); + var CRON_hr = trigger_dt.getHours(); + var CRON_date= trigger_dt.getDate(); + var CRON_month = trigger_dt.toLocaleString('en-US', {month: 'short'}).toUpperCase(); + var CRON_day = trigger_dt.toLocaleString('en-US', {weekday: 'short'}).toUpperCase(); + var CRON_year = trigger_dt.getFullYear(); + if (RecurrenceOpt ==="One-Time") { + CRON_day = '?' + } else { + if (RecurrenceOpt ==="Hourly") { + CRON_hr = '*'; + CRON_date = '*' + CRON_month = '*' + CRON_day = '?' + CRON_year = '*' + } else if (RecurrenceOpt ==="Daily") { + CRON_date = '*' + CRON_month = '*' + CRON_day = '?' + CRON_year = '*' + } else if (RecurrenceOpt ==="Weekly") { + CRON_date = '*' + CRON_month = '*' + CRON_year = '*' + } + } + + var CRON_Expression = [CRON_sec, CRON_min, CRON_hr, CRON_date, CRON_month, CRON_day, CRON_year]; + return CRON_Expression.join(" "); + } + + $scope.ok = function() { + + // DateTime for the start time: it should be noted that the start time + // for a CRON job should be prior to the trigger time. + $scope.trigger_dt = new Date( $scope.dt.getFullYear() + + "-" + ("0"+($scope.dt.getMonth()+1)).slice(-2) + + "-" +("0"+ $scope.dt.getDate()).slice(-2) + + " " + ("0" + $scope.selectFirstHour.value).slice(-2) + + ":" +("0" + $scope.selectFirstMinute.value).slice(-2) + + ":00.0"); + + $scope.startDateTime_CRON = GenerateCronExpression($scope.trigger_dt, $scope.selectRecurrenceOpt.value) + + //roll back the the start date time by 30 seconds (start time should be 30 seconds prior to trigger time) + dt_st = new Date($scope.trigger_dt - 30*1000) + + startDateTime = dt_st.getFullYear() + + "-" + ("0"+(dt_st.getMonth()+1)).slice(-2) + + "-" +("0"+ dt_st.getDate()).slice(-2) + + " " + ("0" + dt_st.getHours()).slice(-2) + + ":" +("0" + dt_st.getMinutes()).slice(-2) + + ":" + ("0" + dt_st.getSeconds()).slice(-2) +".0"; + $scope.startDateTime = startDateTime; + + $scope.endDateTime = $scope.dt2.getFullYear() + + "-" + ("0"+($scope.dt2.getMonth()+1)).slice(-2) + + "-" +("0"+ $scope.dt2.getDate()).slice(-2) + + " " + ("0"+ $scope.selectLastHour.value).slice(-2) + + ":" +("0" + $scope.selectLastMinute.value).slice(-2) + + ":00.0" + + $scope.WorkflowScheduleObject = {}; + $scope.WorkflowScheduleObject['startDateTime_CRON'] = $scope.startDateTime_CRON; + $scope.WorkflowScheduleObject['startDateTime'] = $scope.startDateTime; + $scope.WorkflowScheduleObject['endDateTime'] = $scope.endDateTime; + $scope.WorkflowScheduleObject['workflowKey'] = $scope.workflowToSchedule.workflowKey; + $scope.WorkflowScheduleObject['recurrence'] = $scope.selectRecurrenceOpt.value; + $scope.WorkflowScheduleObject['workflow_arguments'] = "test"; + $scope.WorkflowScheduleObject['workflow_server_url'] = $scope.workflowToSchedule.runLink; + + + TimeFromNowToStart = new Date($scope.startDateTime)-new Date() + TimeStartToEnd = new Date($scope.endDateTime)-new Date($scope.startDateTime) + + if (TimeFromNowToStart<=0) { + console.log("invalid start time input") + alert("Please ensure the scheduled start date time is later than current time.") + return; + } + if (TimeStartToEnd<=0) { + console.log("invalid end time input") + alert("Please ensure the schduled end date time is later than the start time.") + return; + } + // if successful then save and close + $scope.saveCronJob($scope.WorkflowScheduleObject); + $uibModalInstance.close(); + + }; + + $scope.saveCronJob = function(cronJobData){ + + console.log('saving cron job data: ' + cronJobData); + var uuu = "workflows/saveCronJob.htm"; + var postData={cronJobDataObj: cronJobData}; + $.ajax({ + type : 'POST', + url : uuu, + //dataType: 'json', // data type expected from server + contentType: 'application/json', + data: JSON.stringify(postData), // data type sent to server + success : function(data){ + $scope.$apply(function(){ + //$scope.availableRoleFunctions=[];$scope.$apply(); + // new // $scope.availableFnMenuItems=data.availableFnMenuItems; + } + ); + //alert("Update Successful.") ; + //$scope.editRoleFunction = null; + // new /// $modalInstance.close({availableFnMenuItems:$scope.availableRoleFunctions}); + }, + error : function(data){ + alert("Error while saving."); + } + }); + + }; + + $scope.cancel = function() { + console.log("cancel triggered") + $uibModalInstance.dismiss(); + }; + }] + }); + + modalInstance.result.then(function () { + $scope.$emit('workflowRemoved'); + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + + }; + + + + + + + + + $scope.previewWorkflow = function(workflowToPreview,modalSize){ + var modalInstance = $uibModal.open({ + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-preview.html', + size:modalSize, + controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { + $scope.workflowToPreview = workflowToPreview; + console.log('previewWorkFlow invoked'); + console.log($scope.workflowToPreview); + + $scope.cancel = function() { + $uibModalInstance.dismiss(); + }; + }] + }); + + modalInstance.result.then(function () { + $scope.$emit('workflowRemoved'); + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + + }; + + + /* change work flow status based on the boolean variable "suspendBool" which corresponds whether + * we would like to suspend or activate a workflow specified by key. */ + $scope.changeWorkflowStatus = function(workflowToChangeStatus,suspendBool){ + if (workflowToChangeStatus!==null) { + var statusUrl= workflowToChangeStatus.runLink+"/engine-rest/process-definition/key/"+workflowToChangeStatus.workflowKey + var suspendedUrl= statusUrl+"/suspended" + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open('PUT', suspendedUrl, false); + xmlHttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); + xmlHttp.onload = function() { + if (suspendBool) { + console.log("process definition is now suspended"); + workflowToChangeStatus.active="false" + } else { + console.log("process definition is now activated"); + workflowToChangeStatus.active="true" + } + }; + xmlHttp.send(JSON.stringify({ + "suspended" : suspendBool, + "includeProcessInstances" : true, + "executionDate" : "2013-11-21T10:49:45" + })); + } + + }; + + $scope.activateWorkflow = function(workflowToActivate){ + $scope.changeWorkflowStatus(workflowToActivate,false) + + }; + + $scope.suspendWorkflow = function(workflowToActivate){ + $scope.changeWorkflowStatus(workflowToActivate,true) + }; + + $scope.checkWorkflowStatus = function(workflow) { + if (workflow!==null) { + var statusUrl= workflow.runLink+"/engine-rest/process-definition/key/"+workflow.workflowKey + var xmlHttp3 = new XMLHttpRequest(); + xmlHttp3.open('GET', statusUrl, true); + xmlHttp3.withCredentials = true; + xmlHttp3.send(); + xmlHttp3.onreadystatechange = function() { + if (xmlHttp3.readyState == 4 && xmlHttp3.status == 200) { + // do something with the response in the variable data + var temp = JSON.parse(xmlHttp3.responseText) + if (temp.suspended == false){ + console.log("Activated") + workflow.active="true" + } else { + console.log("Suspended") + workflow.active="false" + } + } + } + } + }; + + $scope.StartWorkflowInstance = function(workflowToStart){ + if (workflowToStart!==null) { + var statusUrl= workflowToStart.runLink+"/engine-rest/process-definition/key/"+workflowToStart.workflowKey + var suspendedUrl= statusUrl+"/submit-form" + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open('POST', suspendedUrl, false); + xmlHttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); + xmlHttp.onload = function() { + }; + xmlHttp.send(JSON.stringify({ + "variables": { + "customerId": {"value":"asdasda","type":"String"}, + "amount":{"value":"100","type":"String"} + } + })); + } + + }; + + + $scope.$on('workflowAdded', function(event, newWorkflow) { + console.log("New Workflow to be added in list scope " + JSON.stringify(newWorkflow)); + //$scope.workflows.push(newWorkflow); + $scope.fetchWorkflowsList(); + console.log('newly added workflow = ' + JSON.stringify(newWorkflow)); + }); + + $scope.$on('workflowRemoved', function(event) { + $scope.fetchWorkflowsList(); + }); + + $scope.fetchWorkflowsList(); + + + +}); + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborateList-route.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborateList-route.js new file mode 100644 index 00000000..d402fd7b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaborateList-route.js @@ -0,0 +1,19 @@ +appDS2.config(function($routeProvider) { + $routeProvider + .when('/collaborate_list', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/collaborate-list.html', + controller: 'collaborateListControllerDS2' + }) + .when('/notebook', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-page.html', + controller: 'nbookController' + }) + .when('/leafletMap', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-samplePages/leafletMap.html', + controller: 'leafletController' + }) + .when('/notebook', { + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-page.html', + controller: 'nbookController' + }) +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaboration-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaboration-controller.js new file mode 100644 index 00000000..a800c009 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/collaboration-controller.js @@ -0,0 +1,266 @@ + + +appDS2.controller('collaborationControllerDS2', function ($scope,$http, $modal) { + console.log("modal", $modal); + var popupModalService; + + }); + + + $(document).ready(function () { + + // OUTER-LAYOUT + panelLayout = $('body').layout({ + center__paneSelector: ".outer-center" + , west__paneSelector: ".outer-west" + , east__paneSelector: ".outer-east" + //, west__size: 800 + //, east__size: 125 + , spacing_open: 8 // ALL panes + , spacing_closed: 12 // ALL panes + + , center__childOptions: { + center__paneSelector: ".inner-center" + , west__paneSelector: ".inner-west" + , east__paneSelector: ".inner-east" + , west__size: 75 + , east__size: 75 + , spacing_open: 8 // ALL panes + , spacing_closed: 8 // ALL panes + , west__spacing_closed: 12 + , east__spacing_closed: 12 + } + + + + + }); + + + function initializeConnections() { + + var channelId = null; + channelId = location.href.replace(/\/|:|#|%|\.|\[|\]/g, ''); + var videoChannelId = channelId.concat("video"); + var screenChannelId = channelId.concat("screen"); + + videoConnection = new RTCMultiConnection(videoChannelId); + screenConnection = new RTCMultiConnection(screenChannelId); + + configConnection(videoConnection,true,true,false,true,false); + configConnection(screenConnection,false,false,true,false,true); + + }; + + function configConnection(_connection, _audio, _video, _screen, _data, _oneway) { + _connection.session = { + audio: _audio, // by default, it is true + video: _video, // by default, it is true + screen: _screen, + data: _data, + oneway: _oneway, + broadcast: false + }; + + _connection.direction = "one-to-one"; + + if( _data == true ) { + _connection.onmessage = function(e) { + appendDIV(e.data); + + console.debug(e.userid, 'posted', e.data); + console.log('latency:', e.latency, 'ms'); + }; + } + + + }; + + function assignStreamToDom() { + + + screenConnection.screenbody = document.querySelector('.screenContainer1'); + screenConnection.videobody = document.querySelector('.videoContainer2'); + + videoConnection.screenbody = document.querySelector('.screenContainer2'); + videoConnection.videobody = document.querySelector('.videoContainer1'); + }; + + function maximizeLayout() { + + // open the panes and maximize the window. + top.window.resizeTo(screen.availWidth,screen.availHeight); + panelLayout.open('west'); + // panelLayout.open('south'); is not working due to state initialization problem; debug to find out. so replacing the call with work around below - hack. + $(".ui-layout-toggler-south-closed").first().click(); + + }; + + function minimizeLayout() { + + // close the panes and minimize the window. + top.window.resizeTo(screen.availWidth - 2*screen.availWidth/3, screen.availHeight - screen.availHeight/2); + panelLayout.close('west'); + // panelLayout.close('south'); is not working due to state initialization problem; debug to find out. so replacing the call with work around below - hack. + $(".ui-layout-toggler-south-opened").first().click(); + }; + + function emptyContainers() { + $('.screenContainer1').empty(); + $('.videoContainer2').empty(); + + $('.screenContainer2').empty(); + $('.videoContainer1').empty(); + }; + + function appendDIV(div, parent) { + if (typeof div === 'string') { + var content = div; + div = document.createElement('div'); + div.innerHTML = content; + }; + + var chatOutput = document.getElementById('chat-output'), + fileProgress = document.getElementById('file-progress'); + + if (!parent) chatOutput.insertBefore(div, chatOutput.firstChild); + else fileProgress.insertBefore(div, fileProgress.firstChild); + + div.tabIndex = 0; + $('#chat-input').focus(); + }; + + function confirmClose() { + var message = "Are you sure you want to close the session?"; + + /* if(popupModalService != undefined) { + popupModalService.popupConfirmWin("Confirm", message, function(){ location.reload();}); + } + + else */ + if (confirm(message) == true) { + location.reload(); + //window.opener.location.reload(); // go to the parent window + //close(); + } else { + // do nothing + } + + }; + + function notifyOthers() { + + // var websocket = localStorage.getItem('notifySocket'); + //if( websocket != null) { + // handling websocket peer broadcast session + var currentUser = "${sessionScope.user.sbcid}"; + var initialPageVisit = "${sessionScope.initialPageVisit}"; + var remoteUser = ''; + + var userList = location.search.split('chat_id=')[1].split('-'); + for(var i=0;i-1) { + $scope.showBackButton = true; + $scope.parentReportUrlParams = $routeParams.reportUrlParams.substring($routeParams.reportUrlParams.indexOf("parent___params===")+18); + $scope.currentReportUrlParams = $routeParams.reportUrlParams.substring(0,$routeParams.reportUrlParams.indexOf("parent___params===")); + } else { + $scope.currentReportUrlParams = $routeParams.reportUrlParams; + } + console.log($routeParams.reportUrlParams); + var parseQueryString = function( queryString ) { + var params = {}, queries, temp, i, l; + // Split into key/value pairs + queries = queryString.split("&"); + // Convert the array of strings into an object + for ( i = 0, l = queries.length; i < l; i++ ) { + temp = queries[i].split('='); + //console.log(temp[0]); + //console.log(temp[0] != "refresh"); + if(temp[0] && temp[0] != "refresh") + params[temp[0]] = temp[1]; + } + return params; + }; + + var convertQueryString = function(queryString) { + var keys = ""; var str = ""; + keys = Object.keys(queryString); + //console.log(keys); + for ( i = 0, l = keys.length; i < l; i++ ) { + str += keys[i]+"="+queryString[keys[i]] + "&"; + + } + return str; + //queryString = + } + + + + + $scope.urlParams = parseQueryString($scope.currentReportUrlParams); + + $scope.reportChartURL = 'report#/report_chart_wizard/'+$scope.urlParams.c_master; + + $scope.reportEditURL = 'report_wizard.htm?action=report.edit&c_master='+$scope.urlParams.c_master; + + + $http.get('raptor.htm?action=report.run.container&'+$scope.currentReportUrlParams).then( + function(response){ + console.log(response); + $scope.isInProgress = false; + $scope.reportData = response.data; + console.log('reportData report run container response',$scope.reportData); + if ($scope.reportData.reportTitle) { + $scope.reportData.reportHeading = $scope.reportData.reportTitle; + if ($scope.reportData.reportSubTitle) { + $scope.reportData.reportSubTitle = $scope.reportData.reportSubTitle; + } + } + else + $scope.reportData.reportHeading = $scope.reportData.reportName; + if(!$scope.urlParams.hideChart && $scope.reportData.chartAvailable && $scope.reportData.totalRows>1){ + console.log('raptor.htm?action=chart.run&'+convertQueryString($scope.urlParams)); + $http.get('raptor.htm?action=chart.run&'+convertQueryString($scope.urlParams)).then( + function(response){ + $scope.showChart = true; + document.getElementById('chartiframe').contentWindow.document.write(response.data); + document.getElementById('chartiframe').contentWindow.document.close(); + }); + } + + if($scope.reportData.displayForm && $scope.reportData.formFieldList && $scope.reportData.formFieldList.length>0 && !$scope.urlParams.hideFormFields){ + $scope.showFormFields = true; + } + }); + $scope.getFormFieldSelectedValuesAsURL = function(){ + var formFieldsUrl = ''; + $scope.reportData.formFieldList.forEach(function(formField) { + if(formField.fieldType==='LIST_BOX') { + if($scope.formFieldSelectedValues && $scope.formFieldSelectedValues[formField.fieldId] && $scope.formFieldSelectedValues[formField.fieldId].value != '') { + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId].value+'&'; + } + } else if(formField.fieldType==='LIST_MULTI_SELECT') { + if($scope.formFieldSelectedValues[formField.fieldId].length >0) { + for (var i = 0; i < $scope.formFieldSelectedValues[formField.fieldId].length; i++) { + if($scope.formFieldSelectedValues[formField.fieldId][i].defaultValue){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId][i].value+'&'; + } + } + } + } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && formField.validationType === 'DATE'){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+dateFilter($scope.formFieldSelectedValues[formField.fieldId],$scope.dateformat)+'&'; + } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && formField.validationType === 'TIMESTAMP_MIN'){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+dateFilter($scope.formFieldSelectedValues[formField.fieldId],$scope.datetimeformat)+'&'; + } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && $scope.formFieldSelectedValues[formField.fieldId] && $scope.formFieldSelectedValues[formField.fieldId] != ''){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId]+'&'; + } + }); + return formFieldsUrl; + + } + + $scope.runReport = function(pagination){ + var formFieldsUrl = $scope.getFormFieldSelectedValuesAsURL(); + /*if ($scope.reportData.reportTitle) + $scope.reportData.reportHeading = $scope.reportData.reportTitle; + else + $scope.reportData.reportHeading = $scope.reportData.reportName;*/ + + console.log("pagination"); + if(!pagination) { + //console.log("refreshed ..."); + $scope.gridOptions.pageNumber = 1; + paginationOptions.pageNumber = 1; + paginationOptions.pageSize = $scope.reportData.pageSize; + //console.log($scope.gridOptions); + $scope.gridOptions.paginationCurrentPage = 1; + $scope.gridOptions.paginationPageSizes= [$scope.reportData.pageSize]; + $scope.gridOptions.paginationPageSize= $scope.reportData.pageSize; + if($scope.reportData.totalRows<14){ + $scope.gridHeight = ($scope.reportData.totalRows+7)*30+'px'; + } else{ + $scope.gridHeight = '400px'; + } + $scope.gridOptions.totalItems = $scope.reportData.totalRows; + $scope.gridOptions.data= $scope.reportData.reportDataRows; + $scope.gridOptions.exporterPdfHeader.text= $scope.reportData.reportName; + + } + $scope.currentReportUrlParams = 'c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'&display_content=Y&r_page='+(paginationOptions.pageNumber-1); + console.log('raptor.htm?action=report.run.container&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)); + $http.get('raptor.htm?action=report.run.container&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)).then( + function(response){ + $scope.reportData = response.data; + if ($scope.reportData.reportTitle) { + $scope.reportData.reportHeading = $scope.reportData.reportTitle; + if ($scope.reportData.reportSubTitle) { + $scope.reportData.reportSubTitle = $scope.reportData.reportSubTitle; + } + } + else + $scope.reportData.reportHeading = $scope.reportData.reportName; + + if($scope.reportData.errormessage) { + //console.log($scope.reportData); + var stacktraceFP = $scope.reportData.stacktrace.substring(0, $scope.reportData.stacktrace.indexOf(":")+1); + document.getElementById('errorDiv').innerHTML = stacktraceFP + " " + $scope.reportData.errormessage; + //console.log(document.getElementById('errorDiv').innerHtml); + //console.log(stacktraceFP + " " + $scope.reportData.errormessage); + } + if(!pagination) { + if(!$scope.urlParams.hideChart && $scope.reportData.chartAvailable && $scope.reportData.totalRows>1){ + console.log('raptor.htm?action=chart.run&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'display_content=Y&r_page='+(paginationOptions.pageNumber-1)); + $http.get('raptor.htm?action=chart.run&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'display_content=Y&r_page='+(paginationOptions.pageNumber-1)).then( + function(response) { + console.log(response.data); + $scope.showChart = true; + console.log('response.data',response.data); + document.getElementById('chartiframe').contentWindow.document.write(response.data); + document.getElementById('chartiframe').contentWindow.document.close(); + }); + } else { + $scope.showChart = false; + } + } + if($scope.reportData.displayForm && $scope.reportData.formFieldList && $scope.reportData.formFieldList.length>0 && !$scope.urlParams.hideFormFields && !$scope.reportData.hideFormFieldsAfterRun){ + $scope.showFormFields = true; + } else { + $scope.showFormFields = false; + } + }); + }; + + var paginationOptions = { + pageNumber: 1, + pageSize: 5, + sort: null + }; + + var correctTotalPaginationTemplate = + //same as normal template, but fixed totals: {{(((grid.options.paginationCurrentPage-1)*grid.options.paginationPageSize)+1)}} {{(grid.options.paginationCurrentPage*grid.options.paginationPageSize>grid.options.totalItems?grid.options.totalItems:grid.options.paginationCurrentPage*grid.options.paginationPageSize)}} + "
    0\">/ {{ paginationApi.getTotalPages() }}
    1\"> {{sizesLabel}}
    {{grid.options.paginationPageSize}} {{sizesLabel}}
    0\">{{(((grid.options.paginationCurrentPage-1)*grid.options.paginationPageSize)+1)}} - {{(grid.options.paginationCurrentPage*grid.options.paginationPageSize>grid.options.totalItems?grid.options.totalItems:grid.options.paginationCurrentPage*grid.options.paginationPageSize)}} {{paginationOf}} {{grid.options.totalItems}} {{totalItemsLabel}}
    "; + + $scope.gridOptions = { + pageNumber: 1, + sort : null, + paginationPageSizes: [5], + paginationPageSize: 5, + paginationTemplate: correctTotalPaginationTemplate, + columnDefs: [], + data: [], + enableGridMenu: true, + enableSelectAll: true, + gridMenuCustomItems : [ + { title : 'All Reports', + action : function($event) { + $window.open('report.htm','_self'); + }, order : 210 }, + { title : 'Edit Report', + action : function($event) { + $window.open($scope.reportEditURL,'_self'); + }, order : 211 }, + { title : 'Export All data as Excel 2007', + action : function($event) { + $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.excel2007.session','_self'); + }, order : 212 }, + { title : 'Export All data as Excel', + action : function($event) { + $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.excel.session','_self'); + }, order : 213 }, + { title : 'Export All data as CSV', + action : function($event) { + $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.csv.session','_self'); + }, order : 214 }, + { title : 'Export All data as PDF', + action : function($event) { + $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.pdf.session','_self'); + }, order : 215 } ], + exporterMenuPdf: false, + exporterMenuCsv: false, + exporterCsvFilename: 'myFile.csv', + exporterPdfDefaultStyle: {fontSize: 9}, + exporterPdfTableStyle: {margin: [30, 30, 30, 30]}, + exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'}, + exporterPdfHeader: { text: "My Header", style: 'headerStyle' }, + exporterPdfFooter: function ( currentPage, pageCount ) { + return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' }; + }, + exporterPdfCustomFormatter: function ( docDefinition ) { + docDefinition.styles.headerStyle = { fontSize: 22, bold: true }; + docDefinition.styles.footerStyle = { fontSize: 10, bold: true }; + return docDefinition; + }, + exporterPdfOrientation: 'portrait', + exporterPdfPageSize: 'LETTER', + exporterPdfMaxGridWidth: 500, + exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")), + onRegisterApi: function(gridApi) { + $scope.gridApi = gridApi; + gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) { + paginationOptions.pageNumber = newPage; + paginationOptions.pageSize = pageSize; + $scope.runReport(true); + }); + } + }; + + $scope.uiGridRefresh = function(){ + var columnDefsArray = []; + var columnFreezeEndColumn = $scope.reportData.colIdxTobeFreezed; + var doColumnNeedToFreeze = false; + if(columnFreezeEndColumn && columnFreezeEndColumn.length>0) { + doColumnNeedToFreeze = true; + } + $scope.reportData.reportDataColumns.forEach(function(entry) { + var tempColumnDef = { displayName: entry.columnTitle, field: entry.colId, enableSorting: entry.sortable, + sortingAlgorithm: function(a, b) { + return rowSorter.sortAlpha(a.displayValue, b.displayValue); + }, + cellTemplate: '
    '+ + '
    {{COL_FIELD.displayValue}}
    ' + + ' {{COL_FIELD.displayValue}}' + + '
    '}; + if(entry.columnWidth && entry.columnWidth!='null' && entry.columnWidth!='pxpx' && entry.columnWidth!='nullpx' && entry.columnWidth!='nullpxpx'){ + tempColumnDef['minWidth'] = entry.columnWidth.substring(0, entry.columnWidth.length - 2); + } else { + tempColumnDef['minWidth'] = '100'; + } + if(doColumnNeedToFreeze) { + tempColumnDef['pinnedLeft']= true; + if(columnFreezeEndColumn === entry.colId){ + doColumnNeedToFreeze = false; + } + } + columnDefsArray.push(tempColumnDef); + }); + + $scope.gridOptions.paginationPageSizes= [$scope.reportData.pageSize]; + $scope.gridOptions.paginationPageSize= $scope.reportData.pageSize; + if($scope.reportData.totalRows<14){ + $scope.gridHeight = ($scope.reportData.totalRows+5)*30+'px'; + }else{ + $scope.gridHeight = '400px'; + } + $scope.gridOptions.totalItems = $scope.reportData.totalRows; + $scope.gridOptions.columnDefs= columnDefsArray; + $scope.gridOptions.data= $scope.reportData.reportDataRows; + $scope.gridOptions.exporterPdfHeader.text= $scope.reportData.reportName; + }; + + $scope.$watch("reportData",function(newValue,oldValue) { + if(!$scope.urlParams.hideGrid){ + if($scope.reportData){ + if($scope.reportData.displayData && $scope.reportData.reportDataColumns){ + $scope.showGrid = true; + $scope.uiGridRefresh(); + } + } + } + }); + + $scope.triggerOtherFormFields = function(){ + console.log("report_run"); + var formFieldsUrl = $scope.getFormFieldSelectedValuesAsURL(); + $http.get('raptor.htm?action=report.formfields.run.container&c_master='+$scope.reportData.reportID+'&'+formFieldsUrl).then( + function(response){ + $scope.reportData = response.data; + }); + }; + $timeout(function() { + $rootScope.isViewRendering = false; + }); +}]); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-search-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-search-controller.js new file mode 100644 index 00000000..1e01a297 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-search-controller.js @@ -0,0 +1,184 @@ +appDS2.requires.push('ui.grid'); +appDS2.requires.push('ui.grid.pagination'); +appDS2.controller("reportSearchController", ['$scope','$rootScope','$http','$timeout','uiGridConstants','$modal','$q','$log','raptorReportFactory',function ($scope,$rootScope,$http,$timeout,uiGridConstants,$modal,$q,$log,raptorReportFactory) { + + $scope.getSearchData = function(){ + raptorReportFactory.getSearchData().then(function(data){ + $scope.searchdData = data; + },function(error){ + $log.error("raptorReportFactory: getSearchData failed."); + }); + } + + $scope.getSearchData(); + + $scope.runReport = function(){ + var searchParams = ''; + if($scope.reportId && $scope.reportId!=''){ + searchParams = '&rep_id='+$scope.reportId+'&rep_id_options='+$scope.operatorRepId.index; + } + if($scope.reportName && $scope.reportName!=''){ + searchParams = searchParams+'&rep_name='+$scope.reportName+'&rep_name_options='+$scope.operatorRepName.index; + } + + var pageSearchParameter = ($scope.paginationOptions.pageNumber-1)+searchParams + raptorReportFactory.getSearchDataAtPage(pageSearchParameter).then(function(data){ + $scope.searchdData = data + },function(error){ + $log.error("raptorReportFactory: getSearchDataAtPage failed."); + }); + }; + + + $scope.paginationOptions = { + pageNumber: 1, + pageSize: 5, + sort: null + }; + + var correctTotalPaginationTemplate = + //same as normal template, but fixed totals: {{(((grid.options.paginationCurrentPage-1)*grid.options.paginationPageSize)+1)}} {{(grid.options.paginationCurrentPage*grid.options.paginationPageSize>grid.options.totalItems?grid.options.totalItems:grid.options.paginationCurrentPage*grid.options.paginationPageSize)}} + "
    0\">/ {{ paginationApi.getTotalPages() }}
    1\"> {{sizesLabel}}
    {{grid.options.paginationPageSize}} {{sizesLabel}}
    0\">{{(((grid.options.paginationCurrentPage-1)*grid.options.paginationPageSize)+1)}} - {{(grid.options.paginationCurrentPage*grid.options.paginationPageSize>grid.options.totalItems?grid.options.totalItems:grid.options.paginationCurrentPage*grid.options.paginationPageSize)}} {{paginationOf}} {{grid.options.totalItems}} {{totalItemsLabel}}
    "; + + $scope.gridOptions = { + paginationPageSizes: [5], + paginationPageSize: 5, + paginationTemplate: correctTotalPaginationTemplate, + columnDefs: [], + data: [], + enableGridMenu: true, + enableSelectAll: true, + exporterMenuPdf: false, + exporterMenuCsv: false, + exporterCsvFilename: 'myFile.csv', + exporterPdfDefaultStyle: {fontSize: 9}, + exporterPdfTableStyle: {margin: [30, 30, 30, 30]}, + exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'}, + exporterPdfHeader: { text: "My Header", style: 'headerStyle' }, + exporterPdfFooter: function ( currentPage, pageCount ) { + return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' }; + }, + exporterPdfCustomFormatter: function ( docDefinition ) { + docDefinition.styles.headerStyle = { fontSize: 22, bold: true }; + docDefinition.styles.footerStyle = { fontSize: 10, bold: true }; + return docDefinition; + }, + exporterPdfOrientation: 'portrait', + exporterPdfPageSize: 'LETTER', + exporterPdfMaxGridWidth: 500, + exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")), + onRegisterApi: function(gridApi) { + gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) { + $scope.paginationOptions.pageNumber = newPage; + $scope.paginationOptions.pageSize = pageSize; + $scope.runReport(); + }); + } + }; + + + var getPage = function() { + $scope.gridOptions.columnDefs = []; + $scope.searchdData.columns[0].forEach(function(entry) { + if(entry.columnTitle=='Run'){ + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId, enableSorting: false, + cellTemplate: '
    ' + }); + } else if(entry.columnTitle=='Edit'){ + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId, enableSorting: false, + cellTemplate: '
    ' + }); + } else if(entry.columnTitle=='Delete'){ + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId, enableSorting: false, + cellTemplate: '
    ' + }); + } else if(entry.columnTitle=='Copy'){ + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId, enableSorting: false, + cellTemplate: '
    ' + }); + } else if(entry.columnTitle=='Schedule'){ + } else if(entry.columnTitle=='No'){ + } else { + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId, + enableSorting: true, + cellTemplate: '
    {{COL_FIELD.displayValue}}
    ' + }); + } + }); + + $scope.gridOptions.paginationPageSizes= [$scope.searchdData.metaReport.pageSize]; + $scope.gridOptions.paginationPageSize= $scope.searchdData.metaReport.pageSize; + $scope.gridOptions.totalItems = $scope.searchdData.metaReport.totalSize; + + $scope.gridOptions.data = []; + $scope.searchdData.rows[0].forEach(function(entry) { + var localData = {}; + entry.forEach(function(rowData){ + localData[rowData["columnId"]]= rowData["searchresultField"]; + }); + $scope.gridOptions.data.push(localData); + }); + }; + + $scope.$watch("searchdData",function(newValue,oldValue) { + if($scope.searchdData){ + getPage(); + } + }); + + $scope.operatorsRepId = [ + {index: 0, value: 'Equal To', text: 'Equal To', alias:'Equal To'}, + {index: 1, value: 'Less Than', text: 'Less Than', alias:'Less Than'}, + {index: 2, value: 'Greater Than', text: 'Greater Than', alias:'Greater Than'}]; + $scope.operatorRepId = {}; + $scope.operatorRepId.value = $scope.operatorsRepId[0].value; + $scope.operatorRepId.index = $scope.operatorsRepId[0].index; + + $scope.operatorsRepName = [ + {index: 0, value: 'Starts With', text: 'Starts With', alias:'Starts With'}, + {index:1, value: 'Ends With', text: 'Ends With', alias:'Ends With'}, + {index: 2, value: 'Contains', text: 'Contains', alias:'Contains'}]; + + $scope.operatorRepName = {}; + $scope.operatorRepName.value = $scope.operatorsRepName[0].value; + $scope.operatorRepName.index = $scope.operatorsRepName[0].index; + + $scope.removeReport = function(reportDeleteUrl,row) { + var modalInstance = $modal.open({ + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-del-confirm.html', + sizeClass: 'modal-small', + controller: ['$scope', '$modalInstance', '$http', '$log','raptorReportFactory', function ($scope, $modalInstance, $http, $log, raptorReportFactory) { + $scope.ok = function() { + raptorReportFactory.getReportDeleteStatus(reportDeleteUrl).then(function(data){ + if (!(data.deleted)) { + $log.error("raptorReportFactory: report removal failed.") + } + $modalInstance.close(); + },function(error){ + $log.error("report removal error.") + }); + }; + + $scope.cancel = function() { + $modalInstance.dismiss(); + }; + }] + }); + + modalInstance.result.then(function () { + $scope.$emit('RefreshGridOptions'); + }, function () { + }); + }; + + $scope.$on('RefreshGridOptions', function(event) { + $scope.getSearchData(); + }); + + $timeout(function() { + $rootScope.isViewRendering = false; + }); + + +}]); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-step-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-step-controller.js new file mode 100644 index 00000000..6133fe64 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-controllers/ds2-reports/report-step-controller.js @@ -0,0 +1,900 @@ +appDS2.controller('reportStepController', function($scope,$http,$location, $routeParams, $q, $modal,$log,$window, raptorReportFactory, stepFormFactory, DOMHelper) { + + // tabs for report wizard steps: + $scope.activeTabsId = 'Definition'; + + // For all the dropdown box, please declare the active selection variable in the following manner: + // $scope.selectedOpt = {}; + // $scope.selectedOpt.value = ""; + $scope.getDefinitionById = function(id) { + raptorReportFactory.getDefinitionByReportId(id).then(function(data){ + $scope.loadDefinition(data); + $scope.definitionData = data; + },function(error){ + $log.error("raptorReportFactory: getSearchData failed."); + }); + } + + + $scope.createNewDefinition = function() { + raptorReportFactory.createNewDefinition().then(function(data){ + $scope.loadDefinition(data); + $scope.definitionData = data; + },function(error){ + $log.error("raptorReportFactory: getSearchData failed."); + }); + } + + var initializeCreateReport = function() { + $scope["selectedReportType"] ={}; + $scope.selectedReportType.value ="linear"; + $scope.selectedReportType2 ={}; + $scope.selectedReportType2.value =""; + $scope.selectedDataSource ={}; + $scope.selectedDataSource.value="local"; + $scope.sqlScript = "SELECT "; + $scope.pageSize = {"value":"50"}; + } + + + var loadSqlInSession = function(){ + raptorReportFactory.getSqlInSession().then(function(data){ + $scope.sqlInSessionJSON = data; + $scope.sqlScript = data.query; + },function(error){ + $log.error("raptorReportFactory: getSearchData failed."); + }); + }; + + initializeCreateReport(); + if ($routeParams.reportMode) { + if ($routeParams.reportMode=="copy") { + raptorReportFactory.copyReportById($routeParams.reportId).then(function(data){ + $scope.$emit('RefreshInsession'); + },function(error){ + $log.error("raptorReportFactory: deleteFormFieldById failed."); + }); + } else if ($routeParams.reportMode=="import") { + $scope.$emit('RefreshInsession'); + } + } else if ($routeParams.reportId) { + $scope.getDefinitionById($routeParams.reportId); + $scope.isEdit = true; + $scope.reportId = $routeParams.reportId; + } else { + $scope.isEdit = false; + $scope.createNewDefinition(); + } + + + $scope.RunCurrentReport = function (){ + $window.location.href = "#/report_run/c_master="+$scope.reportId+"&refresh=Y"; + } + + $scope.deleteFormField = function(rowData) { + var modalInstance = $modal.open({ + scope: $scope, + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-formfield-del-confirm.html', + sizeClass: 'modal-large', + controller: ['$scope', '$modalInstance', '$http', '$log','raptorReportFactory','rowData', function ($scope, $modalInstance, $http, $log, raptorReportFactory, rowData) { + $scope.tempFieldId = rowData.id; + $scope.ok = function() { + raptorReportFactory.deleteFormFieldById(rowData.id).then(function(data){ + $modalInstance.close(); + },function(error){ + $log.error("raptorReportFactory: deleteFormFieldById failed."); + }); + } + $scope.cancel = function() { + $modalInstance.dismiss(); + }; + }], + resolve:{ + rowData: function(){ + return rowData; + } + } + }); + modalInstance.result.then(function () { + $scope.$emit('RefreshFormField'); + }, function () { + }); + } + + $scope.loadDefinition = function(definitionData) { + $scope.reportId = definitionData.reportId+""; + $scope.reportName = definitionData.reportName; + $scope.reportDescr = definitionData.reportDescr; + $scope.formHelpText = definitionData.formHelpText; + $scope.selectedPageSize = {"value": definitionData.pageSize+''}; + $scope.selectedMaxRowsInExcelCSVDownload = {"value": definitionData.maxRowsInExcelCSVDownload}; + $scope.reportTitle = definitionData.reportTitle; + $scope.reportSubTitle = definitionData.reportSubTitle; + $scope.selectedNumFormCols ={"value": definitionData.numFormCols+''}; + $scope.selectedFrozenColumns={"value": definitionData.frozenColumns+''}; + $scope.selectedDataGridAlign = {"value":definitionData.dataGridAlign+''}; + $scope.emptyMessage = definitionData.emptyMessage+''; + $scope.selectedDataContainerHeight = {"value":definitionData.dataContainerHeight+''}; + $scope.selectedDataContainerWidth = {"value":definitionData.dataContainerWidth+''}; + var displayAreaValue = "null" + for (var i=0; i<3; i++ ) { + if (definitionData.displayArea[i].selected) { + displayAreaValue = definitionData.displayArea[i].name; + } + } + $scope.selectedDisplayArea = {"value":displayAreaValue+""}; + + $scope.hideFormFieldsAfterRunSelected = {"value": definitionData.hideFormFieldsAfterRun} + + $scope.hideFormFieldsSelected = {"value":definitionData.displayOptions[0].selected}; + $scope.hideChartSelected = {"value":definitionData.displayOptions[1].selected}; + $scope.hideReportDataSelected = {"value":definitionData.displayOptions[2].selected}; + $scope.hideExcelSelected = {"value":definitionData.displayOptions[3].selected}; + $scope.hidePdfSelected = {"value":definitionData.displayOptions[4].selected}; + $scope.runtimeColSortDisabled = {"value":definitionData.runtimeColSortDisabled}; + } + + + var setDefinition = function(){ + $scope.updatedDefJson = { + "tabName" : "Definition", + "tabId" : "Def", + "reportId" : ($scope.isEdit?$scope.reportId+'':"-1"), + "reportName" : $scope.reportName, + "reportDescr" : $scope.reportDescr, + "reportType" : "Linear", + "dbInfo" : "local", + "formHelpText" : $scope.formHelpText, + "pageSize" : Number($scope.selectedPageSize.value), + "displayArea" : [ { + "id" : "HOME", + "name" : "HOME", + "selected" : ($scope.selectedDisplayArea.value=="HOME") + }, { + "id" : "CUSTOMER", + "name" : "CUSTOMER", + "selected" : ($scope.selectedDisplayArea.value==="CUSTOMER") + }, { + "id" : "REPORTS", + "name" : "REPORTS", + "selected" : ($scope.selectedDisplayArea.value==="REPORTS") + } ], + "hideFormFieldsAfterRun" : $scope.hideFormFieldsAfterRunSelected.value, + "maxRowsInExcelCSVDownload" : Number($scope.selectedMaxRowsInExcelCSVDownload.value), + "frozenColumns" : Number($scope.selectedFrozenColumns.value), + "dataGridAlign" : $scope.selectedDataGridAlign.value, + "emptyMessage" : $scope.emptyMessage, + "dataContainerHeight" : $scope.selectedDataContainerHeight.value, + "dataContainerWidth" : $scope.selectedDataContainerWidth.value, + "displayOptions" : [ { + "name" : "HideFormFields", + "selected" : $scope.hideFormFieldsSelected.value + }, { + "name" : "HideChart", + "selected" : $scope.hideChartSelected.value + }, { + "name" : "HideReportData", + "selected" : $scope.hideReportDataSelected.value + }, { + "name" : "HideExcel", + "selected" : $scope.hideExcelSelected.value + }, { + "name" : "HidePdf", + "selected" : $scope.hidePdfSelected.value + } ], + "runtimeColSortDisabled" : $scope.runtimeColSortDisabled.value, + "numFormCols" : Number($scope.selectedNumFormCols.value), + "reportTitle" : $scope.reportTitle, + "reportSubTitle" : $scope.reportSubTitle + } + + } + + var updateDefinitionData = function() { + setDefinition(); + raptorReportFactory.updateDefinition($scope.updatedDefJson,$scope.isEdit).then(function(data){ + },function(error){ + $log.error("raptorReportFactory: updateDefinition by Id failed."); + }); + } + + var saveNewDefinitionData = function() { + setDefinition(); + raptorReportFactory.saveNewDefinition($scope.updatedDefJson).then(function(data){ + },function(error){ + $log.error("raptorReportFactory: saveNewDefinition by Id failed."); + }); + } + + $scope.testRunSql = function(){ + var queryJSON = {query: $scope.sqlScript}; + queryJSON = JSON.stringify(queryJSON); + raptorReportFactory.testRunSQL(queryJSON).then(function(data){ + var modalInstance = $modal.open({ + scope: $scope, + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-test-run-sql.html', + sizeClass: 'modal-large', + controller: ['$scope', '$modalInstance', '$http', '$log','raptorReportFactory','queriedData', function ($scope, $modalInstance, $http, $log, raptorReportFactory, queriedData) { + var init = function() { + $scope.isError = false; + if (queriedData.errormessage) { + $scope.isError = true; + $scope.errormessage = queriedData.errormessage; + $scope.stacktrace = queriedData.stacktrace; + } else { + $scope.queryData = queriedData; + } + } + init(); + $scope.close = function() { + $modalInstance.dismiss(); + }; + }], + resolve:{ + queriedData: function(){ + return data; + } + } + }) + + },function(error){ + $log.error("raptorReportFactory: test run SQL failed."); + }); + } + + + $scope.formFieldVerifySQL= function(sqlScript){ + var queryJSON = {query: sqlScript}; + queryJSON = JSON.stringify(queryJSON); + raptorReportFactory.formFieldVerifySQL(queryJSON).then(function(data){ + var modalInstance = $modal.open({ + scope: $scope, + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-test-run-sql.html', + sizeClass: 'modal-large', + controller: ['$scope', '$modalInstance', '$http', '$log','raptorReportFactory','queriedData', function ($scope, $modalInstance, $http, $log, raptorReportFactory, queriedData) { + var init = function() { + $scope.isError = false; + if (queriedData.errormessage) { + $scope.isError = true; + $scope.errormessage = queriedData.errormessage; + $scope.stacktrace = queriedData.stacktrace; + } else { + $scope.queryData = queriedData; + } + } + init(); + $scope.close = function() { + $modalInstance.dismiss(); + }; + }], + resolve:{ + queriedData: function(){ + return data; + } + } + }) + + },function(error){ + $log.error("raptorReportFactory: test run SQL failed."); + }); + } + + + /* $scope.selectedDataSource.allowSchedule={}; + $scope.selectedDataSource.allowSchedule.value=""*/ + + var getJsonSrcName = function(stepNum){ + var JsonSrcPrefix = "app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step" + return JsonSrcPrefix + stepNum +".json"; + } + + $scope.gTabs = [ + { + title: 'Definition', + id: 'Definition', + uniqueId: 'uniqueTab1x', + tabPanelId: 'threetab1x' + }, { + title: 'SQL', + id: 'SQL', + uniqueId: 'uniqueTab2x', + tabPanelId: 'threetab2x', + disabled: (!$scope.isEdit) + }, { + title: 'Columns', + id: 'Columns', + uniqueId: 'uniqueTab3x', + tabPanelId: 'threetab3x', + disabled: (!$scope.isEdit) + }, { + title: 'Form Fields', + id: 'Form Fields', + uniqueId: 'uniqueTab4x', + tabPanelId: 'threetab4x', + disabled: (!$scope.isEdit) + }, { + title: 'Run', + id: 'Run', + uniqueId: 'uniqueTab5x', + tabPanelId: 'threetab5x', + disabled: (!$scope.isEdit) + } + ]; + + $scope.unhideAllOtherTabs = function(){ + for (var selectedTab = 0; selectedTab < $scope.gTabs.length; selectedTab++) { + $scope.gTabs[selectedTab].disabled = false; + } + } + + $scope.openColumnPopup = function (rowData) { + var modalInstance = $modal.open({ + scope: $scope, + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-col-edit.html', + sizeClass: 'modal-large', + controller: ['$scope', '$modalInstance', '$http', '$log','raptorReportFactory','colData', function ($scope, $modalInstance, $http, $log, raptorReportFactory, colData) { + raptorReportFactory.getColumnEditInfoById(colData.id).then(function(data){ + $scope.columnEditData = data; + $scope.colId = data.colId; +/* $scope.colName = data.colName;*/ + $scope.colName = {'value':data.colName+''}; + $scope.selectedDisplayAlignment = {"value":data.displayAlignment+''}; + $scope.selectedDisplayHeaderAlignment = {"value":data.displayHeaderAlignment+''}; + $scope.sortable = {"value":''+data.sortable}; + $scope.visible = {"value":''+data.visible}; + $scope.drilldownURL = data.drilldownURL; + $scope.drilldownParams = data.drilldownParams; + $scope.drilldownType = data.drilldownType; + },function(error){ + $log.error("raptorReportFactory: getColumnEditInfoById failed."); + }); + + var init = function() { +/* $scope.colTableRowData = colData;*/ + $scope.displayAlignmentOptions = [ + {value:"null", text:""}, + {value:"Left", text:"Left"}, + {value:"Center", text:"Center"}, + {value:"Right", text:"Right"} + ]; + $scope.ynOptions = [ + {value:"true", text:"Yes"}, + {value:"false", text:"No"} + ]; + $scope.drillDownOptions = [ + {value:"drillDownOpt1", text:"drillDownOpt1"}, + {value:"drillDownOpt2", text:"drillDownOpt2"}, + {value:"drillDownOpt3", text:"drillDownOpt3"} + ]; + } + + init(); + + $scope.save = function() { + var colInfo = { + "tabId" : "ColEdit", + "tabName" : "Column Edit", + "colId" : $scope.colId, + "colName" : $scope.colName.value, + "displayAlignment" : ($scope.selectedDisplayAlignment.value=="null")?null:$scope.selectedDisplayAlignment.value, + "displayHeaderAlignment" : ($scope.selectedDisplayHeaderAlignment.value=="null")?null:$scope.selectedDisplayHeaderAlignment.value, + "sortable" : ($scope.sortable.value=="true"), + "visible" : ($scope.visible.value=="true"), + "drilldownURL" : "", + "drilldownParams" : "", + "drilldownType" : "" + } + raptorReportFactory.saveColumnEditInfo(colInfo).then(function(data){ + $modalInstance.close(); + },function(error){ + $log.error("raptorReportFactory: getColumnEditInfoById failed."); + }); + }; + + $scope.cancel = function() { + $modalInstance.dismiss(); + }; + }], + resolve:{ + colData: function(){ + return rowData; + } + } + }); + + modalInstance.result.then(function () { + $scope.$emit('RefreshColumnList'); + }, function () { + }); + }; + $scope.addNewFormField = function () { + var modalInstance = $modal.open({ + scope: $scope, + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-formfield-edit.html', + sizeClass: 'modal-large', + controller: ['$scope', '$modalInstance', '$http', '$log','raptorReportFactory', function ($scope, $modalInstance, $http, $log, raptorReportFactory) { + raptorReportFactory.getFormFieldEditInfoById("add").then(function(data){ + $scope.formFieldEditData = data; + $scope.fieldId = $scope.formFieldEditData.fieldId; + $scope.fieldName ={"value": $scope.formFieldEditData.fieldName}; + $scope.selectedVisible = {"value":$scope.formFieldEditData.visible+''}; + $scope.defaultValue = {"value": $scope.formFieldEditData.defaultValue}; + $scope.fieldDefaultSQL = {"value": $scope.formFieldEditData.fieldDefaultSQL}; + $scope.fieldSqlContent = {"value": $scope.formFieldEditData.fieldSQL}; + $scope.selectedValidationType = {"value":$scope.formFieldEditData.validationType +''}; + $scope.selectedFieldType = {"value":$scope.formFieldEditData.fieldType +''}; + $scope.sqlDefaultValueSelected= {value:false}; + $scope.sqlDefaultValueSelected ={"value":false}; + if (($scope.fieldDefaultSQL.value)&&($scope.fieldDefaultSQL.value!="")) { + $scope.sqlDefaultValueSelected.value =true; + } + },function(error){ + $log.error("raptorReportFactory: getColumnEditInfoById failed."); + }); + + + $scope.ynOptions = [ + {value:"true", text:"Yes"}, + {value:"false", text:"No"} + ]; + + $scope.verifyFieldValueOptions = [ + {value:"DATE", text:"Date"}, + {value:"TIME_STAMP_HOUR", text:"TimeStamp (Hour)"}, + {value:"TIME_STAMP_HOUR_MIN", text:"TimeStamp (Hour,Min)"}, + {value:"HIDDEN", text:"Hidden"} + ] + + $scope.fieldTypeOptions = [ + {value:"TEXT", text:"Text Box"}, + {value:"LIST_BOX", text:"List Box"}, + {value:"LIST_MULTI_SELECT", text:"Multi-select List Box"}, + {value:"HIDDEN", text:"Hidden"} + ]; + + $scope.save = function() { + var formFieldJSON = { + "tabId" : "FormEdit", + "tabName" : "Form Edit", + "fieldId" : $scope.fieldId, + "fieldName" : $scope.fieldName.value, + "fieldType" : $scope.selectedFieldType.value, + "visible" : ($scope.selectedVisible.value=="true"), + "defaultValue" : ($scope.sqlDefaultValueSelected.value?'':$scope.defaultValue.value), + "fieldDefaultSQL" : ($scope.sqlDefaultValueSelected.value?$scope.fieldDefaultSQL.value:""), + "fieldSQL" :$scope.fieldSqlContent.value, + "validationType" : "NONE", + "predefinedValueList" :null + } + raptorReportFactory.saveFormFieldEditInfo(formFieldJSON).then(function(data){ + $modalInstance.close(); + },function(error){ + $log.error("raptorReportFactory: saveFormFieldEditInfo failed."); + }); + }; + + $scope.cancel = function() { + $modalInstance.dismiss(); + }; + }] + }); + modalInstance.result.then(function () { + $scope.$emit('RefreshFormField'); + }, function () { + }); + }; + + $scope.openFormFieldPopup = function (rowData) { + var modalInstance = $modal.open({ + scope: $scope, + animation: $scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-formfield-edit.html', + sizeClass: 'modal-large', + controller: ['$scope', '$modalInstance', '$http', '$log','raptorReportFactory','fieldData', function ($scope, $modalInstance, $http, $log, raptorReportFactory, fieldData) { + var init = function() { + raptorReportFactory.getFormFieldEditInfoById(fieldData.id).then(function(data){ + $scope.formFieldEditData = data; + $scope.fieldId = $scope.formFieldEditData.fieldId; + $scope.fieldName = {"value":$scope.formFieldEditData.fieldName}; + $scope.selectedVisible = {"value":$scope.formFieldEditData.visible+''}; + $scope.defaultValue = {"value":$scope.formFieldEditData.defaultValue}; + $scope.fieldDefaultSQL = {"value": $scope.formFieldEditData.fieldDefaultSQL}; + $scope.fieldSqlContent = {"value": $scope.formFieldEditData.fieldSQL}; + $scope.selectedValidationType = {"value":$scope.formFieldEditData.validationType +''}; + $scope.selectedFieldType = {"value":$scope.formFieldEditData.fieldType +''}; + $scope.sqlDefaultValueSelected ={"value":false}; + if (($scope.fieldDefaultSQL.value)&&($scope.fieldDefaultSQL.value!="")) { + $scope.sqlDefaultValueSelected.value =true; + } + },function(error){ + $log.error("raptorReportFactory: getColumnEditInfoById failed."); + }); + + $scope.ynOptions = [ + {value:"true", text:"Yes"}, + {value:"false", text:"No"} + ]; + + $scope.verifyFieldValueOptions = [ + {value:"DATE", text:"Date"}, + {value:"TIME_STAMP_HOUR", text:"TimeStamp (Hour)"}, + {value:"TIME_STAMP_HOUR_MIN", text:"TimeStamp (Hour,Min)"}, + {value:"HIDDEN", text:"Hidden"} + ] + + $scope.fieldTypeOptions = [ + {value:"TEXT", text:"Text Box"}, + {value:"LIST_BOX", text:"List Box"}, + {value:"LIST_MULTI_SELECT", text:"Multi-select List Box"}, + {value:"HIDDEN", text:"Hidden"} + ]; + + } + + init(); + + $scope.save = function() { + var formFieldJSON = { + "tabId" : "FormEdit", + "tabName" : "Form Edit", + "fieldId" : $scope.fieldId, + "fieldName" : $scope.fieldName.value, + "fieldType" : $scope.selectedFieldType.value, + "visible" : ($scope.selectedVisible.value=="true"), + "defaultValue" : ($scope.sqlDefaultValueSelected.value?'':$scope.defaultValue.value), + "fieldDefaultSQL" : ($scope.sqlDefaultValueSelected.value?$scope.fieldDefaultSQL.value:""), + "fieldSQL" :$scope.fieldSqlContent.value, + "validationType" : "NONE", + "predefinedValueList" :null + } + raptorReportFactory.saveFormFieldEditInfo(formFieldJSON).then(function(data){ + $modalInstance.close(); + },function(error){ + $log.error("raptorReportFactory: saveFormFieldEditInfo failed."); + }); + }; + + $scope.cancel = function() { + $modalInstance.dismiss(); + }; + }], + resolve:{ + fieldData: function(){ + return rowData; + } + } + }); + + modalInstance.result.then(function () { + $scope.$emit('RefreshFormField'); + }, function () { + }); + }; + + + $scope.$watch('activeTabsId', function (newVal, oldVal) { + if(newVal !== oldVal) { + var selectedTab; + for (selectedTab = 0; selectedTab < $scope.gTabs.length; selectedTab++) { + if ($scope.gTabs[selectedTab].id === newVal) { + $scope.stepNum = selectedTab; +/* stepFormFactory.getStepJSONData(getJsonSrcName($scope.stepNum))*/ + $scope.isColumnStep = false; + $scope.isFormFieldStep = false; + $scope.renderStep(selectedTab+1); + if ($scope.stepNum == 2) { + loadSqlInSession(); + } else if ($scope.stepNum == 3) { + $scope.isColumnStep = true; + + raptorReportFactory.getColumnList().then(function(data){ + $scope.colTableRowData = data; + },function(error){ + $log.error("raptorReportFactory: get column list failed."); }); + + } else if ($scope.stepNum == 4) { + $scope.isFormFieldStep = true; + // put within then function: + raptorReportFactory.getFormFieldList().then(function(data){ + $scope.formFieldData = data; + },function(error){ + $log.error("raptorReportFactory: get formfields failed."); }); + } else if ($scope.stepNum == 5) { + raptorReportFactory.getDefinitionInSession().then(function(data){ + $scope.reportId = data.reportId; + },function(error){ + $log.error("raptorReportFactory: getDefinitionInSession failed."); }); + } + + if ($scope.stepNum>1){ + $scope.unhideAllOtherTabs(); + } + break; + } + } + + var selectedTabPanelElement = document.getElementById($scope.gTabs[selectedTab].tabPanelId); + + var elem = null; + if (selectedTabPanelElement) { + elem = DOMHelper.firstTabableElement(selectedTabPanelElement); + } + + if (elem) { + $timeout(function () { + elem.focus(); + }, 100); + } + } + }); + + + $scope.renderStep = function(stepNum){ + var containerElement = angular.element(document.getElementById("stepView")); + containerElement.empty(); + $scope.stepNum = stepNum; + var jsonSrcName = getJsonSrcName(stepNum); + stepFormFactory.renderForm(jsonSrcName, containerElement, $scope); + } + + // initialize the page at step 1; + $scope.renderStep(1); + + // create a message to display in our view + $scope.allProjects = []; + if(!$routeParams.step && $routeParams.step == "") $routeParams.step = 1; + if($routeParams.proj && $routeParams.proj > 0) + $scope.projid = $routeParams.proj; + if($routeParams.step) + $scope.stepNum = $routeParams.step; + else + $scope.stepNum = 1; + + $scope.jsonSrcName = getJsonSrcName($scope.stepNum); + + $scope.selectAction = function () { + var containerElement = angular.element(document.getElementById("stepView")); + containerElement.empty(); + $scope.project_name = this.prj.projectName; + $scope.stepNum = 1; + var stepNum = $scope.stepNum; + var jsonSrcName = getJsonSrcName(stepNum); + stepFormFactory.renderForm(jsonSrcName, containerElement, $scope); + renderProject(this.prj.id, 1); + }; + + + $scope.createAction = function () { + var containerElement = angular.element(document.getElementById("stepView")); + containerElement.empty(); + $scope.stepNum = 1; + var stepNum = $scope.stepNum; + $scope.jsonSrcName = "app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step"+$scope.stepNum +".json"; + var jsonSrcName = $scope.jsonSrcName; + stepFormFactory.renderForm(jsonSrcName, containerElement, $scope); + }; + + // select current project + renderProject = function (proj_id, stepNum) { + var userSelectedPrjId = proj_id; + $http({ + method: 'GET', + url: 'get_selected_project_data', + params:{'selectedPrjId':userSelectedPrjId, 'step': stepNum} + }).then(function successCallback(response) { + var selectedproject = response.data; + $scope.projid = userSelectedPrjId; + //$scope.allProjects = projectLists; + //$location.path('/'+userSelectedPrjId+'/'+stepNum); + var div = d3.select("#stepView"); + div.select("[name='proj_id']").text(userSelectedPrjId); + div.select("[name='proj_id']").property("value", userSelectedPrjId); + d3.select("[name='project_id']").property("value", userSelectedPrjId); + var h3Text = div.select("h3").text(); + div.select("h3").text($scope.project_name+ " - " + h3Text); + for (var key in selectedproject) { + if (selectedproject.hasOwnProperty(key)) { + var val = selectedproject[key]; + var formElement = d3.selectAll("[name='" + key + "']"); + if(formElement[0].length > 0) + console.log(formElement.attr("type")); + if(formElement[0].length > 0 && formElement.attr("type") === "radio") { + var formRadio = d3.selectAll("[id='" + key +"_"+val + "']"); + formRadio.property('checked', true); + } + if(formElement[0].length > 0 && formElement.property("type") === "textarea") { + div.select("textarea[name='" + key +"']").property('value', val); + } + if(formElement[0].length > 0 && formElement.attr("type") === "text") { + var formText = d3.selectAll("[name='" + key + "']"); + formText.property("value", val); + } + if(formElement[0].length > 0 && formElement.html().startsWith(" 0 && formElementOther.attr("type") === "checkbox") { + var formCheckbox = d3.selectAll("[name='" + key +"_"+val + "']"); + formRadio.property('checked', true); + } + } + } + } + + + + }); + } + + //submit function + $scope.submit = function(){ + let defer = $q.defer(); + + var div = d3.select("#stepView"); + var jsonSrcName = $scope.jsonSrcName; + var stepNum = $scope.stepNum; + var values = ""; + $http({ + method: 'GET', + url: jsonSrcName + }).then(function successCallback(response) { + var json = response.data; + var step = json.step; + if(step > 0) { + var sections = json.content.sections; + sections.forEach(function(d, i) { + var elements = d.elements; + if(elements) { + //elements.forEach(function(element, elementIndex) { + values += "{"; + values += "\"step\""+ ":\"" + step + "\","; + values += "\"proj_id\""+ ":\"" + d3.select('input[name="project_id"]').property("value") + "\","; + + for (elementIndex = 0; elementIndex < elements.length; elementIndex++) { + var element = elements[elementIndex]; + + if(elementIndex > 0) values += ","; + values += "\""+element.name +"\""+ ":" ; + if(element.input === "hidden") { + values += "\""+div.select('input[name="'+element.name+'"]').property("value") +"\""; + } + if(element.input === "radio") { + values += "\""+ div.select('input[name="'+element.name+'"]:checked').property("value") +"\""; + } + if(element.input === "checkbox") { + var checkOptions = element.options; + values += "[{"; + checkOptions.forEach(function(d, i) { + // if(document.getElementById("'"+element.name+"_"+d.id+"'") != null) + values += "\""+d.id+"\""+ ":" + div.select('input[name="'+element.name+"_"+d.id+'"]').property("checked") ; + if(i b[prop]) { + return 1; + } else if (a[prop] < b[prop]) { + return -1; + } + return 0; + } + + }; + + $scope.getParentLabel = function(parentId, parentListSelectData){ + var element; + element = parentListSelectData[0]; + for (var i=0; i 0) { + var childItem = {}; + childItem.name = leftChildItemList[i][j].label; + childItem.href = leftChildItemList[i][j].action; + parentItem.menuItems.push(childItem) + } + } + $scope.menuData.push(parentItem); + } + },function(error){ + console.log("ds2Menu::controller: getLeftMenu failed", error); + }); + + LeftMenuServiceDS2.getAppName().then(function(response){ + var j = response; + try { + if (j && j !== "null" && j!== "undefined"){ + $scope.app_name_full = j.data; + var processed_app_name = j.data; + var n = processed_app_name.length; + if (n > 15) { + n = 15; + } + $scope.app_name = processed_app_name.substr(0, n); + } else { + throw "Get app_name respsone is not an object/is empty"; + } + } catch (e) { + console.log("error happened while trying to get app name "+e); + return; + } + },function(error){ + console.log("error happened while calling getAppName "+error); + }); + + $scope.adjustHeader=function() { + $scope.showHeader = ($cookies.show_app_header == undefined ? true : $cookies.show_app_header); + if ($scope.showHeader == true) { + $scope.drawer_margin_top = 50; + $scope.drawer_custom_top = 54; + $scope.toggle_drawer_top = 55; + } + else { + $scope.drawer_margin_top = 40; + $scope.drawer_custom_top = 0; + $scope.toggle_drawer_top = 10; + } + }; // adjustHeader + + + $scope.adjustHeader(); + $scope.drawerOpen = true; + + + }] + } +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-directives/footer.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-directives/footer.js new file mode 100644 index 00000000..e11c3a05 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-directives/footer.js @@ -0,0 +1,27 @@ +appDS2.directive('ds2Footer', function () { + return { + restrict: 'A', //This means that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements + replace: false, + templateUrl: "app/fusion/scripts/DS2-view-models/footer.html", + controller: ['$scope', '$filter','ManifestService', function ($scope, $filter,ManifestService) { + $scope.build_number = ''; + ManifestService.getManifest().then(function(response){ + $scope.build_number=response['Build-Number']; + }); + }] + } +}); + +/*Analytics for all the pages*/ +$(function() { + portalHook(); + function portalHook() { + var script = document.createElement('script'); + script.src = "api/v2/analytics" + script.async = true; + script.onload = function() { + runAnalytics(); //runAnaltics() has endpoint in epsdk-fw library. + } + document.head.appendChild(script); + } +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/error_modal.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/error_modal.html new file mode 100644 index 00000000..895abaf9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/error_modal.html @@ -0,0 +1,19 @@ +
    +
    +

    Error!

    +
    + +
    +
    +
    +

    {{msg}}

    +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/success_modal.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/success_modal.html new file mode 100644 index 00000000..2584216c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/success_modal.html @@ -0,0 +1,20 @@ +
    +
    +

    Success!

    +
    + +
    +
    +
    + Your change has been saved! {{msg.text}} +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/success_modalpopup.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/success_modalpopup.html new file mode 100644 index 00000000..e0a168ab --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-modal/success_modalpopup.html @@ -0,0 +1,20 @@ +
    +
    +

    Success!

    +
    + +
    +
    +
    +
     {{msg.text}}
    +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/adminMenuService.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/adminMenuService.js new file mode 100644 index 00000000..86bf5cd4 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/adminMenuService.js @@ -0,0 +1,129 @@ +appDS2.factory('AdminMenuService', function ($http, $q) { + return { + getRoleFunctionList: function() { + return $http.get('get_role_functions') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + +getFnMenuItems: function(){ + + return $http.get('admin_fn_menu') + .then(function(response) { + if (typeof response.data === 'object') { + + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + getCollaborateList: function() { + return $http.get('get_collaborate_list') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, +/* saveRoleFunctionList: function(roleData) { + return $http.post('role_function_list/saveRoleFunction',{ + roleData + }) + .then(function(response) { + console.log(response); + if (response.status == 200) { + return response.data; + } else { + console.log('eror'); + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }*/ + saveRoleFunctionList: function(roleData) { + return $http({ + method: "POST", + url: "role_function_list/saveRoleFunction", + data:roleData + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + delRoleFunctionList: function(roleData) { + return $http({ + method: "POST", + url: "role_function_list/removeRoleFunction", + data:roleData + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + clearAdminRegions: function() { + return $http({ + method: "GET", + url: "jcs_admin/clearAll", + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + } + + + + }; +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/adminService.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/adminService.js new file mode 100644 index 00000000..e92ebaf3 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/adminService.js @@ -0,0 +1,453 @@ +appDS2.factory('AdminService', function ($http, $q) { + return { + getRole: function(roleId) { + return $http.get('get_role?role_id=' + roleId) + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + getCollaborateList: function() { + return $http.get('get_collaborate_list') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getCacheRegions: function() { + return $http.get('get_regions') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getUsageList: function() { + return $http.get('get_usage_list') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + +getFnMenuItems: function(){ + + return $http.get('admin_fn_menu') + .then(function(response) { + if (typeof response.data === 'object') { + + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + +/* saveRoleFunctionList: function(roleData) { + return $http.post('role_function_list/saveRoleFunction',{ + roleData + }) + .then(function(response) { + console.log(response); + if (response.status == 200) { + return response.data; + } else { + console.log('eror'); + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }*/ + + getRoleFunctionList: function() { + return $http.get('get_role_functions') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + saveRoleFunctionList: function(roleData) { + return $http({ + method: "POST", + url: "role_function_list/saveRoleFunction", + data:roleData + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + addRoleFunctionList: function(roleData) { + return $http({ + method: "POST", + url: "role_function_list/addRoleFunction", + data:roleData + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + delRoleFunctionList: function(roleData) { + return $http({ + method: "POST", + url: "role_function_list/removeRoleFunction", + data:roleData + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + clearAdminRegions: function() { + return $http({ + method: "GET", + url: "jcs_admin/clearAll" + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + showRegionDetails: function(cacheName) { + return $http({ + method: "GET", + url: "jcs_admin/showRegionDetails?cacheName="+cacheName, + contentType: 'application/json', + }).then(function(response) { + //var parsed = JSON.stringify(response); + var responseData = JSON.stringify(response); + if (response.status == 200) { + return response; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + console.log('response'+response); + // something went wrong + return $q.reject(response.data); + }); + }, + + clearRegionFunction: function(cacheName) { + return $http({ + method: "GET", + url: "jcs_admin/clearRegion?cacheName="+cacheName + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + clearItemnFunction: function(cacheName, key) { + return $http({ + method: "GET", + url: "jcs_admin/clearItem?keyName="+key+"&cacheName="+cacheName + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + showItemDetails: function(cacheName, key) { + return $http({ + method: "GET", + url: "jcs_admin/showItemDetails?keyName="+key+"&cacheName="+cacheName + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + //role deletion + delRoleList: function(roleData) { + return $http({ + method: "POST", + url: "role_list/removeRole", + data:JSON.stringify({role:roleData}) + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + // activate role + activateRole: function(selected,availableRole){ + return $http({ + method: "POST", + url: "role_list/toggleRole", + data:JSON.stringify({role:availableRole}) + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + // save Role + saveRole: function(role,roleId){ + return $http({ + method: "POST", + url: "role/saveRole.htm?role_id="+roleId, + data:JSON.stringify(role) + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + // activate RoleFun Remove + confirmRoleFunRemove: function(selected,availableRole,id){ + return $http({ + method: "POST", + url: "role/removeRoleFunction.htm?role_id=" + id, + data:JSON.stringify({roleFunction:availableRole}) + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + // activate RoleFun Add + confirmRoleFunAdd: function(selected,availableRole,id){ + return $http({ + method: "POST", + url: "role/addRoleFunction.htm?role_id=" + id, + data:JSON.stringify({roleFunction:availableRole}) + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + // activate RoleChild Remove + confirmRoleChildRemove: function(selected,availableRole,id){ + return $http({ + method: "POST", + url: "role/removeChildRole.htm?role_id=" + roleId, + data:JSON.stringify({roleFunction:availableRole}) + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + // activate RoleChild Add + confirmRoleChildAdd: function(selected,availableRole,id){ + return $http({ + method: "POST", + url: "role/addChildRole.htm?role_id=" + roleId, + data:JSON.stringify({roleFunction:availableRole}) + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + //Role Function delete for associated role on Edit Role + removeRoleFunction: function(roleFunction,roleId){ + return $http({ + method: "POST", + url: "role/removeRoleFunction.htm?role_id=" + roleId, + data:JSON.stringify({roleFunction:roleFunction}) + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + } + +/* toggleProfileActiveFunction: function(profileId) { + return $http({ + method: "GET", + url: "jcs_admin/clearRegion?cacheName="+cacheName + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }*/ + }; +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-modal/modalService.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-modal/modalService.js new file mode 100644 index 00000000..061d1ba2 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-modal/modalService.js @@ -0,0 +1,38 @@ +angular.module("modalServices",[]).service('modalService', ['$modal', function ($modal) { + var ModalInstanceCtrl = function ($scope, $modalInstance, items,$rootScope) { + $scope.roleFun=items; + $scope.msg=items; + + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; + }; + this.errorPopUp = function (msg) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/error_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + return msg; + } + } + }); + }; + this.successPopUp = function (msg) { + var modalInstance = $modal.open({ + templateUrl: 'app/fusion/scripts/DS2-modal/success_modal.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-small', + resolve: { + items: function () { + var message = { + title: '', + text: msg + }; + return message; + } + } + }); + }; + }]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-profile/selfProfileService.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-profile/selfProfileService.js new file mode 100644 index 00000000..bc18f2c8 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-profile/selfProfileService.js @@ -0,0 +1,114 @@ +appDS2.factory('SelfProfileService', function ($http, $q) { + return { + getProfileDetail: function(profileId) { + return $http({ + method: "GET", + url: "get_profile?profile_id=" + profileId, + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getSelfProfileDetail: function() { + return $http.get('get_self_profile') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + addRole: function(roleData,profileId) { + return $http({ + method: "POST", + url: "profile/addNewRole?profile_id=" + profileId, + data:roleData + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + deRole: function(roleData,profileId) { + return $http({ + method: "POST", + url: "profile/removeRole?profile_id=" + profileId, + data:roleData + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + saveProfile: function(data,profileId) { + return $http({ + method: "POST", + url: "profile/saveProfile?profile_id=" + profileId, + data:data + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + removeRole: function(data,profileId) { + return $http({ + method: "POST", + url: "profile/removeRole?profile_id=" + profileId, + data:data + + }).then(function(response) { + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + } + }; +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-raptor-report/raptorReportFactory.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-raptor-report/raptorReportFactory.js new file mode 100644 index 00000000..06324d39 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-raptor-report/raptorReportFactory.js @@ -0,0 +1,331 @@ +appDS2.factory('raptorReportFactory', function($http, $q) { + return { + getDefinitionByReportId: function(reportId) { + return $http({ + method: "GET", + url: "report/wizard/retrieve_tab_wise_data/Def/"+reportId, + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getDefinitionByReportId did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getDefinitionByReportId callback failed"); + }); + }, + getDefinitionInSession: function() { + return $http({ + method: "GET", + url: "report/wizard/retrieve_tab_wise_data/Def/InSession", + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getDefinitionInSession did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getDefinitionInSession callback failed"); + }); + }, + + createNewDefinition: function() { + return $http({ + method: "GET", + url: "report/wizard/retrieve_tab_wise_data/Def/Create", + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: createNewDefinition did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: createNewDefinition callback failed"); + }); + }, + updateDefinition: function(updatedJson,isUpdate) { + return $http({ + method: "POST", + url: (isUpdate?("report/wizard/save_def_tab_data/"+updatedJson.reportId):"report/wizard/save_def_tab_data/Create"), + data: updatedJson + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: updateDefinition did not return a valid JSON object."); + } + return response.data; + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: updateDefinition callback failed"); + }); + }, + saveNewDefinition: function(updatedJson) { + return $http({ + method: "POST", + url: "report/wizard/save_def_tab_data/InSession", + data: updatedJson + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: saveNewDefinition did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: saveNewDefinition callback failed"); + }); + }, + getSqlInSession: function() { + return $http({ + method: "GET", + url: "report/wizard/retrieve_tab_wise_data/Sql/InSession", + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getSqlInSession did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getSqlInSession callback failed"); + }); + }, + testRunSQL: function(queryJSON) { + return $http({ + method: "POST", + url: "report/wizard/retrieve_data/true", + data: queryJSON + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: testRunSQL did not return a valid JSON object."); + } + return response.data; + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: testRunSQL callback failed"); + }); + }, + formFieldVerifySQL: function(queryJSON) { + return $http({ + method: "POST", + url: "report/wizard/retrieve_data/false", + data: queryJSON + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: formFieldVerifySQL did not return a valid JSON object."); + } + return response.data; + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: formFieldVerifySQL callback failed"); + }); + }, + getColumnList: function() { + return $http({ + method: "GET", + url: "report/wizard/list_columns", + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getColumnList did not return a valid JSON object."); + } + return response.data; + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getColumnList callback failed"); + }); + }, + + getColumnEditInfoById: function(columnId){ + return $http({ + method: "GET", + url: "report/wizard/retrieve_tab_wise_data/ColEdit/"+columnId, + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getColumnEditInfoById did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getColumnEditInfoById callback failed"); + }); + }, + saveColumnEditInfo: function(updatedColumnJson){ + return $http({ + method: "POST", + url: "report/wizard/save_col_tab_data", + data: updatedColumnJson + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: saveColumnEditInfo did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: saveColumnEditInfo callback failed"); + }); + }, + postImportXml: function(importXMLJSON){ + return $http({ + method: "POST", + url: "report/wizard/import_report", + data: importXMLJSON + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: importXml did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: importXml callback failed"); + }); + }, + copyReportById: function(reportId) { + return $http({ + method: "GET", + url: "report/wizard/copy_report/"+reportId, + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: copyReportById did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: copyReportById callback failed"); + }); + }, + saveFormFieldEditInfo: function(updatedFormFieldJson){ + return $http({ + method: "POST", + url: "report/wizard/save_formfield_tab_data", + data: updatedFormFieldJson + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: saveFormFieldEditInfo did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: saveFormFieldEditInfo callback failed"); + }); + }, + getFormFieldList: function() { + return $http({ + method: "GET", + url: "report/wizard/list_formfields", + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getFormFieldList did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getFormFieldList callback failed"); + }); + }, + getFormFieldEditInfoById: function(fieldId){ + return $http({ + method: "GET", + url: "report/wizard/retrieve_tab_wise_data/FormEdit/"+fieldId, + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getColumnEditInfoById did not return a valid JSON object."); + } + return response.data; + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getFormFieldEditInfoById callback failed"); + }); + }, + deleteFormFieldById: function(fieldId){ + return $http({ + method: "GET", + url: "report/wizard/retrieve_tab_wise_data/FormEdit/delete/"+fieldId, + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: deleteFormFieldById did not return a valid JSON object."); + } + return response.data; + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: deleteFormFieldById callback failed"); + }); + }, + getColumns: function() { + return $http + .get('raptor.htm?action=report.search.execute&r_page=0') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getColumns did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getColumns callback failed"); + }); + }, + + getSearchData : function() { + return $http + .get('raptor.htm?action=report.search.execute&r_page=0') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getSearchData did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getSearchData callback failed"); + }); + }, + + getSearchDataAtPage : function(pageSearchParameter) { + return $http + .get('raptor.htm?action=report.search.execute&r_page='+pageSearchParameter) + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getSearchDataAtPage did not return a valid JSON object."); + } + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getSearchDataAtPage callback failed"); + }); + }, + getReportDeleteStatus : function(deleteUrl) { + return $http.get(deleteUrl).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject("raptorReportFactory: getReportDeleteStatus did not return a valid JSON object."); + } + + }, function(response) { + // something went wrong + return $q.reject("raptorReportFactory: getReportDeleteStatus callback failed"); + }); + } + }; +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-raptor-report/stepFormFactory.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-raptor-report/stepFormFactory.js new file mode 100644 index 00000000..5c711425 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-raptor-report/stepFormFactory.js @@ -0,0 +1,198 @@ +(function(){ + var stepFormFactory = function($http, $compile, $q, $log) { + + var factory = {}; + + factory.getStepJSONData = function(jsonSrcName) { + $http({ + method: "GET", + url: jsonSrcName, + }).then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + } + + + factory.renderColumnForm = function(scope) { + + } + factory.renderForm = function(jsonSrcName, elem, scope) { + let defer = $q.defer(); + var divStepForm = document.getElementById('stepView'); + var textStyle = "width:300px" + var textAreaStyle = "width:300px" + if(divStepForm) + while(divStepForm && divStepForm.firstChild){ + divStepForm.removeChild(divStepForm.firstChild); + } + $http({ + method: 'GET', + url: jsonSrcName + }).then(function successCallback(response) { + // this callback will be called asynchronously + // when the response is available + if (typeof response.data === 'object') { + var json = response.data; + var step = json.step; + var div =d3.select(elem[0]); + var modelNameDict = {}; + + div.append("h1").attr({"class":"font-color:blue"}).text(json.content.title); + div.append("div").html(json.content.contentHtml); + var sections = json.content.sections; + sections.forEach(function(d, i) { + var sectionDiv = div.append("div"); + sectionDiv.attr("id", "section_"+i); + if(d.title != "finalButton") + sectionDiv.append("h4").text(d.title); + var proj_id_hidden = sectionDiv.append("input"); + proj_id_hidden.attr({"type":"hidden", "value":"", "name": "proj_id", "ng-model":"proj_id", "style": "" }); + + var elements = d.elements; + var buttons = d.buttons; + var elementTable ; + if(elements) { + elements.forEach(function(element, elementIndex) { + + var elementBody ; + if(elementIndex == 0) { + elementTable = sectionDiv.append("table").attr({"border":"0", "cellpadding":"4", "cellspacing":"0"}); + elementBody = elementTable.append("tbody"); + } else { + elementBody = elementTable = sectionDiv.select("tbody"); + } + if(element.input == 'hidden') { + + } else { + var tr = elementBody.append("tr") + var cellWidthStyle = {"width":"50%"} + + if (!(element.spanOverTwoColumns)){ + var td = tr.append("td").attr({"width":"30%","class":"tdLeftColumn"}); + if (element.input=="checkboxGroup") { + td = td.attr({"rowspan":element.checkboxes.length}) + } + td.text(element.displayName); + var cellWidthStyle = {"width":"500px;"} + } + td = tr.append("td").attr(cellWidthStyle); + var model_name_appendix=''; + if (element.name in modelNameDict) { + modelNameDict[element.name]=modelNameDict[element.name]+1 + model_name_appendix ='_'+modelNameDict[element.name] + } else { + modelNameDict[element.name]=0 + } + if(element.input == 'text') { + var inp_text = td.append("input"); + inp_text.attr({"type":"text", "value":element.defaultValue, "name": element.name, "ng-model":element.name+model_name_appendix, "style": (element.style?element.style:textStyle) }); + } + else if(element.input === 'checkbox') { + var temptd= td.append("label").attr({"class":"checkbox"}); + var temptd2= temptd.append("input").attr({"type":"checkbox", "ng-model": element.checkbox.value}); + var temptd3= temptd.append("i").attr({"class":"skin"}) + var temptd3= temptd.append("span").text(element.checkbox.text); + + } else if (element.input === 'radio') { + element.options.forEach(function(d,i) { + td.append("input").attr({"type":"radio", "id":element.name+"_"+d.id, "ng-model":element.name+model_name_appendix, "name": element.name, "value": d.id}); + td.append("label").text(d.name); + }) + } else if (element.input === 'checkboxGroup') { + + element.checkboxes.forEach(function(d,i) { + if (i==0) { + var temptd= td.append("label").attr({"class":"checkbox"}); + var temptd2= temptd.append("input").attr({"type":"checkbox", "ng-model": d.value}); + var temptd3= temptd.append("i").attr({"class":"skin"}) + var temptd3= temptd.append("span").text(d.text); + } else { + var tr = elementBody.append("tr") + td = tr.append("td").attr({"width":"50%"}); + var temptd= td.append("label").attr({"class":"checkbox"}); + var temptd2= temptd.append("input").attr({"type":"checkbox", "ng-model": d.value}); + var temptd3= temptd.append("i").attr({"class":"skin"}) + var temptd3= temptd.append("span").text(d.text); + } + }) + } else if (element.input === 'textarea') { + td.append("textarea").attr({"rows":"4", "cols":"50", "ng-model":element.name+model_name_appendix, "name": element.name, "style": (element.style?element.style:textAreaStyle)}); + } + else if (element.input === 'select') { + var select = td.append("select"); + // need to store options into element name; + select + .attr({"name": element.name,"b2b-dropdown":"","ng-model":element.ngModelName,"style":"width:300px"}) + .attr("placeholder-text","Select"); + + + /* var data = ["Option 1", "Option 2", "Option 3"]*/ + var options = select + .selectAll('option') + .data(element.options).enter() + .append('option').attr("value", function(d) {return d.value}) + .attr("b2b-dropdown-list","") + .text(function (d) { return d.text; }) + ; + } else if (element.input === 'tabletext') { + var colArray = element.columns.split(','); + var table = td.append("table"); + table.attr("border", "1"); + + colArray.forEach(function(d) { + table.append("th").text(d); + }) + + } + } + }) + if (buttons) { + buttons.forEach(function(button, buttonIndex) { + sectionDiv.append("input").attr({"type":"button", "value": button.text, "ng-click":button.ngFunction,"class":"btn btn-alt btn-small"}); + }) + sectionDiv.append("br"); + } + } + else { //if elements + if((json.step != "1")&&(!json.hideBackButton)) + sectionDiv.append("input").attr({"type":"button", "value": "Back", "ng-click":"previous()","class":"btn btn-alt btn-small"}); + if((d.title == "finalButton")&(!json.hideSaveButton)) + sectionDiv.append("input").attr({"type":"button", "value": "Save", "ng-click":"save()", "class":"btn btn-alt btn-small"}); + if(!json.last_step) + sectionDiv.append("input").attr({"type":"button", "value": "Next", "ng-click":"next()", "class":"btn btn-alt btn-small"}); + + } + }) + elem.html(div.html()); + elem.removeAttr("step-form"); + $compile(elem.contents())(scope); + defer.resolve(); + } else { + $log.error + return $q.reject(response.data); + } + }, function errorCallback(response) { + // called asynchronously if an error occurs + // or server returns response with an error status. + $log.error("reponse data is not a valid JSON object"); + defer.resolve(); + }); + //} + return defer.promise; + }; + + return factory; + }; + + stepFormFactory.$inject = ['$http', '$compile', '$q']; + + appDS2.factory('stepFormFactory', stepFormFactory); + +}()) diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-sample-page/droolsService.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-sample-page/droolsService.js new file mode 100644 index 00000000..90c3d00d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/ds2-sample-page/droolsService.js @@ -0,0 +1,53 @@ +appDS2.factory('DroolsService', function ($http, $q) { + return { + getDroolsList: function() { + return $http.get('getDrools') + .then(function(response) { + console.log(response); + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getDroolDetails: function(selectedFile) { + return $http.get('getDroolDetails'+'?selectedFile=' + selectedFile ) + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + executeDrools:function(droolsData) { + return $http({ + method: "POST", + url: "post_drools/execute", + data:droolsData + }).then(function(response) { + console.log(response); + if (response.status == 200) { + return response.data; + } else { + return $q.reject(response.data); + } + return response.data; + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + } + }; +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/headerServiceDS2.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/headerServiceDS2.js new file mode 100644 index 00000000..92a99be0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/headerServiceDS2.js @@ -0,0 +1,483 @@ +appDS2.directive('qHeader', function () { + + return { + restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements + replace: false, + templateUrl: "app/fusion/scripts/DS2-view-models/ds2Header.html", + controller: ['$scope', '$filter','$http','$timeout', '$log','UserInfoServiceDS2', '$window', '$cookies', function ($scope, $filter, $http, $timeout, $log,UserInfoServiceDS2, $window, $cookies) { + + //alert("in header service") + /*Define fields*/ + $scope.userName; + $scope.userFirstName; + $scope.redirectUrl; + $scope.contactUsUrl; + $scope.getAccessUrl; + $scope.childData=[]; + $scope.parentData=[]; + $scope.menuItems = []; + $scope.loadMenufail=false; + $scope.megaMenuDataObject=[]; + $scope.activeClickSubMenu = { + x: '' + }; + $scope.activeClickMenu = { + x: '' + }; + $scope.favoritesMenuItems = []; + $scope.favoriteItemsCount = 0; + $scope.showFavorites = false; + $scope.emptyFavorites = false; + $scope.favoritesWindow = false; + + /* Menu Structure + var menuStructureConvert = function(menuItems) { + console.log(menuItems); + $scope.megaMenuDataObjectTemp = + [ + { + text: "ECOMP", + children: menuItems + }, + { + text: "Help", + children: [ + { + text:"Contact Us", + url:$scope.contactUsUrl + }, + { + text:"Get Access", + url:$scope.getAccessUrl + }] + } + ]; + return $scope.megaMenuDataObjectTemp; + }; + */ + /***************functions**************/ + /*Put user info into fields*/ + $scope.inputUserInfo = function(userInfo){ + if (typeof(userInfo) != "undefined" && userInfo!=null && userInfo!=''){ + if(typeof(userInfo.USER_FIRST_NAME) != "undefined" && userInfo.USER_FIRST_NAME!=null){ + $scope.userFirstName = userInfo.USER_FIRST_NAME; + } + } + } + /*getting user info from session*/ + $scope.getUserNameFromSession = function(){ + UserInfoServiceDS2.getFunctionalMenuStaticDetailSession() + .then(function (res) { + $scope.contactUsUrl=res.contactUsLink; + $scope.userName = res.userName; + $scope.userFirstName = res.firstName; + $scope.redirectUrl = res.portalUrl; + $scope.getAccessUrl = res.getAccessUrl; + }); + } + $scope.getTopMenuStaticInfo=function() { + var promise = UserInfoServiceDS2.getFunctionalMenuStaticDetailShareContext(); + promise.then( + function(res) { + if(res==null || res==''){ + $log.info('failed getting static User information'); + $scope.getUserNameFromSession(); + }else{ + $log.info('Received static User information'); + + var resData = res; + console.log(resData); + $scope.inputUserInfo(resData); + $scope.userName = $scope.firstName+ ' '+ $scope.lastName; + } + }, + function(err) { + $log.info('failed getting static User information'); + } + ); + } + + $scope.returnToPortal=function(){ + window.location.href = $scope.redirectUrl; + } + + var unflatten = function( array, parent, tree ){ + tree = typeof tree !== 'undefined' ? tree : []; + parent = typeof parent !== 'undefined' ? parent : { menuId: null }; + var children = _.filter( array, function(child){ return child.parentMenuId == parent.menuId; }); + if( !_.isEmpty( children ) ){ + if( parent.menuId === null ){ + tree = children; + }else{ + parent['children'] = children + } + _.each( children, function( child ){ unflatten( array, child ) } ); + } + return tree; + } + + $scope.getMenu=function() { + $scope.getTopMenuStaticInfo(); + $http({ + method: "GET", + url: 'get_functional_menu', +// TIMEOUT USED FOR LOCAL TESTING ONLY +// timeout: 100 + }).success(function (response) { + + if (response == '101: Timeout') { + $log.debug('Timeout attempting to get_functional_menu'); + $scope.megaMenuDataObject = menuStructureConvert(""); +// $scope.createErrorMenu(); + //$scope.loadMenufail=true; + } else { + if(typeof response != 'undefined' && response.length!=0 && typeof response[0] != 'undefined' && typeof response[0].error!="undefined"){ + $log.debug('Timeout attempting to get_functional_menu'); + $scope.menuItems = unflatten( response); + $scope.megaMenuDataObject = menuStructureConvert($scope.menuItems); +// $scope.createErrorMenu(); + //$scope.loadMenufail=true; + }else{ + $scope.loadMenufail=false; + $scope.contactUsURL = response.contactUsLink; + $log.debug('functional_menu',response); + $scope.megaMenuDataObject = menuStructureConvert(""); + } + } + }).error(function (response){ + $scope.megaMenuDataObject = menuStructureConvert(""); +// $scope.createErrorMenu(); + //$scope.loadMenufail=true; + $log.debug('REST API failed get_functional_menu...'); + }); + + } + + /*$scope.adjustHeader=function() { + $scope.showHeader = ($cookies.show_app_header == undefined ? true : $cookies.show_app_header); + + if($scope.showHeader == true) { + $scope.drawer_margin_top = 70; + $scope.drawer_custom_top = 54; + $scope.toggle_drawer_top = 55; + } + else { + + $scope.drawer_margin_top = 60; + $scope.drawer_custom_top = 0; + $scope.toggle_drawer_top = 10; + } + + }*/ + + $scope.getMenu(); + // $scope.adjustHeader(); + +/* **************************************************************************/ +/* Logic for the favorite menus is here */ + + $scope.loadFavorites = function () { + $log.debug('loadFavorites has happened.'); + if ($scope.favoritesMenuItems == '') { + $scope.generateFavoriteItems(); + $log.debug('loadFavorites is calling generateFavoriteItems()'); + } else { + $log.debug('loadFavorites is NOT calling generateFavoriteItems()'); + } + } + + $scope.goToUrl = function (item) { + $log.info("goToUrl called") + $log.info(item); + + var url = item.url; + var restrictedApp = item.restrictedApp; + $log.debug('Restricted app status is: ' + restrictedApp); + if (!url) { + $log.info('No url found for this application, doing nothing..'); + return; + } + if (restrictedApp) { + $window.open(url, '_blank'); + } else { + $window.open(url, '_self'); + } + + } + + $scope.submenuLevelAction = function(index, column) { + if ($scope.favoritesMenuItems == '') { + $scope.generateFavoriteItems(); + $log.debug('submenuLevelAction is calling generateFavoriteItems()'); + } + $log.debug('item hovered/clicked: ' + index + '; column = ' + column); + if (column == 2) { // 2 is Design + $scope.favoritesWindow = false; + $scope.showFavorites = false; + $scope.emptyFavorites = false; + } + if (index=='Favorites' && $scope.favoriteItemsCount != 0) { + $log.debug('Showing Favorites window'); + $scope.favoritesWindow = true; + $scope.showFavorites = true; + $scope.emptyFavorites = false; + } + if (index=='Favorites' && $scope.favoriteItemsCount == 0) { + $log.debug('Hiding Favorites window in favor of No Favorites Window'); + $scope.favoritesWindow = true; + $scope.showFavorites = false; + $scope.emptyFavorites = true; + } + if (column > 2) { + $scope.favoritesWindow = false; + $scope.showFavorites = false; + $scope.emptyFavorites = false; + } + }; + + $scope.hideFavoritesWindow = function() { + $log.debug('$scope.hideFavoritesWindow has been called'); + $scope.showFavorites = false; + $scope.emptyFavorites = false; + } + + $scope.isUrlFavorite = function (menuId) { +// $log.debug('array objects in menu favorites = ' + $scope.favoriteItemsCount + '; menuId=' + menuId); + var jsonMenu = JSON.stringify($scope.favoritesMenuItems); + var isMenuFavorite = jsonMenu.indexOf('menuId\":' + menuId); + if (isMenuFavorite==-1) { + return false; + } else { + return true; + } + + } + + $scope.generateFavoriteItems = function() { + $http({ + method: "GET", + url: 'get_favorites', +// TIMEOUT USED FOR LOCAL TESTING ONLY +// timeout: 100 + }).success(function (response) { + if (response == '101: Timeout') { + $log.error('Timeout attempting to get_favorites_menu'); + } else { + if(typeof response != 'undefined' && response.length!=0 && typeof response[0] != 'undefined' && typeof response[0].error!="undefined"){ + $log.error('REST API failed get_favorites' + response); + }else{ + $log.debug('get_favorites = ' + JSON.stringify(response)); + $scope.favoritesMenuItems = response; + $scope.favoriteItemsCount = Object.keys($scope.favoritesMenuItems).length; + $log.info('number of favorite menus: ' + $scope.favoriteItemsCount); + } + } + }).error(function (response){ + $log.error('REST API failed get_favorites' + response); +//createFavoriteErrorMenu() USED FOR LOCAL TESTING ONLY +// $scope.createFavoriteErrorMenu(); + }); + } + + $scope.createFavoriteErrorMenu=function() { + $scope.favoritesMenuItems = []; + $scope.favoriteItemsCount = Object.keys($scope.favoritesMenuItems).length; + $log.info('number of favorite menus: ' + $scope.favoriteItemsCount); + } + + /* end of Favorite Menu code */ + /* **************************************************************************/ + + + /* **************************************************************************/ + // THIS IS USED FOR LOCAL TESTING ONLY + /* **************************************************************************/ + $scope.createErrorMenu=function() { + $log.debug('Creating fake menu now...'); +// $scope.loadMenufail=true; + $scope.menuItems = [ + { + "menuId": 1, + "column": 2, + "text": "Design", + "parentMenuId": null, + "url": "" + }, + { + "menuId": 2, + "column": 3, + "text": "Infrastructure Ordering", + "parentMenuId": null, + "url": "" + }, + { + "menuId": 3, + "column": 4, + "text": "Service Creation", + "parentMenuId": null, + "url": "" + }, + { + "menuId": 4, + "column": 5, + "text": "Service Mgmt", + "parentMenuId": null, + "url": "" + }, + { + "menuId": 90, + "column": 1, + "text": "Google", + "parentMenuId": 1, + "url": "http://google.com" + }, + { + "menuId": 91, + "column": 1, + "text": "Mike Little's Coffee Cup", + "parentMenuId": 2, + "url": "http://coffee.com" + }, + { + "menuId": 92, + "column": 2, + "text": "Andy and his Astrophotgraphy", + "parentMenuId": 3, + "url": "http://nightskypix.com" + }, + { + "menuId": 93, + "column": 1, + "text": "JSONLint", + "parentMenuId": 4, + "url": "http://http://jsonlint.com" + }, + { + "menuId": 94, + "column": 2, + "text": "HROneStop", + "parentMenuId": 4, + "url": "http://ebiz.sbc.com/hronestop" + }, + { + "menuId": 95, + "column": 2, + "text": "4th Level App4a R16", + "parentMenuId": 4, + "url": "http://www.e-access.att.com/ecomp_portal_ist/ecompportal/widgets" + }, + { + "menuId": 96, + "column": 3, + "text": "3rd Level App1c R200", + "parentMenuId": 4, + "url": "http://app1c.com" + }, + { + "menuId": 97, + "column": 1, + "text": "3rd Level App4b R16", + "parentMenuId": 5, + "url": "http://app4b.com" + }, + { + "menuId": 98, + "column": 2, + "text": "3rd Level App2b R16", + "parentMenuId": 5, + "url": "http://app2b.com" + }, + { + "menuId": 99, + "column": 1, + "text": "Favorites", + "parentMenuId": null, + "url": "" + } + ]; + $scope.menuItems = unflatten( $scope.menuItems ); + //remove this + $scope.megaMenuDataObject = menuStructureConvert($scope.menuItems); + } + }] + } +}); + +appDS2.filter("ellipsis", function(){ + return function(text, length){ + if (text) { + var ellipsis = text.length > length ? "..." : ""; + return text.slice(0, length) + ellipsis; + }; + return text; + } +}); +function reloadPageOnce() { + if( window.localStorage ) + { + if( !localStorage.getItem('firstLoad') ) + { + localStorage['firstLoad'] = true; + window.location.reload(); + } + else + localStorage.removeItem('firstLoad'); + } +} +appDS2.controller('loginSnippetCtrl', function ($scope,$http, $log,UserInfoServiceDS2){ + /*Define fields*/ + $scope.userProfile={ + firstName:'', + lastName:'', + fullName:'', + email:'', + } + /*Put user info into fields*/ + $scope.inputUserInfo = function(userInfo){ + if (typeof(userInfo) != "undefined" && userInfo!=null && userInfo!=''){ + if (typeof(userInfo.USER_FIRST_NAME) != "undefined" && userInfo.USER_FIRST_NAME!=null && userInfo.USER_FIRST_NAME!='') + $scope.userProfile.firstName = userInfo.USER_FIRST_NAME; + if (typeof(userInfo.USER_LAST_NAME) != "undefined" && userInfo.USER_LAST_NAME!=null && userInfo.USER_LAST_NAME!='') + $scope.userProfile.lastName = userInfo.USER_LAST_NAME; + if (typeof(userInfo.USER_EMAIL) != "undefined" && userInfo.USER_EMAIL!=null && userInfo.USER_EMAIL!='') + $scope.userProfile.email = userInfo.USER_EMAIL; + + } + } + /*getting user info from session*/ + $scope.getUserNameFromSession = function(){ + UserInfoServiceDS2.getFunctionalMenuStaticDetailSession() + .then(function (response) { + $scope.userProfile.fullName = response.userName; + $scope.userProfile.email = response.email; + }); + } + /*getting user info from shared context*/ + $scope.getUserName=function() { + var promise = UserInfoServiceDS2.getFunctionalMenuStaticDetailShareContext(); + promise.then( + function(res) { + if(res==null || res==''){ + $log.info('headerServiceDS2: get user information from session'); + $scope.getUserNameFromSession(); + + }else{ + // $log.info('Received User information from shared context',res); + var resData = res; + console.log(resData); + $scope.inputUserInfo(resData); + $scope.userProfile.fullName = $scope.userProfile.firstName+ ' '+ $scope.userProfile.lastName; + } + }, + function(err) { + console.log('error'); + } + ); + }; + /*call the get user info function*/ + try{ + $scope.getUserName(); + }catch(err){ + $log.info('Error while getting User information',err); + } +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/leftMenuServiceDS2.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/leftMenuServiceDS2.js new file mode 100644 index 00000000..879da8e7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/leftMenuServiceDS2.js @@ -0,0 +1,110 @@ +function isRealValue(obj){ + return obj && obj !== "null" && obj!== "undefined"; +} +appDS2.factory('LeftMenuServiceDS2', function ($http,$log, $q) { + return { + getLeftMenu: function() { + return $http.get('get_menu') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + getAppName: function() { + return $http.get('get_app_name') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + } + + }; +}); + +/* check if the body height has changed */ +function onElementHeightChange(elm, callback){ + if (!elm) { + console.log('onElementHeightChange: null element!'); + return; + } + var lastHeight = elm.clientHeight, newHeight; + (function run(){ + newHeight = elm.clientHeight; + if( lastHeight != newHeight ) + callback(); + lastHeight = newHeight; + + if( elm.onElementHeightChangeTimer ) + clearTimeout(elm.onElementHeightChangeTimer); + elm.onElementHeightChangeTimer = setTimeout(run, 200); + })(); +} + +/*adjust height of left menu*/ +function adjustLeftMenuHeight() { + + try{ + var footerTop = $('.footer-container').offset().top; + var scrollTop = $(window).scrollTop(); + $(".menu-container").css({ + "height" : footerTop- scrollTop, + }); + }catch(err){ + console.log('adjustLeftMenuHeight failed', err) + } +} +/* adjust left menu height on scroll */ +window.onscroll = function (e) { + adjustLeftMenuHeight(); +} + +function adjustHeader() { + var showHeader = getCookie("show_app_header"); + if(showHeader==''){ + $(".menu-container").css({ + "margin-top" : 45, + }); + }else{ + $(".menu-container").css({ + "margin-top" : 0, + }); + } +}; +/* adjust left menu height on page load */ +$(function() { + adjustLeftMenuHeight(); + adjustHeader(); +}); + + +onElementHeightChange(document.body, function(){ + adjustLeftMenuHeight(); +}); + +function getCookie(cname) { + var name = cname + "="; + var decodedCookie = decodeURIComponent(document.cookie); + var ca = decodedCookie.split(';'); + for(var i = 0; i \n" + + "
    sdfdsfsfd
    \n" + + ""); + }]); + +angular.module('ddh.att.modalsAndAlerts') + +.controller('modalsAndAlertsController', function ($scope, $modal, $log) { + $scope.name='eeee'; + $scope.items = ['item1', 'item2', 'item3']; + $scope.dt = new Date("March 10, 2014 00:00:00"); + $scope.helperText = "The date you selected is $date. Double tap to open calendar. Select a date to close the calendar."; + $scope.open = function (event) { + var modalInstance = $modal.open({ + templateUrl: 'template/modalsAndAlerts/modal-demo.html', + controller: ModalInstanceCtrl, + sizeClass: 'modal-long-adjust', + resolve: { + items: function () { + return $scope.items; + } + } + }); + + modalInstance.result.then(function (selectedItem) { + $scope.selected = selectedItem; + event.target.focus(); + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + event.target.focus(); + }); + }; + $scope.ok = function () { + //add the ok functionality + console.log("ok"); + }; + $scope.cancel = function () { + //add the cancel functionality + console.log("cancel"); + }; +}) + +var ModalInstanceCtrl = function ($scope, $modalInstance, items) { + $scope.items = items; + $scope.selected = { + item: $scope.items[0] + }; + $scope.ok = function () { + $modalInstance.close($scope.selected.item); + }; + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; +}; diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/modalServiceDS2.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/modalServiceDS2.js new file mode 100644 index 00000000..d3cd8737 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/modalServiceDS2.js @@ -0,0 +1,31 @@ +angular.module("modalServicesDS2",[]).service('modalService', ['$modal', function ($modal) { + + this.popupConfirmWinWithCancel = function(title, msgBody, callback,dismissCallback){ + debugger; + var modalInstance = $modal.open({ + templateUrl: 'confirmation_informativeDS2.html', + //controller: 'modalpopupControllerDS2', + //size: 'sm', + resolve: { + message: function () { + var message = { + title: title, + text: msgBody + }; + return message; + } + } + }); + var args = Array.prototype.slice.call( arguments, 0 ); + args.splice( 0, 3); + modalInstance.result.then(function(){ + callback.apply(null, args); + }, function() { + dismissCallback(); + })['finally'](function(){ + modalInstance = undefined; + }); + + }; + + }]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/profileServiceDS2.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/profileServiceDS2.js new file mode 100644 index 00000000..1ca373f9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/profileServiceDS2.js @@ -0,0 +1,78 @@ +appDS2.factory('ProfileServiceDS2', function ($http, $q) { + return { + getProfile: function() { + return $http.get('get_user') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getProfilePagination: function(pageNum,viewPerPage) { + return $http.get('get_user_pagination?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage) + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getPostProfile: function() { + return $http.get('post_search_sample') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getProfileDetail: function(profileId) { + return $http.get('get_profile?profile_id='+profileId) + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getSelfProfileDetail: function() { + return $http.get('get_self_profile') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + } + }; +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/sampleService.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/sampleService.js new file mode 100644 index 00000000..d762dc9c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/sampleService.js @@ -0,0 +1,19 @@ +appDS2.factory('SampleService', function ($http, $q) { + return { + getCollaborateList: function() { + return $http.get('get_collaborate_list') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + } +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/userInfoServiceDS2.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/userInfoServiceDS2.js new file mode 100644 index 00000000..cfb12dd5 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-services/userInfoServiceDS2.js @@ -0,0 +1,32 @@ +appDS2.factory('UserInfoServiceDS2', function ($http, $q,$log) { + return { + getFunctionalMenuStaticDetailShareContext: function(contextId,key) { + var deferred = $q.defer(); + $http({ + method: "GET", + url: "get_userinfo", + }).success( function(res) { + if(res==null || res=='') + $log.error('userInfoServiceDs2: failed to get user info'); + deferred.resolve(res); + }).error( function(status) { + deferred.reject(status); + }); + return deferred.promise; + }, + getFunctionalMenuStaticDetailSession: function() { + var deferred = $q.defer(); + $http({ + method: "GET", + url: "get_topMenuInfo", + }).success(function(res) { + if(res==null || res=='') + $log.error('userInfoServiceDs2: failed to get top menu info'); + deferred.resolve(res); + }).error( function(status) { + deferred.reject(status); + }); + return deferred.promise; + } + }; +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-landing.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-landing.html new file mode 100644 index 00000000..fc90c273 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-landing.html @@ -0,0 +1,66 @@ + + + + + + + + Workflow + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-listing.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-listing.html new file mode 100644 index 00000000..452dcafa --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-listing.html @@ -0,0 +1,65 @@ + +
    +
    +
    +

    Workflow

    + +
    +
    +
    +
    + +
    +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdNameKeyDescriptionWorkflow Server URLViewActiveCreated Created ByActionScheduleEditDelete?
    {{workflow.id}}{{workflow.name}}{{workflow.workflowKey}}{{workflow.description}}{{workflow.runLink}}
    {{workflow.active}}{{workflow.created}}{{workflow.createdBy}}
    +
    +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-new.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-new.html new file mode 100644 index 00000000..9daebd07 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-new.html @@ -0,0 +1,110 @@ +
    +
    +

    Create Workflows

    +
    + +
    +
    +
    +
    +
    + + +
    + + +
    + Workflow Name is required !!! +
    + +
    +
    + + +
    + +
    + + +
    + Workflow Key is required !!! +
    + +
    +
    + + +
    + + +
    + +
    +
    + +
    + +
    + +
    + +
    + Run Link is required !!! + Not valid url! +
    + +
    + + + + + + +
    + + + + + +
    +
    + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-preview.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-preview.html new file mode 100644 index 00000000..0fb1ffa2 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-preview.html @@ -0,0 +1,24 @@ +
    +
    +

    View Workflow

    +
    + +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-remove.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-remove.html new file mode 100644 index 00000000..a355c07e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-remove.html @@ -0,0 +1,26 @@ +
    +
    +

    Remove Workflow

    +
    + +
    +
    +
    +
    + +
    + +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-schedule.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-schedule.html new file mode 100644 index 00000000..b939a598 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-schedule.html @@ -0,0 +1,130 @@ +
    +
    +

    Workflow: {{workflowToSchedule.name}}

    +
    + +
    + +
    + + + +
    Workflow Key: {{workflowToSchedule.workflowKey}}
    Workflow Description: {{workflowToSchedule.description}}
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + : + + + + + + +
    + + +
    +
    + +
    +
    + +
    +
    + + +Pick a date: + +Hour: + +Minute: +
    +
    + +
    +
    + + + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + + + +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/b2b-leftnav-ext.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/b2b-leftnav-ext.html new file mode 100644 index 00000000..fad0e041 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/b2b-leftnav-ext.html @@ -0,0 +1,43 @@ +
    +
    + +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin-menu-edit.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin-menu-edit.html new file mode 100644 index 00000000..69fd324b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin-menu-edit.html @@ -0,0 +1,102 @@ +
    +
    +

    Admin Menu Items

    +
    +
    + +
    + +

    + Existing menu items +

    + +
    + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Menu IDLabelParentIdSort OrderActionFunctionActiveServletQuery StringExternal URLTargetMenu Set CodeSeparatorImage SourceEditDelete
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    + +
    + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin.html new file mode 100644 index 00000000..8b352652 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin.html @@ -0,0 +1,66 @@ + + + + + + + + Admin + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin_closed_loop.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin_closed_loop.html new file mode 100644 index 00000000..4f65e7b3 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/admin_closed_loop.html @@ -0,0 +1,17 @@ +
    +
    + +

    Closed Loop

    +
    +
    +
    +
    + Cloop Server +
    +
    +
    +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/collaborate-list.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/collaborate-list.html new file mode 100644 index 00000000..05c316c8 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/collaborate-list.html @@ -0,0 +1,76 @@ + +
    +
    + +
    +

    User List

    +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    User IDLast NameFirst NameEmailOrganization User IDOnline/Offline
    {{rowData.id}}{{rowData.lastName}}{{rowData.firstName}}{{rowData.email}}{{rowData.loginId}} +
    Offline
    +
    Online
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/collaboration.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/collaboration.html new file mode 100644 index 00000000..cca54a6b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/collaboration.html @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    +
    + + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/jcs_admin.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/jcs_admin.html new file mode 100644 index 00000000..fd8a5302 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/jcs_admin.html @@ -0,0 +1,73 @@ +
    + +
    +

    Cache Regions

    +
    + +
    +

    + These are the regions which are currently defined in the cache. 'Items' and 'Bytes' refer to the elements currently in memory (not spooled). + You can clear all items for a region by clicking on the Clear icon next to the desired region below. You can also clear all regions + which empties the entire cache.

    +
    + + +
    +
    +
    Cache Name
    +
    # of Items
    +
    Bytes
    +
    Status
    +
    Memory Hits
    +
    Aux Hits
    +
    Not Found Misses
    +
    Expired Misses
    +
    Clear?
    +
    Items
    +
    + +
    +
    + +
    {{region.size}}
    +
    {{region.byteCount}}
    +
    {{region.status}}
    +
    {{region.hitCountRam}}
    +
    {{region.hitCountAux}}
    +
    {{region.missCountNotFound}}
    +
    {{region.missCountExpired}}
    +
    +
    +
    +
    +
    +
    +
    + +
    Key
    +
    Eternal?
    +
    Created
    +
    Max Life
    +
    Expires
    +
    Clear?
    +
    +
    +
    + + +
    {{item.eternal}}
    +
    {{item.createTime}}
    +
    {{item.maxLifeSeconds}}
    +
    {{item.expiresInSeconds}}
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/admin-menu-del-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/admin-menu-del-confirm.html new file mode 100644 index 00000000..5d6cb16c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/admin-menu-del-confirm.html @@ -0,0 +1,22 @@ +
    +
    +

    Menu Item Deletion

    +
    + +
    +
    +
    + You are about to delete '{{fnMenuItem.label}}' Menu Item. Please click 'OK' to continue. +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-confirm.html new file mode 100644 index 00000000..d3eda5e4 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-confirm.html @@ -0,0 +1,22 @@ +
    +
    +

    Clear All Cache Regions

    +
    + +
    +
    +
    + You are about to clear all cache regions. Please click 'OK' to continue. +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-region-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-region-confirm.html new file mode 100644 index 00000000..5f43e2a0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/cache-menu-clear-region-confirm.html @@ -0,0 +1,22 @@ +
    +
    +

    Clear Cache Region

    +
    + +
    +
    +
    + You are about to clear all of the items in the cache region {{msg.text}}. Please click 'OK' to continue. +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/clearItem-region-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/clearItem-region-confirm.html new file mode 100644 index 00000000..004b49d8 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/clearItem-region-confirm.html @@ -0,0 +1,22 @@ +
    +
    +

    Clear Item Cache Region

    +
    + +
    +
    +
    + You are about to clear this item from the cache region {{msg.text}}. Please click 'OK' to continue. +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/collaborate-list-toggle-profile-active-status.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/collaborate-list-toggle-profile-active-status.html new file mode 100644 index 00000000..6a91cb0a --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/collaborate-list-toggle-profile-active-status.html @@ -0,0 +1,22 @@ +
    +
    +

    Change User Status

    +
    + +
    +
    +
    + You are about to change user's active status. Please click 'OK' to continue. +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fn-menu-edit.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fn-menu-edit.html new file mode 100644 index 00000000..2ccdf2af --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fn-menu-edit.html @@ -0,0 +1,129 @@ + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fnmenu-add.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fnmenu-add.html new file mode 100644 index 00000000..167defb7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/popup-modal-fnmenu-add.html @@ -0,0 +1,136 @@ +
    +
    +

    {{label}}

    +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    + + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-child-add-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-child-add-confirm.html new file mode 100644 index 00000000..62f05269 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-child-add-confirm.html @@ -0,0 +1,25 @@ +
    + + + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-confirm-activation.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-confirm-activation.html new file mode 100644 index 00000000..7a663cf3 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-confirm-activation.html @@ -0,0 +1,23 @@ +
    +
    +

    +

    Confirm

    +
    + +
    +
    +
    + You are about to {{msg.text}} the {{msg.roleName}} role. Do you want to continue? +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-delete-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-delete-confirm.html new file mode 100644 index 00000000..45e5ddfc --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-delete-confirm.html @@ -0,0 +1,22 @@ +
    +
    +

    Confrim

    +
    + +
    +
    +
    + You are about to delete {{msg.roleName}} role. Click 'OK' to continue. +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-add-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-add-confirm.html new file mode 100644 index 00000000..ff5ac253 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-add-confirm.html @@ -0,0 +1,25 @@ +
    +
    +

    +

    Confirm

    +
    + +
    +
    +
    + You are about to add the role function {{msg.roleFun}} to the role for {{msg.role}}. Do you want to continue? +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-role-del-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-role-del-confirm.html new file mode 100644 index 00000000..f293152c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-fun-role-del-confirm.html @@ -0,0 +1,22 @@ +
    + + + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-add.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-add.html new file mode 100644 index 00000000..a6912571 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-add.html @@ -0,0 +1,32 @@ +
    +
    +

    Role Function Create

    +
    + +
    +
    + +
    + +
    + Name +
    +
    + Code + +
    +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-del-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-del-confirm.html new file mode 100644 index 00000000..31109112 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-del-confirm.html @@ -0,0 +1,22 @@ +
    +
    +

    Role Function Delete

    +
    + +
    +
    +
    + You are about to delete this role function, '{{msg.text}}'. Click 'OK' to continue. +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-edit.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-edit.html new file mode 100644 index 00000000..ecf69b5a --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-function-edit.html @@ -0,0 +1,22 @@ +
    +
    +

    Role Function Edit

    +
    + +
    +
    +
    +
    + Name +
    +
    + Code +
    +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-child-roles-modal.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-child-roles-modal.html new file mode 100644 index 00000000..94211773 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-child-roles-modal.html @@ -0,0 +1,34 @@ +
    +
    +
    +

    Select Child Roles

    +
    +
    +
    + + + + + + + + + + + + + +
    Role
    + + {{ roleFunction.name }}
    +
    + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-modal.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-modal.html new file mode 100644 index 00000000..c4115c4a --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/modals/role-functions-modal.html @@ -0,0 +1,36 @@ +
    +
    +

    Select Role Functions

    + +
    + +
    + + + + + + + + + + + + + +
    Role Function
    + + {{roleFunction.name}}
    +
    + + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role-function.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role-function.html new file mode 100644 index 00000000..0b07d6e8 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role-function.html @@ -0,0 +1,63 @@ +
    +

    Role Function

    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    + +
    + + + + + + + + + + + + + + + + + + + +
    NameCodeEditDelete
    +
    + +
    +
    +
    + +
    +
    +
    +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role.html new file mode 100644 index 00000000..12d8df70 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role.html @@ -0,0 +1,96 @@ +
    +
    +

    Manage Roles

    +
    +
    +

    Please edit the role details below:

    +
    + +
    + +
    + +
    + +
    + +
    + + +
    +
    +
    +
    +

    Role Functions

    + + + + + + + + + + + + + + + +
    Role Function NameRemove
    {{ roleFunction.name }} +
    +
    +
    +
    + +
    +

    Child Roles

    + + + + + + + + + + + + + + + +
    NameRemove?
    {{ role.name }} +
    +
    +
    +
    + + +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role_list.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role_list.html new file mode 100644 index 00000000..a608a0db --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/role_list.html @@ -0,0 +1,42 @@ +
    +
    +

    Roles

    +
    + +
    + +
    +

    Click on a Role to view its details.

    + + + + + + + + + + + + + + + + + + + + +
    NamePriorityEditActive?Delete?
    {{ availableRole.name }}{{ availableRole.priority }} + + +
    + +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/usage.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/usage.html new file mode 100644 index 00000000..8e411141 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-admin/usage.html @@ -0,0 +1,43 @@ +
    +
    +

    Current Usage

    +
    + +

    + The following table shows all current user sessions. Click the icon to end a user's session. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    User IdUser NameEmailLast Access Time (minutes)Time Remaining (minutes)Expire User Session?
    {{user.id}}{{user.lastName}}{{user.email}}{{user.lastAccess}}{{user.remaining}}
    Current Session
    +
    + +
    +
    + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-add-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-add-confirm.html new file mode 100644 index 00000000..edaa0a1e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-add-confirm.html @@ -0,0 +1,25 @@ +
    +
    +

    +

    Confirm

    +
    + +
    +
    +
    + You are about to change the role {{msg.roleFun}} Do you want to continue? +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-add.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-add.html new file mode 100644 index 00000000..d662fc01 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-add.html @@ -0,0 +1,36 @@ +
    +
    +

    Select Role Functions

    + +
    + +
    + + + + + + + + + + + + + +
    Role Function
    + + {{roleFunction.name}}
    +
    + + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-del-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-del-confirm.html new file mode 100644 index 00000000..b795d35f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/modals/role-del-confirm.html @@ -0,0 +1,23 @@ +
    +
    +

    +

    Confirm

    +
    + +
    +
    +
    + You are about to delete the role '{{msg.role.name}}'. Do you want to continue? +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/profile.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/profile.html new file mode 100644 index 00000000..97bb9aee --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-profile/profile.html @@ -0,0 +1,67 @@ + + + + + + + + Profile Search + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/all-reports.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/all-reports.html new file mode 100644 index 00000000..c90f95b4 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/all-reports.html @@ -0,0 +1,74 @@ + + + + + + + Reports + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/directive/dynamicform.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/directive/dynamicform.js new file mode 100644 index 00000000..9064b0dc --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/directive/dynamicform.js @@ -0,0 +1,113 @@ +appDS2 +.directive('formBuilder', ['$q', '$parse', '$http', '$templateCache', '$compile', '$document', '$timeout', function ($q, $parse, $http, $templateCache, $compile, $document, $timeout) { + return { + restrict: 'E', // supports using directive as element only + scope:{ + ngModel: '=', + ngFormFields: '=', + ngNumFormCols: '=', + ngTriggerMethod: '=', + ngShowFieldId: '=' + }, + link: function ($scope, element, attrs) { + $scope.element=element; + $scope.datetimeformat = "MM/dd/yyyy hh:mm a"; + console.log("$scope"); + console.log($scope); + $scope.buildField = function (field, parentElement) { + var x = ''; + if(field.visible) { + if (field.fieldType === 'LIST_MULTI_SELECT') { + x = angular.element('
    '+ + '
    '+ + ''+ + '
    '); + } else if (field.fieldType === 'LIST_BOX') { + x = angular.element('
    '); + } else if((field.fieldType === 'text' || field.fieldType === 'TEXT') && field.validationType === 'DATE'){ + x = angular.element('
    '); + } else if((field.fieldType === 'text' || field.fieldType === 'TEXT') && field.validationType === 'TIMESTAMP_MIN'){ + x = angular.element('
    '); + } else if(field.fieldType === 'text' || field.fieldType === 'TEXT'){ + x = angular.element('
    '); + } else if(field.fieldType === 'CHECK_BOX'){ + x = angular.element('
    '); + } + } + parentElement.append(x); + $compile(x)($scope); + }; + $scope.buildForm = function() { + // create elements and a + var tbl = angular.element("
    "); + var tblBody = angular.element(""); + var row = angular.element(""); + + var ngFormFieldsLength = $scope.ngFormFields.length; + + for (var j = 0; j < ngFormFieldsLength; j++) { + var cell = angular.element(""); + $scope.buildField($scope.ngFormFields[j],cell); + row.append(cell); + + if((j!=0 && (j+1)%$scope.ngNumFormCols==0) || j==(ngFormFieldsLength-1)){ + tblBody.append(row); + row = angular.element(""); + } + } + tbl.append(tblBody); + angular.element($scope.element).html(''); + $scope.element.append(tbl); + }; + + + $scope.formFieldLuValues = {}; + $scope.getEBZFormat = function() { + if($scope.ngFormFields && $scope.ngFormFields.length>0){ + $scope.ngFormFields.forEach(function(formField) { + if(formField.fieldType === 'LIST_MULTI_SELECT') { + $scope.ngModel[formField.fieldId]= []; + if(formField.formFieldValues && formField.formFieldValues.length>0){ + formField.formFieldValues.forEach(function(entry,i) { + $scope.ngModel[formField.fieldId].push({ index: i, value: entry.id, title: entry.name, defaultValue: entry.defaultValue}); + }); + } + } else if(formField.fieldType==='LIST_BOX') { + $scope.formFieldLuValues[formField.fieldId]= []; + if(formField.formFieldValues && formField.formFieldValues.length>0){ + formField.formFieldValues.forEach(function(entry,i) { + $scope.formFieldLuValues[formField.fieldId].push({ index: i, value: entry.id, title: entry.name}); + if(entry.defaultValue){ + $scope.ngModel[formField.fieldId]={ index: i, value: entry.id, title: entry.name}; + } + }); + } + } else if(formField.fieldType === 'text' || formField.fieldType === 'TEXT' || + formField.validationType === 'DATE' || formField.validationType === 'TIMESTAMP_MIN') { + if(formField.formFieldValues && formField.formFieldValues.length>0){ + $scope.ngModel[formField.fieldId]=formField.formFieldValues[0].id; + } + } + }); + } + }; + + $scope.$watch("ngFormFields",function(newValue,oldValue) { + if($scope.ngFormFields){ + $scope.getEBZFormat(); + $scope.buildForm(); + } + }); + + $scope.triggerFormFields = function(triggerFlag) { + if(triggerFlag){ + $scope.element.html('Loading...'); + $scope.ngTriggerMethod(); + } + }; + + } + }; + }]); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/directive/step-form-directive.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/directive/step-form-directive.js new file mode 100644 index 00000000..a64309bf --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/directive/step-form-directive.js @@ -0,0 +1,14 @@ +appDS2 +.directive('stepForm', function($compile,$http, stepFormFactory) { + return { + restrict: 'AE', + + // scope: { + // jsonSource: '=' + // }, + link: function(scope, elem, attrs) { + var jsonSrcName = "app/fusionapp/scripts/view-models/wz_steps/json/step1.json"; + stepFormFactory.renderForm(jsonSrcName, elem, scope); + } + } +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-del-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-del-confirm.html new file mode 100644 index 00000000..da255bbf --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-del-confirm.html @@ -0,0 +1,26 @@ +
    +
    +

    Remove Report

    +
    + +
    +
    +
    +
    + +
    + +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-formfield-del-confirm.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-formfield-del-confirm.html new file mode 100644 index 00000000..7bdf5a29 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-formfield-del-confirm.html @@ -0,0 +1,26 @@ +
    +
    +

    Remove Formfield

    +
    + +
    +
    +
    +
    + +
    + +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-col-edit.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-col-edit.html new file mode 100644 index 00000000..ad081991 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-col-edit.html @@ -0,0 +1,125 @@ + + +
    +
    +

    Report Column - Edit

    +
    + +
    +
    +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Column ID:{{columnEditData.colId}}
    Display Name:
    Display Alignment: + +
    Display Header Alignment: + +
    Sortable: + +
    Visible: + +
    +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-formfield-edit.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-formfield-edit.html new file mode 100644 index 00000000..c88eb596 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-formfield-edit.html @@ -0,0 +1,149 @@ + + +
    +
    +

    Report Form Field - Edit

    +
    + +
    +
    +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Field Name:
    Field Type: + +
    Visible: + +
    SQL as Default Value: + +
    Default Value:
    Default SQL: + + +

    +
    SQL Generating Custom List of Values: + + +

    +
    +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-test-run-sql.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-test-run-sql.html new file mode 100644 index 00000000..a7955cad --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/modal/report-wizard-test-run-sql.html @@ -0,0 +1,62 @@ + + +
    +
    +

    SQL Test Run - {{isError?'Failed':'Executed'}}

    +
    + +
    +
    +
    +
    + +
    + +
    +

    Error Message:


    +

    {{errormessage}}

    +

    Stack Trace:


    +

    {{stacktrace}}

    + +
    + + + + + + + + + + + + +
    {{colName}}
    {{rowData[keyName]}}
    +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-import.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-import.html new file mode 100644 index 00000000..cd64b09f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-import.html @@ -0,0 +1,14 @@ +
    + +

    Report Import

    + +

    Import XML

    + +
    +

    {{errorMessage}}

    +
    + + + + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-run.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-run.html new file mode 100644 index 00000000..82b7e878 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-run.html @@ -0,0 +1,91 @@ + + +
    + +

    {{reportData.reportHeading}} + + +     +     + + +

    + +

    {{reportData.reportSubTitle}}

    + +
    Loading...
    + +
    + +

    + +
    + Back + +
    +
    +
    +
    +
    + {{reportData.message}} +
    +
    +
    +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-search.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-search.html new file mode 100644 index 00000000..7524acca --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/report-search.html @@ -0,0 +1,54 @@ +
    + +

    Report search

    +
    +
    + + +
    + +
    + +
    + +
    + + + +
    + +
    + +
    + +
    + +
    + +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step1.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step1.json new file mode 100644 index 00000000..091d47e5 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step1.json @@ -0,0 +1,218 @@ +{ + "step" : "1", + "content": { + "title": "Step 1 : Report Definition", + "sections": [ + { + "title": "", + "elements": [ + { + "input": "hidden", + "name": "proj_id", + "displayName": "Project Id", + "defaultValue": "" + }, + { + "input": "text", + "name": "reportName", + "displayName": "Report Name:", + "defaultValue": "" + }, + { + "input": "textarea", + "name": "reportDescr", + "displayName": "Report Description:", + "style":"width:300px;height:80px;" + }, + { + "input": "select", + "name": "reportType", + "ngModelName":"selectedReportType.value", + "displayName": "Report Type: ", + "defaultValue": "no", + "action": "", + "action_img": "", + "optionsName":"reportTypes", + "options":[{"value":"linear", "text":"Linear"}] + }, + { + "input": "select", + "name": "dataSource", + "ngModelName":"selectedDataSource.value", + "displayName": "Data Source:", + "defaultValue": "no", + "action": "", + "action_img": "", + "optionsName":"DataSources", + "options":[{"value":"local", "text":"Local"}] + }, + { + "input": "textarea", + "name": "formHelpText", + "displayName": "Form Help Text:", + "style":"width:300px;height:80px;" + }, + { + "input": "select", + "name": "pageSize", + "ngModelName":"selectedPageSize.value", + "displayName": "Page Size:", + "defaultValue": "no", + "action": "", + "action_img": "", + "optionsName":"PageSizes", + "options":[ {"value":"10", "text":"10"}, + {"value":"20", "text":"20"}, + {"value":"50", "text":"50"}, + {"value":"100", "text":"100"}, + {"value":"500", "text":"500"} + ] + }, + { + "input": "checkboxGroup", + "name":"displayArea", + "displayName": "Display Area:", + "defaultValue": "no", + "action": "", + "action_img": "", + "checkboxes":[{"value":"homeSelected.value", "text":"HOME"}, + {"value":"customerSelected.value", "text":"CUSTOMER"}, + {"value":"reportsSelected.value", "text":"REPORTS"} + ] + }, + + { + "input": "checkboxGroup", + "name": "hideFormFieldsAfterRun", + "displayName": "Hide Form Fields After Run:", + "defaultValue": "no", + "action": "", + "action_img": "", + "optionsName":"HideFormFieldsAfterRun", + "checkboxes":[{"value":"hideFormFieldsAfterRunSelected.value", "text":""} + ] + }, + { + "input": "select", + "name": "maxRowsInExcelCSVDownload", + "ngModelName":"selectedMaxRowsInExcelCSVDownload.value", + "displayName": "Max Rows in Excel/CSV Download:", + "defaultValue": "no", + "action": "", + "action_img": "", + "optionsName":"PageSizes", + "options":[{"value":"500","text":"500"},{"value":"1000","text":"1000"},{"value":"2000","text":"2000"},{"value":"3000","text":"3000"},{"value":"4000","text":"4000"},{"value":"5000","text":"5000"},{"value":"10000","text":"10000"},{"value":"15000","text":"15000"},{"value":"20000","text":"20000"},{"value":"25000","text":"25000"},{"value":"30000","text":"30000"},{"value":"35000","text":"35000"},{"value":"40000","text":"40000"},{"value":"45000","text":"45000"},{"value":"50000","text":"50000"},{"value":"65000","text":"65000"}] + }, + { + "input": "select", + "name": "frozenColumns", + "ngModelName":"selectedFrozenColumns.value", + "displayName": "Columns to be Frozen:", + "defaultValue": "", + "action": "", + "action_img": "", + "optionsName":"frozenColumnsOptions", + "options":[{"value":"0","text":"0"},{"value":"1","text":"1"},{"value":"2","text":"2"},{"value":"3","text":"3"},{"value":"4","text":"4"}] + }, + { + "input": "select", + "name": "dataGridAlign", + "ngModelName":"selectedDataGridAlign.value", + "displayName": "Data Grid Align:", + "defaultValue": "", + "action": "", + "action_img": "", + "optionsName":"selectedDataGridAlignOptions", + "options":[{"value":"left","text":"Left"},{"value":"right","text":"Right"},{"value":"center","text":"Center"}] + }, + { + "input": "textarea", + "name": "emptyMessage", + "displayName": "Empty Message:", + "style":"width:300px;height:80px;" + }, + { + "input": "select", + "name": "dataContainerHeight", + "ngModelName":"selectedDataContainerHeight.value", + "displayName": "Height of the Data Container:", + "defaultValue": "", + "action": "", + "action_img": "", + "optionsName":"dataContainerHeightOptions", + "options":[{"value":"200","text":"200%"},{"value":"190","text":"190%"},{"value":"180","text":"180%"},{"value":"170","text":"170%"},{"value":"160","text":"160%"},{"value":"150","text":"150%"},{"value":"140","text":"140%"},{"value":"130","text":"130%"},{"value":"120","text":"120%"},{"value":"110","text":"110%"},{"value":"100","text":"100%"},{"value":"90","text":"90%"},{"value":"80","text":"80%"},{"value":"70","text":"70%"},{"value":"60","text":"60%"},{"value":"50","text":"50%"},{"value":"40","text":"40%"},{"value":"30","text":"30%"},{"value":"20","text":"20%"},{"value":"10","text":"10%"}] + }, + { + "input": "select", + "name": "dataContainerWidth", + "ngModelName":"selectedDataContainerWidth.value", + "displayName": "Width of the Data Container:", + "defaultValue": "", + "action": "", + "action_img": "", + "optionsName":"dataContainerWidthOptions", + "options":[{"value":"200","text":"200%"},{"value":"190","text":"190%"},{"value":"180","text":"180%"},{"value":"170","text":"170%"},{"value":"160","text":"160%"},{"value":"150","text":"150%"},{"value":"140","text":"140%"},{"value":"130","text":"130%"},{"value":"120","text":"120%"},{"value":"110","text":"110%"},{"value":"100","text":"100%"},{"value":"90","text":"90%"},{"value":"80","text":"80%"},{"value":"70","text":"70%"},{"value":"60","text":"60%"},{"value":"50","text":"50%"},{"value":"40","text":"40%"},{"value":"30","text":"30%"},{"value":"20","text":"20%"},{"value":"10","text":"10%"}] + }, + { + "input": "checkboxGroup", + "name": "displayOptions", + "displayName": "Display Options:", + "defaultValue": "no", + "action": "", + "action_img": "", + "checkboxes":[{"value":"hideFormFieldsSelected.value", "text":"Hide Form Fields"}, + {"value":"hideChartSelected.value", "text":"Hide Chart"}, + {"value":"hideReportDataSelected.value", "text":"Hide Report Data"}, + {"value":"hideExcelSelected.value", "text":"Hide Excel"}, + {"value":"hidePdfSelected.value", "text":"Hide PDF"} + ] + }, + { + "input": "checkboxGroup", + "name":"runtimeColSort", + "displayName": "Disable column sort at runtime:", + "defaultValue": "no", + "action": "", + "action_img": "", + "checkboxes":[{"value":"runtimeColSortDisabled.value", "text":""} + ] + }, + { + "input": "select", + "name": "runtimeFormNumberColumns", + "ngModelName":"selectedNumFormCols.value", + "displayName": "Run-time Form Number Columns:", + "defaultValue": "no", + "action": "", + "action_img": "", + "optionsName":"runtimeFormNumberColumns", + "options":[ {"value":"1", "text":"1"}, + {"value":"2", "text":"2"}, + {"value":"3", "text":"3"}, + {"value":"3", "text":"4"} + ] + }, + { + "input": "text", + "name": "reportTitle", + "displayName": "Report Title:", + "defaultValue": "" + }, + { + "input": "text", + "name": "reportSubTitle", + "displayName": "Report Subtitle:", + "defaultValue": "" + } + ] + + }, + { + "title": "finalButton", + "submitAction" : "", + "next":"Microservice Config", + "previous":"none" + } + ] + } +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step2.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step2.json new file mode 100644 index 00000000..ca01985d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step2.json @@ -0,0 +1,34 @@ +{ + "step" : "2", + "content": { + "title": "Step 2 : Report SQL", + "sections": [ + { + "title": "", + "elements": [ + { + "input": "textarea", + "spanOverTwoColumns":"true", + "name": "sqlScript", + "displayName": "SQL script:", + "defaultValue":"SELECT ", + "style":"width: 600px; height: 400px" + } + ], + "buttons": [ + { + "text":"Validate/Test Run SQL", + "value":"next", + "ngFunction":"testRunSql()" + }] + + }, + { + "title": "finalButton", + "submitAction" : "", + "next":"Microservice Config", + "previous":"none" + } + ] + } +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step3.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step3.json new file mode 100644 index 00000000..9ea9b6f4 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step3.json @@ -0,0 +1,19 @@ +{ + "step" : "3", + "content": { + "title": "", + "sections": [ + { + "title": "", + "elements": [ + ] + }, + { + "title": "finalButton", + "submitAction" : "", + "next":"Microservice Config", + "previous":"none" + } + ] + } +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step4.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step4.json new file mode 100644 index 00000000..971a0cf3 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step4.json @@ -0,0 +1,25 @@ +{ + "step" : "4", + "content": { + "title": "", + "sections": [ + { + "title": "", + "elements": [ + ], + "buttons": [ + { + "text":"Add", + "value":"add", + "ngFunction":"addNewFormField()" + }] + }, + { + "title": "finalButton", + "submitAction" : "", + "next":"Microservice Config", + "previous":"none" + } + ] + } +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step5.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step5.json new file mode 100644 index 00000000..e1675cde --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/json/step5.json @@ -0,0 +1,28 @@ +{ + "step" : "5", + "last_step": true, + "hideSaveButton":true, + "hideBackButton":true, + "content": { + "title": "Step 5 : Run", + "sections": [ + { + "elements": [ + ], + "buttons": [ + { + "text":"Run Report", + "value":"next", + "ngFunction":"RunCurrentReport()" + }] + }, + { + "title": "finalButton", + "submitAction" : "", + "next":"Microservice Config", + "previous":"none" + } + ] + + } +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/report-step.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/report-step.html new file mode 100644 index 00000000..5767afb2 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-reports/wz_steps/report-step.html @@ -0,0 +1,101 @@ + + + +
    +

    Report Wizard

    + + + + + + + {{tab.title}} + + +

    + + + + +
    +

    Step 3 : Columns

    + + + + + + + + + + + + + + + + + +
    NoColumn NameIDEdit
    {{$index+1}}{{rowData.name}}{{rowData.id}}
    +
    + +
    +

    Step 4 : Form Fields

    + + + + + + + + + + + + + + + + + + +
    NoField NameEditDelete
    {{$index+1}}{{rowData.name}}[{{rowData.id}}]
    +
    + +
    + +
    + + + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/drools-list.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/drools-list.html new file mode 100644 index 00000000..b94b5c08 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/drools-list.html @@ -0,0 +1,32 @@ +
    +

    Drools List

    +
    + + + + + + + + + + + + + + + + +
    Drools File NameClass NameRun Rule
    +
    + +
    +
    + +
    No records found
    +
    + Go to Drools Rule Engine import page + +
    + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/drools.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/drools.html new file mode 100644 index 00000000..cbc0cfc0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/drools.html @@ -0,0 +1,55 @@ + +
    +
    +

    Drools Rule Engine

    +
    +
    +

    Please enter below details:

    +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    +
    + + Go to Drools list page +
    +
    + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/frame_insert.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/frame_insert.html new file mode 100644 index 00000000..5c2e45f9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/frame_insert.html @@ -0,0 +1,27 @@ +
    test
    + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-frame.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-frame.html new file mode 100644 index 00000000..c9bcc27d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-frame.html @@ -0,0 +1,74 @@ + + + + + + + Notebook Page + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-page.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-page.html new file mode 100644 index 00000000..0db933d6 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-page.html @@ -0,0 +1,80 @@ +
    +
    +

    Notebook

    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    + + Remove +
    + +
    +
    +
    +
    + + + + +
    + +
    + Submit +
    + + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-viz.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-viz.html new file mode 100644 index 00000000..4c89ee41 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-viz.html @@ -0,0 +1,7 @@ +
    + + +
    + + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2Header.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2Header.html new file mode 100644 index 00000000..ef847518 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2Header.html @@ -0,0 +1,69 @@ +
    +
    + +
    + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2Left_menu.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2Left_menu.html new file mode 100644 index 00000000..c30a0b69 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/ds2Left_menu.html @@ -0,0 +1,3 @@ +
    + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/loginSnippet.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/loginSnippet.html new file mode 100644 index 00000000..19868bb6 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/loginSnippet.html @@ -0,0 +1,63 @@ + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-content.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-content.html new file mode 100644 index 00000000..2626d01a --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-content.html @@ -0,0 +1,191 @@ +
    + + +
    +
      +
    • +
      +
      + + + + + + +
      +

      {{item.headerText}}

      +

      {{item.headerText.length<36?item.headerText:item.headerText.substring(0,35)+' ...'}}

      +
      +
      +
      + + + + +
      + + +
      +
      +
      +
      + +
      + +
      +
      + +
      +
      + +
      +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      +
      + +
      + + +
      +
      + +
      + +
      +
      +
        +
      • {{Daytab.title}}
      • +
      +
      +
      +
      + + + + + + + +
      +
      + +
      +
      +
        +
      • {{TrafficTab.title}}
      • +
      +
      +
      +
      + + + + + +
      +
      + +
      + + + + + + + + + + + + + + + + + + + + + +
      JQuery + +
      Network Simulation + +
      Animated Map + +
      Chat Session + +
      +
      +
      +
      +
      + +
      + + + + + + + + +
      + +
      +
      +
      +
    • +
    +
    + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-sample.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-sample.html new file mode 100644 index 00000000..52305d55 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome-sample.html @@ -0,0 +1,112 @@ + + + + + + Welcome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome.html new file mode 100644 index 00000000..b2cafdac --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/DS2-view-models/welcome.html @@ -0,0 +1,151 @@ + + + + + + + + Welcome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/att_angular_gridster/angular-gridster.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/att_angular_gridster/angular-gridster.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/att_angular_gridster/angular-gridster.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/att_angular_gridster/angular-gridster.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/att_angular_gridster/ui-gridster-tpls.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/att_angular_gridster/ui-gridster-tpls.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/att_angular_gridster/ui-gridster-tpls.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/att_angular_gridster/ui-gridster-tpls.js diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/admin-closed-cloop.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/admin-closed-cloop.js new file mode 100644 index 00000000..39ef50e8 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/admin-closed-cloop.js @@ -0,0 +1,28 @@ +app.controller('adminClosedLoopController', ['$scope','$http','$q','$log',function ($scope, $http,$q, $log){ + $scope.camunda_cockpit_url = ''; + var deferred = $q.defer(); + $http({ + method: "GET", + url: "get_camunda_cockpit_link", + }).success( function(res) { + // if the returned response is error HTML page in string format + if(res.link_defined=='false'){ + $log.error('Retrieval of camunda cockpit link failed. Please make sure the variable "camunda_cockpit_url" is defined in the system.properties file.'); + deferred.reject(status); + } + // valid cockpit url + else if(res.camunda_cockpit_link!=null & res.camunda_cockpit_link!= '') { + $scope.camunda_cockpit_url = res.camunda_cockpit_link; + deferred.resolve(res); + // if the defined url is empty; + } else { + $log.error('Please ensure the variable "camunda_cockpit_url" is properly defined in system.properties file (i.e., neither null nor empty).'); + deferred.reject(status); + } + // API call fails + }).error( function(status) { + $log.error('get_camunda_cockpit_link RestAPI call failed.'); + deferred.reject(status); + }); + return deferred.promise; +}]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/admin-whitelist.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/admin-whitelist.js new file mode 100644 index 00000000..5eed3003 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/admin-whitelist.js @@ -0,0 +1,3 @@ +app.config(function ($sceDelegateProvider) { + $sceDelegateProvider.resourceUrlWhitelist(['self','**']); +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/ase-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/ase-controller.js new file mode 100644 index 00000000..3d92220f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/ase-controller.js @@ -0,0 +1,3 @@ +app.controller('aseCtrl', function ($scope){ +/* do nothing yet*/ +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/broadcast-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/broadcast-controller.js new file mode 100644 index 00000000..a6cde5ae --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/broadcast-controller.js @@ -0,0 +1,60 @@ +app.controller('broadcastController', function ($scope, modalService, $modal,AdminService,$routeParams){ + //$scope.broadcastMessage=${broadcastMessage}; + //$scope.broadcastSites=${broadcastSites}; + //console.log($scope.broadcastMessage); + $scope.broadcastMessage=[]; + $scope.broadcastSites=[]; + AdminService.getBroadcast($routeParams.messageLocationId, $routeParams.messageLocation, $routeParams.messageId).then(function(data){ + var j = data; + $scope.data = JSON.parse(j.data); + $scope.broadcastMessage=JSON.parse($scope.data.broadcastMessage); + $scope.broadcastSites=JSON.parse($scope.data.broadcastSites); + console.log($scope.broadcastMessage); + console.log($scope.broadcastMessage.id); + console.log($scope.broadcastSites); + //$scope.resetMenu(); + + },function(error){ + console.log("failed"); + reloadPageOnce(); + }); + + $scope.save = function() { + var uuu = "broadcast/save"; + var postData={broadcastMessage: $scope.broadcastMessage}; + $.ajax({ + type : 'POST', + url : uuu, + dataType: 'json', + contentType: 'application/json', + data: JSON.stringify(postData), + success : function(data){ + window.location.href = "admin#/broadcast_list"; + }, + error : function(data){ + modalService.showFailure("Fail","Error while saving."); + } + }); + }; + + $scope.close = function() { + window.location.href = "admin#/broadcast_list"; +}; + +}); + +$(function() { + $( "#startDatepicker" ).datepicker(); + $( "#endDatepicker" ).datepicker(); + + $( "#startDatepicker" ).change(function() { + var tempStartDate = moment($( "#startDatepicker" ).val()).format('YYYY-MM-DD hh:mm:ss.S'); + $( "#startDateHidden" ).val(tempStartDate.toString()); + //alert( $( "#startDateHidden" ).val() ); + }); + $( "#endDatepicker" ).change(function() { + var tempEndDate = moment($( "#endDatepicker" ).val()).format('YYYY-MM-DD hh:mm:ss.S'); + $( "#endDateHidden" ).val(tempEndDate.toString()); + //alert( $( "#endDateHidden" ).val() ); + }); +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/broadcast-list-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/broadcast-list-controller.js new file mode 100644 index 00000000..0af15b78 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/broadcast-list-controller.js @@ -0,0 +1,101 @@ +app.controller('broadcastListController', function ($scope, modalService, $modal,AdminService){ + //$scope.broadcastMessage=${broadcastMessage}; + //$scope.broadcastSites=${broadcastSites}; + //console.log($scope.broadcastMessage); + var messagesMap = {}; + AdminService.getBroadcastList().then(function(data){ + + var j = data; + $scope.data = JSON.parse(j.data); + $scope.messagesList=(($scope.data.messagesList===null) ? [""]:$scope.data.messagesList); + $scope.messageLocations=(($scope.data.messageLocations===null) ? [""]:$scope.data.messageLocations); + console.log("messages: "+$scope.messagesList); + console.log("location: "+$scope.messageLocations); + $.each($scope.messageLocations, function(i, a){ + //var result = []; + angular.forEach($scope.messagesList, function(value, key) { + if (key+'' === a.value+'') { + //var objsJSON = JSON.parse(value); + + $.each(value, function(i, a){ + var startDateLong = a.startDate; + var tempStartDate = new Date(startDateLong); + tempStartDate = moment(tempStartDate).format('DD MMM YYYY hh:mmA zz');//03 Jun 2013 04:15PM EDT + a.displayStartDate=tempStartDate.toString(); + + var endDateLong = a.endDate; + var tempEndDate = new Date(endDateLong); + tempEndDate = moment(tempEndDate).format('DD MMM YYYY hh:mmA zz');//03 Jun 2013 04:15PM EDT + a.displayEndDate=tempEndDate.toString(); + }); + a.messages = value; + } + }); + console.log(a.messages); + }); + + //$scope.resetMenu(); + + },function(error){ + console.log("failed"); + reloadPageOnce(); + }); + + + $scope.editMessage = function(location) { + + editMessage(location.value, location.label); + }; + + $scope.toggleActive = function(broadcastMessage) { + + //alert('deleted'+role.name); + var uuu = "broadcast_list/toggleActive"; + var postData={broadcastMessage:broadcastMessage}; + $.ajax({ + type : 'POST', + url : uuu, + dataType: 'json', + contentType: 'application/json', + data: JSON.stringify(postData), + success : function(data){ + //window.location.reload(); + }, + error : function(data){ + console.log(data); + modalService.showFailure("Fail","Error while toggling: "+ data.responseText); + + } + }); + + + }; + + $scope.remove = function(broadcastMessage) { + + //alert('deleted'+role.name); + var uuu = "broadcast_list/remove"; + var postData={broadcastMessage:broadcastMessage}; + $.ajax({ + type : 'POST', + url : uuu, + dataType: 'json', + contentType: 'application/json', + data: JSON.stringify(postData), + success : function(data){ + window.location.reload(); + }, + error : function(data){ + console.log(data); + modalService.showFailure("Fail","Error while deleting: "+ data.responseText); + } + }); + + + }; + +}); + +function editMessage(messageLocationId, messageLocation, messageId) { + window.location='admin#/broadcast/'+messageLocationId + '/' + messageLocation + ((messageId != null) ? '/' + messageId : ''); +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/collaborate-list-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/collaborate-list-controller.js new file mode 100644 index 00000000..a1831b7e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/collaborate-list-controller.js @@ -0,0 +1,44 @@ +app.controller("collaborateListController", function ($scope,$http,modalService, $modal,AdminService) { + // Table Data + AdminService.getCollaborateList().then(function(data){ + + var j = data; + $scope.tableData = JSON.parse(j.data); + //$scope.resetMenu(); + + },function(error){ + console.log("failed"); + reloadPageOnce(); + }); + + $scope.viewPerPage = 20; + $scope.scrollViewsPerPage = 2; + $scope.currentPage = 1; + $scope.totalPage; + $scope.searchCategory = ""; + $scope.searchString = ""; + /* modalService.showSuccess('','Modal Sample') ; */ + for(x in $scope.tableData){ + if($scope.tableData[x].active_yn=='Y') + $scope.tableData[x].active_yn=true; + else + $scope.tableData[x].active_yn=false; + } + $scope.openCollaboration = function(chatId){ + openInNewTab('openCollaboration?chat_id=' + chatId); + } + + $scope.toggleProfileActive = function(profileId) { + modalService.popupConfirmWin("Confirm","You are about to change user's active status. Do you want to continue?", + function(){ + $http.get("profile/toggleProfileActive?profile_id="+profileId).success(function(){}); + + }) + }; + +}); + +function openInNewTab(url) { + var win = window.open(url, '_blank'); + win.focus(); +}; \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/dummy.txt diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/modelpopupController.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/modelpopupController.js new file mode 100644 index 00000000..48fbbc03 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/controllers/modelpopupController.js @@ -0,0 +1,21 @@ +var modalpopupController = function ($scope, $modalInstance, message){ + + $scope.message = message; + + + $scope.hello = function () { + $modalInstance.close($scope.digitPattern); + }; + $modalInstance.ok = function() { + //add the ok functionality + alert("Logout"); + }; + $modalInstance.cancel = function() { + //add the cancel functionality + alert("Keep Log in"); + }; + $modalInstance.cancelbutton = function() { + //add the cancel functionality + alert("Modal Waring popup close event"); + }; +} \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/dummy.txt diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/footer.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/footer.js new file mode 100644 index 00000000..d49f5980 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/footer.js @@ -0,0 +1,11 @@ +app.directive('qFooter', function () { + return { + restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements + replace: false, + templateUrl: "app/fusion/scripts/view-models/footer.html", + controller: ['$scope', '$filter', function ($scope, $filter) { + // Your behaviour goes here :) + }] + } +}); + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/header.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/header.js new file mode 100644 index 00000000..7696251e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/header.js @@ -0,0 +1,479 @@ +app.directive('qHeader', function () { + return { + restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements + replace: false, + templateUrl: "app/fusion/scripts/view-models/header.html", + controller: ['$scope', '$filter','$http','$timeout', '$log','UserInfoService', '$window', '$cookies', function ($scope, $filter, $http, $timeout, $log,UserInfoService, $window, $cookies) { + + /*Define fields*/ + $scope.userName; + $scope.userFirstName; + $scope.redirectUrl; + $scope.contactUsUrl; + $scope.getAccessUrl; + $scope.childData=[]; + $scope.parentData=[]; + $scope.menuItems = []; + $scope.loadMenufail=false; + $scope.megaMenuDataObject=[]; + $scope.activeClickSubMenu = { + x: '' + }; + $scope.activeClickMenu = { + x: '' + }; + $scope.favoritesMenuItems = []; + $scope.favoriteItemsCount = 0; + $scope.showFavorites = false; + $scope.emptyFavorites = false; + $scope.favoritesWindow = false; + + /*Menu Structure*/ + var menuStructureConvert = function(menuItems) { + // console.log(menuItems); + $scope.megaMenuDataObjectTemp = + [ + { + text: "ECOMP", + children: menuItems + }, + { + text: "Help", + children: [ + { + text:"Contact Us", + url:$scope.contactUsUrl + }, + { + text:"Get Access", + url:$scope.getAccessUrl + }] + } + ]; + return $scope.megaMenuDataObjectTemp; + }; + + /***************functions**************/ + /*Put user info into fields*/ + $scope.inputUserInfo = function(userInfo){ + if (typeof(userInfo) != "undefined" && userInfo!=null && userInfo!=''){ + if(typeof(userInfo.USER_FIRST_NAME) != "undefined" && userInfo.USER_FIRST_NAME!=null){ + $scope.userFirstName = userInfo.USER_FIRST_NAME; + } + } + } + /*getting user info from session*/ + $scope.getUserNameFromSession = function(){ + UserInfoService.getFunctionalMenuStaticDetailSession() + .then(function (res) { + $scope.contactUsUrl=res.contactUsLink; + $scope.userName = res.userName; + $scope.userFirstName = res.firstName; + $scope.redirectUrl = res.portalUrl; + $scope.getAccessUrl = res.getAccessUrl; + }); + } + $scope.getTopMenuStaticInfo=function() { + var promise = UserInfoService.getFunctionalMenuStaticDetailShareContext(); + promise.then( + function(res) { + if(res==null || res==''){ + $log.error('failed to get static User information'); + $scope.getUserNameFromSession(); + }else{ + // $log.info('Received static User information'); + var resData = res; + // console.log(resData); + $scope.inputUserInfo(resData); + $scope.userName = $scope.firstName+ ' '+ $scope.lastName; + } + }, + function(err) { + $log.error('getFunctionalMenuStaticDetailShareContext failed', err); + } + ); + } + + $scope.returnToPortal=function(){ + window.location.href = $scope.redirectUrl; + } + + var unflatten = function( array, parent, tree ){ + tree = typeof tree !== 'undefined' ? tree : []; + parent = typeof parent !== 'undefined' ? parent : { menuId: null }; + var children = _.filter( array, function(child){ return child.parentMenuId == parent.menuId; }); + if( !_.isEmpty( children ) ){ + if( parent.menuId === null ){ + tree = children; + }else{ + parent['children'] = children + } + _.each( children, function( child ){ unflatten( array, child ) } ); + } + return tree; + } + + $scope.getMenu=function() { + $scope.getTopMenuStaticInfo(); + $http({ + method: "GET", + url: 'get_functional_menu', +// TIMEOUT USED FOR LOCAL TESTING ONLY +// timeout: 100 + }).success(function (response) { + + if (response == '101: Timeout') { + $log.debug('Timeout attempting to get_functional_menu'); + $scope.megaMenuDataObject = menuStructureConvert(""); +// $scope.createErrorMenu(); + //$scope.loadMenufail=true; + } else { + if(typeof response != 'undefined' && response.length!=0 && typeof response[0] != 'undefined' && typeof response[0].error!="undefined"){ + $log.debug('Timeout attempting to get_functional_menu'); + $scope.menuItems = unflatten( response); + $scope.megaMenuDataObject = menuStructureConvert($scope.menuItems); +// $scope.createErrorMenu(); + //$scope.loadMenufail=true; + }else{ + $scope.loadMenufail=false; + $scope.contactUsURL = response.contactUsLink; + $log.debug('functional_menu',response); + $scope.megaMenuDataObject = menuStructureConvert(""); + } + } + }).error(function (response){ + $scope.megaMenuDataObject = menuStructureConvert(""); +// $scope.createErrorMenu(); + //$scope.loadMenufail=true; + $log.debug('REST API failed get_functional_menu...'); + }); + + } + + $scope.adjustHeader=function() { + $scope.showHeader = ($cookies.show_app_header == undefined ? true : $cookies.show_app_header); + + if($scope.showHeader == true) { + $scope.drawer_margin_top = 70; + $scope.drawer_custom_top = 54; + $scope.toggle_drawer_top = 55; + } + else { + + $scope.drawer_margin_top = 60; + $scope.drawer_custom_top = 0; + $scope.toggle_drawer_top = 10; + } + + } + + $scope.getMenu(); + $scope.adjustHeader(); + +/* **************************************************************************/ +/* Logic for the favorite menus is here */ + + $scope.loadFavorites = function () { + $log.debug('loadFavorites has happened.'); + if ($scope.favoritesMenuItems == '') { + $scope.generateFavoriteItems(); + $log.debug('loadFavorites is calling generateFavoriteItems()'); + } else { + $log.debug('loadFavorites is NOT calling generateFavoriteItems()'); + } + } + + $scope.goToUrl = function (item) { + $log.debug("goToUrl called", item); + + var url = item.url; + var restrictedApp = item.restrictedApp; + // $log.debug('Restricted app status is: ' + restrictedApp); + if (!url) { + $log.error('No url found for this application, doing nothing..'); + return; + } + if (restrictedApp) { + $window.open(url, '_blank'); + } else { + $window.open(url, '_self'); + } + + } + + $scope.submenuLevelAction = function(index, column) { + if ($scope.favoritesMenuItems == '') { + $scope.generateFavoriteItems(); + $log.debug('submenuLevelAction is calling generateFavoriteItems()'); + } + $log.debug('item hovered/clicked: ' + index + '; column = ' + column); + if (column == 2) { // 2 is Design + $scope.favoritesWindow = false; + $scope.showFavorites = false; + $scope.emptyFavorites = false; + } + if (index=='Favorites' && $scope.favoriteItemsCount != 0) { + $log.debug('Showing Favorites window'); + $scope.favoritesWindow = true; + $scope.showFavorites = true; + $scope.emptyFavorites = false; + } + if (index=='Favorites' && $scope.favoriteItemsCount == 0) { + $log.debug('Hiding Favorites window in favor of No Favorites Window'); + $scope.favoritesWindow = true; + $scope.showFavorites = false; + $scope.emptyFavorites = true; + } + if (column > 2) { + $scope.favoritesWindow = false; + $scope.showFavorites = false; + $scope.emptyFavorites = false; + } + }; + + $scope.hideFavoritesWindow = function() { + $log.debug('$scope.hideFavoritesWindow has been called'); + $scope.showFavorites = false; + $scope.emptyFavorites = false; + } + + $scope.isUrlFavorite = function (menuId) { +// $log.debug('array objects in menu favorites = ' + $scope.favoriteItemsCount + '; menuId=' + menuId); + var jsonMenu = JSON.stringify($scope.favoritesMenuItems); + var isMenuFavorite = jsonMenu.indexOf('menuId\":' + menuId); + if (isMenuFavorite==-1) { + return false; + } else { + return true; + } + + } + + $scope.generateFavoriteItems = function() { + $http({ + method: "GET", + url: 'get_favorites', +// TIMEOUT USED FOR LOCAL TESTING ONLY +// timeout: 100 + }).success(function (response) { + if (response == '101: Timeout') { + $log.error('Timeout attempting to get_favorites_menu'); + } else { + if(typeof response != 'undefined' && response.length!=0 && typeof response[0] != 'undefined' && typeof response[0].error!="undefined"){ + $log.error('REST API failed get_favorites' + response); + }else{ + $log.debug('get_favorites = ' + JSON.stringify(response)); + $scope.favoritesMenuItems = response; + $scope.favoriteItemsCount = Object.keys($scope.favoritesMenuItems).length; + // $log.info('number of favorite menus: ' + $scope.favoriteItemsCount); + } + } + }).error(function (response){ + $log.error('REST API failed get_favorites' + response); +//createFavoriteErrorMenu() USED FOR LOCAL TESTING ONLY +// $scope.createFavoriteErrorMenu(); + }); + } + + $scope.createFavoriteErrorMenu=function() { + $scope.favoritesMenuItems = []; + $scope.favoriteItemsCount = Object.keys($scope.favoritesMenuItems).length; + // $log.info('number of favorite menus: ' + $scope.favoriteItemsCount); + } + + /* end of Favorite Menu code */ + /* **************************************************************************/ + + + /* **************************************************************************/ + // THIS IS USED FOR LOCAL TESTING ONLY + /* **************************************************************************/ + $scope.createErrorMenu=function() { + $log.debug('Creating fake menu now...'); +// $scope.loadMenufail=true; + $scope.menuItems = [ + { + "menuId": 1, + "column": 2, + "text": "Design", + "parentMenuId": null, + "url": "" + }, + { + "menuId": 2, + "column": 3, + "text": "Infrastructure Ordering", + "parentMenuId": null, + "url": "" + }, + { + "menuId": 3, + "column": 4, + "text": "Service Creation", + "parentMenuId": null, + "url": "" + }, + { + "menuId": 4, + "column": 5, + "text": "Service Mgmt", + "parentMenuId": null, + "url": "" + }, + { + "menuId": 90, + "column": 1, + "text": "Google", + "parentMenuId": 1, + "url": "http://google.com" + }, + { + "menuId": 91, + "column": 1, + "text": "Mike Little's Coffee Cup", + "parentMenuId": 2, + "url": "http://coffee.com" + }, + { + "menuId": 92, + "column": 2, + "text": "Andy and his Astrophotgraphy", + "parentMenuId": 3, + "url": "http://nightskypix.com" + }, + { + "menuId": 93, + "column": 1, + "text": "JSONLint", + "parentMenuId": 4, + "url": "http://http://jsonlint.com" + }, + { + "menuId": 94, + "column": 2, + "text": "HROneStop", + "parentMenuId": 4, + "url": "http://ebiz.sbc.com/hronestop" + }, + { + "menuId": 95, + "column": 2, + "text": "4th Level App4a R16", + "parentMenuId": 4, + "url": "http://www.e-access.att.com/ecomp_portal_ist/ecompportal/widgets" + }, + { + "menuId": 96, + "column": 3, + "text": "3rd Level App1c R200", + "parentMenuId": 4, + "url": "http://app1c.com" + }, + { + "menuId": 97, + "column": 1, + "text": "3rd Level App4b R16", + "parentMenuId": 5, + "url": "http://app4b.com" + }, + { + "menuId": 98, + "column": 2, + "text": "3rd Level App2b R16", + "parentMenuId": 5, + "url": "http://app2b.com" + }, + { + "menuId": 99, + "column": 1, + "text": "Favorites", + "parentMenuId": null, + "url": "" + } + ]; + $scope.menuItems = unflatten( $scope.menuItems ); + //remove this + $scope.megaMenuDataObject = menuStructureConvert($scope.menuItems); + } + }] + } +}); + +app.filter("ellipsis", function(){ + return function(text, length){ + if (text) { + var ellipsis = text.length > length ? "..." : ""; + return text.slice(0, length) + ellipsis; + }; + return text; + } +}); + +function reloadPageOnce() { + if( window.localStorage ) + { + if( !localStorage.getItem('firstLoad') ) + { + localStorage['firstLoad'] = true; + window.location.reload(); + } + else + localStorage.removeItem('firstLoad'); + } +} +app.controller('loginSnippetCtrl', function ($scope,$http, $log,UserInfoService){ + /*Define fields*/ + $scope.userProfile={ + firstName:'', + lastName:'', + fullName:'', + email:'', + } + /*Put user info into fields*/ + $scope.inputUserInfo = function(userInfo){ + if (typeof(userInfo) != "undefined" && userInfo!=null && userInfo!=''){ + if (typeof(userInfo.USER_FIRST_NAME) != "undefined" && userInfo.USER_FIRST_NAME!=null && userInfo.USER_FIRST_NAME!='') + $scope.userProfile.firstName = userInfo.USER_FIRST_NAME; + if (typeof(userInfo.USER_LAST_NAME) != "undefined" && userInfo.USER_LAST_NAME!=null && userInfo.USER_LAST_NAME!='') + $scope.userProfile.lastName = userInfo.USER_LAST_NAME; + if (typeof(userInfo.USER_EMAIL) != "undefined" && userInfo.USER_EMAIL!=null && userInfo.USER_EMAIL!='') + $scope.userProfile.email = userInfo.USER_EMAIL; + + } + } + /*getting user info from session*/ + $scope.getUserNameFromSession = function(){ + UserInfoService.getFunctionalMenuStaticDetailSession() + .then(function (response) { + $scope.userProfile.fullName = response.userName; + $scope.userProfile.email = response.email; + }); + } + /*getting user info from shared context*/ + $scope.getUserName=function() { + var promise = UserInfoService.getFunctionalMenuStaticDetailShareContext(); + promise.then( + function(res) { + if(res==null || res==''){ + $log.error('getFunctionalMenuStaticDetailShareContext failed'); + $scope.getUserNameFromSession(); + }else{ + // $log.info('Received User information from shared context',res); + var resData = res; + // console.log(resData); + $scope.inputUserInfo(resData); + $scope.userProfile.fullName = $scope.userProfile.firstName+ ' '+ $scope.userProfile.lastName; + } + }, + function(err) { + console.log('getFunctionalMenuStaticDetailShareContext failed', err); + } + ); + }; + /*call the get user info function*/ + try{ + $scope.getUserName(); + }catch(err){ + $log.info('getUserName failed', err); + } +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/leftMenu.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/leftMenu.js new file mode 100644 index 00000000..f42276fe --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/directives/leftMenu.js @@ -0,0 +1,184 @@ + +app.directive('qMenu', function () { + return { + restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements + replace: false, + templateUrl: "app/fusion/scripts/view-models/left_menu.html", + controller: ['$scope', '$filter','$http','$timeout','$cookies','LeftMenuService', function ($scope, $filter, $http,$timeout,$cookies,LeftMenuService) { + + $scope.leftChildData=[]; + $scope.leftParentData=[]; + $scope.leftMenuItems = []; + $scope.app_name = ""; + $scope.app_name_full; + LeftMenuService.getLeftMenu().then(function(response){ + var j = response; + try{ + if(j && j !== "null" && j!== "undefined"){ + $scope.leftParentData = JSON.parse(j.data); + $scope.leftChildData = JSON.parse(j.data2); + }else{ + throw "Get Left Menu response is not an object/is empty"; + } + try{ + var leftChildItemList = $scope.leftChildData; + var pageUrl = window.location.href.split('/')[window.location.href.split('/').length-1]; + var leftParentList =$scope.leftParentData; + for (var i = 0; i < leftParentList.length; i++) { + $scope.item = { + parentLabel : leftParentList[i].label, + parentAction : leftParentList[i].action, + parentImageSrc : leftParentList[i].imageSrc, + open:pageUrl==leftParentList[i].action?true:false, + childItemList : leftChildItemList[i] + } + $scope.leftMenuItems.push($scope.item); + }; + }catch(err){ + console.log("failed to set left menu structure", err); + } + }catch (e) { + console.log("failed to get left menu items", e); + reloadPageOnce(); + return; + } + },function(error){ + console.log("error happened while calling getLeftMenu", error); + }); + + LeftMenuService.getAppName().then(function(response){ + var j = response; + try{ + if(j && j !== "null" && j!== "undefined"){ + // console.log("app name is " + $scope.app_name); + $scope.app_name_full = j.data; + var processed_app_name = j.data; + var n = processed_app_name.length; + if (n > 15) { + n = 15; + } + $scope.app_name = processed_app_name.substr(0, n); + }else{ + throw "Get app_name respsone is not an object/is empty"; + } + }catch (e) { + console.log("failed to get app name", e); + return; + } + },function(error){ + console.log("failed in getAppName", error); + }); + + $scope.adjustHeader=function() { + $scope.showHeader = ($cookies.show_app_header == undefined ? true : $cookies.show_app_header); + + if($scope.showHeader == true) { + $scope.drawer_margin_top = 50; + $scope.drawer_custom_top = 54; + $scope.toggle_drawer_top = 55; + } + else { + + $scope.drawer_margin_top = 40; + $scope.drawer_custom_top = 0; + $scope.toggle_drawer_top = 10; + } + + + }; + + $scope.adjustHLeftMenu = function (type){ + $scope.showHeader = ($cookies.show_app_header == undefined ? true : $cookies.show_app_header); + + if($scope.showHeader == true) { + $scope.drawer_margin_top = 60; + $scope.drawer_custom_top = 54; + $scope.toggle_drawer_top = 55; + } + else { + + $scope.drawer_margin_top = 50; + $scope.drawer_custom_top = 0; + $scope.toggle_drawer_top = 10; + } + if(type=='burgerIcon'){ + return { "top": $scope.toggle_drawer_top+"px"}; + }else if(type=='leftMenu'){ + return { "margin-top": $scope.drawer_margin_top+"px"}; + }else + return; + } + $scope.adjustHeader(); + $scope.drawerOpen = true; + + $scope.toggleDrawer = function() { + $scope.drawerOpen = !($scope.drawerOpen); + if ($scope.drawerOpen) { + // setCookie('drawerOpen','open',30); + $scope.arrowShow = true; + + + if (document.getElementById('fnMenueContent')!=null) + document.getElementById('fnMenueContent').style.marginLeft = "0px"; + + if (document.getElementById('rightContentAdmin')!=null) + document.getElementById('rightContentAdmin').style.marginLeft = "210px"; + + else if (document.getElementById('rightContentProfile')!=null) + document.getElementById('rightContentProfile').style.marginLeft = "210px"; + + + + } else { + + $scope.arrowShow = false; + + if (document.getElementById('fnMenueContent')!=null) + document.getElementById('fnMenueContent').style.marginLeft = "-150px"; + + if (document.getElementById('rightContentAdmin')!=null) { + document.getElementById('rightContentAdmin').style.marginLeft = "50px"; + + } + + else if (document.getElementById('rightContentProfile')!=null) + document.getElementById('rightContentProfile').style.marginLeft = "50px"; + + + + + } + }; + + $timeout(function() { + detectScrollEvent(); + }, 800); + }] + } + +}); +$(window).scroll(function() { + if ($('.att-drawer').is(':visible')) { + detectScrollEvent(); + } + +}); + +function detectScrollEvent() { + try{ + var footerOff = $('#footerContainer').offset().top; + var headOff = $('#headerContainer').offset().top; + var winHeight = $(window).height(); + if ((footerOff - headOff) <= winHeight) { + $('.att-drawer').css({ + "height" : footerOff - headOff - 55 + }); + } else { + $('.att-drawer').css({ + "height" : "94vh" + }); + } + }catch(err){ + console.log('detectScrollEvent failed', err) + } +} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/jquery.resize.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/jquery.resize.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/jquery.resize.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/jquery.resize.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/layout/debug.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/layout/debug.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/layout/debug.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/layout/debug.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/layout/jquery-latest.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/layout/jquery-latest.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/layout/jquery-latest.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/layout/jquery-latest.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/layout/jquery-ui-latest.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/layout/jquery-ui-latest.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/layout/jquery-ui-latest.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/layout/jquery-ui-latest.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/layout/jquery.layout-latest.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/layout/jquery.layout-latest.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/layout/jquery.layout-latest.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/layout/jquery.layout-latest.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/modalService.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/modalService.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/modalService.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/modalService.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/moment.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/moment.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/moment.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/moment.min.js diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/network/net_map.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/network/net_map.js new file mode 100644 index 00000000..49599503 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/network/net_map.js @@ -0,0 +1,947 @@ +var graph,paper; +var zoomIndex = 1; +var recentCallFlow; +var recentCallFlowStep; +var hash_map = new Object(); +var hashVertexDomainXMap = new Object(); + +var globalCollapseDomanString = ""; +var changeIcon = false; +var colorSet = ["#0000FF","#8A2BE2","#DEB887", + "#5F9EA0","#7FFF00","#D2691E","#6495ED","#DC143C", + "#000000","#A9A9A9","#BDB76B", + "#FF1493","#48D1CC","#A52A2A","#FF7F50","#DAA520","#32CD32"]; +var colorIndex = 0; +String.prototype.startsWith = function (str) +{ + return this.indexOf(str) == 0; +} + +String.prototype.replaceAt=function(index, character) { + return this.substr(0, index) + character + this.substr(index+character.length); +} +function getColor(id1,id2) { + + var color = colorSet[colorIndex]; + colorIndex++; + return color; +} +///////////////////////////////////////////////////////////////////////////////////// + $('.legend-toggle').click(function (a) { + + $('.legend-toggle .toggle').hasClass("on")?($('.legend-toggle .toggle').removeClass("on"),$("#legend").fadeOut(350)):($('.legend-toggle .toggle').addClass("on"),$("#legend").fadeIn(350)); + + }); + + $('.symbols-toggle').click(function (a) { + + $('.symbols-toggle .toggle').hasClass("on")?($('.symbols-toggle .toggle').removeClass("on"),$("#symbols").fadeOut(350)):($('.symbols-toggle .toggle').addClass("on"),$("#symbols").fadeIn(350)); + }); + + + +plotNodes = function(domain) { + + if(domain.containerList) { + + var containerList = domain.containerList; + + for(var i=0; i' + '
    '); + + +} + +plotContainer = function(container, cssType) { + + attributes = container; + //console.log(attributes); + if(cssType === 'domain'){ + $('#networkModelContainer').append('

    ' + attributes.name + '

    '); + $('#networkModelContainer').append('
    ' + '
    '); + + + }else if(attributes.visibilityType==='invisible'){ + + $('#networkModelContainer').append('

    ' + attributes.name + '

    '); + + }else{ + + if(!recentCallFlow){ + $('#networkModelContainer').append('
    ' + '
    '); + //$('#networkModelContainer').append('

    '+ attributes.name + '

    '); + plotHeader(attributes,cssType); + }else{ + $('#networkModelContainer').append('
    ' + '
    '); + //$('#networkModelContainer').append('

    '+ attributes.name + '

    '); + plotHeader(attributes,cssType); + } + + } + + plotNodes(container); + + } + +plotContainerIcon = function(container, cssType) { + attributes = container; + //console.log(attributes); + if(cssType === 'domain'){ + $('#networkModelContainer').append('

    ' + attributes.name + '

    '); + $('#networkModelContainer').append('
    ' + '
    '); + + }else if(attributes.visibilityType==='invisible'){ + + $('#networkModelContainer').append('

    ' + attributes.name + '

    '); + } + else{ + if(!recentCallFlow){ + $('#networkModelContainer').append('
    ' + '
    '); + //$('#networkModelContainer').append('

    '+ attributes.name + '

    '); + plotHeader(attributes,cssType); + }else{ + $('#networkModelContainer').append('
    ' + '
    '); + //$('#networkModelContainer').append('

    '+ attributes.name + '

    '); + plotHeader(attributes,cssType); + } + } + + plotNodesIcon(container); + +} + +joint.shapes.basic.newRect = joint.shapes.basic.Generic.extend({ + + markup: '', + + defaults: joint.util.deepSupplement({ + + type: 'basic.newRect', + attrs: { + 'rect': { fill: 'white', stroke: 'black', 'follow-scale': true, width: 80, height: 40}, + 'text': { 'font-size': 14, 'ref-x': .5, 'ref-y': .5, ref: 'rect', 'y-alignment': 'middle', 'x-alignment': 'middle'} + }, + shortname: 'Transcoder', + description: 'Reconciles mismatched CODECs', + longname: 'ACME SBC device providing dedicated Transcoder function', + vendor: 'ORACLE ACME', + primary_function: 'Allows endpoints utilizing different CODECs to communicate', + key_interface: 'SBC, MSC', + network_domain: 'Universal Services Platform - Access Module Group - ISA Core Office', + +}, joint.shapes.basic.Generic.prototype.defaults)}); + +plotHeader = function(attributes,cssType){ + + var nameLength = attributes.name.length; + var headName; + if (nameLength>22){ + headName = attributes.name.substring(0,12) + "-\n" + attributes.name.substring(12); + + }else{ + headName = attributes.name; + } + + var thisElement = new joint.shapes.basic.newRect({ + position: { x: attributes.left+10, y: attributes.top + 4 }, + size: { width: attributes.width-20, height: 15 }, + attrs: { + rect: { fill: "gray" ,stroke: "gray",opacity:"0.8"}, + text: { text: headName, fill: 'black' ,'font-size':10, 'font-weight':'700','text-transform': 'capitalize'} + + } + }); + if(cssType==="outContainer"){ + + thisElement.attr({ + rect:{fill:"#e7e7e7", stroke: "#e7e7e7",opacity:"0.8"} + }); + + }else{ + + thisElement.attr({ + rect:{fill:"ghostwhite", stroke: "ghostwhite",opacity:"0.8"} + }); + + + } + graph.addCells([thisElement]); + +} +plotElement = function(element) { + + if(element.left){ + if(!element.id.startsWith("com.att.trinity.ue")){ + left = element.left ; + var thisColor = element.bgColor; + var thisElement = new joint.shapes.basic.newRect({ + id:element.id, + position: { x: element.left, y: element.top }, + size: { width: element.width, height: element.height*2 }, + + attrs: { + rect: { fill: "lightgray" ,stroke: "gray"}, + text: { text: element.name.replace(" ","\n"), fill: 'black' ,'font-size': 9, 'font-weight': 'bold','font-variant': 'small-caps', 'text-transform': 'capitalize'} + + } + + }); + if(!recentCallFlow){ + thisElement.attr({ + rect:{fill:element.bgColor, stroke: thisColor} + }); + + } + //thisElement.attr({rect:{style:{"pointer-events":"none"}}}); + thisElement.set('bg-color', (element.bgColor!= null?element.bgColor:"blue")); + thisElement.set('icon_path', (element.imgFileName != null? element.imgFileName: "static/img/map/icons/sgw-icon.png")); + thisElement.set('shortname', element.name); + thisElement.set('description', element.details.description); + thisElement.set('longname', element.details.display_longname); + thisElement.set('vendor', element.details.vendor); + thisElement.set('primary_function', element.details.primary_function); + thisElement.set('key_interface', element.details.key_interfaces); + thisElement.set('location', element.details.location); + thisElement.set('network_function', (element.details.network_function=="V")? "Virtual" : "Physical" ); + if(element.borderType == 'dashed'){ + + thisElement.attr({ + rect: {stroke: 'black','stroke-width':"2",'stroke-dasharray': "5,2" }, + }); + + } + + + hash_map[element.name+'']=thisElement.name; + graph.addCells([thisElement]); + + }else{ + plotElementIcon(element); + } + } + +} + +joint.shapes.basic.DecoratedRect = joint.shapes.basic.Generic.extend({ + + markup: '', + + defaults: joint.util.deepSupplement({ + + type: 'basic.DecoratedRect', + size: { width: 100, height: 60 }, + attrs: { + 'rect': { fill: 'lightgray', width: 100, height: 60 }, + 'text': { 'font-size': 14, text: '', 'ref-x': .5, 'ref-y': .5, ref: 'rect', 'y-alignment': 'middle', 'x-alignment': 'middle', fill: 'black'}, + 'image': { ref: 'rect', width: 35, height: 25} + }, + shortname: 'Transcoder', + description: 'Reconciles mismatched CODECs', + longname: 'ACME SBC device providing dedicated Transcoder function', + vendor: 'ORACLE ACME', + primary_function: 'Allows endpoints utilizing different CODECs to communicate', + key_interface: 'SBC, MSC', + network_domain: 'Universal Services Platform - Access Module Group - ISA Core Office', + + }, joint.shapes.basic.Generic.prototype.defaults) +}); + +plotElementIcon = function(element) { + + + if(element.left){ + + left = element.left ; + uetop = element.top; + if(element.id.startsWith("com.att.trinity.ue")) { + uetop = element.top - 30; + } else { + uetop = element.top ; + } + var thisElement = new joint.shapes.basic.DecoratedRect({ + id:element.id, + position: { x: element.left, y: uetop }, + size: { width:element.width, height: element.height*2 }, + // style:{'pointer-events':'none'}, + attrs: { + //image: { 'xlink:href': 'static/img/map/icons/sgw-icon.png' + image: { 'xlink:href': element.imgFileName} + //rect:{style:{"pointer-events":"none"}} + // style:{'pointer-events':'none'} + // 'pointer-events':'none' + } + }); + // thisElement.attr({rect:{style:{"pointer-events":"none"}}}); + thisElement.set('bg-color', element.bgColor); + thisElement.set('icon_path', element.imgFileName); + thisElement.set('shortname', element.name); + thisElement.set('description', element.details.description); + thisElement.set('longname', element.details.display_longname); + thisElement.set('vendor', element.details.vendor); + thisElement.set('primary_function', element.details.primary_function); + thisElement.set('key_interface', element.details.key_interfaces); + thisElement.set('location', element.details.location); + thisElement.set('network_function', (element.details.network_function=="V")? "Virtual" : "Physical"); + + if(!recentCallFlow ){ + thisElement.attr({ + rect:{fill:element.bgColor } + }); + + } + if(element.borderType == 'dashed'){ + + thisElement.attr({ + rect: {stroke: 'lightskyblue','stroke-width':"2",'stroke-dasharray': "5,2" }, + }); + + } + if(element.id.startsWith("com.att.trinity.ue")){ + thisElement.attr({ + rect: {fill: 'white', style:{'pointer-events':'none'}}, + image: { style:{'pointer-events':'none'}} + }); + + //thisElement.css('pointer-events', 'none'); + // paper.thisElement.css('pointer-events', 'none'); + } + hash_map[element.name+'']=thisElement.name; + graph.addCells([thisElement]); + + } + +} + + +plotNetMapCallFlow = function(callFlow, callFlowStep, collapsedDomainString, expandedDomainString, icon) { + + init(); + + recentCallFlow = callFlow; //callFlow != null ? callFlow : recentCallFlow; + recentCallFlowStep = callFlowStep; //callFlowStep != null ? callFlowStep : recentCallFlowStep; + + // $.get( "static/trisim_files/network_map.yml", function( data ) { + + if(callFlow != null &&callFlow.title != null) { + + $(".map-title").html(callFlow.title); + + }else{ + $(".map-title").html("Network Map"); + + } + $.post('network_model.htm?action=layout', { + collapsedDomains : collapsedDomainString, + expandedDomains : expandedDomainString + }, function(data) { + var yamlObject = jsyaml.load(data); + + var layout = yamlObject.domainList; + for(var i=0; i -1)|| (globalCollapseDomanString.indexOf("RAN") > -1)|| (globalCollapseDomanString.indexOf("EPC") > -1)) { + hashVertexDomainXMap["USP"] = -999; + hashVertexDomainXMap["RAN"] = -999; + hashVertexDomainXMap["EPC"] = -999; + } + + } + + + addCollapseEvents(); //onclick="alert(\'hello\')" + //console.log(yamlObject); + //addLink('EATF','SDG'); + if(icon == false) + $('.icons-toggle .toggle').removeClass("on"); + + + if(callFlow != null && callFlow.id != null) { + + // var callFlowLinkFile = callFlow + "_" + callFlowStep + ".yml"; + + $.post('network_model.htm?action=callflow', { + callFlowName : callFlow.id, + callFlowStep : callFlowStep + }, function( data ) { + + try{ + var yamlObject = jsyaml.load(data); + //addLink("EATF","MRF"); + var layout = yamlObject.linkList; + + var hashLinkElements = new Object(); + for(var i=0; i
    + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/left_menu.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/left_menu.html new file mode 100644 index 00000000..ad4e5d91 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/left_menu.html @@ -0,0 +1,27 @@ + +
    + + + +     {{app_name}} + +
    +
    +
    +
    + + + + + +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/admin_closed_loop.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/admin_closed_loop.html new file mode 100644 index 00000000..a3a5dfc1 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/admin_closed_loop.html @@ -0,0 +1,20 @@ +
    +
    + +

    Closed Loop

    +
    +
    +
    +
    + Cloop Server +
    +
    + +
    +
    + +
    + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast.html new file mode 100644 index 00000000..9ffd9810 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast.html @@ -0,0 +1,42 @@ +
    +
    +

    Broadcast Message Edit

    +
    + +
    + Please edit the broadcast message details below: 

    +
    +
    + +
    +
    +
    +
    + + +
    + +
    +
    + + +
    + +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast_list.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast_list.html new file mode 100644 index 00000000..512ce7e8 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast_list.html @@ -0,0 +1,52 @@ +
    + +
    + +

    Broadcast Messages

    +
    +
    + {{location.label}} Messages +
    + + + + + + + + + + + + + + + + + {{message.id}} + + + + + + + + + + + +
    No.Message TextStart DateEnd DateSort OrderServerActive?Delete?
    {{$index+1}}{{message.messageText}} + {{message.displayStartDate}} + {{message.displayEndDate}}{{message.sortOrder}}{{message.siteCd}} +
    + +
    +
    +
    +
    +
    + +


    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal.html new file mode 100644 index 00000000..433e0c3f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal.html @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_add.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_add.html new file mode 100644 index 00000000..b1c9135a --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_add.html @@ -0,0 +1,136 @@ + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_edit.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_edit.html new file mode 100644 index 00000000..2ccdf2af --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_edit.html @@ -0,0 +1,129 @@ + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_role.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_role.html new file mode 100644 index 00000000..cbfd6133 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_role.html @@ -0,0 +1,75 @@ + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_rolefunction.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_rolefunction.html new file mode 100644 index 00000000..b5fd76ad --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_rolefunction.html @@ -0,0 +1,27 @@ + + + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/customWidgetSettings.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/customWidgetSettings.js new file mode 100644 index 00000000..6cabe9f2 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/customWidgetSettings.js @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +app + .controller('CustomSettingsDemoCtrl', function($scope, $interval, $window, widgetDefinitions, defaultWidgets, RandomDataModel) { + + + // Add an additional widget with setting overrides + var definitions = [{ + name: 'congfigurable widget', + directive: 'wt-scope-watch', + dataAttrName: 'value', + dataModelType: RandomDataModel, + dataModelOptions: { + limit: 10 + }, + settingsModalOptions: { + partialTemplateUrl: 'template/configurableWidgetModalOptions.html' + }, + onSettingsClose: function (result, widget) { + if (widget.dataModel && widget.dataModel.updateLimit) { + widget.dataModel.updateLimit(result.dataModelOptions.limit); + } + } + }, { + name: 'override modal widget', + directive: 'wt-scope-watch', + dataAttrName: 'value', + dataModelType: RandomDataModel, + settingsModalOptions: { + templateUrl: 'template/WidgetSpecificSettings.html', + controller: 'WidgetSpecificSettingsCtrl', + backdrop: false + }, + onSettingsClose: function(result, widget) { + console.log('Widget-specific settings resolved!'); + jQuery.extend(true, widget, result); + }, + onSettingsDismiss: function(reason, scope) { + console.log('Settings have been dismissed: ', reason); + console.log('Dashboard scope: ', scope); + } + }]; + + var defaultWidgets = [ + { name: 'congfigurable widget' }, + { name: 'override modal widget' } + ]; + + $scope.dashboardOptions = { + widgetButtons: true, + widgetDefinitions: definitions, + defaultWidgets: defaultWidgets, + storage: $window.localStorage, + storageId: 'custom-settings', + + /* + // Overrides default $uibModal options. + // This can also be set on individual + // widget definition objects (see above). + settingsModalOptions: { + // This will completely override the modal template for all widgets. + // You also have the option to add to the default modal template with settingsModalOptions.partialTemplateUrl (see "configurable widget" above) + templateUrl: 'template/customSettingsTemplate.html' + // We could pass a custom controller name here to be used + // with the widget settings dialog, but for this demo we + // will just keep the default. + // + // controller: 'CustomSettingsModalCtrl' + // + // Other options passed to $uibModal.open can be put here, + // eg: + // + // backdrop: false, + // keyboard: false + // + // @see http://angular-ui.github.io/bootstrap/#/modal <-- heads up: routing on their site was broken as of this writing + }, + */ + + // Called when a widget settings dialog is closed + // by the "ok" method (i.e., the promise is resolved + // and not rejected). This can also be set on individual + // widgets (see above). + onSettingsClose: function(result, widget, scope) { + console.log('Settings result: ', result); + console.log('Widget: ', widget); + console.log('Dashboard scope: ', scope); + jQuery.extend(true, widget, result); + }, + + // Called when a widget settings dialog is closed + // by the "cancel" method (i.e., the promise is rejected + // and not resolved). This can also be set on individual + // widgets (see above). + onSettingsDismiss: function(reason, scope) { + console.log('Settings have been dismissed: ', reason); + console.log('Dashboard scope: ', scope); + } + }; + }) + .controller('WidgetSpecificSettingsCtrl', function ($scope, $uibModalInstance, widget) { + // add widget to scope + $scope.widget = widget; + + // set up result object + $scope.result = jQuery.extend(true, {}, widget); + + $scope.ok = function () { + console.log('calling ok from widget-specific settings controller!'); + $uibModalInstance.close($scope.result); + }; + + $scope.cancel = function () { + console.log('calling cancel from widget-specific settings controller!'); + $uibModalInstance.dismiss('cancel'); + }; + }) diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/dataModel.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/dataModel.js new file mode 100644 index 00000000..d9be52ea --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/dataModel.js @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +app + .factory('RandomDataModel', function ($interval, WidgetDataModel) { + function RandomDataModel() { + } + + RandomDataModel.prototype = Object.create(WidgetDataModel.prototype); + RandomDataModel.prototype.constructor = WidgetDataModel; + + angular.extend(RandomDataModel.prototype, { + init: function () { + var dataModelOptions = this.dataModelOptions; + this.limit = (dataModelOptions && dataModelOptions.limit) ? dataModelOptions.limit : 100; + + this.updateScope('-'); + this.startInterval(); + }, + + startInterval: function () { + $interval.cancel(this.intervalPromise); + + this.intervalPromise = $interval(function () { + var value = Math.floor(Math.random() * this.limit); + this.updateScope(value); + }.bind(this), 500); + }, + + updateLimit: function (limit) { + this.dataModelOptions = this.dataModelOptions ? this.dataModelOptions : {}; + this.dataModelOptions.limit = limit; + this.limit = limit; + }, + + destroy: function () { + WidgetDataModel.prototype.destroy.call(this); + $interval.cancel(this.intervalPromise); + } + }); + + return RandomDataModel; + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/demo.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/demo.js new file mode 100644 index 00000000..d598f0d0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/demo.js @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +app +.config(function ($routeProvider) { + $routeProvider + .when('/view', { + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/view.html', + controller: 'DemoCtrl', + title: 'simple', + description: 'This is the simplest demo.' + }) + .when('/resize', { + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/view.html', + controller: 'ResizeDemoCtrl', + title: 'resize', + description: 'This demo showcases widget resizing.' + }) + .when('/custom-settings', { + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/view.html', + controller: 'CustomSettingsDemoCtrl', + title: 'custom widget settings', + description: 'This demo showcases overriding the widget settings dialog/modal ' + + 'for the entire dashboard and for a specific widget. Click on the cog of each ' + + 'widget to see the custom modal. \n"configurable widget" has "limit" option in the modal ' + + 'that controls RandomDataModel.' + }) + .when('/explicit-saving', { + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/view.html', + controller: 'ExplicitSaveDemoCtrl', + title: 'explicit saving', + description: 'This demo showcases an option to only save the dashboard state '+ + 'explicitly, e.g. by user input. Notice the "all saved" button in the controls ' + + 'updates as you make saveable changes.' + }) + .when('/layouts', { + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/layouts.html', + controller: 'LayoutsDemoCtrl', + title: 'dashboard layouts', + description: 'This demo showcases the ability to have "dashboard layouts", ' + + 'meaning the ability to have multiple arbitrary configurations of widgets. For more ' + + 'information, take a look at [issue #31](https://github.com/DataTorrent/malhar-angular-dashboard/issues/31)' + }) + .when('/', { + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/layouts.html', + controller: 'LayoutsDemoExplicitSaveCtrl', + title: 'layouts explicit saving', + description: 'This demo showcases dashboard layouts with explicit saving enabled.' + }) + .otherwise({ + redirectTo: '/' + }); + }) + .controller('NavBarCtrl', function($scope, $route) { + $scope.$route = $route; + }) + .factory('widgetDefinitions', function(RandomDataModel) { + return [ + { + name: 'random', + directive: 'wt-scope-watch', + attrs: { + value: 'randomValue' + } + }, + { + name: 'time', + directive: 'wt-time' + }, + { + name: 'datamodel', + directive: 'wt-scope-watch', + dataAttrName: 'value', + dataModelType: RandomDataModel + }, + { + name: 'resizable', + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/resizable.html', + attrs: { + class: 'demo-widget-resizable' + } + }, + { + name: 'fluid', + directive: 'wt-fluid', + size: { + width: '50%', + height: '250px' + } + }, + { + name: 'raptor-report-data', + directive: 'raptor-report-data', + size: { + width: '50%', + height: '300px' + } + }, + { + name: 'raptor-report-chart', + directive: 'raptor-report-chart', + size: { + width: '50%', + height: '300px' + } + }, + { + name: 'r-cloud', + directive: 'r-cloud', + size: { + width: '50%', + height: '300px' + } + } + ]; + + }) + .value('defaultWidgets', [ +// { name: 'random' }, +// { name: 'time' }, +// { name: 'datamodel' }, +// { +// name: 'random', +// style: { +// width: '50%', +// minWidth: '39%' +// } +// }, +// { +// name: 'time', +// style: { +// width: '50%' +// } +// } +// {"name":"raptor-report","title":"Spam Source Line Chart","style":{},"size":{"height":"450px","width":"40%"},"attrs":{"value":"randomValue"},"report_id":"3360"} + + ]) + .controller('DemoCtrl', function ($scope, $interval, $window, widgetDefinitions, defaultWidgets) { + + $scope.dashboardOptions = { + widgetButtons: true, + widgetDefinitions: widgetDefinitions, + defaultWidgets: defaultWidgets, + storage: $window.localStorage, + storageId: 'demo_simple' + }; + $scope.randomValue = Math.random(); + $interval(function () { + $scope.randomValue = Math.random(); + }, 500); + + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/demo.less b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/demo.less new file mode 100644 index 00000000..91f4cee9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/demo.less @@ -0,0 +1,24 @@ +body { + margin: 15px; + padding-top: 50px; +} +a { + cursor: pointer; +} +.layout-tabs { + margin-bottom: 10px; +} + +.demo-widget-fluid { + border: 1px solid blue; + height: 100%; +} + +.demo-widget-fluid > div { + border: 1px solid red; + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/directives.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/directives.js new file mode 100644 index 00000000..fe3ee7f7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/directives.js @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +app + .directive('wtTime', function ($interval) { + return { + restrict: 'A', + scope: true, + replace: true, + template: '
    Time
    {{time}}
    ', + link: function (scope) { + function update() { + scope.time = new Date().toLocaleTimeString(); + } + + update(); + + var promise = $interval(update, 500); + + scope.$on('$destroy', function () { + $interval.cancel(promise); + }); + } + }; + }) + .directive('wtScopeWatch', function () { + return { + restrict: 'A', + replace: true, + template: '
    Value
    {{value}}
    ', + scope: { + value: '=value' + } + }; + }) + .directive('wtFluid', function () { + return { + restrict: 'A', + replace: true, + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/fluid.html', + scope: true, + controller: function ($scope) { + $scope.$on('widgetResized', function (event, size) { + $scope.width = size.width || $scope.width; + $scope.height = size.height || $scope.height; + }); + } + }; + }) + .directive('raptorReportChart', ['widgetDefinitions','defaultWidgets',function (widgetDefinitions, defaultWidgets) { + return { + restrict: 'A', + replace: true, + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/raptor-report.html', + scope: true, + controller: function ($scope,$http, $rootScope) { +// console.log('================= Raptor Report scope ================='); +// console.log($scope); + $scope.showChart = false; + $scope.url = "report_embedded#/report_run/c_master="+$scope.widget.report_id+ "&refresh=Y&hideGrid=Y&width="+Math.floor($scope.width*13)+"&height=300"; +// $scope.url = "report_embedded#/report_run/c_master="+$scope.widget.report_id+ "&refresh=Y&hideGrid="+$scope.hideGrid+"&width=550&height=300"; + $rootScope.showdataContainer = false; + $rootScope.$watch('showdataContainer', function () { + console.log('change showdataContainer'); + console.log($rootScope.showdataContainer); + $scope.gridOptions = $rootScope.gridOptions; + $scope.gridOptions = $rootScope.gridOptions; + $scope.uiGridRefresh = function(){ + var columnDefsArray = []; + var columnFreezeEndColumn = $scope.widget.reportData.colIdxTobeFreezed; + var doColumnNeedToFreeze = false; + if(columnFreezeEndColumn && columnFreezeEndColumn.length>0) { + doColumnNeedToFreeze = true; + } + $scope.widget.reportData.reportDataColumns.forEach(function(entry) { + var tempColumnDef = { displayName: entry.columnTitle, field: entry.colId, enableSorting: entry.sortable, + sortingAlgorithm: function(a, b) { + return rowSorter.sortAlpha(a.displayValue, b.displayValue); + }, + cellTemplate: '
    '+ + '
    {{COL_FIELD.displayValue}}
    ' + + ' {{COL_FIELD.displayValue}}' + + '
    '}; + if(entry.columnWidth && entry.columnWidth!='null' && entry.columnWidth!='pxpx' && entry.columnWidth!='nullpx' && entry.columnWidth!='nullpxpx'){ + tempColumnDef['minWidth'] = entry.columnWidth.substring(0, entry.columnWidth.length - 2); + } else { + tempColumnDef['minWidth'] = '100'; + } + if(doColumnNeedToFreeze) { + tempColumnDef['pinnedLeft']= true; + if(columnFreezeEndColumn === entry.colId){ + doColumnNeedToFreeze = false; + } + } + columnDefsArray.push(tempColumnDef); + }); + + $scope.gridOptions.paginationPageSizes= [$scope.widget.reportData.pageSize]; + $scope.gridOptions.paginationPageSize= $scope.widget.reportData.pageSize; + if($scope.widget.reportData.totalRows<14){ + $scope.widget.gridHeight = (widget.reportData.totalRows+5)*30+'px'; + }else{ + $scope.gridHeight = '400px'; + } + $scope.gridOptions.totalItems = $scope.widget.reportData.totalRows; + $scope.gridOptions.columnDefs= columnDefsArray; + $scope.gridOptions.data= $scope.widget.reportData.reportDataRows; + $scope.gridOptions.exporterPdfHeader.text= $scope.widget.reportData.reportName; + }; + $scope.uiGridRefresh(); + + + /*presence.setGlobal({ + u: $rootScope.currentUser, + s: 'on' + })*/ + }) + $scope.$on('widgetResized', function (event, size) { + console.log("===$scope==="); + console.log($scope); + $scope.width = size.width || $scope.width; + $scope.height = size.height || $scope.height; + $scope.url = "report_embedded#/report_run/c_master="+$scope.widget.report_id+ "&refresh=Y&hideGrid=Y&width="+Math.floor($scope.width*13)+"&height=300"; + }); + } + }; + }]) + .directive('raptorReportData', ['widgetDefinitions','defaultWidgets',function (widgetDefinitions, defaultWidgets) { + return { + restrict: 'A', + replace: true, + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/raptor-report.html', + scope: true, + controller: function ($scope,$http, $rootScope) { +// console.log('================= Raptor Report scope ================='); +// console.log($scope); + $scope.showChart = false; + $scope.url = "report_embedded#/report_run/c_master="+$scope.widget.report_id+ "&refresh=Y&hideChart=Y&width="+Math.floor($scope.width*13)+"&height=300"; +// $scope.url = "report_embedded#/report_run/c_master="+$scope.widget.report_id+ "&refresh=Y&hideGrid="+$scope.hideGrid+"&width=550&height=300"; + $rootScope.showdataContainer = false; + $rootScope.$watch('showdataContainer', function () { + console.log('change showdataContainer'); + console.log($rootScope.showdataContainer); + $scope.gridOptions = $rootScope.gridOptions; + $scope.gridOptions = $rootScope.gridOptions; + $scope.uiGridRefresh = function(){ + var columnDefsArray = []; + var columnFreezeEndColumn = $scope.widget.reportData.colIdxTobeFreezed; + var doColumnNeedToFreeze = false; + if(columnFreezeEndColumn && columnFreezeEndColumn.length>0) { + doColumnNeedToFreeze = true; + } + $scope.widget.reportData.reportDataColumns.forEach(function(entry) { + var tempColumnDef = { displayName: entry.columnTitle, field: entry.colId, enableSorting: entry.sortable, + sortingAlgorithm: function(a, b) { + return rowSorter.sortAlpha(a.displayValue, b.displayValue); + }, + cellTemplate: '
    '+ + '
    {{COL_FIELD.displayValue}}
    ' + + ' {{COL_FIELD.displayValue}}' + + '
    '}; + if(entry.columnWidth && entry.columnWidth!='null' && entry.columnWidth!='pxpx' && entry.columnWidth!='nullpx' && entry.columnWidth!='nullpxpx'){ + tempColumnDef['minWidth'] = entry.columnWidth.substring(0, entry.columnWidth.length - 2); + } else { + tempColumnDef['minWidth'] = '100'; + } + if(doColumnNeedToFreeze) { + tempColumnDef['pinnedLeft']= true; + if(columnFreezeEndColumn === entry.colId){ + doColumnNeedToFreeze = false; + } + } + columnDefsArray.push(tempColumnDef); + }); + + $scope.gridOptions.paginationPageSizes= [$scope.widget.reportData.pageSize]; + $scope.gridOptions.paginationPageSize= $scope.widget.reportData.pageSize; + if($scope.widget.reportData.totalRows<14){ + $scope.widget.gridHeight = (widget.reportData.totalRows+5)*30+'px'; + }else{ + $scope.gridHeight = '400px'; + } + $scope.gridOptions.totalItems = $scope.widget.reportData.totalRows; + $scope.gridOptions.columnDefs= columnDefsArray; + $scope.gridOptions.data= $scope.widget.reportData.reportDataRows; + $scope.gridOptions.exporterPdfHeader.text= $scope.widget.reportData.reportName; + }; + $scope.uiGridRefresh(); + + + /*presence.setGlobal({ + u: $rootScope.currentUser, + s: 'on' + })*/ + }) + } + }; + }]) + .directive('rCloud', function () { + return { + restrict: 'A', + replace: true, + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/app/template/r-cloud.html', + scope: true, + controller: function ($scope,$http) { + $scope.showChart = false; + $scope.hideGrid = 'true'; + $scope.url = $scope.widget.rcloud_url; + $scope.$on('widgetResized', function (event, size) { + $scope.width = size.width || $scope.width; + $scope.height = size.height || $scope.height; + }); + } + }; + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/explicitSave.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/explicitSave.js new file mode 100644 index 00000000..ad959b21 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/explicitSave.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +app + .controller('ExplicitSaveDemoCtrl', function ($scope, $interval, $window, widgetDefinitions, defaultWidgets) { + $scope.dashboardOptions = { + widgetButtons: true, + widgetDefinitions: widgetDefinitions, + defaultWidgets: defaultWidgets, + storage: $window.localStorage, + storageId: 'explicitSave', + explicitSave: true + }; + $scope.randomValue = Math.random(); + $interval(function () { + $scope.randomValue = Math.random(); + }, 500); + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.css new file mode 100644 index 00000000..c05f70c1 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.css @@ -0,0 +1,146 @@ +/* #rightContentUiDashboard { + display:inline-block; +} */ + +#rightContentUiDashboard .browsehappy { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; +} +#rightContentUiDashboard .thumbnail { + height: 200px; +} +#rightContentUiDashboard .thumbnail img.pull-right { + width: 50px; +} +#rightContentUiDashboard body { + margin: 15px; + padding-top: 50px; +} +#rightContentUiDashboard a { + cursor: pointer; +} +#rightContentUiDashboard .layout-tabs { + margin-bottom: 10px; +} +#rightContentUiDashboard .demo-widget-fluid { + border: 1px solid blue; + height: 100%; +} +#rightContentUiDashboard .demo-widget-fluid > div { + border: 1px solid red; + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +#rightContentUiDashboard .dashboard-widget-area { + margin: 10px 0 30px; + min-height: 200px; +} +#rightContentUiDashboard .widget-container { + float: left; + display: inline-block; + width: 33%; + padding-bottom: 0em; +} +#rightContentUiDashboard .widget { + margin: 0 1em 0 0; + background-color: white; + border-radius: 5px; + position: relative; + height: 100%; +} +#rightContentUiDashboard .widget-header { + overflow: hidden; + width:100%; /* for overlaying effect start*/ + position: absolute; + z-index: 10; + opacity: 0.8; + top: 1px; + filter: alpha(opacity=80); /* For IE8 and earlier */ + -webkit-transition: width 2s, height 4s; /* Safari */ + transition: width 2s, height 4s; +} +#rightContentUiDashboard .widget-header .label { + display: inline-block; + vertical-align: middle; +} +#rightContentUiDashboard .widget-header .glyphicon { + cursor: pointer; + float: right; + opacity: 0.5; + margin-left: 5px; +} +#rightContentUiDashboard .widget-header .glyphicon:hover { + opacity: 1; +} +#rightContentUiDashboard .widget-header .widget-title { + vertical-align: middle; +} +#rightContentUiDashboard .widget-header form.widget-title { + display: inline; +} +#rightContentUiDashboard .widget-header form.widget-title input.form-control { + width: auto; + display: inline-block; +} +#rightContentUiDashboard .widget-content { + padding:0px; + overflow: hidden; + position: relative; /* for overlaying effect */ +} +#rightContentUiDashboard .widget .widget-ew-resizer { + position: absolute; + width: 5px; + right: -2px; + height: 100%; + top: 0; + cursor: ew-resize; +} +#rightContentUiDashboard .widget .widget-s-resizer { + cursor: ns-resize; + height: 5px; + width: 100%; + bottom: -7px; + left: 0; +} +#rightContentUiDashboard .widget .widget-resizer-marquee { + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5); + position: absolute; + top: 0; + left: 0; + z-index: 2; +} +#rightContentUiDashboard .remove-layout-icon { + vertical-align: text-top; + cursor: pointer; + opacity: 0.3; +} +#rightContentUiDashboard .remove-layout-icon:hover { + opacity: 1; +} +#rightContentUiDashboard .layout-title { + display: inline-block; +} + +/* +#container { + width: 100px; + height: 100px; + position: relative; +} +#navi, +#infoi { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; +} +#infoi { + z-index: 10; +} + + */ \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.js new file mode 100644 index 00000000..b4cfb97d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.js @@ -0,0 +1,3 @@ +'use strict'; + +angular.module('dashboard', ['ui.bootstrap']); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.less b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.less new file mode 100644 index 00000000..87955cbe --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index.less @@ -0,0 +1,16 @@ +.browsehappy { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; +} + +.thumbnail { + height: 200px; + + img.pull-right { + width: 50px; + } +} +// injector +// endinjector diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index_original.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index_original.css new file mode 100644 index 00000000..d5cebfb0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/index_original.css @@ -0,0 +1,113 @@ +.browsehappy { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; +} +.thumbnail { + height: 200px; +} +.thumbnail img.pull-right { + width: 50px; +} +body { + margin: 15px; + padding-top: 50px; +} +a { + cursor: pointer; +} +.layout-tabs { + margin-bottom: 10px; +} +.demo-widget-fluid { + border: 1px solid blue; + height: 100%; +} +.demo-widget-fluid > div { + border: 1px solid red; + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +.dashboard-widget-area { + margin: 10px 0 30px; + min-height: 200px; +} +.widget-container { + float: left; + display: inline-block; + width: 33%; + padding-bottom: 1em; +} +.widget { + margin: 0 1em 0 0; + background-color: white; + border: 2px solid #444; + border-radius: 5px; + position: relative; + height: 100%; +} +.widget-header { + overflow: hidden; +} +.widget-header .label { + display: inline-block; + vertical-align: middle; +} +.widget-header .glyphicon { + cursor: pointer; + float: right; + opacity: 0.5; + margin-left: 5px; +} +.widget-header .glyphicon:hover { + opacity: 1; +} +.widget-header .widget-title { + vertical-align: middle; +} +.widget-header form.widget-title { + display: inline; +} +.widget-header form.widget-title input.form-control { + width: auto; + display: inline-block; +} +.widget-content { + overflow: hidden; +} +.widget .widget-ew-resizer { + position: absolute; + width: 5px; + right: -2px; + height: 100%; + top: 0; + cursor: ew-resize; +} +.widget .widget-s-resizer { + cursor: ns-resize; + height: 5px; + width: 100%; + bottom: -7px; + left: 0; +} +.widget .widget-resizer-marquee { + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5); + position: absolute; + top: 0; + left: 0; + z-index: 2; +} +.remove-layout-icon { + vertical-align: text-top; + cursor: pointer; + opacity: 0.3; +} +.remove-layout-icon:hover { + opacity: 1; +} +.layout-title { + display: inline-block; +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/layouts.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/layouts.js new file mode 100644 index 00000000..154a6b08 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/layouts.js @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +app + .controller('LayoutsDemoCtrl', function($scope, widgetDefinitions, defaultWidgets, LayoutStorage, $interval) { + $scope.layoutOptions = { + storageId: 'demo-layouts', + storage: localStorage, + storageHash: 'fs4df4d51', + widgetDefinitions: widgetDefinitions, + defaultWidgets: defaultWidgets, + lockDefaultLayouts: true, + defaultLayouts: [ + { title: 'Layout 1', active: true , defaultWidgets: defaultWidgets }, + { title: 'Layout 2', active: false, defaultWidgets: defaultWidgets }, + { title: 'Layout 3', active: false, defaultWidgets: defaultWidgets, locked: false } + ] + }; + $scope.randomValue = Math.random(); + $interval(function () { + $scope.randomValue = Math.random(); + }, 500); + + }) + .controller('LayoutsDemoExplicitSaveCtrl', function($scope, widgetDefinitions, defaultWidgets, LayoutStorage, $interval, $http) { + $http.get('raptor.htm?action=report.search.execute').then( + function(result){ + var data = result.data; + var report_id_name = []; + for (var i in data.rows[0]) { + report_id_name.push({index:i, value: data.rows[0][i][1].searchresultField.displayValue, title: data.rows[0][i][2].searchresultField.displayValue}) + } + $scope.reports = report_id_name; + console.log($scope.reports); + $scope.report1 = $scope.reports[1]; + }); + + $scope.rcloud_url= "https://rcloud.research.att.com/mini.html?notebook=c131ea997453e75303588699936d1896"; + $scope.layoutOptions = { + storageId: 'demo-layouts-explicit-save', + storage: localStorage, + storageHash: 'fs4df4d51', + widgetDefinitions: widgetDefinitions, + defaultWidgets: defaultWidgets, + explicitSave: true, + defaultLayouts: [ + { title: 'Layout 1', active: true , defaultWidgets: defaultWidgets }, + { title: 'Layout 2', active: false, defaultWidgets: defaultWidgets }, + { title: 'Layout 3', active: false, defaultWidgets: defaultWidgets } + ] + }; + $scope.randomValue = Math.random(); + $interval(function () { + $scope.randomValue = Math.random(); + }, 500); + + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/report_whitelist.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/report_whitelist.js new file mode 100644 index 00000000..f1e76096 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/report_whitelist.js @@ -0,0 +1,3 @@ +app.config(function ($sceDelegateProvider) { + $sceDelegateProvider.resourceUrlWhitelist(['self','https://rcloud.research.att.com/**']); +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/resize.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/resize.js new file mode 100644 index 00000000..db22e548 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/resize.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +app + .controller('ResizeDemoCtrl', function ($scope, $interval, $window, widgetDefinitions, defaultWidgets) { + defaultWidgets = [ + { name: 'fluid' }, + { name: 'resizable' }, + { name: 'random', style: { width: '50%' } }, + { name: 'time', style: { width: '50%' } } + ]; + + $scope.dashboardOptions = { + widgetButtons: true, + widgetDefinitions: widgetDefinitions, + defaultWidgets: defaultWidgets, + storage: $window.localStorage, + storageId: 'demo_resize' + }; + $scope.randomValue = Math.random(); + $interval(function () { + $scope.randomValue = Math.random(); + }, 500); + }) + .controller('ResizableCtrl', function ($scope) { + $scope.$on('widgetResized', function (event, size) { + $scope.width = size.width || $scope.width; + $scope.height = size.height || $scope.height; + }); + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/configurableWidgetModalOptions.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/configurableWidgetModalOptions.html new file mode 100644 index 00000000..b12c3ade --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/configurableWidgetModalOptions.html @@ -0,0 +1,6 @@ +
    + +
    + +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/customSettingsTemplate.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/customSettingsTemplate.html new file mode 100644 index 00000000..be13a89b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/customSettingsTemplate.html @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/fluid.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/fluid.html new file mode 100644 index 00000000..4bb0c94a --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/fluid.html @@ -0,0 +1,8 @@ +
    +
    +

    Widget takes 100% height (blue border).

    +

    Resize the widget vertically to see that this text (red border) stays middle aligned.

    +

    New width: {{width}}

    +

    New height: {{height}}

    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/layouts.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/layouts.html new file mode 100644 index 00000000..8d6854f7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/layouts.html @@ -0,0 +1 @@ +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/r-cloud.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/r-cloud.html new file mode 100644 index 00000000..46cf7b8b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/r-cloud.html @@ -0,0 +1,8 @@ +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/raptor-report.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/raptor-report.html new file mode 100644 index 00000000..fed32ada --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/raptor-report.html @@ -0,0 +1,29 @@ +
    +
    + +
    + +
    + + + +
    +
    +
    +
    +
    + {{reportData.message}} +
    +
    +
    +
    +
    + + + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/resizable.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/resizable.html new file mode 100644 index 00000000..6abaad81 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/resizable.html @@ -0,0 +1,6 @@ +
    +
    +
    New width: {{width}}
    +
    New height: {{height}}
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/view.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/view.html new file mode 100644 index 00000000..23b72c28 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/view.html @@ -0,0 +1,5 @@ +
    +
    +
    +
    +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/widgetSpecificSettings.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/widgetSpecificSettings.html new file mode 100644 index 00000000..3b93a0a9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/template/widgetSpecificSettings.html @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/vendor.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/vendor.css new file mode 100644 index 00000000..a7e815ed --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/vendor.css @@ -0,0 +1,6658 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + font-size: 2em; + margin: 0.67em 0; +} +mark { + background: #ff0; + color: #000; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + box-sizing: content-box; + height: 0; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-appearance: textfield; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +legend { + border: 0; + padding: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + background: transparent !important; + color: #000 !important; + box-shadow: none !important; + text-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('../../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot'); + src: url('../../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../../bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../../bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../../bower_components/boostrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../../bower_components/boostrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\002a"; +} +.glyphicon-plus:before { + content: "\002b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} +* { + box-sizing: border-box; +} +*:before, +*:after { + box-sizing: border-box; +} +html { + font-size: 10px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333333; + background-color: #ffffff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + padding: 4px; + line-height: 1.42857143; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + transition: all 0.2s ease-in-out; + display: inline-block; + max-width: 100%; + height: auto; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eeeeee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +[role="button"] { + cursor: pointer; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +mark, +.mark { + background-color: #fcf8e3; + padding: .2em; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777777; +} +.text-primary { + color: #337ab7; +} +a.text-primary:hover, +a.text-primary:focus { + color: #286090; +} +.text-success { + color: #3c763d; +} +a.text-success:hover, +a.text-success:focus { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover, +a.text-info:focus { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover, +a.text-warning:focus { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover, +a.text-danger:focus { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #337ab7; +} +a.bg-primary:hover, +a.bg-primary:focus { + background-color: #286090; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover, +a.bg-success:focus { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover, +a.bg-info:focus { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover, +a.bg-warning:focus { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover, +a.bg-danger:focus { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eeeeee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; + margin-left: -5px; +} +.list-inline > li { + display: inline-block; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eeeeee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; + text-align: right; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #ffffff; + background-color: #333333; + border-radius: 3px; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + word-break: break-all; + word-wrap: break-word; + color: #333333; + background-color: #f5f5f5; + border: 1px solid #cccccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +.row { + margin-left: -15px; + margin-right: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0%; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0%; + } +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777777; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #dddddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #dddddd; +} +.table .table { + background-color: #ffffff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #dddddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #dddddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + float: none; + display: table-column; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + float: none; + display: table-cell; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + overflow-x: auto; + min-height: 0.01%; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #dddddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + padding: 0; + margin: 0; + border: 0; + min-width: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555555; + background-color: #ffffff; + background-image: none; + border: 1px solid #cccccc; + border-radius: 4px; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.form-control::-moz-placeholder { + color: #999999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999999; +} +.form-control::-webkit-input-placeholder { + color: #999999; +} +.form-control::-ms-expand { + border: 0; + background-color: transparent; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #eeeeee; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; + min-height: 34px; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-left: 0; + padding-right: 0; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.form-group-sm select.form-control { + height: 30px; + line-height: 30px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 6px 10px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.form-group-lg select.form-control { + height: 46px; + line-height: 46px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 11px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #2b542c; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + border-color: #3c763d; + background-color: #dff0d8; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #66512c; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + border-color: #8a6d3b; + background-color: #fcf8e3; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #843534; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + border-color: #a94442; + background-color: #f2dede; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 7px; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-left: -15px; + margin-right: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 7px; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 11px; + font-size: 18px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 12px; + } +} +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333333; + text-decoration: none; +} +.btn:active, +.btn.active { + outline: 0; + background-image: none; + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + opacity: 0.65; + filter: alpha(opacity=65); + box-shadow: none; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333333; + background-color: #ffffff; + border-color: #cccccc; +} +.btn-default:focus, +.btn-default.focus { + color: #333333; + background-color: #e6e6e6; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #333333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #ffffff; + border-color: #cccccc; +} +.btn-default .badge { + color: #ffffff; + background-color: #333333; +} +.btn-primary { + color: #ffffff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:focus, +.btn-primary.focus { + color: #ffffff; + background-color: #286090; + border-color: #122b40; +} +.btn-primary:hover { + color: #ffffff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #ffffff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #ffffff; + background-color: #204d74; + border-color: #122b40; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #ffffff; +} +.btn-success { + color: #ffffff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:focus, +.btn-success.focus { + color: #ffffff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #ffffff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #ffffff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #ffffff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #ffffff; +} +.btn-info { + color: #ffffff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:focus, +.btn-info.focus { + color: #ffffff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #ffffff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #ffffff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #ffffff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #ffffff; +} +.btn-warning { + color: #ffffff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:focus, +.btn-warning.focus { + color: #ffffff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #ffffff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #ffffff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #ffffff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #ffffff; +} +.btn-danger { + color: #ffffff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:focus, +.btn-danger.focus { + color: #ffffff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #ffffff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #ffffff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #ffffff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #ffffff; +} +.btn-link { + color: #337ab7; + font-weight: normal; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + transition-property: height, visibility; + transition-duration: 0.35s; + transition-timing-function: ease; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 14px; + text-align: left; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + text-decoration: none; + color: #262626; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + outline: 0; + background-color: #337ab7; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: not-allowed; +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + left: auto; + right: 0; +} +.dropdown-menu-left { + left: 0; + right: auto; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + left: auto; + right: 0; + } + .navbar-right .dropdown-menu-left { + left: 0; + right: auto; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn-group.open .dropdown-toggle.btn-link { + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-right-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + float: none; + display: table-cell; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-left: 0; + padding-right: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group .form-control:focus { + z-index: 3; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555555; + text-align: center; + background-color: #eeeeee; + border: 1px solid #cccccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; +} +.nav { + margin-bottom: 0; + padding-left: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.nav > li.disabled > a { + color: #777777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777777; + text-decoration: none; + background-color: transparent; + cursor: not-allowed; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eeeeee; + border-color: #337ab7; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #dddddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #dddddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555555; + background-color: #ffffff; + border: 1px solid #dddddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #dddddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #dddddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #ffffff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #ffffff; + background-color: #337ab7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #dddddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #dddddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #ffffff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + overflow-x: visible; + padding-right: 15px; + padding-left: 15px; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-left: 0; + padding-right: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; + height: 50px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + margin-right: 15px; + padding: 9px 10px; + margin-top: 8px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} +.navbar-form { + margin-left: -15px; + margin-right: -15px; + padding: 10px 15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + margin-top: 8px; + margin-bottom: 8px; +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + border: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + padding-bottom: 0; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-left: 15px; + margin-right: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777777; +} +.navbar-default .navbar-nav > li > a { + color: #777777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #cccccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #dddddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #dddddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: #e7e7e7; + color: #555555; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #cccccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777777; +} +.navbar-default .navbar-link:hover { + color: #333333; +} +.navbar-default .btn-link { + color: #777777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #cccccc; +} +.navbar-inverse { + background-color: #222222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #ffffff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #ffffff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #ffffff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #ffffff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + background-color: #080808; + color: #ffffff; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #ffffff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #ffffff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #9d9d9d; +} +.navbar-inverse .navbar-link:hover { + color: #ffffff; +} +.navbar-inverse .btn-link { + color: #9d9d9d; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #ffffff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + content: "/\00a0"; + padding: 0 5px; + color: #cccccc; +} +.breadcrumb > .active { + color: #777777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + line-height: 1.42857143; + text-decoration: none; + color: #337ab7; + background-color: #ffffff; + border: 1px solid #dddddd; + margin-left: -1px; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + z-index: 2; + color: #23527c; + background-color: #eeeeee; + border-color: #dddddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 3; + color: #ffffff; + background-color: #337ab7; + border-color: #337ab7; + cursor: default; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777777; + background-color: #ffffff; + border-color: #dddddd; + cursor: not-allowed; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-bottom-left-radius: 6px; + border-top-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-bottom-right-radius: 6px; + border-top-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + list-style: none; + text-align: center; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777777; + background-color: #ffffff; + cursor: not-allowed; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #337ab7; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #286090; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + color: #ffffff; + line-height: 1; + vertical-align: middle; + white-space: nowrap; + text-align: center; + background-color: #777777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge, +.btn-group-xs > .btn .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #337ab7; + background-color: #ffffff; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding-top: 30px; + padding-bottom: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eeeeee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron, +.container-fluid .jumbotron { + border-radius: 6px; + padding-left: 15px; + padding-right: 15px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-left: 60px; + padding-right: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + transition: border 0.2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-left: auto; + margin-right: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #337ab7; +} +.thumbnail .caption { + padding: 9px; + color: #333333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #3c763d; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #31708f; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + background-color: #fcf8e3; + border-color: #faebcc; + color: #8a6d3b; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + background-color: #f2dede; + border-color: #ebccd1; + color: #a94442; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-radius: 4px; + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} +.progress-bar { + float: left; + width: 0%; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #ffffff; + text-align: center; + background-color: #337ab7; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + transition: width 0.6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media, +.media-body { + zoom: 1; + overflow: hidden; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} +.media-object.img-thumbnail { + max-width: none; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} +.media-middle { + vertical-align: middle; +} +.media-bottom { + vertical-align: bottom; +} +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + margin-bottom: 20px; + padding-left: 0; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #ffffff; + border: 1px solid #dddddd; +} +.list-group-item:first-child { + border-top-right-radius: 4px; + border-top-left-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item, +button.list-group-item { + color: #555555; +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #333333; +} +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + text-decoration: none; + color: #555555; + background-color: #f5f5f5; +} +button.list-group-item { + width: 100%; + text-align: left; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + background-color: #eeeeee; + color: #777777; + cursor: not-allowed; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #ffffff; + background-color: #337ab7; + border-color: #337ab7; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #c7ddef; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success, +button.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +button.list-group-item-success:hover, +a.list-group-item-success:focus, +button.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +button.list-group-item-success.active, +a.list-group-item-success.active:hover, +button.list-group-item-success.active:hover, +a.list-group-item-success.active:focus, +button.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info, +button.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +button.list-group-item-info:hover, +a.list-group-item-info:focus, +button.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +button.list-group-item-info.active, +a.list-group-item-info.active:hover, +button.list-group-item-info.active:hover, +a.list-group-item-info.active:focus, +button.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning, +button.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +button.list-group-item-warning:hover, +a.list-group-item-warning:focus, +button.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +button.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus, +button.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger, +button.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +button.list-group-item-danger:hover, +a.list-group-item-danger:focus, +button.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +button.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus, +button.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #ffffff; + border: 1px solid transparent; + border-radius: 4px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #dddddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-left: 15px; + padding-right: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #dddddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + border: 0; + margin-bottom: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #dddddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #dddddd; +} +.panel-default { + border-color: #dddddd; +} +.panel-default > .panel-heading { + color: #333333; + background-color: #f5f5f5; + border-color: #dddddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #dddddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #dddddd; +} +.panel-primary { + border-color: #337ab7; +} +.panel-primary > .panel-heading { + color: #ffffff; + background-color: #337ab7; + border-color: #337ab7; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; +} +.panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #ffffff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + left: 0; + bottom: 0; + height: 100%; + width: 100%; + border: 0; +} +.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.modal-open { + overflow: hidden; +} +.modal { + display: none; + overflow: hidden; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transform: translate(0, -25%); + transform: translate(0, -25%); + transition: -webkit-transform 0.3s ease-out; + transition: transform 0.3s ease-out; +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #ffffff; + border: 1px solid #999999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; + outline: 0; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} +.modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + font-size: 12px; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + background-color: #000000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + right: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + font-size: 14px; + background-color: #ffffff; + background-clip: padding-box; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top > .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top > .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right > .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; +} +.popover.bottom > .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom > .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left > .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; +} +.carousel-inner > .item { + display: none; + position: relative; + transition: 0.6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + transition: -webkit-transform 0.6s ease-in-out; + transition: transform 0.6s ease-in-out; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + left: 0; + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + left: 0; + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + left: 0; + } +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 15%; + opacity: 0.5; + filter: alpha(opacity=50); + font-size: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + background-color: rgba(0, 0, 0, 0); +} +.carousel-control.left { + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} +.carousel-control.right { + left: auto; + right: 0; + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} +.carousel-control:hover, +.carousel-control:focus { + outline: 0; + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + margin-top: -10px; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + line-height: 1; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid #ffffff; + border-radius: 10px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); +} +.carousel-indicators .active { + margin: 0; + width: 12px; + height: 12px; + background-color: #ffffff; +} +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -10px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -10px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -10px; + } + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-header:before, +.modal-header:after, +.modal-footer:before, +.modal-footer:after { + content: " "; + display: table; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-header:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-left: auto; + margin-right: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/vendor.less b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/vendor.less new file mode 100644 index 00000000..2d0f5cc6 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/app/vendor.less @@ -0,0 +1,3 @@ +@import '../../bower_components/bootstrap/less/bootstrap.less'; + +@icon-font-path: '/fonts/'; diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/angular-markdown-directive/markdown.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/angular-markdown-directive/markdown.js new file mode 100644 index 00000000..989a6bec --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/angular-markdown-directive/markdown.js @@ -0,0 +1,36 @@ +/* + * angular-markdown-directive v0.3.1 + * (c) 2013-2014 Brian Ford http://briantford.com + * License: MIT + */ + +'use strict'; + +angular.module('btford.markdown', ['ngSanitize']). + provider('markdownConverter', function () { + var opts = {}; + return { + config: function (newOpts) { + opts = newOpts; + }, + $get: function () { + return new Showdown.converter(opts); + } + }; + }). + directive('btfMarkdown', ['$sanitize', 'markdownConverter', function ($sanitize, markdownConverter) { + return { + restrict: 'AE', + link: function (scope, element, attrs) { + if (attrs.btfMarkdown) { + scope.$watch(attrs.btfMarkdown, function (newVal) { + var html = newVal ? $sanitize(markdownConverter.makeHtml(newVal)) : ''; + element.html(html); + }); + } else { + var html = $sanitize(markdownConverter.makeHtml(element.text())); + element.html(html); + } + } + }; + }]); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/WidgetSettingsCtrl.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/WidgetSettingsCtrl.js new file mode 100644 index 00000000..4b420a27 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/WidgetSettingsCtrl.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .controller('WidgetSettingsCtrl', ['$scope', '$uibModalInstance', 'widget', function ($scope, $uibModalInstance, widget) { + // add widget to scope + $scope.widget = widget; + + // set up result object + $scope.result = jQuery.extend(true, {}, widget); + + $scope.ok = function () { + $uibModalInstance.close($scope.result); + }; + + $scope.cancel = function () { + $uibModalInstance.dismiss('cancel'); + }; + }]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/WidgetSettingsRaptorReportCtrl.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/WidgetSettingsRaptorReportCtrl.js new file mode 100644 index 00000000..fd6a0b02 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/WidgetSettingsRaptorReportCtrl.js @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .controller('WidgetSettingsRaptorReportCtrl', ['$http','$scope','$rootScope','$uibModalInstance', 'widget', function ($http,$scope,$rootScope,$uibModalInstance, widget) { + + // add watch function for widget here + // leave ajax call to the dashboard.js + + console.log("============= WidgetSettingsRaptorReportCtrl scope ================="); + console.log($scope); + + var getFormFieldListUrl = "raptor.htm?action=report.run.container&c_master="+widget.report_id + "&refresh=Y" + console.log("============= getFormFieldListUrl ============="); + console.log(getFormFieldListUrl); + $http.get(getFormFieldListUrl).then( + function(res){ + $scope.reportData = res.data; + // add widget to scope + $scope.showFormFieldIds = false; + $scope.formFieldSelectedValues = {}; +}); + + var parseQueryString = function( queryString ) { + var params = {}, queries, temp, i, l; + // Split into key/value pairs + queries = queryString.split("&"); + // Convert the array of strings into an object + for ( i = 0, l = queries.length; i < l; i++ ) { + temp = queries[i].split('='); + //console.log(temp[0]); + //console.log(temp[0] != "refresh"); + if(temp[0] && temp[0] != "refresh") + params[temp[0]] = temp[1]; + } + return params; + }; + + var paginationOptions = { + pageNumber: 1, + pageSize: 5, + sort: null + }; + + $scope.gridOptions = { + paginationPageSizes: [5], + paginationPageSize: 5, + useExternalPagination: true, + columnDefs: [], + data: [], + enableGridMenu: true, + enableSelectAll: true, + exporterMenuPdf: false, + exporterMenuCsv: false, + exporterCsvFilename: 'myFile.csv', + exporterPdfDefaultStyle: {fontSize: 9}, + exporterPdfTableStyle: {margin: [30, 30, 30, 30]}, + exporterPdfTableHeaderStyle: {fontSize: 10, bol$rootScoped: true, italics: true, color: 'red'}, + exporterPdfHeader: { text: "My Header", style: 'headerStyle' }, + exporterPdfFooter: function ( currentPage, pageCount ) { + return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' }; + }, + exporterPdfCustomFormatter: function ( docDefinition ) { + docDefinition.styles.headerStyle = { fontSize: 22, bold: true }; + docDefinition.styles.footerStyle = { fontSize: 10, bold: true }; + return docDefinition; + }, + exporterPdfOrientation: 'portrait', + exporterPdfPageSize: 'LETTER', + exporterPdfMaxGridWidth: 500, + exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")), + onRegisterApi: function(gridApi) { + $scope.gridApi = gridApi; + gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) { + paginationOptions.pageNumber = newPage; + paginationOptions.pageSize = pageSize; + $scope.runReport(); + }); + } + }; + + + + $scope.getFormFieldSelectedValuesAsURL = function(){ + var formFieldsUrl = ''; + $scope.widget.reportData.formFieldList.forEach(function(formField) { + if(formField.fieldType==='LIST_BOX') { + if($scope.formFieldSelectedValues && $scope.formFieldSelectedValues[formField.fieldId] && $scope.formFieldSelectedValues[formField.fieldId].value != '') { + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId].value+'&'; + } + } else if(formField.fieldType==='LIST_MULTI_SELECT') { + if($scope.formFieldSelectedValues[formField.fieldId].length >0) { + for (var i = 0; i < $scope.formFieldSelectedValues[formField.fieldId].length; i++) { + if($scope.formFieldSelectedValues[formField.fieldId][i].defaultValue){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId][i].value+'&'; + } + } + } + } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && formField.validationType === 'DATE'){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+dateFilter($scope.formFieldSelectedValues[formField.fieldId],$scope.dateformat)+'&'; + } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && formField.validationType === 'TIMESTAMP_MIN'){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+dateFilter($scope.formFieldSelectedValues[formField.fieldId],$scope.datetimeformat)+'&'; + } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && $scope.formFieldSelectedValues[formField.fieldId] && $scope.formFieldSelectedValues[formField.fieldId] != ''){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId]+'&'; + } + }); + return formFieldsUrl; + + } + + $scope.triggerOtherFormFields = function(){ + console.log("report_run"); + var formFieldsUrl = $scope.getFormFieldSelectedValuesAsURL(); + $http.get('raptor.htm?action=report.formfields.run.container&c_master='+widget.report_id+'&'+formFieldsUrl).then( + function(response){ + $scope.widget.reportData = response.data; + }); + }; + + + $scope.runReport = function(pagination){ + var formFieldsUrl = $scope.getFormFieldSelectedValuesAsURL(); + console.log("pagination"); + if(!pagination) { + console.log("refreshed ..."); + $scope.gridOptions.pageNumber = 1; + $scope.gridOptions.paginationPageSizes= [widget.reportData.pageSize]; + $scope.gridOptions.paginationPageSize= widget.reportData.pageSize; + if(widget.reportData.totalRows<14){ + $scope.gridHeight = (widget.reportData.totalRows+7)*30+'px'; + } else{ + $scope.gridHeight = '400px'; + } + $scope.gridOptions.totalItems = widget.reportData.totalRows; + $scope.gridOptions.data= widget.reportData.reportDataRows; + $scope.gridOptions.exporterPdfHeader.text= widget.reportData.reportName; + } +/* $scope.currentReportUrlParams = 'c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'&display_content=Y&r_page='+(paginationOptions.pageNumber-1); + console.log('raptor.htm?action=report.run.container&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)); + $http.get('raptor.htm?action=report.run.container&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)).then( + */ + $scope.currentReportUrlParams = 'c_master='+ widget.report_id+'&'+formFieldsUrl+'&display_content=Y&r_page='+(paginationOptions.pageNumber-1); + $scope.urlParams = parseQueryString($scope.currentReportUrlParams); + + console.log('raptor.htm?action=report.run.container&c_master='+ widget.report_id +'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)); + $http.get('raptor.htm?action=report.run.container&c_master='+widget.report_id+'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)).then( + function(response){ + widget.reportData = response.data; + if(widget.reportData.errormessage) { + document.getElementById('errorDiv').innerHTML = widget.reportData.errormessage; + console.log(document.getElementById('errorDiv').innerHtml); + console.log(widget.reportData.errormessage); + } + if(!pagination) { + if(!$scope.urlParams.hideChart && widget.reportData.chartAvailable && widget.reportData.totalRows>1){ + console.log('raptor.htm?action=chart.run&c_master='+widget.report_id+'&'+formFieldsUrl+'display_content=Y&r_page='+(paginationOptions.pageNumber-1)); + $http.get('raptor.htm?action=chart.run&c_master='+widget.report_id +'&'+formFieldsUrl+'display_content=Y&r_page='+(paginationOptions.pageNumber-1)).then( + function(response) { + console.log(response.data); + $scope.showChart = true; + document.getElementById('chartiframe').contentWindow.document.write(response.data); + document.getElementById('chartiframe').contentWindow.document.close(); + }); + } else { + $scope.showChart = false; + } + } + if($scope.reportData.displayForm && $scope.reportData.formFieldList && $scope.reportData.formFieldList.length>0 && !$scope.urlParams.hideFormFields){ + $scope.showFormFields = true; + } else { + $scope.showFormFields = false; + } + }); + $rootScope.gridOptions = $scope.gridOptions; + $rootScope.gridHeight = $scope.gridHeight; + $rootScope.showdataContainer = true; + }; + + + + + + // set up result object + $scope.result = jQuery.extend(true, {}, widget); + + $scope.ok = function () { + $uibModalInstance.close($scope.result); + }; + + $scope.okay = function () { + console.log("$scope.okay!") + console.log($scope); + $scope.runReport(); +/* $uibModalInstance.close($scope.result);*/ + }; + + $scope.cancel = function () { + $uibModalInstance.dismiss('cancel'); + }; + }]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-raptor-report-template.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-raptor-report-template.html new file mode 100644 index 00000000..00d6c41a --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-raptor-report-template.html @@ -0,0 +1,26 @@ +
    + + +
    +
    +
    +
    Report Name:
    +
    + + + chart + data + +
    + + + + +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-rcloud-notebook-template.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-rcloud-notebook-template.html new file mode 100644 index 00000000..239497c9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-rcloud-notebook-template.html @@ -0,0 +1,22 @@ +
    + + +
    +
    +
    +
    RCloud Notebook URL:
    + + +
    + + +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/altDashboard.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/altDashboard.html new file mode 100644 index 00000000..189bccea --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/altDashboard.html @@ -0,0 +1,49 @@ +
    +
    +
    + + + + +
    + +
    + +
    + + + + + + +
    + +
    +
    +
    +
    +

    + {{widget.title}} +
    + +
    + {{widget.name}} + + +

    +
    +
    +
    +
    +
    +
    +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.html new file mode 100644 index 00000000..e891b565 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.html @@ -0,0 +1,74 @@ + +
    +
    +
    + + + + + +
    + +
    + +
    + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    + +
    + +
    + {{widget.name}} + + + +

    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.js new file mode 100644 index 00000000..4062694e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.js @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ +'use strict'; + +angular.module('ui.dashboard', ['ui.bootstrap', 'ui.sortable']); + +angular.module('ui.dashboard') + + .directive('dashboard', ['$http','WidgetModel', 'WidgetDefCollection', '$uibModal', 'DashboardState', '$log', function ($http, WidgetModel, WidgetDefCollection, $uibModal, DashboardState, $log) { + + return { + restrict: 'A', + templateUrl: function(element, attr) { + return attr.templateUrl ? attr.templateUrl : 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.html'; + }, + scope: true, + + controller: ['$scope', '$attrs', function (scope, attrs) { + // default options + var defaults = { + stringifyStorage: true, + hideWidgetSettings: false, + hideWidgetClose: false, + settingsModalOptions: { + // templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-template.html', + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-raptor-report-template.html', + // controller: 'WidgetSettingsCtrl' + controller: 'WidgetSettingsRaptorReportCtrl' + }, + onSettingsClose: function(result, widget) { // NOTE: dashboard scope is also passed as 3rd argument + jQuery.extend(true, widget, result); + }, + onSettingsDismiss: function(reason) { // NOTE: dashboard scope is also passed as 2nd argument + $log.info('widget settings were dismissed. Reason: ', reason); + } + }; + + scope.hoverEdit = false; + + scope.hoverIn = function(){ + this.hoverEdit = true; + }; + + scope.hoverOut = function(){ + this.hoverEdit = false; + }; + + // from dashboard="options" + scope.options = scope.$eval(attrs.dashboard); + + // Deep options + scope.options.settingsModalOptions = scope.options.settingsModalOptions || {}; + _.each(['settingsModalOptions'], function(key) { + // Ensure it exists on scope.options + scope.options[key] = scope.options[key] || {}; + // Set defaults + _.defaults(scope.options[key], defaults[key]); + }); + + // Shallow options + _.defaults(scope.options, defaults); + + // sortable options + var sortableDefaults = { + stop: function () { + scope.saveDashboard(); + }, + handle: '.widget-header', + distance: 5 + }; + scope.sortableOptions = angular.extend({}, sortableDefaults, scope.options.sortableOptions || {}); + + }], + link: function (scope) { + + // Save default widget config for reset + scope.defaultWidgets = scope.options.defaultWidgets; + + scope.widgetDefs = new WidgetDefCollection(scope.options.widgetDefinitions); + var count = 1; + + // Instantiate new instance of dashboard state + scope.dashboardState = new DashboardState( + scope.options.storage, + scope.options.storageId, + scope.options.storageHash, + scope.widgetDefs, + scope.options.stringifyStorage + ); + + /** + * Instantiates a new widget on the dashboard + * @param {Object} widgetToInstantiate The definition object of the widget to be instantiated + */ + scope.addWidget = function (widgetToInstantiate, doNotSave) { + + if (typeof widgetToInstantiate === 'string') { + widgetToInstantiate = { + name: widgetToInstantiate + }; + } + + var defaultWidgetDefinition = scope.widgetDefs.getByName(widgetToInstantiate.name); + if (!defaultWidgetDefinition) { + throw 'Widget ' + widgetToInstantiate.name + ' is not found.'; + } + + // Determine the title for the new widget + var title; + if (!widgetToInstantiate.title && !defaultWidgetDefinition.title) { + widgetToInstantiate.title = 'Widget ' + count++; + } + + // Instantiation + var widget = new WidgetModel(defaultWidgetDefinition, widgetToInstantiate); + + // Add to the widgets array + scope.widgets.push(widget); + if (!doNotSave) { + scope.saveDashboard(); + } + + return widget; + }; + + /** + * Removes a widget instance from the dashboard + * @param {Object} widget The widget instance object (not a definition object) + */ + scope.removeWidget = function (widget) { + scope.widgets.splice(_.indexOf(scope.widgets, widget), 1); + scope.saveDashboard(); + }; + + /** + * Opens a dialog for setting and changing widget properties + * @param {Object} widget The widget instance object + */ + scope.openWidgetSettings = function (widget) { +/* console.log('======= widgets ======='); + console.log(widget); + console.log('widget.report_id'); + console.log(widget.report_id); +*/ + if (widget.directive.includes("raptor-report")) { + var getFormFieldListUrl = "raptor.htm?action=report.run.container&c_master="+widget.report_id + "&refresh=Y"; + $http.get(getFormFieldListUrl).then( + function(res){ + widget.reportData = res.data; + }); + + // Set up $uibModal options + var options = _.defaults( + { scope: scope }, + widget.settingsModalOptions, + scope.options.settingsModalOptions); + +/* console.log('======= options ======='); + console.log(options); +*/ + // Ensure widget is resolved + options.resolve = { + widget: function () { + return widget; + } + }; + + // Create the modal + var modalInstance = $uibModal.open(options); + var onClose = widget.onSettingsClose || scope.options.onSettingsClose; + var onDismiss = widget.onSettingsDismiss || scope.options.onSettingsDismiss; + + // Set resolve and reject callbacks for the result promise + modalInstance.result.then( + function (result) { + + // Call the close callback + onClose(result, widget, scope); + + //AW Persist title change from options editor + scope.$emit('widgetChanged', widget); + }, + function (reason) { + + // Call the dismiss callback + onDismiss(reason, scope); + + } + ); + + } + + }; + + /** + * Remove all widget instances from dashboard + */ + scope.clear = function (doNotSave) { + scope.widgets = []; + if (doNotSave === true) { + return; + } + scope.saveDashboard(); + }; + + /** + * Used for preventing default on click event + * @param {Object} event A click event + * @param {Object} widgetDef A widget definition object + */ + scope.addWidgetInternal = function (event, widgetDef) { +// event.preventDefault(); + scope.addWidget(widgetDef); + }; + + /** + * Add report to dashboard + */ + scope.popupAddReport = function () { + var modalInstance = $uibModal.open({ + animation: scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-raptor-report-template.html', + size:'sm', + controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { + $scope.radioValue="chart" + $http.get('raptor.htm?action=report.search.execute').then( + function(result){ + var data = result.data; + var report_id_name = []; + for (var i in data.rows[0]) { + report_id_name.push({index:i, value: data.rows[0][i][1].searchresultField.displayValue, title: data.rows[0][i][2].searchresultField.displayValue}) + } + $scope.raptorReportList = report_id_name; + }); + + $scope.ok = function() { + scope.addReport($scope.selectedRaptorReport,$scope.radioValue); + $uibModalInstance.close(); + }; + $scope.cancel = function() { + $uibModalInstance.dismiss(); + }; + }] + }); + modalInstance.result.then(function () { + $scope.$emit('raptorReportWidgetAdded'); + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + }; + + + scope.popupAddRCloudNotebook = function () { + var modalInstance = $uibModal.open({ + animation: scope.animationsEnabled, + templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-rcloud-notebook-template.html', + size:'sm', + controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { + $scope.rcloud_url = "" + + $scope.ok = function() { + scope.addRCloudNotebook($scope.rcloud_url); + $uibModalInstance.close(); + }; + $scope.cancel = function() { + $uibModalInstance.dismiss(); + }; + }] + }); + modalInstance.result.then(function () { + $scope.$emit('raptorReportWidgetAdded'); + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + }; + + + scope.addReport = function (report1,radioValue) { + scope.report1 =report1 + var raptor_report_type = "raptor-report-chart" + if (radioValue ==='data') { + raptor_report_type = 'raptor-report-data' + } + console.log("report1") + console.log(report1); +// event.preventDefault(); + var newreport = {"title":report1.title,"name":raptor_report_type ,"style":{},"size":{"height":"350px","width":"40%"},"attrs":{"value":"randomValue"},"report_id":report1.value}; + scope.addWidget(newreport, true); + console.log("widgets"); + console.log(scope.widgets); + ++scope.options.unsavedChangeCount; + return false; + }; + + /** + * Add rcloud notebook to dashboard + */ + scope.addRCloudNotebook = function (rcloud_url) { + ++scope.options.unsavedChangeCount; + /* open a new prompt window */ + //event.preventDefault(); + var newreport = {"title":"R-Cloud","name":"r-cloud","style":{},"size":{"height":"450px","width":"40%"},"attrs":{"value":"randomValue"},"rcloud_url":rcloud_url}; +// console.log("newport"); + console.log(newreport) + scope.addWidget(newreport, true); + /* scope.addWidget("raptor-report");*/ + return false; + }; + + /** + * Uses dashboardState service to save state + */ + scope.saveDashboard = function (force) { + if (!scope.options.explicitSave) { + scope.dashboardState.save(scope.widgets); + } else { + if (!angular.isNumber(scope.options.unsavedChangeCount)) { + scope.options.unsavedChangeCount = 0; + } + if (force) { + scope.options.unsavedChangeCount = 0; + scope.dashboardState.save(scope.widgets); + + } else { + ++scope.options.unsavedChangeCount; + } + } + }; + + /** + * Wraps saveDashboard for external use. + */ + scope.externalSaveDashboard = function(force) { + if (angular.isDefined(force)) { + scope.saveDashboard(force); + } else { + scope.saveDashboard(true); + } + }; + + /** + * Clears current dash and instantiates widget definitions + * @param {Array} widgets Array of definition objects + */ + scope.loadWidgets = function (widgets) { + // AW dashboards are continuously saved today (no "save" button). + console.log("widgets") + scope.defaultWidgets = widgets; + widgets = + [ +// {"title":"DEMO Bar Chart","name":"raptor-report-chart","style":{},"size":{"height":"450px","width":"40%"},"attrs":{"value":"randomValue"},"report_id":"2"}, +// {"title":"Pie Chart","name":"raptor-report-data","style":{},"size":{"height":"450px","width":"40%"},"attrs":{"value":"randomValue"},"report_id":"5"}, +// {"title":"Pie Chart","name":"raptor-report-chart","style":{},"size":{"height":"450px","width":"40%"},"attrs":{"value":"randomValue"},"report_id":"5"} + ]; + console.log('widgets: '); + console.log(JSON.stringify(widgets)); + + scope.savedWidgetDefs = widgets; + scope.clear(true); + _.each(widgets, function (widgetDef) { + scope.addWidget(widgetDef, true); + }); + }; + + /** + * Resets widget instances to default config + * @return {[type]} [description] + */ + scope.resetWidgetsToDefault = function () { + scope.loadWidgets(scope.defaultWidgets); + scope.saveDashboard(); + }; + + // Set default widgets array + var savedWidgetDefs = scope.dashboardState.load(); + + // Success handler + function handleStateLoad(saved) { + scope.options.unsavedChangeCount = 0; + if (saved && saved.length) { + scope.loadWidgets(saved); + } else if (scope.defaultWidgets) { + scope.loadWidgets(scope.defaultWidgets); + } else { + scope.clear(true); + } + } + + if (angular.isArray(savedWidgetDefs)) { + handleStateLoad(savedWidgetDefs); + } else if (savedWidgetDefs && angular.isObject(savedWidgetDefs) && angular.isFunction(savedWidgetDefs.then)) { + savedWidgetDefs.then(handleStateLoad, handleStateLoad); + } else { + handleStateLoad(); + } + + // expose functionality externally + // functions are appended to the provided dashboard options + scope.options.addWidget = scope.addWidget; + scope.options.loadWidgets = scope.loadWidgets; + scope.options.saveDashboard = scope.externalSaveDashboard; + scope.options.removeWidget = scope.removeWidget; + scope.options.openWidgetSettings = scope.openWidgetSettings; + scope.options.clear = scope.clear; + scope.options.resetWidgetsToDefault = scope.resetWidgetsToDefault + + // save state + scope.$on('widgetChanged', function (event) { + event.stopPropagation(); + scope.saveDashboard(); + }); + } + }; + }]); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.less b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.less new file mode 100644 index 00000000..6b5b717f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.less @@ -0,0 +1,88 @@ +.dashboard-widget-area { + margin: 10px 0 30px; + min-height: 200px; +} + +.widget-container { + float:left; + display: inline-block; + width: 33%; + padding-bottom: 1em; +} + +.widget { + margin: 0 1em 0 0; + background-color: white; + border: 2px solid #444; + border-radius: 5px; + position: relative; + height: 100%; +} +.widget-header { + overflow: hidden; +} +.widget-header .label { + display: inline-block; + vertical-align: middle; +} +.widget-header .glyphicon { + cursor: pointer; + float: right; + opacity: 0.5; + margin-left: 5px; +} +.widget-header .glyphicon:hover { + opacity: 1; +} +.widget-header .widget-title { + vertical-align: middle; +} +.widget-header form.widget-title { + display: inline; +} + +.widget-header form.widget-title input.form-control { + width: auto; + display: inline-block; +} + +.widget-content { + overflow: hidden; +} + +.widget .widget-ew-resizer { + position: absolute; + width: 5px; + right: -2px; + height:100%; + top:0; + cursor: ew-resize; +} + +.widget .widget-s-resizer { + cursor: ns-resize; + height: 5px; + width: 100%; + bottom: -7px; + left: 0; +} + +.widget .widget-resizer-marquee { + box-shadow: inset 0 0 0 1px rgba(0,0,0,0.5); + position: absolute; + top: 0; + left: 0; + z-index: 2; +} + +.remove-layout-icon { + vertical-align: text-top; + cursor: pointer; + opacity: 0.3; +} +.remove-layout-icon:hover { + opacity: 1; +} +.layout-title { + display: inline-block; +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.spec.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.spec.js new file mode 100644 index 00000000..453de431 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.spec.js @@ -0,0 +1,878 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +describe('Directive: dashboard', function () { + + var scope, element, childScope, DashboardState, mockModal, modalOptions, $compile, $q, mockLog; + + // mock UI Sortable + beforeEach(function () { + angular.module('ui.sortable', []); + }); + + // load the directive's module + beforeEach(module('ui.dashboard', function($provide) { + mockModal = { + open: function(options) { + modalOptions = options; + } + }; + mockLog = { + info: function() { + + } + }; + $provide.value('$uibModal', mockModal); + $provide.value('$log', mockLog); + })); + + beforeEach(inject(function (_$compile_, $rootScope, _DashboardState_, _$q_) { + // services + scope = $rootScope.$new(); + $compile = _$compile_; + DashboardState = _DashboardState_; + $q = _$q_; + + // options + var widgetDefinitions = [ + { + name: 'wt-one', + template: '
    {{2 + 2}}
    ' + }, + { + name: 'wt-two', + template: '{{value}}' + } + ]; + var defaultWidgets = _.clone(widgetDefinitions); + scope.dashboardOptions = { + widgetButtons: true, + widgetDefinitions: widgetDefinitions, + defaultWidgets: defaultWidgets, + sortableOptions: { + testProperty: 'foobar' + } + }; + scope.value = 10; + + // element setup + element = $compile('
    ')(scope); + scope.$digest(); + childScope = element.scope(); + })); + + it('should have toolbar', function () { + var toolbar = element.find('.btn-toolbar'); + expect(toolbar.length).toEqual(1); + }); + + it('should have UI.Sortable directive', function () { + var widgetArea = element.find('.dashboard-widget-area'); + expect(widgetArea.attr('ui-sortable')).toBeDefined(); + }); + + it('should render widgets', function () { + var widgets = element.find('.widget'); + expect(widgets.length).toEqual(2); + }); + + it('should evaluate widget expressions', function () { + var divWidget = element.find('.wt-one-value'); + expect(divWidget.html()).toEqual('4'); + }); + + it('should evaluate scope expressions', function () { + var spanWidget = element.find('.wt-two-value'); + expect(spanWidget.html()).toEqual('10'); + }); + + it('should fill options with defaults', function() { + expect(scope.dashboardOptions.stringifyStorage).toEqual(true); + }); + + it('should not overwrite specified options with defaults', inject(function($compile) { + scope.dashboardOptions.stringifyStorage = false; + element = $compile('
    ')(scope); + $compile(element)(scope); + scope.$digest(); + expect(scope.dashboardOptions.stringifyStorage).toEqual(false); + })); + + it('should be able to use a different dashboard template', inject(function($compile, $templateCache) { + $templateCache.put( + 'myCustomTemplate.html', + '
    ' + + '
    ' + + '
    ' + + '

    ' + + '{{widget.title}}' + + '' + + '' + + '

    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + ); + var customElement = $compile('
    ')(scope); + scope.$digest(); + expect(customElement.find('.custom-widget').length).toEqual(2); + })); + + it('should set scope.widgets to an empty array if no defaultWidgets are specified', inject(function($compile) { + delete scope.dashboardOptions.defaultWidgets; + var element2 = $compile('
    ')(scope); + scope.$digest(); + var childScope2 = element2.scope(); + expect(childScope2.widgets instanceof Array).toEqual(true); + })); + + it('should set options.unsavedChangeCount to 0 upon load', function() { + expect(scope.dashboardOptions.unsavedChangeCount).toEqual(0); + }); + + it('should not call saveDashboard on load', inject(function($compile) { + spyOn(DashboardState.prototype, 'save'); + var s = scope.$new(); + element = $compile('
    ')(s); + scope.$digest(); + expect(DashboardState.prototype.save).not.toHaveBeenCalled(); + })); + + describe('the sortableOptions', function() { + + it('should exist', function() { + expect(typeof childScope.sortableOptions).toEqual('object'); + }); + + it('should be possible to be extendable from the dashboardOptions', function() { + expect(childScope.sortableOptions.testProperty).toEqual('foobar'); + }) + + it('should have a stop function that calls $scope.saveDashboard', function() { + expect(typeof childScope.sortableOptions.stop).toEqual('function'); + spyOn(childScope, 'saveDashboard'); + childScope.sortableOptions.stop(); + expect(childScope.saveDashboard).toHaveBeenCalled(); + }); + }); + + describe('the addWidget function', function() { + + var widgetCreated, widgetPassed, widgetDefault; + + beforeEach(function() { + childScope.widgets.push = function(w) { + widgetCreated = w; + } + }); + + it('should be a function', function() { + expect(typeof childScope.addWidget).toEqual('function'); + }); + + it('should throw if no default widgetDefinition was found', function() { + spyOn(childScope.widgetDefs, 'getByName').and.returnValue(false); + function fn () { + childScope.addWidget({ name: 'notReal' }); + } + expect(fn).toThrow(); + }); + + it('should look to the passed widgetToInstantiate object for the title before anything else', function() { + spyOn(childScope.widgetDefs, 'getByName').and.returnValue({ title: 'defaultTitle', name: 'A' }); + childScope.addWidget({ title: 'highestPrecedence', name: 'A' }); + expect(widgetCreated.title).toEqual('highestPrecedence'); + }); + + it('should use the defaultWidget\'s title second', function() { + spyOn(childScope.widgetDefs, 'getByName').and.returnValue({ title: 'defaultTitle', name: 'A' }); + childScope.addWidget({ name: 'A' }); + expect(widgetCreated.title).toEqual('defaultTitle'); + }); + + it('should call the saveDashboard method (internal)', function() { + spyOn(childScope.widgetDefs, 'getByName').and.returnValue({ title: 'defaultTitle', name: 'A' }); + spyOn(childScope, 'saveDashboard'); + childScope.addWidget({ name: 'A' }); + expect(childScope.saveDashboard).toHaveBeenCalled(); + }); + + it('should support passing just the widget name as a string', function() { + spyOn(childScope.widgetDefs, 'getByName').and.returnValue({ title: 'defaultTitle', name: 'A' }); + childScope.addWidget('A'); + expect(childScope.widgetDefs.getByName).toHaveBeenCalledWith('A'); + expect(widgetCreated.title).toEqual('defaultTitle'); + }); + + describe('@awashbrook Test Case', function() { + beforeEach(function() { + spyOn(childScope.widgetDefs, 'getByName').and.returnValue(widgetDefault = { + "name": "nvLineChartAlpha", + "directive": "nvd3-line-chart", + "dataAttrName": "data", + "attrs": { + "isArea": true, + "height": 400, + "showXAxis": true, + "showYAxis": true, + "xAxisTickFormat": "xAxisTickFormat()", + "interactive": true, + "useInteractiveGuideline": true, + "tooltips": true, + "showLegend": true, + "noData": "No data for YOU!", + "color": "colorFunction()", + "forcey": "[0,2]" + }, + "dataModelOptions": { + "params": { + "from": "-2h", + "until": "now" + } + }, + "style": { + "width": "400px" + }, + }); + childScope.addWidget(widgetPassed = { + "title": "Andy", + "name": "nvLineChartAlpha", + "style": { + "width": "400px" + }, + "dataModelOptions": { + "params": { + "from": "-1h", + "target": [ + "randomWalk(\"random Andy 1\")", + "randomWalk(\"random walk 2\")", + "randomWalk(\"random walk 3\")" + ] + } + }, + "attrs": { + "height": 400, + "showXAxis": true, + "showYAxis": true, + "xAxisTickFormat": "xAxisTickFormat()", + "interactive": false, + "useInteractiveGuideline": true, + "tooltips": true, + "showLegend": true, + "noData": "No data for YOU!", + "color": "colorFunction()", + "forcey": "[0,2]", + "data": "widgetData" + } + }); + }); + + it('should keep overrides from widgetPassed', function() { + expect(widgetCreated.attrs.interactive).toEqual(widgetPassed.attrs.interactive); + }); + + it('should fill in default attrs', function() { + expect(widgetCreated.attrs.isArea).toEqual(widgetDefault.attrs.isArea); + }); + + it('should override deep options in dataModelOptions', function() { + expect(widgetCreated.dataModelOptions.params.from).toEqual(widgetPassed.dataModelOptions.params.from); + }); + + it('should fill in deep default attrs', function() { + expect(widgetCreated.dataModelOptions.params.until).toEqual(widgetDefault.dataModelOptions.params.until); + }); + }); + + describe('the doNotSave parameter', function() { + + it('should prevent save from being called if set to true', function() { + spyOn(childScope.widgetDefs, 'getByName').and.returnValue({ title: 'defaultTitle', name: 'A' }); + spyOn(childScope, 'saveDashboard'); + childScope.addWidget({ name: 'A' }, true); + expect(childScope.saveDashboard).not.toHaveBeenCalled(); + }); + + }); + + }); + + describe('the removeWidget function', function() { + + it('should be a function', function() { + expect(typeof childScope.removeWidget).toEqual('function'); + }); + + it('should remove the provided widget from childScope.widgets array', function() { + var startingLength = childScope.widgets.length; + var expectedLength = startingLength - 1; + + var widgetToRemove = childScope.widgets[0]; + childScope.removeWidget(widgetToRemove); + + expect(childScope.widgets.length).toEqual(expectedLength); + expect(childScope.widgets.indexOf(widgetToRemove)).toEqual(-1); + }); + + it('should call saveDashboard', function() { + spyOn(childScope, 'saveDashboard'); + var widgetToRemove = childScope.widgets[0]; + childScope.removeWidget(widgetToRemove); + expect(childScope.saveDashboard).toHaveBeenCalled(); + }); + + }); + + describe('the saveDashboard function', function() { + + it('should be attached to the options object after initialization', function() { + expect(typeof scope.dashboardOptions.saveDashboard).toEqual('function'); + expect(scope.dashboardOptions.saveDashboard === childScope.externalSaveDashboard).toEqual(true); + }); + + it('should call scope.dashboardState.save when called internally if explicitSave is falsey', function() { + spyOn(childScope.dashboardState, 'save').and.returnValue(true); + childScope.saveDashboard(); + expect(childScope.dashboardState.save).toHaveBeenCalled(); + }); + + it('should not call scope.dashboardState.save when called internally if explicitSave is truthy', function() { + scope.dashboardOptions.explicitSave = true; + spyOn(childScope.dashboardState, 'save').and.returnValue(true); + childScope.saveDashboard(); + expect(childScope.dashboardState.save).not.toHaveBeenCalled(); + }); + + it('should call scope.dashboardState.save when called externally, no matter what explicitSave value is', function() { + spyOn(childScope.dashboardState, 'save').and.returnValue(true); + + scope.dashboardOptions.explicitSave = false; + scope.dashboardOptions.saveDashboard(); + expect(childScope.dashboardState.save.calls.count()).toEqual(1); + + scope.dashboardOptions.explicitSave = true; + scope.dashboardOptions.saveDashboard(); + expect(childScope.dashboardState.save.calls.count()).toEqual(2); + }); + + it('should keep a count of unsaved changes as unsavedChangeCount', function() { + scope.dashboardOptions.explicitSave = true; + spyOn(childScope.dashboardState, 'save').and.returnValue(true); + childScope.saveDashboard(); + expect(scope.dashboardOptions.unsavedChangeCount).toEqual(1); + childScope.saveDashboard(); + childScope.saveDashboard(); + expect(scope.dashboardOptions.unsavedChangeCount).toEqual(3); + }); + + it('should reset the cound of unsaved changes if a successful force save occurs', function() { + scope.dashboardOptions.explicitSave = true; + spyOn(childScope.dashboardState, 'save').and.returnValue(true); + + childScope.saveDashboard(); + childScope.saveDashboard(); + childScope.saveDashboard(); + + childScope.saveDashboard(true); + + expect(scope.dashboardOptions.unsavedChangeCount).toEqual(0); + }); + + }); + + describe('the loadWidgets function', function() { + + it('should be a function', function() { + expect(typeof childScope.loadWidgets).toEqual('function'); + }); + + it('should set savedWidgetDefs on scope as passed array', function() { + var widgets = []; + childScope.loadWidgets(widgets); + expect(childScope.savedWidgetDefs === widgets).toEqual(true); + }); + + it('should call clear on the scope with true as the only argument', function() { + spyOn(childScope, 'clear'); + childScope.loadWidgets([]); + expect(childScope.clear).toHaveBeenCalled(); + expect(childScope.clear.calls.argsFor(0)).toEqual([true]); + }); + + it('should call addWidget for each widget in the array', function() { + spyOn(childScope, 'addWidget').and.returnValue(null); + var widgets = [{},{},{}]; + childScope.loadWidgets(widgets); + expect(childScope.addWidget.calls.count()).toEqual(3); + }); + + it('should call addWidget for each widget with true as the second parameter (doNotSave)', function() { + spyOn(childScope, 'addWidget').and.returnValue(null); + var widgets = [{},{},{}]; + childScope.loadWidgets(widgets); + expect(childScope.addWidget.calls.argsFor(0)).toEqual( [ widgets[0], true] ); + expect(childScope.addWidget.calls.argsFor(1)).toEqual( [ widgets[1], true] ); + expect(childScope.addWidget.calls.argsFor(2)).toEqual( [ widgets[2], true] ); + }); + + }); + + describe('the clear function', function() { + + it('should set the scope to an empty array', function() { + childScope.clear(); + expect(childScope.widgets).toEqual([]); + }); + + it('should not call saveDashboard if first arg is true', function() { + spyOn(childScope, 'saveDashboard'); + childScope.clear(true); + expect(childScope.saveDashboard).not.toHaveBeenCalled(); + }); + + it('should call saveDashboard if first arg is not true', function() { + spyOn(childScope, 'saveDashboard'); + childScope.clear(); + expect(childScope.saveDashboard).toHaveBeenCalled(); + }); + + }); + + describe('the openWidgetSettings function', function() { + + it('should be a function', function() { + expect(typeof childScope.openWidgetSettings).toEqual('function'); + }); + + it('should call $uibModal.open with default options', function() { + var widget = {}; + spyOn(mockModal, 'open').and.returnValue({ + result: { then: function(fn) {} } + }); + childScope.openWidgetSettings(widget); + expect(mockModal.open).toHaveBeenCalled(); + }); + + it('should have widget in the resolve object', function() { + var widget = {}; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + childScope.openWidgetSettings(widget); + expect(modalOptions.resolve.widget() === widget).toEqual(true); + }); + + it('should set the templateUrl in modal options to the default ("app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-template.html")', function() { + var widget = {}; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + childScope.openWidgetSettings(widget); + expect(modalOptions.templateUrl).toEqual('app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-template.html'); + }); + + it('should set the templateUrl in modal options to scope.options.settingsModalOptions.templateUrl', function() { + var other; + scope.dashboardOptions.settingsModalOptions = { + templateUrl: other = 'some/other/url.html' + }; + var widget = {}; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + childScope.openWidgetSettings(widget); + expect(modalOptions.templateUrl).toEqual(other); + }); + + it('should set the templateUrl in modal options to widget.settingsModalOptions.templateUrl, if present', function() { + var expected; + var widget = { + settingsModalOptions: { + templateUrl: expected = 'specific/template.html' + } + }; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + childScope.openWidgetSettings(widget); + expect(modalOptions.templateUrl).toEqual(expected); + }); + + it('should set the controller in modal options to the default ("WidgetSettingsCtrl")', function() { + var widget = {}; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + childScope.openWidgetSettings(widget); + expect(modalOptions.controller).toEqual('WidgetSettingsCtrl'); + }); + + it('should set the controller in modal options to the default ("WidgetSettingsCtrl"), even when settingsModalOptions is supplied in options', inject(function($rootScope) { + + scope = $rootScope.$new(); + + // options + var widgetDefinitions = [ + { + name: 'wt-one', + template: '
    {{2 + 2}}
    ' + }, + { + name: 'wt-two', + template: '{{value}}' + } + ]; + var defaultWidgets = _.clone(widgetDefinitions); + scope.dashboardOptions = { + widgetButtons: true, + widgetDefinitions: widgetDefinitions, + defaultWidgets: defaultWidgets, + sortableOptions: { + testProperty: 'foobar' + }, + settingsModalOptions: { + backdrop: false + } + }; + scope.value = 10; + + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + + // element setup + element = $compile('
    ')(scope); + scope.$digest(); + childScope = element.scope(); + + childScope.openWidgetSettings({}); + expect(modalOptions.controller).toEqual('WidgetSettingsCtrl'); + + })); + + it('should set the controller in modal options to the default ("WidgetSettingsCtrl"), even when settingsModalOptions is supplied in widget', inject(function($rootScope) { + + scope = $rootScope.$new(); + + // options + var widgetDefinitions = [ + { + name: 'wt-one', + template: '
    {{2 + 2}}
    ' + }, + { + name: 'wt-two', + template: '{{value}}' + } + ]; + var defaultWidgets = _.clone(widgetDefinitions); + scope.dashboardOptions = { + widgetButtons: true, + widgetDefinitions: widgetDefinitions, + defaultWidgets: defaultWidgets, + sortableOptions: { + testProperty: 'foobar' + }, + settingsModalOptions: { + backdrop: false + } + }; + scope.value = 10; + + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + + // element setup + element = $compile('
    ')(scope); + scope.$digest(); + childScope = element.scope(); + + childScope.openWidgetSettings({ + settingsModalOptions: { + templateUrl: 'custom/widget/template.html' + } + }); + expect(modalOptions.controller).toEqual('WidgetSettingsCtrl'); + expect(modalOptions.backdrop).toEqual(false); + expect(modalOptions.templateUrl).toEqual('custom/widget/template.html'); + + })); + + it('should set the controller to scope.options.settingsModalOptions.controller if provided', function() { + scope.dashboardOptions.settingsModalOptions = {}; + var expected = scope.dashboardOptions.settingsModalOptions.controller = 'MyCustomCtrl'; + var widget = {}; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + childScope.openWidgetSettings(widget); + expect(modalOptions.controller).toEqual(expected); + }); + + it('should set the controller to widget.settingsModalOptions.controller if provided', function() { + var expected; + var widget = { + settingsModalOptions: { + controller: expected = 'MyWidgetCtrl' + } + }; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + childScope.openWidgetSettings(widget); + expect(modalOptions.controller).toEqual(expected); + }); + + it('should pass in other modal options set in scope.options.settingsModalOptions', function() { + scope.dashboardOptions.settingsModalOptions = { + keyboard: false, + windowClass: 'my-extra-class' + }; + var widget = {}; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + childScope.openWidgetSettings(widget); + expect(modalOptions.keyboard).toEqual(false); + expect(modalOptions.windowClass).toEqual('my-extra-class'); + }); + + it('should pass in other modal options set in widget.settingsModalOptions', function() { + scope.dashboardOptions.settingsModalOptions = { + keyboard: false, + windowClass: 'my-extra-class' + }; + var widget = { + settingsModalOptions: { + keyboard: true, + size: 'sm' + } + }; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + childScope.openWidgetSettings(widget); + expect(modalOptions.keyboard).toEqual(true); + expect(modalOptions.size).toEqual('sm'); + expect(modalOptions.windowClass).toEqual('my-extra-class'); + }); + + it('should emit a "widgetChanged" event on the childScope when the modal promise is called', function(done) { + var widget = {}; + var result = {}; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + spyOn(childScope.options, 'onSettingsClose'); + childScope.openWidgetSettings(widget); + childScope.$on('widgetChanged', done); + dfr.resolve(result, widget); + childScope.$digest(); + }); + + it('should call scope.options.onSettingsClose when the modal promise is resolved by default', function() { + var widget = {}; + var result = {}; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + spyOn(childScope.options, 'onSettingsClose'); + childScope.openWidgetSettings(widget); + dfr.resolve(result); + childScope.$digest(); + expect(scope.dashboardOptions.onSettingsClose).toHaveBeenCalledWith(result, widget, childScope); + }); + + it('should call scope.options.onSettingsDismiss when the modal promise is rejected by default', function() { + var widget = {}; + var result = {}; + var dfr = $q.defer(); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + spyOn(childScope.options, 'onSettingsDismiss'); + childScope.openWidgetSettings(widget); + dfr.reject('Testing failure'); + childScope.$digest(); + expect(scope.dashboardOptions.onSettingsDismiss).toHaveBeenCalledWith('Testing failure', childScope); + }); + + it('should call widget.onSettingsClose if provided when the modal promise is resolved', function() { + var widget = { + onSettingsClose: function(result, widget, scope) { + + } + }; + var result = {}; + var dfr = $q.defer(); + spyOn(widget, 'onSettingsClose'); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + spyOn(childScope.options, 'onSettingsClose'); + childScope.openWidgetSettings(widget); + dfr.resolve(result); + childScope.$digest(); + expect(scope.dashboardOptions.onSettingsClose).not.toHaveBeenCalled(); + expect(widget.onSettingsClose).toHaveBeenCalledWith(result, widget, childScope); + }); + + it('should call widget.onSettingsDismiss if provided when the modal promise is rejected', function() { + var widget = { + onSettingsDismiss: function(result, widget, scope) { + + } + }; + var result = {}; + var dfr = $q.defer(); + spyOn(widget, 'onSettingsDismiss'); + spyOn(mockModal, 'open').and.callFake(function(options) { + modalOptions = options; + return { + result: dfr.promise + }; + }); + spyOn(childScope.options, 'onSettingsDismiss'); + childScope.openWidgetSettings(widget); + dfr.reject('Testing failure'); + childScope.$digest(); + expect(scope.dashboardOptions.onSettingsDismiss).not.toHaveBeenCalled(); + expect(widget.onSettingsDismiss).toHaveBeenCalledWith('Testing failure', childScope); + }); + + }); + + describe('the default onSettingsClose callback', function() { + + var onSettingsClose; + + beforeEach(function() { + onSettingsClose = childScope.options.onSettingsClose; + }); + + it('should exist', function() { + expect(typeof onSettingsClose).toEqual('function'); + }); + + it('should deep extend widget with result', function() { + var result = { + title: 'andy', + style: { + 'float': 'left' + } + }; + var widget = { + title: 'scott', + style: { + width: '100px' + } + }; + onSettingsClose(result, widget, {}); + expect(widget).toEqual({ + title: 'andy', + style: { + width: '100px', + 'float': 'left' + } + }); + }); + + }); + + describe('the default onSettingsDismiss callback', function() { + + var onSettingsDismiss; + + beforeEach(function() { + onSettingsDismiss = childScope.options.onSettingsDismiss; + }); + + it('should exist', function() { + expect(typeof onSettingsDismiss).toEqual('function'); + }); + + it('should call $log.info with the reason', function() { + spyOn(mockLog, 'info'); + onSettingsDismiss('dismiss reason'); + expect(mockLog.info).toHaveBeenCalled(); + }); + + }); + +}); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-raptor-report-template.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-raptor-report-template.html new file mode 100644 index 00000000..7a533c3f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-raptor-report-template.html @@ -0,0 +1,58 @@ + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-template.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-template.html new file mode 100644 index 00000000..a57d4366 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-template.html @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/SaveChangesModal.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/SaveChangesModal.html new file mode 100644 index 00000000..f9f6f361 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/SaveChangesModal.html @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/SaveChangesModalCtrl.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/SaveChangesModalCtrl.js new file mode 100644 index 00000000..252f9df4 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/SaveChangesModalCtrl.js @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .controller('SaveChangesModalCtrl', ['$scope', '$uibModalInstance', 'layout', function ($scope, $uibModalInstance, layout) { + + // add layout to scope + $scope.layout = layout; + + $scope.ok = function () { + $uibModalInstance.close(); + }; + + $scope.cancel = function () { + $uibModalInstance.dismiss(); + }; + }]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.html new file mode 100644 index 00000000..54aef297 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.html @@ -0,0 +1,19 @@ + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.js new file mode 100644 index 00000000..bbf107a8 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.js @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .directive('dashboardLayouts', ['LayoutStorage', '$timeout', '$uibModal', + function(LayoutStorage, $timeout, $uibModal) { + return { + scope: true, + templateUrl: function(element, attr) { + return attr.templateUrl ? attr.templateUrl : 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.html'; + }, + link: function(scope, element, attrs) { + + scope.options = scope.$eval(attrs.dashboardLayouts); + + var layoutStorage = new LayoutStorage(scope.options); + + scope.layouts = layoutStorage.layouts; + + scope.createNewLayout = function() { + var newLayout = { + title: 'Custom', + defaultWidgets: scope.options.defaultWidgets || [] + }; + layoutStorage.add(newLayout); + scope.makeLayoutActive(newLayout); + layoutStorage.save(); + return newLayout; + }; + + scope.removeLayout = function(layout) { + layoutStorage.remove(layout); + layoutStorage.save(); + }; + + scope.makeLayoutActive = function(layout) { + + var current = layoutStorage.getActiveLayout(); + + if (current && current.dashboard.unsavedChangeCount) { + var modalInstance = $uibModal.open({ + templateUrl: 'template/SaveChangesModal.html', + resolve: { + layout: function() { + return layout; + } + }, + controller: 'SaveChangesModalCtrl' + }); + + // Set resolve and reject callbacks for the result promise + modalInstance.result.then( + function() { + current.dashboard.saveDashboard(); + scope._makeLayoutActive(layout); + }, + function() { + scope._makeLayoutActive(layout); + } + ); + } else { + scope._makeLayoutActive(layout); + } + + }; + + scope._makeLayoutActive = function(layout) { + angular.forEach(scope.layouts, function(l) { + if (l !== layout) { + l.active = false; + } else { + l.active = true; + } + }); + layoutStorage.save(); + }; + + scope.isActive = function(layout) { + return !!layout.active; + }; + + scope.editTitle = function(layout) { + if (layout.locked) { + return; + } + + var input = element.find('input[data-layout="' + layout.id + '"]'); + layout.editingTitle = true; + + $timeout(function() { + input.focus()[0].setSelectionRange(0, 9999); + }); + }; + + // saves whatever is in the title input as the new title + scope.saveTitleEdit = function(layout) { + layout.editingTitle = false; + layoutStorage.save(); + }; + + scope.options.saveLayouts = function() { + layoutStorage.save(true); + }; + scope.options.addWidget = function() { + var layout = layoutStorage.getActiveLayout(); + if (layout) { + layout.dashboard.addWidget.apply(layout.dashboard, arguments); + } + }; + scope.options.loadWidgets = function() { + var layout = layoutStorage.getActiveLayout(); + if (layout) { + layout.dashboard.loadWidgets.apply(layout.dashboard, arguments); + } + }; + scope.options.saveDashboard = function() { + console.log("================= saveDashboard called =================") + var layout = layoutStorage.getActiveLayout(); + console.log("===================== layout ==========================="); + console.log(layout); + if (layout) { + layout.dashboard.saveDashboard.apply(layout.dashboard, arguments); + } + }; + + var sortableDefaults = { + stop: function() { + scope.options.saveLayouts(); + }, + distance: 5 + }; + scope.sortableOptions = angular.extend({}, sortableDefaults, scope.options.sortableOptions || {}); + } + }; + } + ]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.spec.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.spec.js new file mode 100644 index 00000000..8533a211 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboardLayouts/dashboardLayouts.spec.js @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +describe('Directive: dashboard-layouts', function () { + + var $rootScope, element, options, childScope, DashboardState, LayoutStorage, $mockModal, $mockTimeout, toFn; + + // mock UI Sortable + beforeEach(function () { + angular.module('ui.sortable', []); + }); + + // load the directive's module + beforeEach(module('ui.dashboard', function($provide) { + $mockModal = { + open: function() {} + }; + $mockTimeout = function(fn, delay) { + toFn = fn; + }; + $provide.value('$uibModal', $mockModal); + $provide.value('$timeout', $mockTimeout); + })); + + beforeEach(inject(function ($compile, _$rootScope_, _DashboardState_, _LayoutStorage_) { + // services + $rootScope = _$rootScope_; + DashboardState = _DashboardState_; + LayoutStorage = _LayoutStorage_; + + // options + var widgetDefinitions = [ + { + name: 'wt-one', + template: '
    {{2 + 2}}
    ' + }, + { + name: 'wt-two', + template: '{{value}}' + } + ]; + var defaultWidgets = _.clone(widgetDefinitions); + $rootScope.dashboardOptions = options = { + widgetButtons: true, + widgetDefinitions: widgetDefinitions, + defaultLayouts: [ + { + title: 'first', + active: true, + defaultWidgets: defaultWidgets + }, + { + title: 'second', + active: false, + defaultWidgets: defaultWidgets + } + ], + defaultWidgets: defaultWidgets, + storage: { + setItem: function(key, val) { + + }, + getItem: function(key) { + + }, + removeItem: function(key) { + + } + } + }; + $rootScope.value = 10; + + // element setup + element = $compile('
    ')($rootScope); + $rootScope.$digest(); + childScope = element.scope(); + })); + + it('should not require storage', inject(function($compile) { + delete $rootScope.dashboardOptions.storage; + expect(function() { + var noStorageEl = $compile('
    ')($rootScope); + $rootScope.$digest(); + }).not.toThrow(); + + })); + + it('should be able to use a different dashboard-layouts template', inject(function($compile, $templateCache) { + $templateCache.put( + 'myCustomTemplate.html', + '' + + '
    ' + ); + var customElement = $compile('
    ')($rootScope); + $rootScope.$digest(); + expect(customElement.find('ul.my-custom-tabs').length).toEqual(1); + + })); + + it('should set the first dashboard to active if there is not one already active', inject(function($compile) { + options.defaultLayouts[0].active = options.defaultLayouts[1].active = false; + element = $compile('
    ')($rootScope); + $rootScope.$digest(); + childScope = element.scope(); + + var layouts = childScope.layouts; + var active; + for (var i = 0; i < layouts.length; i++) { + if (layouts[i].active) { + active = layouts[i]; + break; + } + }; + expect(active).not.toBeUndefined(); + })); + + describe('the createNewLayout method', function() { + + it('should call the add and save methods of LayoutStorage', function() { + spyOn(LayoutStorage.prototype, 'add'); + spyOn(LayoutStorage.prototype, 'save'); + + childScope.createNewLayout(); + expect(LayoutStorage.prototype.add).toHaveBeenCalled(); + expect(LayoutStorage.prototype.save).toHaveBeenCalled(); + }); + + it('should return the newly created layout object', function() { + var result = childScope.createNewLayout(); + expect(typeof result).toEqual('object'); + }); + + it('should set active=true on the newly created layout', function() { + var result = childScope.createNewLayout(); + expect(result.active).toEqual(true); + }); + + it('should set defaultWidgets to dashboardOptions.defaultWidgets if it is present', function() { + var result = childScope.createNewLayout(); + expect(result.defaultWidgets === options.defaultWidgets).toEqual(true); + }); + + it('should set defaultWidgets to an empty array if dashboardOptions.defaultWidgets is not present', inject(function($compile) { + delete options.defaultWidgets; + element = $compile('
    ')($rootScope); + $rootScope.$digest(); + childScope = element.scope(); + var result = childScope.createNewLayout(); + expect(result.defaultWidgets).toEqual([]); + })); + + }); + + describe('the removeLayout method', function() { + + it('should call the remove and save methods of LayoutStorage', function() { + spyOn(LayoutStorage.prototype, 'remove'); + spyOn(LayoutStorage.prototype, 'save'); + + childScope.removeLayout(childScope.layouts[0]); + expect(LayoutStorage.prototype.remove).toHaveBeenCalled(); + expect(LayoutStorage.prototype.save).toHaveBeenCalled(); + }); + + it('should call remove with the layout it was passed', function() { + spyOn(LayoutStorage.prototype, 'remove'); + var layout = childScope.layouts[0]; + childScope.removeLayout(layout); + expect(LayoutStorage.prototype.remove.calls.argsFor(0)[0]).toEqual(layout); + }); + + }); + + describe('the makeLayoutActive method', function() { + + it('should call _makeLayoutActive if there is not a currently active dashboard with unsaved changes', function() { + spyOn(childScope, '_makeLayoutActive'); + var layout = childScope.layouts[1]; + childScope.makeLayoutActive(layout); + expect(childScope._makeLayoutActive).toHaveBeenCalled(); + }); + + describe('when there are unsaved changes on the current dashboard', function() { + + var current, options, successCb, errorCb, layout; + + beforeEach(function() { + current = childScope.layouts[0]; + current.dashboard.unsavedChangeCount = 1; + + spyOn($mockModal, 'open').and.callFake(function(arg) { + options = arg; + return { + result: { + then: function(success, error) { + successCb = success; + errorCb = error; + } + } + } + }); + + layout = childScope.layouts[1]; + childScope.makeLayoutActive(layout); + }); + + it('should create a modal', function() { + expect($mockModal.open).toHaveBeenCalled(); + }); + + it('should resolve layout to the layout to be made active', function() { + expect(options.resolve.layout()).toEqual(layout); + }); + + it('should provide a success callback that saves the current dashboard and then calls _makeLayoutActive', function() { + spyOn(current.dashboard, 'saveDashboard'); + spyOn(childScope, '_makeLayoutActive'); + successCb(); + expect(current.dashboard.saveDashboard).toHaveBeenCalled(); + expect(childScope._makeLayoutActive).toHaveBeenCalled(); + expect(childScope._makeLayoutActive.calls.argsFor(0)[0]).toEqual(layout); + }); + + it('should provide an error callback that only calls _makeLayoutActive', function() { + spyOn(current.dashboard, 'saveDashboard'); + spyOn(childScope, '_makeLayoutActive'); + errorCb(); + expect(current.dashboard.saveDashboard).not.toHaveBeenCalled(); + expect(childScope._makeLayoutActive).toHaveBeenCalled(); + expect(childScope._makeLayoutActive.calls.argsFor(0)[0]).toEqual(layout); + }); + + }); + + }); + + describe('the editTitle method', function() { + + it('should set the editingTitle attribute to true on the layout it is passed', function() { + var layout = { id: '1' }; + childScope.editTitle(layout); + $rootScope.$digest(); + expect(layout.editingTitle).toEqual(true); + toFn(); + }); + + }); + + describe('the saveTitleEdit method', function() { + + it('should set editingTitle to false', function() { + var layout = { id: '1' }; + childScope.saveTitleEdit(layout); + expect(layout.editingTitle).toEqual(false); + }); + + it('should call layoutStorage.save', function() { + var layout = { id: '1' }; + spyOn(LayoutStorage.prototype, 'save').and.callThrough(); + childScope.saveTitleEdit(layout); + expect(LayoutStorage.prototype.save).toHaveBeenCalled(); + }); + + }); + + describe('the saveLayouts method', function() { + + it('should call LayoutStorage.save', function() { + spyOn(LayoutStorage.prototype, 'save').and.callThrough(); + $rootScope.dashboardOptions.saveLayouts(); + expect(LayoutStorage.prototype.save).toHaveBeenCalled(); + }); + + it('should call LayoutStorage.save with true as the first arg', function() { + spyOn(LayoutStorage.prototype, 'save').and.callThrough(); + $rootScope.dashboardOptions.saveLayouts(); + expect(LayoutStorage.prototype.save.calls.argsFor(0)[0]).toEqual(true); + }); + + }); + describe('the proxy methods to active layout', function() { + + var mockDash, galSpy; + + beforeEach(function() { + mockDash = { + active: true, + dashboard: { + addWidget: function() {}, + loadWidgets: function() {}, + saveDashboard: function() {} + } + }; + spyOn(mockDash.dashboard, 'addWidget'); + spyOn(mockDash.dashboard, 'loadWidgets'); + spyOn(mockDash.dashboard, 'saveDashboard'); + galSpy = spyOn(LayoutStorage.prototype, 'getActiveLayout').and; + galSpy.returnValue(mockDash); + }); + + describe('the addWidget method', function() { + + it('should call dashboard.addWidget method of the active layout', function() { + options.addWidget(1,2,3); + expect(mockDash.dashboard.addWidget).toHaveBeenCalled(); + var firstCall = mockDash.dashboard.addWidget.calls.first(); + expect(firstCall.object).toEqual(mockDash.dashboard); + expect(firstCall.args).toEqual([1,2,3]); + }); + + it('should do nothing if there is no active layout', function() { + galSpy.returnValue(null); + expect(function() { + options.addWidget(); + }).not.toThrow(); + }); + + }); + + describe('the loadWidgets method', function() { + + it('should call dashboard.loadWidgets of the current layout', function() { + options.loadWidgets(1,2,3); + expect(mockDash.dashboard.loadWidgets).toHaveBeenCalled(); + var firstCall = mockDash.dashboard.loadWidgets.calls.first(); + expect(firstCall.object).toEqual(mockDash.dashboard); + expect(firstCall.args).toEqual([1,2,3]); + }); + + it('should do nothing if there is no active layout', function() { + galSpy.returnValue(null); + expect(function() { + options.loadWidgets(); + }).not.toThrow(); + }); + + }); + + describe('the saveDashboard method', function() { + + it('should call dashboard.saveDashboard of the current layout', function() { + options.saveDashboard(1,2,3); + expect(mockDash.dashboard.saveDashboard).toHaveBeenCalled(); + var firstCall = mockDash.dashboard.saveDashboard.calls.first(); + expect(firstCall.object).toEqual(mockDash.dashboard); + expect(firstCall.args).toEqual([1,2,3]); + }); + + it('should do nothing if there is no active layout', function() { + galSpy.returnValue(null); + expect(function() { + options.saveDashboard(); + }).not.toThrow(); + }); + + }); + + }); + +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/DashboardWidgetCtrl.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/DashboardWidgetCtrl.js new file mode 100644 index 00000000..9ac57b19 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/DashboardWidgetCtrl.js @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .controller('DashboardWidgetCtrl', ['$scope', '$element', '$compile', '$window', '$timeout', + function($scope, $element, $compile, $window, $timeout) { + + $scope.status = { + isopen: false + }; + + // Fills "container" with compiled view + $scope.makeTemplateString = function() { + + var widget = $scope.widget; + + // First, build template string + var templateString = ''; + + if (widget.templateUrl) { + + // Use ng-include for templateUrl + templateString = '
    '; + + } else if (widget.template) { + + // Direct string template + templateString = widget.template; + + } else { + + // Assume attribute directive + templateString = '
    '); + widgetElm.append($marquee); + // create an overlaying div to block other widgets in order to stop their iframe events from being triggered + var $marquee2 = angular.element('
    '); + widgetElm.append($marquee2); + + // determine the unit/pixel ratio + var transformMultiplier = unitWidth / pixelWidth; + + // updates marquee with preview of new width + var mousemove = function(e) { + var curX = e.clientX; +// console.log(curX); +// console.log(e); + var pixelChange = curX - initX; + var newWidth = pixelWidth + pixelChange; + $marquee.css('width', newWidth + 'px'); + $marquee2.css('width', (newWidth + 200) + 'px'); + + }; + + // sets new widget width on mouseup + var mouseup = function(e) { + // remove listener and marquee + jQuery($window).off('mousemove', mousemove); + $marquee.remove(); + $marquee2.remove(); + + // calculate change in units + var curX = e.clientX; + var pixelChange = curX - initX; + var unitChange = Math.round(pixelChange * transformMultiplier * 100) / 100; + + // add to initial unit width + var newWidth = unitWidth * 1 + unitChange; + widget.setWidth(newWidth, widthUnits); + $scope.$emit('widgetChanged', widget); + $scope.$apply(); + $scope.$broadcast('widgetResized', { + width: newWidth + }); + }; + +// jQuery($window).on('mousemove', mousemove).one('mouseup', mouseup); + jQuery($window).on('mousemove', mousemove).one('mouseup', mouseup); + }; + + //TODO refactor + $scope.grabSouthResizer = function(e) { + var widgetElm = $element.find('.widget'); + + // ignore middle- and right-click + if (e.which !== 1) { + return; + } + + e.stopPropagation(); + e.originalEvent.preventDefault(); + + // get the starting horizontal position + var initY = e.clientY; + // console.log('initX', initX); + + // Get the current width of the widget and dashboard + var pixelWidth = widgetElm.width(); + var pixelHeight = widgetElm.height(); + + // create marquee element for resize action + var $marquee = angular.element('
    '); + widgetElm.append($marquee); + + // updates marquee with preview of new height + var mousemove = function(e) { + var curY = e.clientY; + var pixelChange = curY - initY; + var newHeight = pixelHeight + pixelChange; + $marquee.css('height', newHeight + 'px'); + }; + + // sets new widget width on mouseup + var mouseup = function(e) { + // remove listener and marquee + jQuery($window).off('mousemove', mousemove); + $marquee.remove(); + + // calculate height change + var curY = e.clientY; + var pixelChange = curY - initY; + + //var widgetContainer = widgetElm.parent(); // widget container responsible for holding widget width and height + var widgetContainer = widgetElm.find('.widget-content'); + + var diff = pixelChange; + var height = parseInt(widgetContainer.css('height'), 10); + var newHeight = (height + diff); + + //$scope.widget.style.height = newHeight + 'px'; + + $scope.widget.setHeight(newHeight + 'px'); + + $scope.$emit('widgetChanged', $scope.widget); + $scope.$apply(); // make AngularJS to apply style changes + + $scope.$broadcast('widgetResized', { + height: newHeight + }); + }; + + jQuery($window).on('mousemove', mousemove).one('mouseup', mouseup); + }; + + // replaces widget title with input + $scope.editTitle = function(widget) { + var widgetElm = $element.find('.widget'); + widget.editingTitle = true; + // HACK: get the input to focus after being displayed. + $timeout(function() { + widgetElm.find('form.widget-title input:eq(0)').focus()[0].setSelectionRange(0, 9999); + }); + }; + + // saves whatever is in the title input as the new title + $scope.saveTitleEdit = function(widget) { + widget.editingTitle = false; + $scope.$emit('widgetChanged', widget); + }; + + $scope.compileTemplate = function() { + var container = $scope.findWidgetContainer($element); + var templateString = $scope.makeTemplateString(); + var widgetElement = angular.element(templateString); + + container.empty(); + container.append(widgetElement); + $compile(widgetElement)($scope); + }; + + $scope.findWidgetContainer = function(element) { + // widget placeholder is the first (and only) child of .widget-content + return element.find('.widget-content'); + }; + } + ]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/DashboardWidgetCtrl.spec.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/DashboardWidgetCtrl.spec.js new file mode 100644 index 00000000..55604646 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/DashboardWidgetCtrl.spec.js @@ -0,0 +1,164 @@ +'use strict'; + +describe('Controller: DashboardWidgetCtrl', function() { + + var $scope, $element, $timeout, injections; + + beforeEach(module('ui.dashboard')); + + beforeEach(inject(function($rootScope, $controller){ + $scope = $rootScope.$new(); + $element = angular.element('
    '); + $timeout = function timeout(fn) { + fn(); + }; + injections = { + $scope: $scope, + $element: $element, + $timeout: $timeout + }; + spyOn(injections, '$timeout'); + $controller('DashboardWidgetCtrl', injections); + })); + + describe('the makeTemplateString method', function() { + + it('should return a string', function() { + $scope.widget = { + templateUrl: 'some/template.html' + }; + expect(typeof $scope.makeTemplateString()).toEqual('string'); + }); + + it('should use ng-include if templateUrl is specified on widget, despite any other options', function() { + $scope.widget = { + templateUrl: 'some/template.html', + template: 'not this one', + directive: 'or-this', + attrs: { + something: 'awesome', + other: 'thing' + } + }; + expect($scope.makeTemplateString()).toMatch(/ng-include="'some\/template\.html'"/); + }); + + it('should return widget.template if specified, regardless of presence of directive or attrs', function() { + $scope.widget = { + template: '
    ', + directive: 'no-good' + }; + expect($scope.makeTemplateString()).toEqual($scope.widget.template); + }); + + it('should use widget.directive as attribute directive', function() { + $scope.widget = { + directive: 'ng-awesome' + }; + expect($scope.makeTemplateString()).toEqual('
    '); + }); + + it('should attach attributes if provided', function() { + $scope.widget = { + directive: 'ng-awesome', + attrs: { + 'ng-awesome': 'test1', + other: 'attr', + more: 'stuff' + } + }; + expect($scope.makeTemplateString()).toEqual('
    '); + }); + + it('should place widgetData into dataAttrName attribute if specified', function() { + $scope.widget = { + directive: 'ng-awesome', + attrs: { + 'ng-awesome': 'test1', + other: 'attr', + more: 'stuff' + }, + dataAttrName: 'data' + }; + expect($scope.makeTemplateString()).toEqual('
    '); + }); + + it('should add attrs to the widget object if it does not exist and dataAttrName is specified', function() { + $scope.widget = { + directive: 'ng-awesome', + dataAttrName: 'data' + }; + expect($scope.makeTemplateString()).toEqual('
    '); + }); + + }); + + describe('the grabResizer method', function() { + + var evt, widget, WidgetModel; + + beforeEach(inject(function (_WidgetModel_) { + WidgetModel = _WidgetModel_; + })); + + beforeEach(function() { + evt = { + stopPropagation: jasmine.createSpy('stopPropagation'), + originalEvent: { + preventDefault: jasmine.createSpy('preventDefault') + }, + clientX: 100, + which: 1 + }; + $scope.widget = widget = new WidgetModel({ + style: { + width: '30%' + } + }); + }); + + it('should do nothing if event.which is not 1 (left click)', function() { + evt.which = 2; + $scope.grabResizer(evt); + expect(evt.stopPropagation).not.toHaveBeenCalled(); + }); + + it('should call stopPropagation and preventDefault', function() { + $scope.grabResizer(evt); + expect(evt.stopPropagation).toHaveBeenCalled(); + expect(evt.originalEvent.preventDefault).toHaveBeenCalled(); + }); + + it('should add a .widget-resizer-marquee element to the .widget element', function() { + $scope.grabResizer(evt); + expect($element.find('.widget-resizer-marquee').length).toBeGreaterThan(0); + }); + + }); + + describe('the editTitle method', function() { + + it('should set editingTitle=true on the widget object', function() { + var widget = {}; + $scope.editTitle(widget); + expect(widget.editingTitle).toEqual(true); + }); + + it('should call $timeout', function() { + var widget = {}; + $scope.editTitle(widget); + expect(injections.$timeout).toHaveBeenCalled(); + }); + + }); + + describe('the saveTitleEdit method', function() { + + it('should set editingTitle=false', function() { + var widget = { editingTitle: true }; + $scope.saveTitleEdit(widget); + expect(widget.editingTitle).toEqual(false); + }); + }); + +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/widget.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/widget.js new file mode 100644 index 00000000..f5a6ebef --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/widget.js @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .directive('widget', ['$injector', function ($injector) { + + return { + + controller: 'DashboardWidgetCtrl', + + link: function (scope) { + + var widget = scope.widget; + var dataModelType = widget.dataModelType; + + // set up data source + if (dataModelType) { + var DataModelConstructor; // data model constructor function + + if (angular.isFunction(dataModelType)) { + DataModelConstructor = dataModelType; + } else if (angular.isString(dataModelType)) { + $injector.invoke([dataModelType, function (DataModelType) { + DataModelConstructor = DataModelType; + }]); + } else { + throw new Error('widget dataModelType should be function or string'); + } + + var ds; + if (widget.dataModelArgs) { + ds = new DataModelConstructor(widget.dataModelArgs); + } else { + ds = new DataModelConstructor(); + } + widget.dataModel = ds; + ds.setup(widget, scope); + ds.init(); + scope.$on('$destroy', _.bind(ds.destroy,ds)); + } + + // Compile the widget template, emit add event + scope.compileTemplate(); + scope.$emit('widgetAdded', widget); + + } + + }; + }]); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/widget.spec.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/widget.spec.js new file mode 100644 index 00000000..0997e071 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/widget/widget.spec.js @@ -0,0 +1,104 @@ +// 'use strict'; + +describe('Directive: widget', function () { + + var element, scope, rootScope, isoScope, compile, provide; + + function Type() { + } + + Type.prototype = { + setup: function () { + }, + init: function () { + }, + destroy: function () { + } + }; + + beforeEach(function () { + spyOn(Type.prototype, 'setup'); + spyOn(Type.prototype, 'init'); + spyOn(Type.prototype, 'destroy'); + // define mock objects here + }); + + // load the directive's module + beforeEach(module('ui.dashboard', function ($provide, $controllerProvider) { + provide = $provide; + // Inject dependencies like this: + $controllerProvider.register('DashboardWidgetCtrl', function ($scope) { + + }); + + })); + + beforeEach(inject(function ($compile, $rootScope) { + // Cache these for reuse + rootScope = $rootScope; + compile = $compile; + + // Other setup, e.g. helper functions, etc. + + // Set up the outer scope + scope = $rootScope.$new(); + scope.widget = { + dataModelType: Type + }; + + compileTemplate = jasmine.createSpy('compileTemplate'); + scope.compileTemplate = compileTemplate; + })); + + function compileWidget() { + // Define and compile the element + element = angular.element('
    '); + element = compile(element)(scope); + scope.$digest(); + isoScope = element.isolateScope(); + } + + it('should create a new instance of dataModelType if provided in scope.widget', function () { + compileWidget(); + expect(scope.widget.dataModel instanceof Type).toBe(true); + }); + + it('should call setup and init on the new dataModel', function () { + compileWidget(); + expect(Type.prototype.setup).toHaveBeenCalled(); + expect(Type.prototype.init).toHaveBeenCalled(); + }); + + it('should call compile template', function () { + compileWidget(); + expect(scope.compileTemplate).toHaveBeenCalled(); + }); + + it('should create a new instance of dataModelType from string name', function () { + // register data model with $injector + provide.factory('StringNameDataModel', function () { + return Type; + }); + + scope.widget = { + dataModelType: 'StringNameDataModel' + }; + + compileWidget(); + + expect(scope.widget.dataModel instanceof Type).toBe(true); + expect(Type.prototype.setup).toHaveBeenCalled(); + expect(Type.prototype.init).toHaveBeenCalled(); + }); + + it('should validate data model type', function () { + scope.widget = { + dataModelType: {} + }; + + expect(function () { + compileWidget() + }).toThrowError(); + }); + +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/DashboardState.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/DashboardState.js new file mode 100644 index 00000000..67948ead --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/DashboardState.js @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .factory('DashboardState', ['$log', '$q', function ($log, $q) { + function DashboardState(storage, id, hash, widgetDefinitions, stringify) { + this.storage = storage; + this.id = id; + this.hash = hash; + this.widgetDefinitions = widgetDefinitions; + this.stringify = stringify; + } + + DashboardState.prototype = { + /** + * Takes array of widget instance objects, serializes, + * and saves state. + * + * @param {Array} widgets scope.widgets from dashboard directive + * @return {Boolean} true on success, false on failure + */ + save: function (widgets) { + + if (!this.storage) { + return true; + } + + var serialized = _.map(widgets, function (widget) { + return widget.serialize(); + }); + + var item = { widgets: serialized, hash: this.hash }; + + if (this.stringify) { + item = JSON.stringify(item); + } + + this.storage.setItem(this.id, item); + return true; + }, + + /** + * Loads dashboard state from the storage object. + * Can handle a synchronous response or a promise. + * + * @return {Array|Promise} Array of widget definitions or a promise + */ + load: function () { + + if (!this.storage) { + return null; + } + + var serialized; + + // try loading storage item + serialized = this.storage.getItem( this.id ); + + if (serialized) { + // check for promise + if (angular.isObject(serialized) && angular.isFunction(serialized.then)) { + return this._handleAsyncLoad(serialized); + } + // otherwise handle synchronous load + return this._handleSyncLoad(serialized); + } else { + return null; + } + }, + + _handleSyncLoad: function(serialized) { + + var deserialized, result = []; + + if (!serialized) { + return null; + } + + if (this.stringify) { + try { // to deserialize the string + + deserialized = JSON.parse(serialized); + + } catch (e) { + + // bad JSON, log a warning and return + $log.warn('Serialized dashboard state was malformed and could not be parsed: ', serialized); + return null; + + } + } + else { + deserialized = serialized; + } + + // check hash against current hash + if (deserialized.hash !== this.hash) { + + $log.info('Serialized dashboard from storage was stale (old hash: ' + deserialized.hash + ', new hash: ' + this.hash + ')'); + this.storage.removeItem(this.id); + return null; + + } + + // Cache widgets + var savedWidgetDefs = deserialized.widgets; + + // instantiate widgets from stored data + for (var i = 0; i < savedWidgetDefs.length; i++) { + + // deserialized object + var savedWidgetDef = savedWidgetDefs[i]; + + // widget definition to use + var widgetDefinition = this.widgetDefinitions.getByName(savedWidgetDef.name); + + // check for no widget + if (!widgetDefinition) { + // no widget definition found, remove and return false + $log.warn('Widget with name "' + savedWidgetDef.name + '" was not found in given widget definition objects'); + continue; + } + + // check widget-specific storageHash + if (widgetDefinition.hasOwnProperty('storageHash') && widgetDefinition.storageHash !== savedWidgetDef.storageHash) { + // widget definition was found, but storageHash was stale, removing storage + $log.info('Widget Definition Object with name "' + savedWidgetDef.name + '" was found ' + + 'but the storageHash property on the widget definition is different from that on the ' + + 'serialized widget loaded from storage. hash from storage: "' + savedWidgetDef.storageHash + '"' + + ', hash from WDO: "' + widgetDefinition.storageHash + '"'); + continue; + } + + // push instantiated widget to result array + result.push(savedWidgetDef); + } + + return result; + }, + + _handleAsyncLoad: function(promise) { + var self = this; + var deferred = $q.defer(); + promise.then( + // success + function(res) { + var result = self._handleSyncLoad(res); + if (result) { + deferred.resolve(result); + } else { + deferred.reject(result); + } + }, + // failure + function(res) { + deferred.reject(res); + } + ); + + return deferred.promise; + } + + }; + return DashboardState; + }]); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/LayoutStorage.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/LayoutStorage.js new file mode 100644 index 00000000..3685fd3f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/LayoutStorage.js @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .factory('LayoutStorage', function() { + + var noopStorage = { + setItem: function() { + + }, + getItem: function() { + + }, + removeItem: function() { + + } + }; + + + + function LayoutStorage(options) { + + var defaults = { + storage: noopStorage, + storageHash: '', + stringifyStorage: true + }; + + angular.extend(defaults, options); + angular.extend(options, defaults); + + this.id = options.storageId; + this.storage = options.storage; + this.storageHash = options.storageHash; + this.stringifyStorage = options.stringifyStorage; + this.widgetDefinitions = options.widgetDefinitions; + this.defaultLayouts = options.defaultLayouts; + this.lockDefaultLayouts = options.lockDefaultLayouts; + this.widgetButtons = options.widgetButtons; + this.explicitSave = options.explicitSave; + this.defaultWidgets = options.defaultWidgets; + this.settingsModalOptions = options.settingsModalOptions; + this.onSettingsClose = options.onSettingsClose; + this.onSettingsDismiss = options.onSettingsDismiss; + this.options = options; + this.options.unsavedChangeCount = 0; + + this.layouts = []; + this.states = {}; + this.load(); + this._ensureActiveLayout(); + } + + LayoutStorage.prototype = { + + add: function(layouts) { + if (!angular.isArray(layouts)) { + layouts = [layouts]; + } + var self = this; + angular.forEach(layouts, function(layout) { + layout.dashboard = layout.dashboard || {}; + layout.dashboard.storage = self; + layout.dashboard.storageId = layout.id = self._getLayoutId.call(self,layout); + layout.dashboard.widgetDefinitions = layout.widgetDefinitions || self.widgetDefinitions; + layout.dashboard.stringifyStorage = false; + layout.dashboard.defaultWidgets = layout.defaultWidgets || self.defaultWidgets; + layout.dashboard.widgetButtons = self.widgetButtons; + layout.dashboard.explicitSave = self.explicitSave; + layout.dashboard.settingsModalOptions = self.settingsModalOptions; + layout.dashboard.onSettingsClose = self.onSettingsClose; + layout.dashboard.onSettingsDismiss = self.onSettingsDismiss; + self.layouts.push(layout); + }); + }, + + remove: function(layout) { + var index = this.layouts.indexOf(layout); + if (index >= 0) { + this.layouts.splice(index, 1); + delete this.states[layout.id]; + + // check for active + if (layout.active && this.layouts.length) { + var nextActive = index > 0 ? index - 1 : 0; + this.layouts[nextActive].active = true; + } + } + }, + + save: function() { + + var state = { + layouts: this._serializeLayouts(), + states: this.states, + storageHash: this.storageHash + }; + + if (this.stringifyStorage) { + state = JSON.stringify(state); + } + + this.storage.setItem(this.id, state); + this.options.unsavedChangeCount = 0; + }, + + load: function() { + + var serialized = this.storage.getItem(this.id); + + this.clear(); + + if (serialized) { + // check for promise + if (angular.isObject(serialized) && angular.isFunction(serialized.then)) { + this._handleAsyncLoad(serialized); + } else { + this._handleSyncLoad(serialized); + } + } else { + this._addDefaultLayouts(); + } + }, + + clear: function() { + this.layouts = []; + this.states = {}; + }, + + setItem: function(id, value) { + this.states[id] = value; + this.save(); + }, + + getItem: function(id) { + return this.states[id]; + }, + + removeItem: function(id) { + delete this.states[id]; + this.save(); + }, + + getActiveLayout: function() { + var len = this.layouts.length; + for (var i = 0; i < len; i++) { + var layout = this.layouts[i]; + if (layout.active) { + return layout; + } + } + return false; + }, + + _addDefaultLayouts: function() { + var self = this; + var defaults = this.lockDefaultLayouts ? { locked: true } : {}; + angular.forEach(this.defaultLayouts, function(layout) { + self.add(angular.extend(_.clone(defaults), layout)); + }); + }, + + _serializeLayouts: function() { + var result = []; + angular.forEach(this.layouts, function(l) { + result.push({ + title: l.title, + id: l.id, + active: l.active, + locked: l.locked, + defaultWidgets: l.dashboard.defaultWidgets + }); + }); + return result; + }, + + _handleSyncLoad: function(serialized) { + + var deserialized; + + if (this.stringifyStorage) { + try { + + deserialized = JSON.parse(serialized); + + } catch (e) { + this._addDefaultLayouts(); + return; + } + } else { + + deserialized = serialized; + + } + + if (this.storageHash !== deserialized.storageHash) { + this._addDefaultLayouts(); + return; + } + this.states = deserialized.states; + this.add(deserialized.layouts); + }, + + _handleAsyncLoad: function(promise) { + var self = this; + promise.then( + angular.bind(self, this._handleSyncLoad), + angular.bind(self, this._addDefaultLayouts) + ); + }, + + _ensureActiveLayout: function() { + for (var i = 0; i < this.layouts.length; i++) { + var layout = this.layouts[i]; + if (layout.active) { + return; + } + } + if (this.layouts[0]) { + this.layouts[0].active = true; + } + }, + + _getLayoutId: function(layout) { + if (layout.id) { + return layout.id; + } + var max = 0; + for (var i = 0; i < this.layouts.length; i++) { + var id = this.layouts[i].id; + max = Math.max(max, id * 1); + } + return max + 1; + } + + }; + return LayoutStorage; + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/LayoutStorage.spec.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/LayoutStorage.spec.js new file mode 100644 index 00000000..3310cad9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/LayoutStorage.spec.js @@ -0,0 +1,692 @@ +'use strict'; + +describe('Factory: LayoutStorage', function () { + + // mock UI Sortable + beforeEach(function () { + angular.module('ui.sortable', []); + }); + + // load the service's module + beforeEach(module('ui.dashboard')); + + // instantiate service + var LayoutStorage; + beforeEach(inject(function (_LayoutStorage_) { + LayoutStorage = _LayoutStorage_; + })); + + describe('the constructor', function() { + + var storage, options; + + beforeEach(function() { + options = { + storageId: 'testingStorage', + storage: { + setItem: function(key, value) { + + }, + getItem: function(key) { + + }, + removeItem: function(key) { + + } + }, + storageHash: 'ds5f9d1f', + stringifyStorage: true, + widgetDefinitions: [ + + ], + defaultLayouts: [ + {title: 'something'}, + {title: 'something'}, + {title: 'something'} + ], + widgetButtons: false, + explicitSave: false, + settingsModalOptions: {}, + onSettingsClose: function() { + + }, + onSettingsDismiss: function() { + + } + }; + storage = new LayoutStorage(options); + }); + + it('should provide an empty implementation of storage if it is not provided', function() { + delete options.storage; + var stateless = new LayoutStorage(options); + var noop = stateless.storage; + angular.forEach(['setItem', 'getItem', 'removeItem'], function(method) { + expect(typeof noop[method]).toEqual('function'); + expect(noop[method]).not.toThrow(); + noop[method](); + }); + }); + + it('should set a subset of the options directly on the LayoutStorage instance itself', function() { + var properties = { + id: 'storageId', + storage: 'storage', + storageHash: 'storageHash', + stringifyStorage: 'stringifyStorage', + widgetDefinitions: 'widgetDefinitions', + defaultLayouts: 'defaultLayouts', + widgetButtons: 'widgetButtons', + explicitSave: 'explicitSave', + settingsModalOptions: 'settingsModalOptions', + onSettingsClose: 'onSettingsClose', + onSettingsDismiss: 'onSettingsDismiss' + }; + + angular.forEach(properties, function(val, key) { + expect( storage[key] ).toEqual( options[val] ); + }); + + }); + + it('should set stringify as true by default', function() { + delete options.stringifyStorage; + storage = new LayoutStorage(options); + expect(storage.stringifyStorage).toEqual(true); + }); + + it('should allow stringify to be overridden by option', function() { + options.stringifyStorage = false; + storage = new LayoutStorage(options); + expect(storage.stringifyStorage).toEqual(false); + }); + + it('should create a layouts array and states object', function() { + expect(storage.layouts instanceof Array).toEqual(true); + expect(typeof storage.states).toEqual('object'); + }); + + it('should call load', function() { + spyOn(LayoutStorage.prototype, 'load'); + storage = new LayoutStorage(options); + expect(LayoutStorage.prototype.load).toHaveBeenCalled(); + }); + + }); + + describe('the load method', function() { + + var options, storage; + + beforeEach(function() { + options = { + storageId: 'testingStorage', + storage: { + setItem: function(key, value) { + + }, + getItem: function(key) { + + }, + removeItem: function(key) { + + } + }, + storageHash: 'ds5f9d1f', + stringifyStorage: true, + widgetDefinitions: [ + + ], + defaultLayouts: [ + {title: 'something'}, + {title: 'something'}, + {title: 'something'} + ], + widgetButtons: false, + explicitSave: false + } + storage = new LayoutStorage(options); + }); + + it('should use the default layouts if no stored info was found', function() { + expect(storage.layouts.length).toEqual(options.defaultLayouts.length); + }); + + it('should clone default layouts rather than use them directly', function() { + expect(storage.layouts.indexOf(options.defaultLayouts[0])).toEqual(-1); + }); + + it('should use the result from getItem for layouts.', function() { + spyOn(options.storage, 'getItem').and.returnValue(JSON.stringify({ + storageHash: 'ds5f9d1f', + layouts: [ + { id: 0, title: 'title', defaultWidgets: [], active: true }, + { id: 1, title: 'title2', defaultWidgets: [], active: false }, + { id: 2, title: 'title3', defaultWidgets: [], active: false }, + { id: 3, title: 'custom', defaultWidgets: [], active: false } + ], + states: { + 0: {}, + 1: {}, + 2: {} + } + })); + storage.load(); + expect(storage.layouts.map(function(l) {return l.title})).toEqual(['title', 'title2', 'title3', 'custom']); + }); + + it('should NOT use result from getItem for layouts if the storageHash doesnt match', function() { + spyOn(options.storage, 'getItem').and.returnValue(JSON.stringify({ + storageHash: 'alskdjf02iej', + layouts: [ + { id: 0, title: 'title', defaultWidgets: [], active: true }, + { id: 1, title: 'title2', defaultWidgets: [], active: false }, + { id: 2, title: 'title3', defaultWidgets: [], active: false }, + { id: 3, title: 'custom', defaultWidgets: [], active: false } + ], + states: { + 0: {}, + 1: {}, + 2: {} + } + })); + storage.load(); + expect(storage.layouts.map(function(l) {return l.title})).toEqual(['something', 'something', 'something']); + }); + + it('should be able to handle async loading via promise', inject(function($rootScope,$q) { + var deferred = $q.defer(); + spyOn(options.storage, 'getItem').and.returnValue(deferred.promise); + storage.load(); + expect(storage.layouts).toEqual([]); + deferred.resolve(JSON.stringify({ + storageHash: 'ds5f9d1f', + layouts: [ + { id: 0, title: 'title', defaultWidgets: [], active: true }, + { id: 1, title: 'title2', defaultWidgets: [], active: false }, + { id: 2, title: 'title3', defaultWidgets: [], active: false }, + { id: 3, title: 'custom', defaultWidgets: [], active: false } + ], + states: { + 0: {}, + 1: {}, + 2: {} + } + })); + $rootScope.$apply(); + expect(storage.layouts.map(function(l) {return l.title})).toEqual(['title', 'title2', 'title3', 'custom']); + })); + + it('should load defaults if the deferred is rejected', inject(function($rootScope,$q) { + var deferred = $q.defer(); + spyOn(options.storage, 'getItem').and.returnValue(deferred.promise); + storage.load(); + deferred.reject(); + $rootScope.$apply(); + expect(storage.layouts.map(function(l) {return l.title})).toEqual(['something', 'something', 'something']); + })); + + it('should load defaults if the json is malformed', inject(function($rootScope,$q) { + var deferred = $q.defer(); + spyOn(options.storage, 'getItem').and.returnValue(deferred.promise); + storage.load(); + expect(storage.layouts).toEqual([]); + deferred.resolve(JSON.stringify({ + storageHash: 'ds5f9d1f', + layouts: [ + { id: 0, title: 'title', defaultWidgets: [], active: true }, + { id: 1, title: 'title2', defaultWidgets: [], active: false }, + { id: 2, title: 'title3', defaultWidgets: [], active: false }, + { id: 3, title: 'custom', defaultWidgets: [], active: false } + ], + states: { + 0: {}, + 1: {}, + 2: {} + } + }).replace('{','{{')); + $rootScope.$apply(); + expect(storage.layouts.map(function(l) {return l.title})).toEqual(['something', 'something', 'something']); + })); + + it('should not try to JSON.parse the result if stringifyStorage is false.', function() { + options.stringifyStorage = false; + storage = new LayoutStorage(options); + spyOn(options.storage, 'getItem').and.returnValue({ + storageHash: 'ds5f9d1f', + layouts: [ + { id: 0, title: 'title', defaultWidgets: [], active: true }, + { id: 1, title: 'title2', defaultWidgets: [], active: false }, + { id: 2, title: 'title3', defaultWidgets: [], active: false }, + { id: 3, title: 'custom', defaultWidgets: [], active: false } + ], + states: { + 0: {}, + 1: {}, + 2: {} + } + }); + storage.load(); + expect(storage.layouts.map(function(l) {return l.title})).toEqual(['title', 'title2', 'title3', 'custom']); + }); + + }); + + describe('the add method', function() { + + var storage, options; + + beforeEach(function() { + options = { + storageId: 'testingStorage', + storage: { + setItem: function(key, value) { + + }, + getItem: function(key) { + + }, + removeItem: function(key) { + + } + }, + storageHash: 'ds5f9d1f', + stringifyStorage: true, + widgetDefinitions: [ + + ], + defaultLayouts: [], + widgetButtons: false, + explicitSave: false + } + + spyOn(LayoutStorage.prototype, 'load' ); + + storage = new LayoutStorage(options); + + }); + + it('should add to storage.layouts', function() { + var newLayout = { title: 'my-layout' }; + storage.add(newLayout); + expect(storage.layouts[0]).toEqual(newLayout); + }); + + it('should be able to take an array of new layouts', function() { + var newLayouts = [ { title: 'my-layout' }, { title: 'my-layout-2' } ]; + storage.add(newLayouts); + expect(storage.layouts.length).toEqual(2); + expect(storage.layouts.indexOf(newLayouts[0])).not.toEqual(-1); + expect(storage.layouts.indexOf(newLayouts[1])).not.toEqual(-1); + }); + + it('should look for defaultWidgets on storage options if not supplied on layout definition', function() { + options.defaultWidgets = [{name: 'a'}, {name: 'b'}, {name: 'c'}]; + storage = new LayoutStorage(options); + + var newLayouts = [ { title: 'my-layout', defaultWidgets: [] }, { title: 'my-layout-2' } ]; + storage.add(newLayouts); + expect(newLayouts[0].dashboard.defaultWidgets === newLayouts[0].defaultWidgets).toEqual(true); + expect(newLayouts[1].dashboard.defaultWidgets === options.defaultWidgets).toEqual(true); + }); + + it('should use defaultWidgets if supplied in the layout definition', function() { + options.defaultWidgets = [{name: 'a'}, {name: 'b'}, {name: 'c'}]; + storage = new LayoutStorage(options); + + var newLayouts = [ { title: 'my-layout', defaultWidgets: [] }, { title: 'my-layout-2' } ]; + storage.add(newLayouts); + expect(newLayouts[0].dashboard.defaultWidgets).toEqual([]); + expect(newLayouts[1].dashboard.defaultWidgets).toEqual(options.defaultWidgets); + }); + + it('should look for widgetDefinitions on storage options if not supplied on layout definition', function() { + options.widgetDefinitions = [{name: 'a'}, {name: 'b'}, {name: 'c'}]; + storage = new LayoutStorage(options); + + var newLayouts = [ { title: 'my-layout', widgetDefinitions: [] }, { title: 'my-layout-2' } ]; + storage.add(newLayouts); + expect(newLayouts[0].dashboard.widgetDefinitions === newLayouts[0].widgetDefinitions).toEqual(true); + expect(newLayouts[1].dashboard.widgetDefinitions === options.widgetDefinitions).toEqual(true); + }); + + it('should use widgetDefinitions if supplied in the layout definition', function() { + options.widgetDefinitions = [{name: 'a'}, {name: 'b'}, {name: 'c'}]; + storage = new LayoutStorage(options); + + var newLayouts = [ { title: 'my-layout', widgetDefinitions: [] }, { title: 'my-layout-2' } ]; + storage.add(newLayouts); + expect(newLayouts[0].dashboard.widgetDefinitions).toEqual([]); + expect(newLayouts[1].dashboard.widgetDefinitions).toEqual(options.widgetDefinitions); + }); + + }); + + describe('the remove method', function() { + + var storage, options; + + beforeEach(function() { + options = { + storageId: 'testingStorage', + storageHash: 'ds5f9d1f', + stringifyStorage: true, + widgetDefinitions: [ + { name: 'A' }, + { name: 'B' }, + { name: 'C' } + ], + defaultLayouts: [ + { title: '1' }, + { title: '2', active: true }, + { title: '3' } + ], + widgetButtons: false, + explicitSave: false + } + + storage = new LayoutStorage(options); + }); + + it('should remove the supplied layout', function() { + var layout = storage.layouts[1]; + storage.remove(layout); + expect(storage.layouts.indexOf(layout)).toEqual(-1); + }); + + it('should delete the state', function() { + var layout = storage.layouts[1]; + storage.setItem(layout.id, {}); + storage.remove(layout); + expect(storage.states[layout.id]).toBeUndefined(); + }); + + it('should do nothing if layout is not in layouts', function() { + var layout = {}; + var before = storage.layouts.length; + storage.remove(layout); + var after = storage.layouts.length; + expect(before).toEqual(after); + }); + + it('should set another dashboard to active if the layout removed was active', function() { + var layout = storage.layouts[1]; + storage.remove(layout); + expect(storage.layouts[0].active || storage.layouts[1].active).toEqual(true); + }); + + it('should set the layout at index 0 to active if the removed layout was 0', function() { + storage.layouts[1].active = false; + storage.layouts[0].active = true; + storage.remove(storage.layouts[0]); + expect(storage.layouts[0].active).toEqual(true); + }); + + it('should not change the active layout if it was not the one that got removed', function() { + var active = storage.layouts[1]; + var layout = storage.layouts[0]; + storage.remove(layout); + expect(active.active).toEqual(true); + }); + + }); + + describe('the save method', function() { + + var options, storage; + + beforeEach(function() { + options = { + storageId: 'testingStorage', + storage: { + setItem: function(key, value) { + + }, + getItem: function(key) { + + }, + removeItem: function(key) { + + } + }, + storageHash: 'ds5f9d1f', + stringifyStorage: true, + widgetDefinitions: [ + + ], + defaultLayouts: [ + {title: 'something'}, + {title: 'something'}, + {title: 'something'} + ], + widgetButtons: false, + explicitSave: false + } + storage = new LayoutStorage(options); + }); + + it('should call options.storage.setItem with a stringified object', function() { + spyOn(options.storage, 'setItem' ); + storage.save(); + expect(options.storage.setItem).toHaveBeenCalled(); + expect(options.storage.setItem.calls.argsFor(0)[0]).toEqual(storage.id); + expect(typeof options.storage.setItem.calls.argsFor(0)[1]).toEqual('string'); + expect(function(){ + JSON.parse(options.storage.setItem.calls.argsFor(0)[1]); + }).not.toThrow(); + }); + + it('should save an object that has layouts, states, and storageHash', function() { + spyOn(options.storage, 'setItem' ); + storage.save(); + var obj = JSON.parse(options.storage.setItem.calls.argsFor(0)[1]); + expect(obj.hasOwnProperty('layouts')).toEqual(true); + expect(obj.layouts instanceof Array).toEqual(true); + expect(obj.hasOwnProperty('states')).toEqual(true); + expect(typeof obj.states).toEqual('object'); + expect(obj.hasOwnProperty('storageHash')).toEqual(true); + expect(typeof obj.storageHash).toEqual('string'); + }); + + it('should call options.storage.setItem with an object when stringifyStorage is false', function() { + options.stringifyStorage = false; + storage = new LayoutStorage(options); + spyOn(options.storage, 'setItem' ); + storage.save(); + expect(options.storage.setItem).toHaveBeenCalled(); + expect(options.storage.setItem.calls.argsFor(0)[0]).toEqual(storage.id); + expect(typeof options.storage.setItem.calls.argsFor(0)[1]).toEqual('object'); + }); + + }); + + describe('the setItem method', function() { + + var options, storage; + + beforeEach(function() { + options = { + storageId: 'testingStorage', + storage: { + setItem: function(key, value) { + + }, + getItem: function(key) { + + }, + removeItem: function(key) { + + } + }, + storageHash: 'ds5f9d1f', + stringifyStorage: true, + widgetDefinitions: [ + + ], + defaultLayouts: [ + {title: 'something'}, + {title: 'something'}, + {title: 'something'} + ], + widgetButtons: false, + explicitSave: false + } + storage = new LayoutStorage(options); + }); + + it('should set storage.states[id] to the second argument', function() { + var state = { some: 'thing'}; + storage.setItem('id', state); + expect(storage.states.id).toEqual(state); + }); + + it('should call save', function() { + spyOn(storage, 'save'); + var state = { some: 'thing'}; + storage.setItem('id', state); + expect(storage.save).toHaveBeenCalled(); + }); + + }); + + describe('the getItem method', function() { + + var options, storage; + + beforeEach(function() { + options = { + storageId: 'testingStorage', + storage: { + setItem: function(key, value) { + + }, + getItem: function(key) { + + }, + removeItem: function(key) { + + } + }, + storageHash: 'ds5f9d1f', + stringifyStorage: true, + widgetDefinitions: [ + + ], + defaultLayouts: [ + {title: 'something'}, + {title: 'something'}, + {title: 'something'} + ], + widgetButtons: false, + explicitSave: false + } + storage = new LayoutStorage(options); + }); + + it('should return states[id]', function() { + storage.states['myId'] = {}; + var result = storage.getItem('myId'); + expect(result === storage.states['myId']).toEqual(true); + }); + + }); + + describe('the getActiveLayout method', function() { + var options, storage; + + beforeEach(function() { + options = { + storageId: 'testingStorage', + storage: { + setItem: function(key, value) { + + }, + getItem: function(key) { + + }, + removeItem: function(key) { + + } + }, + storageHash: 'ds5f9d1f', + stringifyStorage: true, + widgetDefinitions: [ + + ], + defaultLayouts: [ + {title: 'i am active', active: true}, + {title: 'i am not'}, + {title: 'me neither'} + ], + widgetButtons: false, + explicitSave: false + } + storage = new LayoutStorage(options); + }); + + it('should return the layout with active:true', function() { + var layout = storage.getActiveLayout(); + expect(layout.title).toEqual('i am active'); + }); + + it('should return false if no layout is active', function() { + var layout = storage.getActiveLayout(); + layout.active = false; + var result = storage.getActiveLayout(); + expect(result).toEqual(false); + }); + + }); + + describe('the removeItem', function() { + + var options, storage; + + beforeEach(function() { + options = { + storageId: 'testingStorage', + storage: { + setItem: function(key, value) { + + }, + getItem: function(key) { + + }, + removeItem: function(key) { + + } + }, + storageHash: 'ds5f9d1f', + stringifyStorage: true, + widgetDefinitions: [ + + ], + defaultLayouts: [ + {title: 'i am active', active: true}, + {title: 'i am not'}, + {title: 'me neither'} + ], + widgetButtons: false, + explicitSave: false + } + storage = new LayoutStorage(options); + }); + + it('should remove states[id]', function() { + var state = {}; + storage.setItem('1', state); + storage.removeItem('1'); + expect(storage.states['1']).toBeUndefined(); + }); + + it('should call save', function() { + spyOn(storage, 'save'); + var state = {}; + storage.setItem('1', state); + storage.removeItem('1'); + expect(storage.save).toHaveBeenCalled(); + }); + + }); + +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetDataModel.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetDataModel.js new file mode 100644 index 00000000..547f2e96 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetDataModel.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .factory('WidgetDataModel', function () { + function WidgetDataModel() { + } + + WidgetDataModel.prototype = { + setup: function (widget, scope) { + this.dataAttrName = widget.dataAttrName; + this.dataModelOptions = widget.dataModelOptions; + this.widgetScope = scope; + }, + + updateScope: function (data) { + this.widgetScope.widgetData = data; + }, + + init: function () { + // to be overridden by subclasses + }, + + destroy: function () { + // to be overridden by subclasses + } + }; + + return WidgetDataModel; + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetDefCollection.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetDefCollection.js new file mode 100644 index 00000000..27765440 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetDefCollection.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .factory('WidgetDefCollection', function () { + + function convertToDefinition(d) { + if (typeof d === 'function') { + return new d(); + } + return d; + } + + function WidgetDefCollection(widgetDefs) { + + widgetDefs = widgetDefs.map(convertToDefinition); + + this.push.apply(this, widgetDefs); + + // build (name -> widget definition) map for widget lookup by name + var map = {}; + _.each(widgetDefs, function (widgetDef) { + map[widgetDef.name] = widgetDef; + }); + this.map = map; + } + + WidgetDefCollection.prototype = Object.create(Array.prototype); + + WidgetDefCollection.prototype.getByName = function (name) { + return this.map[name]; + }; + + WidgetDefCollection.prototype.add = function(def) { + def = convertToDefinition(def); + this.push(def); + this.map[def.name] = def; + }; + + return WidgetDefCollection; + }); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetModel.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetModel.js new file mode 100644 index 00000000..c378d3b6 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetModel.js @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved. + * + * Licensed 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. + */ + +'use strict'; + +angular.module('ui.dashboard') + .factory('WidgetModel', function ($log) { + + function defaults() { + return { + title: 'Widget', + style: {}, + size: {}, + enableVerticalResize: true, + containerStyle: { width: '33%' }, // default width + contentStyle: {} + }; + }; + + // constructor for widget model instances + function WidgetModel(widgetDefinition, overrides) { + + // Extend this with the widget definition object with overrides merged in (deep extended). + angular.extend(this, defaults(), _.merge(angular.copy(widgetDefinition), overrides)); + + this.updateContainerStyle(this.style); + + if (!this.templateUrl && !this.template && !this.directive) { + this.directive = widgetDefinition.name; + } + + if (this.size && _.has(this.size, 'height')) { + this.setHeight(this.size.height); + } + + if (this.style && _.has(this.style, 'width')) { //TODO deprecate style attribute + this.setWidth(this.style.width); + } + + if (this.size && _.has(this.size, 'width')) { + this.setWidth(this.size.width); + } + } + + WidgetModel.prototype = { + // sets the width (and widthUnits) + setWidth: function (width, units) { + width = width.toString(); + units = units || width.replace(/^[-\.\d]+/, '') || '%'; + + this.widthUnits = units; + width = parseFloat(width); + + // check with min width if set, unit refer to width's unit + if (this.size && _.has(this.size, 'minWidth')) { + width = _.max([parseFloat(this.size.minWidth), width]); + } + + if (width < 0 || isNaN(width)) { + $log.warn('malhar-angular-dashboard: setWidth was called when width was ' + width); + return false; + } + + if (units === '%') { + width = Math.min(100, width); + width = Math.max(0, width); + } + + this.containerStyle.width = width + '' + units; + + this.updateSize(this.containerStyle); + + return true; + }, + + setHeight: function (height) { + this.contentStyle.height = height; + this.updateSize(this.contentStyle); + }, + + setStyle: function (style) { + this.style = style; + this.updateContainerStyle(style); + }, + + updateSize: function (size) { + angular.extend(this.size, size); + }, + + updateContainerStyle: function (style) { + angular.extend(this.containerStyle, style); + }, + serialize: function() { + return _.pick(this, ['title', 'name', 'report_id', 'hideGrid', 'showChart' ,'rcloud_url','reportData','style', 'size', 'dataModelOptions', 'attrs', 'storageHash']); + } + }; + + return WidgetModel; + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetModel.spec.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetModel.spec.js new file mode 100644 index 00000000..151e560a --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/components/models/WidgetModel.spec.js @@ -0,0 +1,156 @@ +'use strict'; + +describe('Factory: WidgetModel', function () { + + // load the service's module + beforeEach(module('ui.dashboard')); + + // instantiate service + var WidgetModel; + beforeEach(inject(function (_WidgetModel_) { + WidgetModel = _WidgetModel_; + })); + + it('should be a function', function() { + expect(typeof WidgetModel).toEqual('function'); + }); + + describe('the constructor', function() { + var m, Class, Class2, overrides; + + beforeEach(function() { + Class = { + name: 'TestWidget', + attrs: {}, + dataAttrName: 'attr-name', + dataModelType: function TestType() {}, + dataModelOptions: {}, + style: { width: '10em' }, + settingsModalOptions: {}, + onSettingsClose: function() {}, + onSettingsDismiss: function() {}, + funkyChicken: { + cool: false, + fun: true + } + }; + + Class2 = { + name: 'TestWidget2', + attrs: {}, + dataAttrName: 'attr-name', + dataModelType: function TestType() {}, + dataModelOptions: {}, + style: { width: '10em' }, + templateUrl: 'my/url.html', + template: '
    some template
    ' + }; + + overrides = { + style: { + width: '15em' + } + }; + spyOn(WidgetModel.prototype, 'setWidth'); + m = new WidgetModel(Class, overrides); + }); + + it('should copy class defaults, so that changes on an instance do not change the Class', function() { + m.style.width = '20em'; + expect(Class.style.width).toEqual('10em'); + }); + + it('should call setWidth', function() { + expect(WidgetModel.prototype.setWidth).toHaveBeenCalled(); + }); + + it('should take overrides as precedent over Class defaults', function() { + expect(m.style.width).toEqual('15em'); + }); + + it('should copy arbitrary data from the widget definition', function() { + expect(m.funkyChicken.cool).toEqual(false); + expect(m.funkyChicken.fun).toEqual(true); + expect(m.funkyChicken===Class.funkyChicken).toEqual(false); + }); + + it('should set templateUrl if and only if it is present on Class', function() { + var m2 = new WidgetModel(Class2, overrides); + expect(m2.templateUrl).toEqual('my/url.html'); + }); + + it('should set template if and only if it is present on Class', function() { + delete Class2.templateUrl; + var m2 = new WidgetModel(Class2, overrides); + expect(m2.template).toEqual('
    some template
    '); + }); + + it('should look for directive if neither templateUrl nor template is found on Class', function() { + delete Class2.templateUrl; + delete Class2.template; + Class2.directive = 'ng-bind'; + var m2 = new WidgetModel(Class2, overrides); + expect(m2.directive).toEqual('ng-bind'); + }); + + it('should set the name as directive if templateUrl, template, and directive are not defined', function() { + delete Class2.templateUrl; + delete Class2.template; + var m2 = new WidgetModel(Class2, overrides); + expect(m2.directive).toEqual('TestWidget2'); + }); + + it('should not require overrides', function() { + var fn = function() { + var m2 = new WidgetModel(Class); + } + expect(fn).not.toThrow(); + }); + + it('should copy references to settingsModalOptions, onSettingsClose, onSettingsDismiss', function() { + var m = new WidgetModel(Class); + expect(m.settingsModalOptions).toEqual(Class.settingsModalOptions); + expect(m.onSettingsClose).toEqual(Class.onSettingsClose); + expect(m.onSettingsDismiss).toEqual(Class.onSettingsDismiss); + }); + + }); + + describe('setWidth method', function() { + + var context, setWidth; + + beforeEach(function() { + context = new WidgetModel({}); + setWidth = WidgetModel.prototype.setWidth; + }); + + it('should take one argument as a string with units', function() { + setWidth.call(context, '100px'); + expect(context.containerStyle.width).toEqual('100px'); + }); + + it('should take two args as a number and string as units', function() { + setWidth.call(context, 100, 'px'); + expect(context.containerStyle.width).toEqual('100px'); + }); + + it('should return false and not set anything if width is less than 0', function() { + var result = setWidth.call(context, -100, 'em'); + expect(result).toEqual(false); + expect(context.containerStyle.width).not.toEqual('-100em'); + }); + + it('should assume % if no unit is given', function() { + setWidth.call(context, 50); + expect(context.containerStyle.width).toEqual('50%'); + }); + + it('should force greater than 0% and less than or equal 100%', function() { + setWidth.call(context, '110%'); + expect(context.containerStyle.width).toEqual('100%'); + }); + + }); + +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/report-dashboard.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/report-dashboard.html new file mode 100644 index 00000000..8fecfb7b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/view-models/reportdashboard-page/src/report-dashboard.html @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/webrtc/RTCMultiConnection.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/webrtc/RTCMultiConnection.js new file mode 100644 index 00000000..3ce348b6 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/webrtc/RTCMultiConnection.js @@ -0,0 +1,6788 @@ +// Last time updated at Monday, December 21st, 2015, 5:25:26 PM + +// Quick-Demo for newbies: http://jsfiddle.net/c46de0L8/ +// Another simple demo: http://jsfiddle.net/zar6fg60/ + +// Latest file can be found here: https://cdn.webrtc-experiment.com/RTCMultiConnection.js + +// Muaz Khan - www.MuazKhan.com +// MIT License - www.WebRTC-Experiment.com/licence +// Documentation - www.RTCMultiConnection.org/docs +// FAQ - www.RTCMultiConnection.org/FAQ +// Changes log - www.RTCMultiConnection.org/changes-log/ +// Demos - www.WebRTC-Experiment.com/RTCMultiConnection + +// _________________________ +// RTCMultiConnection-v2.2.2 + +(function() { + + // RMC == RTCMultiConnection + // usually page-URL is used as channel-id + // you can always override it! + // www.RTCMultiConnection.org/docs/channel-id/ + window.RMCDefaultChannel = location.href.replace(/\/|:|#|\?|\$|\^|%|\.|`|~|!|\+|@|\[|\||]|\|*. /g, '').split('\n').join('').split('\r').join(''); + + // www.RTCMultiConnection.org/docs/constructor/ + window.RTCMultiConnection = function(channel) { + // an instance of constructor + var connection = this; + + // a reference to RTCMultiSession + var rtcMultiSession; + + // setting default channel or channel passed through constructor + connection.channel = channel || RMCDefaultChannel; + + // to allow single user to join multiple rooms; + // you can change this property at runtime! + connection.isAcceptNewSession = true; + + // www.RTCMultiConnection.org/docs/open/ + connection.open = function(args) { + connection.isAcceptNewSession = false; + + // www.RTCMultiConnection.org/docs/session-initiator/ + // you can always use this property to determine room owner! + connection.isInitiator = true; + + var dontTransmit = false; + + // a channel can contain multiple rooms i.e. sessions + if (args) { + if (isString(args)) { + connection.sessionid = args; + } else { + if (!isNull(args.transmitRoomOnce)) { + connection.transmitRoomOnce = args.transmitRoomOnce; + } + + if (!isNull(args.dontTransmit)) { + dontTransmit = args.dontTransmit; + } + + if (!isNull(args.sessionid)) { + connection.sessionid = args.sessionid; + } + } + } + + // if firebase && if session initiator + if (connection.socket && connection.socket.remove) { + connection.socket.remove(); + } + + if (!connection.sessionid) connection.sessionid = connection.channel; + connection.sessionDescription = { + sessionid: connection.sessionid, + userid: connection.userid, + session: connection.session, + extra: connection.extra + }; + + if (!connection.sessionDescriptions[connection.sessionDescription.sessionid]) { + connection.numberOfSessions++; + connection.sessionDescriptions[connection.sessionDescription.sessionid] = connection.sessionDescription; + } + + // connect with signaling channel + initRTCMultiSession(function() { + // "captureUserMediaOnDemand" is disabled by default. + // invoke "getUserMedia" only when first participant found. + rtcMultiSession.captureUserMediaOnDemand = args ? !!args.captureUserMediaOnDemand : false; + + if (args && args.onMediaCaptured) { + connection.onMediaCaptured = args.onMediaCaptured; + } + + // for session-initiator, user-media is captured as soon as "open" is invoked. + if (!rtcMultiSession.captureUserMediaOnDemand) captureUserMedia(function() { + rtcMultiSession.initSession({ + sessionDescription: connection.sessionDescription, + dontTransmit: dontTransmit + }); + + invokeMediaCaptured(connection); + }); + + if (rtcMultiSession.captureUserMediaOnDemand) { + rtcMultiSession.initSession({ + sessionDescription: connection.sessionDescription, + dontTransmit: dontTransmit + }); + } + }); + return connection.sessionDescription; + }; + + // www.RTCMultiConnection.org/docs/connect/ + connection.connect = function(sessionid) { + // a channel can contain multiple rooms i.e. sessions + if (sessionid) { + connection.sessionid = sessionid; + } + + // connect with signaling channel + initRTCMultiSession(function() { + log('Signaling channel is ready.'); + }); + + return this; + }; + + // www.RTCMultiConnection.org/docs/join/ + connection.join = joinSession; + + // www.RTCMultiConnection.org/docs/send/ + connection.send = function(data, _channel) { + if (connection.numberOfConnectedUsers <= 0) { + // no connections + setTimeout(function() { + // try again + connection.send(data, _channel); + }, 1000); + return; + } + + // send file/data or /text + if (!data) + throw 'No file, data or text message to share.'; + + // connection.send([file1, file2, file3]) + // you can share multiple files, strings or data objects using "send" method! + if (data instanceof Array && !isNull(data[0].size) && !isNull(data[0].type)) { + // this mechanism can cause failure for subsequent packets/data + // on Firefox especially; and on chrome as well! + // todo: need to use setTimeout instead. + for (var i = 0; i < data.length; i++) { + data[i].size && data[i].type && connection.send(data[i], _channel); + } + return; + } + + // File or Blob object MUST have "type" and "size" properties + if (!isNull(data.size) && !isNull(data.type)) { + if (!connection.enableFileSharing) { + throw '"enableFileSharing" boolean MUST be "true" to support file sharing.'; + } + + if (!rtcMultiSession.fileBufferReader) { + initFileBufferReader(connection, function(fbr) { + rtcMultiSession.fileBufferReader = fbr; + connection.send(data, _channel); + }); + return; + } + + var extra = merge({ + userid: connection.userid + }, data.extra || connection.extra); + + rtcMultiSession.fileBufferReader.readAsArrayBuffer(data, function(uuid) { + rtcMultiSession.fileBufferReader.getNextChunk(uuid, function(nextChunk, isLastChunk, extra) { + if (_channel) _channel.send(nextChunk); + else rtcMultiSession.send(nextChunk); + }); + }, extra); + } else { + // to allow longest string messages + // and largest data objects + // or anything of any size! + // to send multiple data objects concurrently! + + TextSender.send({ + text: data, + channel: rtcMultiSession, + _channel: _channel, + connection: connection + }); + } + }; + + function initRTCMultiSession(onSignalingReady) { + if (screenFrame) { + loadScreenFrame(); + } + + // RTCMultiSession is the backbone object; + // this object MUST be initialized once! + if (rtcMultiSession) return onSignalingReady(); + + // your everything is passed over RTCMultiSession constructor! + rtcMultiSession = new RTCMultiSession(connection, onSignalingReady); + } + + connection.disconnect = function() { + if (rtcMultiSession) rtcMultiSession.disconnect(); + rtcMultiSession = null; + }; + + function joinSession(session, joinAs) { + if (isString(session)) { + connection.skipOnNewSession = true; + } + + if (!rtcMultiSession) { + log('Signaling channel is not ready. Connecting...'); + // connect with signaling channel + initRTCMultiSession(function() { + log('Signaling channel is connected. Joining the session again...'); + setTimeout(function() { + joinSession(session, joinAs); + }, 1000); + }); + return; + } + + // connection.join('sessionid'); + if (isString(session)) { + if (connection.sessionDescriptions[session]) { + session = connection.sessionDescriptions[session]; + } else + return setTimeout(function() { + log('Session-Descriptions not found. Rechecking..'); + joinSession(session, joinAs); + }, 1000); + } + + // connection.join('sessionid', { audio: true }); + if (joinAs) { + return captureUserMedia(function() { + session.oneway = true; + joinSession(session); + }, joinAs); + } + + if (!session || !session.userid || !session.sessionid) { + error('missing arguments', arguments); + + var error = 'Invalid data passed over "connection.join" method.'; + connection.onstatechange({ + userid: 'browser', + extra: {}, + name: 'Unexpected data detected.', + reason: error + }); + + throw error; + } + + if (!connection.dontOverrideSession) { + connection.session = session.session; + } + + var extra = connection.extra || session.extra || {}; + + // todo: need to verify that if-block statement works as expected. + // expectations: if it is oneway streaming; or if it is data-only connection + // then, it shouldn't capture user-media on participant's side. + if (session.oneway || isData(session)) { + rtcMultiSession.joinSession(session, extra); + } else { + captureUserMedia(function() { + rtcMultiSession.joinSession(session, extra); + }); + } + } + + var isFirstSession = true; + + // www.RTCMultiConnection.org/docs/captureUserMedia/ + + function captureUserMedia(callback, _session, dontCheckChromExtension) { + // capture user's media resources + var session = _session || connection.session; + + if (isEmpty(session)) { + if (callback) callback(); + return; + } + + // you can force to skip media capturing! + if (connection.dontCaptureUserMedia) { + return callback(); + } + + // if it is data-only connection + // if it is one-way connection and current user is participant + if (isData(session) || (!connection.isInitiator && session.oneway)) { + // www.RTCMultiConnection.org/docs/attachStreams/ + connection.attachStreams = []; + return callback(); + } + + var constraints = { + audio: !!session.audio ? { + mandatory: {}, + optional: [{ + chromeRenderToAssociatedSink: true + }] + } : false, + video: !!session.video + }; + + // if custom audio device is selected + if (connection._mediaSources.audio) { + constraints.audio.optional.push({ + sourceId: connection._mediaSources.audio + }); + } + + // if custom video device is selected + if (connection._mediaSources.video) { + constraints.video = { + optional: [{ + sourceId: connection._mediaSources.video + }] + }; + } + + // for connection.session = {}; + if (!session.screen && !constraints.audio && !constraints.video) { + return callback(); + } + + var screen_constraints = { + audio: false, + video: { + mandatory: { + chromeMediaSource: DetectRTC.screen.chromeMediaSource, + maxWidth: screen.width > 1920 ? screen.width : 1920, + maxHeight: screen.height > 1080 ? screen.height : 1080 + }, + optional: [] + } + }; + + if (isFirefox && session.screen) { + if (location.protocol !== 'https:') { + return error(SCREEN_COMMON_FAILURE); + } + warn(Firefox_Screen_Capturing_Warning); + + screen_constraints.video = merge(screen_constraints.video.mandatory, { + mozMediaSource: 'window', // mozMediaSource is redundant here + mediaSource: 'window' // 'screen' || 'window' + }); + + // Firefox is supporting audio+screen from single getUserMedia request + // audio+video+screen will become audio+screen for Firefox + // because Firefox isn't supporting multi-streams feature version < 38 + // version >38 supports multi-stream sharing. + // we can use: firefoxVersion < 38 + // however capturing audio and screen using single getUserMedia is a better option + if (constraints.audio /* && !session.video */ ) { + screen_constraints.audio = true; + constraints = {}; + } + + delete screen_constraints.video.chromeMediaSource; + } + + // if screen is prompted + if (session.screen) { + if (isChrome && DetectRTC.screen.extensionid != ReservedExtensionID) { + useCustomChromeExtensionForScreenCapturing = true; + } + + if (isChrome && !useCustomChromeExtensionForScreenCapturing && !dontCheckChromExtension && !DetectRTC.screen.sourceId) { + listenEventHandler('message', onIFrameCallback); + + function onIFrameCallback(event) { + if (event.data && event.data.chromeMediaSourceId) { + // this event listener is no more needed + window.removeEventListener('message', onIFrameCallback); + + var sourceId = event.data.chromeMediaSourceId; + + DetectRTC.screen.sourceId = sourceId; + DetectRTC.screen.chromeMediaSource = 'desktop'; + + if (sourceId == 'PermissionDeniedError') { + var mediaStreamError = { + message: location.protocol == 'https:' ? 'User denied to share content of his screen.' : SCREEN_COMMON_FAILURE, + name: 'PermissionDeniedError', + constraintName: screen_constraints, + session: session + }; + currentUserMediaRequest.mutex = false; + DetectRTC.screen.sourceId = null; + return connection.onMediaError(mediaStreamError); + } + + captureUserMedia(callback, _session); + } + + if (event.data && event.data.chromeExtensionStatus) { + warn('Screen capturing extension status is:', event.data.chromeExtensionStatus); + DetectRTC.screen.chromeMediaSource = 'screen'; + captureUserMedia(callback, _session, true); + } + } + + if (!screenFrame) { + loadScreenFrame(); + } + + screenFrame.postMessage(); + return; + } + + // check if screen capturing extension is installed. + if (isChrome && useCustomChromeExtensionForScreenCapturing && !dontCheckChromExtension && DetectRTC.screen.chromeMediaSource == 'screen' && DetectRTC.screen.extensionid) { + if (DetectRTC.screen.extensionid == ReservedExtensionID && document.domain.indexOf('webrtc-experiment.com') == -1) { + return captureUserMedia(callback, _session, true); + } + + log('checking if chrome extension is installed.'); + DetectRTC.screen.getChromeExtensionStatus(function(status) { + if (status == 'installed-enabled') { + DetectRTC.screen.chromeMediaSource = 'desktop'; + } + + captureUserMedia(callback, _session, true); + log('chrome extension is installed?', DetectRTC.screen.chromeMediaSource == 'desktop'); + }); + return; + } + + if (isChrome && useCustomChromeExtensionForScreenCapturing && DetectRTC.screen.chromeMediaSource == 'desktop' && !DetectRTC.screen.sourceId) { + DetectRTC.screen.getSourceId(function(sourceId) { + if (sourceId == 'PermissionDeniedError') { + var mediaStreamError = { + message: 'User denied to share content of his screen.', + name: 'PermissionDeniedError', + constraintName: screen_constraints, + session: session + }; + currentUserMediaRequest.mutex = false; + DetectRTC.screen.chromeMediaSource = 'desktop'; + return connection.onMediaError(mediaStreamError); + } + + if (sourceId == 'No-Response') { + error('Chrome extension seems not available. Make sure that manifest.json#L16 has valid content-script matches pointing to your URL.'); + DetectRTC.screen.chromeMediaSource = 'screen'; + return captureUserMedia(callback, _session, true); + } + + captureUserMedia(callback, _session, true); + }); + return; + } + + if (isChrome && DetectRTC.screen.chromeMediaSource == 'desktop') { + screen_constraints.video.mandatory.chromeMediaSourceId = DetectRTC.screen.sourceId; + } + + var _isFirstSession = isFirstSession; + + _captureUserMedia(screen_constraints, constraints.audio || constraints.video ? function() { + + if (_isFirstSession) isFirstSession = true; + + _captureUserMedia(constraints, callback); + } : callback); + } else _captureUserMedia(constraints, callback, session.audio && !session.video); + + function _captureUserMedia(forcedConstraints, forcedCallback, isRemoveVideoTracks, dontPreventSSLAutoAllowed) { + connection.onstatechange({ + userid: 'browser', + extra: {}, + name: 'fetching-usermedia', + reason: 'About to capture user-media with constraints: ' + toStr(forcedConstraints) + }); + + + if (connection.preventSSLAutoAllowed && !dontPreventSSLAutoAllowed && isChrome) { + // if navigator.customGetUserMediaBar.js is missing + if (!navigator.customGetUserMediaBar) { + loadScript(connection.resources.customGetUserMediaBar, function() { + _captureUserMedia(forcedConstraints, forcedCallback, isRemoveVideoTracks, dontPreventSSLAutoAllowed); + }); + return; + } + + navigator.customGetUserMediaBar(forcedConstraints, function() { + _captureUserMedia(forcedConstraints, forcedCallback, isRemoveVideoTracks, true); + }, function() { + connection.onMediaError({ + name: 'PermissionDeniedError', + message: 'User denied permission.', + constraintName: forcedConstraints, + session: session + }); + }); + return; + } + + var mediaConfig = { + onsuccess: function(stream, returnBack, idInstance, streamid) { + onStreamSuccessCallback(stream, returnBack, idInstance, streamid, forcedConstraints, forcedCallback, isRemoveVideoTracks, screen_constraints, constraints, session); + }, + onerror: function(e, constraintUsed) { + // http://goo.gl/hrwF1a + if (isFirefox) { + if (e == 'PERMISSION_DENIED') { + e = { + message: '', + name: 'PermissionDeniedError', + constraintName: constraintUsed, + session: session + }; + } + } + + if (isFirefox && constraintUsed.video && constraintUsed.video.mozMediaSource) { + mediaStreamError = { + message: Firefox_Screen_Capturing_Warning, + name: e.name || 'PermissionDeniedError', + constraintName: constraintUsed, + session: session + }; + + connection.onMediaError(mediaStreamError); + return; + } + + if (isString(e)) { + return connection.onMediaError({ + message: 'Unknown Error', + name: e, + constraintName: constraintUsed, + session: session + }); + } + + // it seems that chrome 35+ throws "DevicesNotFoundError" exception + // when any of the requested media is either denied or absent + if (e.name && (e.name == 'PermissionDeniedError' || e.name == 'DevicesNotFoundError')) { + var mediaStreamError = 'Either: '; + mediaStreamError += '\n Media resolutions are not permitted.'; + mediaStreamError += '\n Another application is using same media device.'; + mediaStreamError += '\n Media device is not attached or drivers not installed.'; + mediaStreamError += '\n You denied access once and it is still denied.'; + + if (e.message && e.message.length) { + mediaStreamError += '\n ' + e.message; + } + + mediaStreamError = { + message: mediaStreamError, + name: e.name, + constraintName: constraintUsed, + session: session + }; + + connection.onMediaError(mediaStreamError); + + if (isChrome && (session.audio || session.video)) { + // todo: this snippet fails if user has two or more + // microphone/webcam attached. + DetectRTC.load(function() { + // it is possible to check presence of the microphone before using it! + if (session.audio && !DetectRTC.hasMicrophone) { + warn('It seems that you have no microphone attached to your device/system.'); + session.audio = session.audio = false; + + if (!session.video) { + alert('It seems that you are capturing microphone and there is no device available or access is denied. Reloading...'); + location.reload(); + } + } + + // it is possible to check presence of the webcam before using it! + if (session.video && !DetectRTC.hasWebcam) { + warn('It seems that you have no webcam attached to your device/system.'); + session.video = session.video = false; + + if (!session.audio) { + alert('It seems that you are capturing webcam and there is no device available or access is denied. Reloading...'); + location.reload(); + } + } + + if (!DetectRTC.hasMicrophone && !DetectRTC.hasWebcam) { + alert('It seems that either both microphone/webcam are not available or access is denied. Reloading...'); + location.reload(); + } else if (!connection.getUserMediaPromptedOnce) { + // make maximum two tries! + connection.getUserMediaPromptedOnce = true; + captureUserMedia(callback, session); + } + }); + } + } + + if (e.name && e.name == 'ConstraintNotSatisfiedError') { + var mediaStreamError = 'Either: '; + mediaStreamError += '\n You are prompting unknown media resolutions.'; + mediaStreamError += '\n You are using invalid media constraints.'; + + if (e.message && e.message.length) { + mediaStreamError += '\n ' + e.message; + } + + mediaStreamError = { + message: mediaStreamError, + name: e.name, + constraintName: constraintUsed, + session: session + }; + + connection.onMediaError(mediaStreamError); + } + + if (session.screen) { + if (isFirefox) { + error(Firefox_Screen_Capturing_Warning); + } else if (location.protocol !== 'https:') { + if (!isNodeWebkit && (location.protocol == 'file:' || location.protocol == 'http:')) { + error('You cannot use HTTP or file protocol for screen capturing. You must either use HTTPs or chrome extension page or Node-Webkit page.'); + } + } else { + error('Unable to detect actual issue. Maybe "deprecated" screen capturing flag was not set using command line or maybe you clicked "No" button or maybe chrome extension returned invalid "sourceId". Please install chrome-extension: http://bit.ly/webrtc-screen-extension'); + } + } + + currentUserMediaRequest.mutex = false; + + // to make sure same stream can be captured again! + var idInstance = JSON.stringify(constraintUsed); + if (currentUserMediaRequest.streams[idInstance]) { + delete currentUserMediaRequest.streams[idInstance]; + } + }, + mediaConstraints: connection.mediaConstraints || {} + }; + + mediaConfig.constraints = forcedConstraints || constraints; + mediaConfig.connection = connection; + getUserMedia(mediaConfig); + } + } + + function onStreamSuccessCallback(stream, returnBack, idInstance, streamid, forcedConstraints, forcedCallback, isRemoveVideoTracks, screen_constraints, constraints, session) { + if (!streamid) streamid = getRandomString(); + + connection.onstatechange({ + userid: 'browser', + extra: {}, + name: 'usermedia-fetched', + reason: 'Captured user media using constraints: ' + toStr(forcedConstraints) + }); + + if (isRemoveVideoTracks) { + stream = convertToAudioStream(stream); + } + + connection.localStreamids.push(streamid); + stream.onended = function() { + if (streamedObject.mediaElement && !streamedObject.mediaElement.parentNode && document.getElementById(stream.streamid)) { + streamedObject.mediaElement = document.getElementById(stream.streamid); + } + + // when a stream is stopped; it must be removed from "attachStreams" array + connection.attachStreams.forEach(function(_stream, index) { + if (_stream == stream) { + delete connection.attachStreams[index]; + connection.attachStreams = swap(connection.attachStreams); + } + }); + + onStreamEndedHandler(streamedObject, connection); + + if (connection.streams[streamid]) { + connection.removeStream(streamid); + } + + // if user clicks "stop" button to close screen sharing + var _stream = connection.streams[streamid]; + if (_stream && _stream.sockets.length) { + _stream.sockets.forEach(function(socket) { + socket.send({ + streamid: _stream.streamid, + stopped: true + }); + }); + } + + currentUserMediaRequest.mutex = false; + // to make sure same stream can be captured again! + if (currentUserMediaRequest.streams[idInstance]) { + delete currentUserMediaRequest.streams[idInstance]; + } + + // to allow re-capturing of the screen + DetectRTC.screen.sourceId = null; + }; + + if (!isIE) { + stream.streamid = streamid; + stream.isScreen = forcedConstraints == screen_constraints; + stream.isVideo = forcedConstraints == constraints && !!constraints.video; + stream.isAudio = forcedConstraints == constraints && !!constraints.audio && !constraints.video; + + // if muted stream is negotiated + stream.preMuted = { + audio: stream.getAudioTracks().length && !stream.getAudioTracks()[0].enabled, + video: stream.getVideoTracks().length && !stream.getVideoTracks()[0].enabled + }; + } + + var mediaElement = createMediaElement(stream, session); + mediaElement.muted = true; + + var streamedObject = { + stream: stream, + streamid: streamid, + mediaElement: mediaElement, + blobURL: mediaElement.mozSrcObject ? URL.createObjectURL(stream) : mediaElement.src, + type: 'local', + userid: connection.userid, + extra: connection.extra, + session: session, + isVideo: !!stream.isVideo, + isAudio: !!stream.isAudio, + isScreen: !!stream.isScreen, + isInitiator: !!connection.isInitiator, + rtcMultiConnection: connection + }; + + if (isFirstSession) { + connection.attachStreams.push(stream); + } + isFirstSession = false; + + connection.streams[streamid] = connection._getStream(streamedObject); + + if (!returnBack) { + connection.onstream(streamedObject); + } + + if (connection.setDefaultEventsForMediaElement) { + connection.setDefaultEventsForMediaElement(mediaElement, streamid); + } + + if (forcedCallback) forcedCallback(stream, streamedObject); + + if (connection.onspeaking) { + initHark({ + stream: stream, + streamedObject: streamedObject, + connection: connection + }); + } + } + + // www.RTCMultiConnection.org/docs/captureUserMedia/ + connection.captureUserMedia = captureUserMedia; + + // www.RTCMultiConnection.org/docs/leave/ + connection.leave = function(userid) { + if (!rtcMultiSession) return; + + isFirstSession = true; + + if (userid) { + connection.eject(userid); + return; + } + + rtcMultiSession.leave(); + }; + + // www.RTCMultiConnection.org/docs/eject/ + connection.eject = function(userid) { + if (!connection.isInitiator) throw 'Only session-initiator can eject a user.'; + if (!connection.peers[userid]) throw 'You ejected invalid user.'; + connection.peers[userid].sendCustomMessage({ + ejected: true + }); + }; + + // www.RTCMultiConnection.org/docs/close/ + connection.close = function() { + // close entire session + connection.autoCloseEntireSession = true; + connection.leave(); + }; + + // www.RTCMultiConnection.org/docs/renegotiate/ + connection.renegotiate = function(stream, session) { + if (connection.numberOfConnectedUsers <= 0) { + // no connections + setTimeout(function() { + // try again + connection.renegotiate(stream, session); + }, 1000); + return; + } + + rtcMultiSession.addStream({ + renegotiate: session || merge({ + oneway: true + }, connection.session), + stream: stream + }); + }; + + connection.attachExternalStream = function(stream, isScreen) { + var constraints = {}; + if (stream.getAudioTracks && stream.getAudioTracks().length) { + constraints.audio = true; + } + if (stream.getVideoTracks && stream.getVideoTracks().length) { + constraints.video = true; + } + + var screen_constraints = { + video: { + chromeMediaSource: 'fake' + } + }; + var forcedConstraints = isScreen ? screen_constraints : constraints; + onStreamSuccessCallback(stream, false, '', null, forcedConstraints, false, false, screen_constraints, constraints, constraints); + }; + + // www.RTCMultiConnection.org/docs/addStream/ + connection.addStream = function(session, socket) { + // www.RTCMultiConnection.org/docs/renegotiation/ + + if (connection.numberOfConnectedUsers <= 0) { + // no connections + setTimeout(function() { + // try again + connection.addStream(session, socket); + }, 1000); + return; + } + + // renegotiate new media stream + if (session) { + var isOneWayStreamFromParticipant; + if (!connection.isInitiator && session.oneway) { + session.oneway = false; + isOneWayStreamFromParticipant = true; + } + + captureUserMedia(function(stream) { + if (isOneWayStreamFromParticipant) { + session.oneway = true; + } + addStream(stream); + }, session); + } else addStream(); + + function addStream(stream) { + rtcMultiSession.addStream({ + stream: stream, + renegotiate: session || connection.session, + socket: socket + }); + } + }; + + // www.RTCMultiConnection.org/docs/removeStream/ + connection.removeStream = function(streamid, dontRenegotiate) { + if (connection.numberOfConnectedUsers <= 0) { + // no connections + setTimeout(function() { + // try again + connection.removeStream(streamid, dontRenegotiate); + }, 1000); + return; + } + + if (!streamid) streamid = 'all'; + if (!isString(streamid) || streamid.search(/all|audio|video|screen/gi) != -1) { + function _detachStream(_stream, config) { + if (config.local && _stream.type != 'local') return; + if (config.remote && _stream.type != 'remote') return; + + // connection.removeStream({screen:true}); + if (config.screen && !!_stream.isScreen) { + connection.detachStreams.push(_stream.streamid); + } + + // connection.removeStream({audio:true}); + if (config.audio && !!_stream.isAudio) { + connection.detachStreams.push(_stream.streamid); + } + + // connection.removeStream({video:true}); + if (config.video && !!_stream.isVideo) { + connection.detachStreams.push(_stream.streamid); + } + + // connection.removeStream({}); + if (!config.audio && !config.video && !config.screen) { + connection.detachStreams.push(_stream.streamid); + } + + if (connection.detachStreams.indexOf(_stream.streamid) != -1) { + log('removing stream', _stream.streamid); + onStreamEndedHandler(_stream, connection); + + if (config.stop) { + connection.stopMediaStream(_stream.stream); + } + } + } + + for (var stream in connection.streams) { + if (connection._skip.indexOf(stream) == -1) { + _stream = connection.streams[stream]; + + if (streamid == 'all') _detachStream(_stream, { + audio: true, + video: true, + screen: true + }); + + else if (isString(streamid)) { + // connection.removeStream('screen'); + var config = {}; + config[streamid] = true; + _detachStream(_stream, config); + } else _detachStream(_stream, streamid); + } + } + + if (!dontRenegotiate && connection.detachStreams.length) { + connection.renegotiate(); + } + + return; + } + + var stream = connection.streams[streamid]; + + // detach pre-attached streams + if (!stream) return warn('No such stream exists. Stream-id:', streamid); + + // www.RTCMultiConnection.org/docs/detachStreams/ + connection.detachStreams.push(stream.streamid); + + log('removing stream', stream.streamid); + onStreamEndedHandler(stream, connection); + + // todo: how to allow "stop" function? + // connection.stopMediaStream(stream.stream) + + if (!dontRenegotiate) { + connection.renegotiate(); + } + }; + + connection.switchStream = function(session) { + if (connection.numberOfConnectedUsers <= 0) { + // no connections + setTimeout(function() { + // try again + connection.switchStream(session); + }, 1000); + return; + } + + connection.removeStream('all', true); + connection.addStream(session); + }; + + // www.RTCMultiConnection.org/docs/sendCustomMessage/ + connection.sendCustomMessage = function(message) { + if (!rtcMultiSession || !rtcMultiSession.defaultSocket) { + return setTimeout(function() { + connection.sendCustomMessage(message); + }, 1000); + } + + rtcMultiSession.defaultSocket.send({ + customMessage: true, + message: message + }); + }; + + // set RTCMultiConnection defaults on constructor invocation + setDefaults(connection); + }; + + function RTCMultiSession(connection, callbackForSignalingReady) { + var socketObjects = {}; + var sockets = []; + var rtcMultiSession = this; + var participants = {}; + + if (!rtcMultiSession.fileBufferReader && connection.session.data && connection.enableFileSharing) { + initFileBufferReader(connection, function(fbr) { + rtcMultiSession.fileBufferReader = fbr; + }); + } + + var textReceiver = new TextReceiver(connection); + + function onDataChannelMessage(e) { + if (e.data.checkingPresence && connection.channels[e.userid]) { + connection.channels[e.userid].send({ + presenceDetected: true + }); + return; + } + + if (e.data.presenceDetected && connection.peers[e.userid]) { + connection.peers[e.userid].connected = true; + return; + } + + if (e.data.type === 'text') { + textReceiver.receive(e.data, e.userid, e.extra); + } else { + if (connection.autoTranslateText) { + e.original = e.data; + connection.Translator.TranslateText(e.data, function(translatedText) { + e.data = translatedText; + connection.onmessage(e); + }); + } else connection.onmessage(e); + } + } + + function onNewSession(session) { + if (connection.skipOnNewSession) return; + + if (!session.session) session.session = {}; + if (!session.extra) session.extra = {}; + + // todo: make sure this works as expected. + // i.e. "onNewSession" should be fired only for + // sessionid that is passed over "connect" method. + if (connection.sessionid && session.sessionid != connection.sessionid) return; + + if (connection.onNewSession) { + session.join = function(forceSession) { + if (!forceSession) return connection.join(session); + + for (var f in forceSession) { + session.session[f] = forceSession[f]; + } + + // keeping previous state + var isDontCaptureUserMedia = connection.dontCaptureUserMedia; + + connection.dontCaptureUserMedia = false; + connection.captureUserMedia(function() { + connection.dontCaptureUserMedia = true; + connection.join(session); + + // returning back previous state + connection.dontCaptureUserMedia = isDontCaptureUserMedia; + }, forceSession); + }; + if (!session.extra) session.extra = {}; + + return connection.onNewSession(session); + } + + connection.join(session); + } + + function updateSocketForLocalStreams(socket) { + for (var i = 0; i < connection.localStreamids.length; i++) { + var streamid = connection.localStreamids[i]; + if (connection.streams[streamid]) { + // using "sockets" array to keep references of all sockets using + // this media stream; so we can fire "onStreamEndedHandler" among all users. + connection.streams[streamid].sockets.push(socket); + } + } + } + + function newPrivateSocket(_config) { + var socketConfig = { + channel: _config.channel, + onmessage: socketResponse, + onopen: function(_socket) { + if (_socket) socket = _socket; + + if (isofferer && !peer) { + peerConfig.session = connection.session; + if (!peer) peer = new PeerConnection(); + peer.create('offer', peerConfig); + } + + _config.socketIndex = socket.index = sockets.length; + socketObjects[socketConfig.channel] = socket; + sockets[_config.socketIndex] = socket; + + updateSocketForLocalStreams(socket); + + if (!socket.__push) { + socket.__push = socket.send; + socket.send = function(message) { + message.userid = message.userid || connection.userid; + message.extra = message.extra || connection.extra || {}; + + socket.__push(message); + }; + } + } + }; + + socketConfig.callback = function(_socket) { + socket = _socket; + socketConfig.onopen(); + }; + + var socket = connection.openSignalingChannel(socketConfig); + if (socket) socketConfig.onopen(socket); + + var isofferer = _config.isofferer, + peer; + + var peerConfig = { + onopen: onChannelOpened, + onicecandidate: function(candidate) { + if (!connection.candidates) throw 'ICE candidates are mandatory.'; + if (!connection.iceProtocols) throw 'At least one must be true; UDP or TCP.'; + + var iceCandidates = connection.candidates; + + var stun = iceCandidates.stun; + var turn = iceCandidates.turn; + + if (!isNull(iceCandidates.reflexive)) stun = iceCandidates.reflexive; + if (!isNull(iceCandidates.relay)) turn = iceCandidates.relay; + + if (!iceCandidates.host && !!candidate.candidate.match(/a=candidate.*typ host/g)) return; + if (!turn && !!candidate.candidate.match(/a=candidate.*typ relay/g)) return; + if (!stun && !!candidate.candidate.match(/a=candidate.*typ srflx/g)) return; + + var protocol = connection.iceProtocols; + + if (!protocol.udp && !!candidate.candidate.match(/a=candidate.* udp/g)) return; + if (!protocol.tcp && !!candidate.candidate.match(/a=candidate.* tcp/g)) return; + + if (!window.selfNPObject) window.selfNPObject = candidate; + + socket && socket.send({ + candidate: JSON.stringify({ + candidate: candidate.candidate, + sdpMid: candidate.sdpMid, + sdpMLineIndex: candidate.sdpMLineIndex + }) + }); + }, + onmessage: function(data) { + if (!data) return; + + var abToStr = ab2str(data); + if (abToStr.indexOf('"userid":') != -1) { + abToStr = JSON.parse(abToStr); + onDataChannelMessage(abToStr); + } else if (data instanceof ArrayBuffer || data instanceof DataView) { + if (!connection.enableFileSharing) { + throw 'It seems that receiving data is either "Blob" or "File" but file sharing is disabled.'; + } + + if (!rtcMultiSession.fileBufferReader) { + var that = this; + initFileBufferReader(connection, function(fbr) { + rtcMultiSession.fileBufferReader = fbr; + that.onmessage(data); + }); + return; + } + + var fileBufferReader = rtcMultiSession.fileBufferReader; + + fileBufferReader.convertToObject(data, function(chunk) { + if (chunk.maxChunks || chunk.readyForNextChunk) { + // if target peer requested next chunk + if (chunk.readyForNextChunk) { + fileBufferReader.getNextChunk(chunk.uuid, function(nextChunk, isLastChunk, extra) { + rtcMultiSession.send(nextChunk); + }); + return; + } + + // if chunk is received + fileBufferReader.addChunk(chunk, function(promptNextChunk) { + // request next chunk + rtcMultiSession.send(promptNextChunk); + }); + return; + } + + connection.onmessage({ + data: chunk, + userid: _config.userid, + extra: _config.extra + }); + }); + return; + } + }, + onaddstream: function(stream, session) { + session = session || _config.renegotiate || connection.session; + + // if it is data-only connection; then return. + if (isData(session)) return; + + if (session.screen && (session.audio || session.video)) { + if (!_config.gotAudioOrVideo) { + // audio/video are fired earlier than screen + _config.gotAudioOrVideo = true; + session.screen = false; + } else { + // screen stream is always fired later + session.audio = false; + session.video = false; + } + } + + var preMuted = {}; + + if (_config.streaminfo) { + var streaminfo = _config.streaminfo.split('----'); + var strInfo = JSON.parse(streaminfo[streaminfo.length - 1]); + + if (!isIE) { + stream.streamid = strInfo.streamid; + stream.isScreen = !!strInfo.isScreen; + stream.isVideo = !!strInfo.isVideo; + stream.isAudio = !!strInfo.isAudio; + preMuted = strInfo.preMuted; + } + + streaminfo.pop(); + _config.streaminfo = streaminfo.join('----'); + } + + var mediaElement = createMediaElement(stream, merge({ + remote: true + }, session)); + + if (connection.setDefaultEventsForMediaElement) { + connection.setDefaultEventsForMediaElement(mediaElement, stream.streamid); + } + + if (!isPluginRTC && !stream.getVideoTracks().length) { + function eventListener() { + setTimeout(function() { + mediaElement.muted = false; + afterRemoteStreamStartedFlowing({ + mediaElement: mediaElement, + session: session, + stream: stream, + preMuted: preMuted + }); + }, 3000); + + mediaElement.removeEventListener('play', eventListener); + } + return mediaElement.addEventListener('play', eventListener, false); + } + + waitUntilRemoteStreamStartsFlowing({ + mediaElement: mediaElement, + session: session, + stream: stream, + preMuted: preMuted + }); + }, + + onremovestream: function(stream) { + if (stream && stream.streamid) { + stream = connection.streams[stream.streamid]; + if (stream) { + log('on:stream:ended via on:remove:stream', stream); + onStreamEndedHandler(stream, connection); + } + } else log('on:remove:stream', stream); + }, + + onclose: function(e) { + e.extra = _config.extra; + e.userid = _config.userid; + connection.onclose(e); + + // suggested in #71 by "efaj" + if (connection.channels[e.userid]) { + delete connection.channels[e.userid]; + } + }, + onerror: function(e) { + e.extra = _config.extra; + e.userid = _config.userid; + connection.onerror(e); + }, + + oniceconnectionstatechange: function(event) { + log('oniceconnectionstatechange', toStr(event)); + + if (peer.connection && peer.connection.iceConnectionState == 'connected' && peer.connection.iceGatheringState == 'complete' && peer.connection.signalingState == 'stable' && connection.numberOfConnectedUsers == 1) { + connection.onconnected({ + userid: _config.userid, + extra: _config.extra, + peer: connection.peers[_config.userid], + targetuser: _config.userinfo + }); + } + + if (!connection.isInitiator && peer.connection && peer.connection.iceConnectionState == 'connected' && peer.connection.iceGatheringState == 'complete' && peer.connection.signalingState == 'stable' && connection.numberOfConnectedUsers == 1) { + connection.onstatechange({ + userid: _config.userid, + extra: _config.extra, + name: 'connected-with-initiator', + reason: 'ICE connection state seems connected; gathering state is completed; and signaling state is stable.' + }); + } + + if (connection.peers[_config.userid] && connection.peers[_config.userid].oniceconnectionstatechange) { + connection.peers[_config.userid].oniceconnectionstatechange(event); + } + + // if ICE connectivity check is failed; renegotiate or redial + if (connection.peers[_config.userid] && connection.peers[_config.userid].peer.connection.iceConnectionState == 'failed') { + connection.onfailed({ + userid: _config.userid, + extra: _config.extra, + peer: connection.peers[_config.userid], + targetuser: _config.userinfo + }); + } + + if (connection.peers[_config.userid] && connection.peers[_config.userid].peer.connection.iceConnectionState == 'disconnected') { + !peer.connection.renegotiate && connection.ondisconnected({ + userid: _config.userid, + extra: _config.extra, + peer: connection.peers[_config.userid], + targetuser: _config.userinfo + }); + peer.connection.renegotiate = false; + } + + if (!connection.autoReDialOnFailure) return; + + if (connection.peers[_config.userid]) { + if (connection.peers[_config.userid].peer.connection.iceConnectionState != 'disconnected') { + _config.redialing = false; + } + + if (connection.peers[_config.userid].peer.connection.iceConnectionState == 'disconnected' && !_config.redialing) { + _config.redialing = true; + warn('Peer connection is closed.', toStr(connection.peers[_config.userid].peer.connection), 'ReDialing..'); + connection.peers[_config.userid].socket.send({ + redial: true + }); + + // to make sure all old "remote" streams are also removed! + connection.streams.remove({ + remote: true, + userid: _config.userid + }); + } + } + }, + + onsignalingstatechange: function(event) { + log('onsignalingstatechange', toStr(event)); + }, + + attachStreams: connection.dontAttachStream ? [] : connection.attachStreams, + iceServers: connection.iceServers, + rtcConfiguration: connection.rtcConfiguration, + bandwidth: connection.bandwidth, + sdpConstraints: connection.sdpConstraints, + optionalArgument: connection.optionalArgument, + disableDtlsSrtp: connection.disableDtlsSrtp, + dataChannelDict: connection.dataChannelDict, + preferSCTP: connection.preferSCTP, + + onSessionDescription: function(sessionDescription, streaminfo) { + sendsdp({ + sdp: sessionDescription, + socket: socket, + streaminfo: streaminfo + }); + }, + trickleIce: connection.trickleIce, + processSdp: connection.processSdp, + sendStreamId: function(stream) { + socket && socket.send({ + streamid: stream.streamid, + isScreen: !!stream.isScreen, + isAudio: !!stream.isAudio, + isVideo: !!stream.isVideo + }); + }, + rtcMultiConnection: connection + }; + + function waitUntilRemoteStreamStartsFlowing(args) { + // chrome for android may have some features missing + if (isMobileDevice || isPluginRTC || (isNull(connection.waitUntilRemoteStreamStartsFlowing) || !connection.waitUntilRemoteStreamStartsFlowing)) { + return afterRemoteStreamStartedFlowing(args); + } + + if (!args.numberOfTimes) args.numberOfTimes = 0; + args.numberOfTimes++; + + if (!(args.mediaElement.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA || args.mediaElement.paused || args.mediaElement.currentTime <= 0)) { + return afterRemoteStreamStartedFlowing(args); + } + + if (args.numberOfTimes >= 60) { // wait 60 seconds while video is delivered! + return socket.send({ + failedToReceiveRemoteVideo: true, + streamid: args.stream.streamid + }); + } + + setTimeout(function() { + log('Waiting for incoming remote stream to be started flowing: ' + args.numberOfTimes + ' seconds.'); + waitUntilRemoteStreamStartsFlowing(args); + }, 900); + } + + function initFakeChannel() { + if (!connection.fakeDataChannels || connection.channels[_config.userid]) return; + + // for non-data connections; allow fake data sender! + if (!connection.session.data) { + var fakeChannel = { + send: function(data) { + socket.send({ + fakeData: data + }); + }, + readyState: 'open' + }; + // connection.channels['user-id'].send(data); + connection.channels[_config.userid] = { + channel: fakeChannel, + send: function(data) { + this.channel.send(data); + } + }; + peerConfig.onopen(fakeChannel); + } + } + + function afterRemoteStreamStartedFlowing(args) { + var mediaElement = args.mediaElement; + var session = args.session; + var stream = args.stream; + + stream.onended = function() { + if (streamedObject.mediaElement && !streamedObject.mediaElement.parentNode && document.getElementById(stream.streamid)) { + streamedObject.mediaElement = document.getElementById(stream.streamid); + } + + onStreamEndedHandler(streamedObject, connection); + }; + + var streamedObject = { + mediaElement: mediaElement, + + stream: stream, + streamid: stream.streamid, + session: session || connection.session, + + blobURL: isPluginRTC ? '' : mediaElement.mozSrcObject ? URL.createObjectURL(stream) : mediaElement.src, + type: 'remote', + + extra: _config.extra, + userid: _config.userid, + + isVideo: isPluginRTC ? !!session.video : !!stream.isVideo, + isAudio: isPluginRTC ? !!session.audio && !session.video : !!stream.isAudio, + isScreen: !!stream.isScreen, + isInitiator: !!_config.isInitiator, + + rtcMultiConnection: connection, + socket: socket + }; + + // connection.streams['stream-id'].mute({audio:true}) + connection.streams[stream.streamid] = connection._getStream(streamedObject); + connection.onstream(streamedObject); + + if (!isEmpty(args.preMuted) && (args.preMuted.audio || args.preMuted.video)) { + var fakeObject = merge({}, streamedObject); + fakeObject.session = merge(fakeObject.session, args.preMuted); + + fakeObject.isAudio = !!fakeObject.session.audio && !fakeObject.session.video; + fakeObject.isVideo = !!fakeObject.session.video; + fakeObject.isScreen = false; + + connection.onmute(fakeObject); + } + + log('on:add:stream', streamedObject); + + onSessionOpened(); + + if (connection.onspeaking) { + initHark({ + stream: stream, + streamedObject: streamedObject, + connection: connection + }); + } + } + + function onChannelOpened(channel) { + _config.channel = channel; + + // connection.channels['user-id'].send(data); + connection.channels[_config.userid] = { + channel: _config.channel, + send: function(data) { + connection.send(data, this.channel); + } + }; + + connection.onopen({ + extra: _config.extra, + userid: _config.userid, + channel: channel + }); + + // fetch files from file-queue + for (var q in connection.fileQueue) { + connection.send(connection.fileQueue[q], channel); + } + + if (isData(connection.session)) onSessionOpened(); + + if (connection.partOfScreen && connection.partOfScreen.sharing) { + connection.peers[_config.userid].sharePartOfScreen(connection.partOfScreen); + } + } + + function updateSocket() { + // todo: need to check following {if-block} MUST not affect "redial" process + if (socket.userid == _config.userid) + return; + + socket.userid = _config.userid; + sockets[_config.socketIndex] = socket; + + connection.numberOfConnectedUsers++; + // connection.peers['user-id'].addStream({audio:true}) + connection.peers[_config.userid] = { + socket: socket, + peer: peer, + userid: _config.userid, + extra: _config.extra, + userinfo: _config.userinfo, + addStream: function(session00) { + // connection.peers['user-id'].addStream({audio: true, video: true); + + connection.addStream(session00, this.socket); + }, + removeStream: function(streamid) { + if (!connection.streams[streamid]) + return warn('No such stream exists. Stream-id:', streamid); + + this.peer.connection.removeStream(connection.streams[streamid].stream); + this.renegotiate(); + }, + renegotiate: function(stream, session) { + // connection.peers['user-id'].renegotiate(); + + connection.renegotiate(stream, session); + }, + changeBandwidth: function(bandwidth) { + // connection.peers['user-id'].changeBandwidth(); + + if (!bandwidth) throw 'You MUST pass bandwidth object.'; + if (isString(bandwidth)) throw 'Pass object for bandwidth instead of string; e.g. {audio:10, video:20}'; + + // set bandwidth for self + this.peer.bandwidth = bandwidth; + + // ask remote user to synchronize bandwidth + this.socket.send({ + changeBandwidth: true, + bandwidth: bandwidth + }); + }, + sendCustomMessage: function(message) { + // connection.peers['user-id'].sendCustomMessage(); + + this.socket.send({ + customMessage: true, + message: message + }); + }, + onCustomMessage: function(message) { + log('Received "private" message from', this.userid, + isString(message) ? message : toStr(message)); + }, + drop: function(dontSendMessage) { + // connection.peers['user-id'].drop(); + + for (var stream in connection.streams) { + if (connection._skip.indexOf(stream) == -1) { + stream = connection.streams[stream]; + + if (stream.userid == connection.userid && stream.type == 'local') { + this.peer.connection.removeStream(stream.stream); + onStreamEndedHandler(stream, connection); + } + + if (stream.type == 'remote' && stream.userid == this.userid) { + onStreamEndedHandler(stream, connection); + } + } + } + + !dontSendMessage && this.socket.send({ + drop: true + }); + }, + hold: function(holdMLine) { + // connection.peers['user-id'].hold(); + + if (peer.prevCreateType == 'answer') { + this.socket.send({ + unhold: true, + holdMLine: holdMLine || 'both', + takeAction: true + }); + return; + } + + this.socket.send({ + hold: true, + holdMLine: holdMLine || 'both' + }); + + this.peer.hold = true; + this.fireHoldUnHoldEvents({ + kind: holdMLine, + isHold: true, + userid: connection.userid, + remoteUser: this.userid + }); + }, + unhold: function(holdMLine) { + // connection.peers['user-id'].unhold(); + + if (peer.prevCreateType == 'answer') { + this.socket.send({ + unhold: true, + holdMLine: holdMLine || 'both', + takeAction: true + }); + return; + } + + this.socket.send({ + unhold: true, + holdMLine: holdMLine || 'both' + }); + + this.peer.hold = false; + this.fireHoldUnHoldEvents({ + kind: holdMLine, + isHold: false, + userid: connection.userid, + remoteUser: this.userid + }); + }, + fireHoldUnHoldEvents: function(e) { + // this method is for inner usages only! + + var isHold = e.isHold; + var kind = e.kind; + var userid = e.remoteUser || e.userid; + + // hold means inactive a specific media line! + // a media line can contain multiple synced sources (ssrc) + // i.e. a media line can reference multiple tracks! + // that's why hold will affect all relevant tracks in a specific media line! + for (var stream in connection.streams) { + if (connection._skip.indexOf(stream) == -1) { + stream = connection.streams[stream]; + + if (stream.userid == userid) { + // www.RTCMultiConnection.org/docs/onhold/ + if (isHold) + connection.onhold(merge({ + kind: kind + }, stream)); + + // www.RTCMultiConnection.org/docs/onunhold/ + if (!isHold) + connection.onunhold(merge({ + kind: kind + }, stream)); + } + } + } + }, + redial: function() { + // connection.peers['user-id'].redial(); + + // 1st of all; remove all relevant remote media streams + for (var stream in connection.streams) { + if (connection._skip.indexOf(stream) == -1) { + stream = connection.streams[stream]; + + if (stream.userid == this.userid && stream.type == 'remote') { + onStreamEndedHandler(stream, connection); + } + } + } + + log('ReDialing...'); + + socket.send({ + recreatePeer: true + }); + + peer = new PeerConnection(); + peer.create('offer', peerConfig); + }, + sharePartOfScreen: function(args) { + // www.RTCMultiConnection.org/docs/onpartofscreen/ + var that = this; + var lastScreenshot = ''; + + function partOfScreenCapturer() { + // if stopped + if (that.stopPartOfScreenSharing) { + that.stopPartOfScreenSharing = false; + + if (connection.onpartofscreenstopped) { + connection.onpartofscreenstopped(); + } + return; + } + + // if paused + if (that.pausePartOfScreenSharing) { + if (connection.onpartofscreenpaused) { + connection.onpartofscreenpaused(); + } + + return setTimeout(partOfScreenCapturer, args.interval || 200); + } + + capturePartOfScreen({ + element: args.element, + connection: connection, + callback: function(screenshot) { + if (!connection.channels[that.userid]) { + throw 'No such data channel exists.'; + } + + // don't share repeated content + if (screenshot != lastScreenshot) { + lastScreenshot = screenshot; + connection.channels[that.userid].send({ + screenshot: screenshot, + isPartOfScreen: true + }); + } + + // "once" can be used to share single screenshot + !args.once && setTimeout(partOfScreenCapturer, args.interval || 200); + } + }); + } + + partOfScreenCapturer(); + }, + getConnectionStats: function(callback, interval) { + if (!callback) throw 'callback is mandatory.'; + + if (!window.getConnectionStats) { + loadScript(connection.resources.getConnectionStats, invoker); + } else invoker(); + + function invoker() { + RTCPeerConnection.prototype.getConnectionStats = window.getConnectionStats; + peer.connection && peer.connection.getConnectionStats(callback, interval); + } + }, + takeSnapshot: function(callback) { + takeSnapshot({ + userid: this.userid, + connection: connection, + callback: callback + }); + } + }; + } + + function onSessionOpened() { + // original conferencing infrastructure! + if (connection.isInitiator && getLength(participants) && getLength(participants) <= connection.maxParticipantsAllowed) { + if (!connection.session.oneway && !connection.session.broadcast) { + defaultSocket.send({ + sessionid: connection.sessionid, + newParticipant: _config.userid || socket.channel, + userData: { + userid: _config.userid || socket.channel, + extra: _config.extra + } + }); + } + } + + // 1st: renegotiation is supported only on chrome + // 2nd: must not renegotiate same media multiple times + // 3rd: todo: make sure that target-user has no such "renegotiated" media. + if (_config.userinfo.browser == 'chrome' && !_config.renegotiatedOnce) { + // this code snippet is added to make sure that "previously-renegotiated" streams are also + // renegotiated to this new user + for (var rSession in connection.renegotiatedSessions) { + _config.renegotiatedOnce = true; + + if (connection.renegotiatedSessions[rSession] && connection.renegotiatedSessions[rSession].stream) { + connection.peers[_config.userid].renegotiate(connection.renegotiatedSessions[rSession].stream, connection.renegotiatedSessions[rSession].session); + } + } + } + } + + function socketResponse(response) { + if (isRMSDeleted) return; + + if (response.userid == connection.userid) + return; + + if (response.sdp) { + _config.userid = response.userid; + _config.extra = response.extra || {}; + _config.renegotiate = response.renegotiate; + _config.streaminfo = response.streaminfo; + _config.isInitiator = response.isInitiator; + _config.userinfo = response.userinfo; + + var sdp = JSON.parse(response.sdp); + + if (sdp.type == 'offer') { + // to synchronize SCTP or RTP + peerConfig.preferSCTP = !!response.preferSCTP; + connection.fakeDataChannels = !!response.fakeDataChannels; + } + + // initializing fake channel + initFakeChannel(); + + sdpInvoker(sdp, response.labels); + } + + if (response.candidate) { + peer && peer.addIceCandidate(JSON.parse(response.candidate)); + } + + if (response.streamid) { + if (!rtcMultiSession.streamids) { + rtcMultiSession.streamids = {}; + } + if (!rtcMultiSession.streamids[response.streamid]) { + rtcMultiSession.streamids[response.streamid] = response.streamid; + connection.onstreamid(response); + } + } + + if (response.mute || response.unmute) { + if (response.promptMuteUnmute) { + if (!connection.privileges.canMuteRemoteStream) { + connection.onstatechange({ + userid: response.userid, + extra: response.extra, + name: 'mute-request-denied', + reason: response.userid + ' tried to mute your stream; however "privileges.canMuteRemoteStream" is "false".' + }); + return; + } + + if (connection.streams[response.streamid]) { + if (response.mute && !connection.streams[response.streamid].muted) { + connection.streams[response.streamid].mute(response.session); + } + if (response.unmute && connection.streams[response.streamid].muted) { + connection.streams[response.streamid].unmute(response.session); + } + } + } else { + var streamObject = {}; + if (connection.streams[response.streamid]) { + streamObject = connection.streams[response.streamid]; + } + + var session = response.session; + var fakeObject = merge({}, streamObject); + fakeObject.session = session; + + fakeObject.isAudio = !!fakeObject.session.audio && !fakeObject.session.video; + fakeObject.isVideo = !!fakeObject.session.video; + fakeObject.isScreen = !!fakeObject.session.screen; + + if (response.mute) connection.onmute(fakeObject || response); + if (response.unmute) connection.onunmute(fakeObject || response); + } + } + + if (response.isVolumeChanged) { + log('Volume of stream: ' + response.streamid + ' has changed to: ' + response.volume); + if (connection.streams[response.streamid]) { + var mediaElement = connection.streams[response.streamid].mediaElement; + if (mediaElement) mediaElement.volume = response.volume; + } + } + + // to stop local stream + if (response.stopped) { + if (connection.streams[response.streamid]) { + onStreamEndedHandler(connection.streams[response.streamid], connection); + } + } + + // to stop remote stream + if (response.promptStreamStop /* && !connection.isInitiator */ ) { + if (!connection.privileges.canStopRemoteStream) { + connection.onstatechange({ + userid: response.userid, + extra: response.extra, + name: 'stop-request-denied', + reason: response.userid + ' tried to stop your stream; however "privileges.canStopRemoteStream" is "false".' + }); + return; + } + warn('Remote stream has been manually stopped!'); + if (connection.streams[response.streamid]) { + connection.streams[response.streamid].stop(); + } + } + + if (response.left) { + // firefox is unable to stop remote streams + // firefox doesn't auto stop streams when peer.close() is called. + if (isFirefox) { + var userLeft = response.userid; + for (var stream in connection.streams) { + stream = connection.streams[stream]; + if (stream.userid == userLeft) { + connection.stopMediaStream(stream); + onStreamEndedHandler(stream, connection); + } + } + } + + if (peer && peer.connection) { + // todo: verify if-block's 2nd condition + if (peer.connection.signalingState != 'closed' && peer.connection.iceConnectionState.search(/disconnected|failed/gi) == -1) { + peer.connection.close(); + } + peer.connection = null; + } + + if (participants[response.userid]) delete participants[response.userid]; + + if (response.closeEntireSession) { + connection.onSessionClosed(response); + connection.leave(); + return; + } + + connection.remove(response.userid); + + onLeaveHandler({ + userid: response.userid, + extra: response.extra || {}, + entireSessionClosed: !!response.closeEntireSession + }, connection); + } + + // keeping session active even if initiator leaves + if (response.playRoleOfBroadcaster) { + if (response.extra) { + // clone extra-data from initial moderator + connection.extra = merge(connection.extra, response.extra); + } + if (response.participants) { + participants = response.participants; + + // make sure that if 2nd initiator leaves; control is shifted to 3rd person. + if (participants[connection.userid]) { + delete participants[connection.userid]; + } + + if (sockets[0] && sockets[0].userid == response.userid) { + delete sockets[0]; + sockets = swap(sockets); + } + + if (socketObjects[response.userid]) { + delete socketObjects[response.userid]; + } + } + + setTimeout(connection.playRoleOfInitiator, 2000); + } + + if (response.changeBandwidth) { + if (!connection.peers[response.userid]) throw 'No such peer exists.'; + + // synchronize bandwidth + connection.peers[response.userid].peer.bandwidth = response.bandwidth; + + // renegotiate to apply bandwidth + connection.peers[response.userid].renegotiate(); + } + + if (response.customMessage) { + if (!connection.peers[response.userid]) throw 'No such peer exists.'; + if (response.message.ejected) { + if (connection.sessionDescriptions[connection.sessionid].userid != response.userid) { + throw 'only initiator can eject a user.'; + } + // initiator ejected this user + connection.leave(); + + connection.onSessionClosed({ + userid: response.userid, + extra: response.extra || _config.extra, + isEjected: true + }); + } else connection.peers[response.userid].onCustomMessage(response.message); + } + + if (response.drop) { + if (!connection.peers[response.userid]) throw 'No such peer exists.'; + connection.peers[response.userid].drop(true); + connection.peers[response.userid].renegotiate(); + + connection.ondrop(response.userid); + } + + if (response.hold || response.unhold) { + if (!connection.peers[response.userid]) throw 'No such peer exists.'; + + if (response.takeAction) { + connection.peers[response.userid][!!response.hold ? 'hold' : 'unhold'](response.holdMLine); + return; + } + + connection.peers[response.userid].peer.hold = !!response.hold; + connection.peers[response.userid].peer.holdMLine = response.holdMLine; + + socket.send({ + isRenegotiate: true + }); + + connection.peers[response.userid].fireHoldUnHoldEvents({ + kind: response.holdMLine, + isHold: !!response.hold, + userid: response.userid + }); + } + + if (response.isRenegotiate) { + connection.peers[response.userid].renegotiate(null, connection.peers[response.userid].peer.session); + } + + // fake data channels! + if (response.fakeData) { + peerConfig.onmessage(response.fakeData); + } + + // sometimes we don't need to renegotiate e.g. when peers are disconnected + // or if it is firefox + if (response.recreatePeer) { + peer = new PeerConnection(); + } + + // remote video failed either out of ICE gathering process or ICE connectivity check-up + // or IceAgent was unable to locate valid candidates/ports. + if (response.failedToReceiveRemoteVideo) { + log('Remote peer hasn\'t received stream: ' + response.streamid + '. Renegotiating...'); + if (connection.peers[response.userid]) { + connection.peers[response.userid].renegotiate(); + } + } + + if (response.redial) { + if (connection.peers[response.userid]) { + if (connection.peers[response.userid].peer.connection.iceConnectionState != 'disconnected') { + _config.redialing = false; + } + + if (connection.peers[response.userid].peer.connection.iceConnectionState == 'disconnected' && !_config.redialing) { + _config.redialing = true; + + warn('Peer connection is closed.', toStr(connection.peers[response.userid].peer.connection), 'ReDialing..'); + connection.peers[response.userid].redial(); + } + } + } + } + + connection.playRoleOfInitiator = function() { + connection.dontCaptureUserMedia = true; + connection.open(); + sockets = swap(sockets); + connection.dontCaptureUserMedia = false; + }; + + connection.askToShareParticipants = function() { + defaultSocket && defaultSocket.send({ + askToShareParticipants: true + }); + }; + + connection.shareParticipants = function(args) { + var message = { + joinUsers: participants, + userid: connection.userid, + extra: connection.extra + }; + + if (args) { + if (args.dontShareWith) message.dontShareWith = args.dontShareWith; + if (args.shareWith) message.shareWith = args.shareWith; + } + + defaultSocket.send(message); + }; + + function sdpInvoker(sdp, labels) { + if (sdp.type == 'answer') { + peer.setRemoteDescription(sdp); + updateSocket(); + return; + } + if (!_config.renegotiate && sdp.type == 'offer') { + peerConfig.offerDescription = sdp; + + peerConfig.session = connection.session; + if (!peer) peer = new PeerConnection(); + peer.create('answer', peerConfig); + + updateSocket(); + return; + } + + var session = _config.renegotiate; + // detach streams + detachMediaStream(labels, peer.connection); + + if (session.oneway || isData(session)) { + createAnswer(); + delete _config.renegotiate; + } else { + if (_config.capturing) + return; + + _config.capturing = true; + + connection.captureUserMedia(function(stream) { + _config.capturing = false; + + peer.addStream(stream); + + connection.renegotiatedSessions[JSON.stringify(_config.renegotiate)] = { + session: _config.renegotiate, + stream: stream + }; + + delete _config.renegotiate; + + createAnswer(); + }, _config.renegotiate); + } + + function createAnswer() { + peer.recreateAnswer(sdp, session, function(_sdp, streaminfo) { + sendsdp({ + sdp: _sdp, + socket: socket, + streaminfo: streaminfo + }); + connection.detachStreams = []; + }); + } + } + } + + function detachMediaStream(labels, peer) { + if (!labels) return; + for (var i = 0; i < labels.length; i++) { + var label = labels[i]; + if (connection.streams[label]) { + peer.removeStream(connection.streams[label].stream); + } + } + } + + function sendsdp(e) { + e.socket.send({ + sdp: JSON.stringify({ + sdp: e.sdp.sdp, + type: e.sdp.type + }), + renegotiate: !!e.renegotiate ? e.renegotiate : false, + streaminfo: e.streaminfo || '', + labels: e.labels || [], + preferSCTP: !!connection.preferSCTP, + fakeDataChannels: !!connection.fakeDataChannels, + isInitiator: !!connection.isInitiator, + userinfo: { + browser: isFirefox ? 'firefox' : 'chrome' + } + }); + } + + // sharing new user with existing participants + + function onNewParticipant(response) { + var channel = response.newParticipant; + + if (!channel || !!participants[channel] || channel == connection.userid) + return; + + var new_channel = connection.token(); + newPrivateSocket({ + channel: new_channel, + extra: response.userData ? response.userData.extra : response.extra, + userid: response.userData ? response.userData.userid : response.userid + }); + + defaultSocket.send({ + participant: true, + targetUser: channel, + channel: new_channel + }); + } + + // if a user leaves + + function clearSession() { + connection.numberOfConnectedUsers--; + + var alertMessage = { + left: true, + extra: connection.extra || {}, + userid: connection.userid, + sessionid: connection.sessionid + }; + + if (connection.isInitiator) { + // if initiator wants to close entire session + if (connection.autoCloseEntireSession) { + alertMessage.closeEntireSession = true; + } else if (sockets[0]) { + // shift initiation control to another user + sockets[0].send({ + playRoleOfBroadcaster: true, + userid: connection.userid, + extra: connection.extra, + participants: participants + }); + } + } + + sockets.forEach(function(socket, i) { + socket.send(alertMessage); + + if (socketObjects[socket.channel]) { + delete socketObjects[socket.channel]; + } + + delete sockets[i]; + }); + + sockets = swap(sockets); + + connection.refresh(); + + webAudioMediaStreamSources.forEach(function(mediaStreamSource) { + // if source is connected; then chrome will crash on unload. + mediaStreamSource.disconnect(); + }); + + webAudioMediaStreamSources = []; + } + + // www.RTCMultiConnection.org/docs/remove/ + connection.remove = function(userid) { + if (rtcMultiSession.requestsFrom && rtcMultiSession.requestsFrom[userid]) delete rtcMultiSession.requestsFrom[userid]; + + if (connection.peers[userid]) { + if (connection.peers[userid].peer && connection.peers[userid].peer.connection) { + if (connection.peers[userid].peer.connection.signalingState != 'closed') { + connection.peers[userid].peer.connection.close(); + } + connection.peers[userid].peer.connection = null; + } + delete connection.peers[userid]; + } + if (participants[userid]) { + delete participants[userid]; + } + + for (var stream in connection.streams) { + stream = connection.streams[stream]; + if (stream.userid == userid) { + onStreamEndedHandler(stream, connection); + delete connection.streams[stream]; + } + } + + if (socketObjects[userid]) { + delete socketObjects[userid]; + } + }; + + // www.RTCMultiConnection.org/docs/refresh/ + connection.refresh = function() { + // if firebase; remove data from firebase servers + if (connection.isInitiator && !!connection.socket && !!connection.socket.remove) { + connection.socket.remove(); + } + + participants = {}; + + // to stop/remove self streams + for (var i = 0; i < connection.attachStreams.length; i++) { + connection.stopMediaStream(connection.attachStreams[i]); + } + + // to allow capturing of identical streams + currentUserMediaRequest = { + streams: [], + mutex: false, + queueRequests: [] + }; + + rtcMultiSession.isOwnerLeaving = true; + + connection.isInitiator = false; + connection.isAcceptNewSession = true; + connection.attachMediaStreams = []; + connection.sessionDescription = null; + connection.sessionDescriptions = {}; + connection.localStreamids = []; + connection.preRecordedMedias = {}; + connection.snapshots = {}; + + connection.numberOfConnectedUsers = 0; + connection.numberOfSessions = 0; + + connection.attachStreams = []; + connection.detachStreams = []; + connection.fileQueue = {}; + connection.channels = {}; + connection.renegotiatedSessions = {}; + + for (var peer in connection.peers) { + if (peer != connection.userid) { + delete connection.peers[peer]; + } + } + + // to make sure remote streams are also removed! + for (var stream in connection.streams) { + if (connection._skip.indexOf(stream) == -1) { + onStreamEndedHandler(connection.streams[stream], connection); + delete connection.streams[stream]; + } + } + + socketObjects = {}; + sockets = []; + participants = {}; + }; + + // www.RTCMultiConnection.org/docs/reject/ + connection.reject = function(userid) { + if (!isString(userid)) userid = userid.userid; + defaultSocket.send({ + rejectedRequestOf: userid + }); + + // remove relevant data to allow him join again + connection.remove(userid); + }; + + rtcMultiSession.leaveHandler = function(e) { + if (!connection.leaveOnPageUnload) return; + + if (isNull(e.keyCode)) { + return clearSession(); + } + + if (e.keyCode == 116) { + clearSession(); + } + }; + + listenEventHandler('beforeunload', rtcMultiSession.leaveHandler); + listenEventHandler('keyup', rtcMultiSession.leaveHandler); + + rtcMultiSession.onLineOffLineHandler = function() { + if (!navigator.onLine) { + rtcMultiSession.isOffLine = true; + } else if (rtcMultiSession.isOffLine) { + rtcMultiSession.isOffLine = !navigator.onLine; + + // defaultSocket = getDefaultSocketRef(); + + // pending tasks should be resumed? + // sockets should be reconnected? + // peers should be re-established? + } + }; + + listenEventHandler('load', rtcMultiSession.onLineOffLineHandler); + listenEventHandler('online', rtcMultiSession.onLineOffLineHandler); + listenEventHandler('offline', rtcMultiSession.onLineOffLineHandler); + + function onSignalingReady() { + if (rtcMultiSession.signalingReady) return; + rtcMultiSession.signalingReady = true; + + setTimeout(callbackForSignalingReady, 1000); + + if (!connection.isInitiator) { + // as soon as signaling gateway is connected; + // user should check existing rooms! + defaultSocket && defaultSocket.send({ + searchingForRooms: true + }); + } + } + + function joinParticipants(joinUsers) { + for (var user in joinUsers) { + if (!participants[joinUsers[user]]) { + onNewParticipant({ + sessionid: connection.sessionid, + newParticipant: joinUsers[user], + userid: connection.userid, + extra: connection.extra + }); + } + } + } + + function getDefaultSocketRef() { + return connection.openSignalingChannel({ + onmessage: function(response) { + // RMS == RTCMultiSession + if (isRMSDeleted) return; + + // if message is sent by same user + if (response.userid == connection.userid) return; + + if (response.sessionid && response.userid) { + if (!connection.sessionDescriptions[response.sessionid]) { + connection.numberOfSessions++; + connection.sessionDescriptions[response.sessionid] = response; + + // fire "onNewSession" only if: + // 1) "isAcceptNewSession" boolean is true + // 2) "sessionDescriptions" object isn't having same session i.e. to prevent duplicate invocations + if (connection.isAcceptNewSession) { + + if (!connection.dontOverrideSession) { + connection.session = response.session; + } + + onNewSession(response); + } + } + } + + if (response.newParticipant && !connection.isAcceptNewSession && rtcMultiSession.broadcasterid === response.userid) { + if (response.newParticipant != connection.userid) { + onNewParticipant(response); + } + } + + if (getLength(participants) < connection.maxParticipantsAllowed && response.targetUser == connection.userid && response.participant) { + if (connection.peers[response.userid] && !connection.peers[response.userid].peer) { + delete participants[response.userid]; + delete connection.peers[response.userid]; + connection.isAcceptNewSession = true; + return acceptRequest(response); + } + + if (!participants[response.userid]) { + acceptRequest(response); + } + } + + if (response.acceptedRequestOf == connection.userid) { + connection.onstatechange({ + userid: response.userid, + extra: response.extra, + name: 'request-accepted', + reason: response.userid + ' accepted your participation request.' + }); + } + + if (response.rejectedRequestOf == connection.userid) { + connection.onstatechange({ + userid: response.userid, + extra: response.extra, + name: 'request-rejected', + reason: response.userid + ' rejected your participation request.' + }); + } + + if (response.customMessage) { + if (response.message.drop) { + connection.ondrop(response.userid); + + connection.attachStreams = []; + // "drop" should detach all local streams + for (var stream in connection.streams) { + if (connection._skip.indexOf(stream) == -1) { + stream = connection.streams[stream]; + if (stream.type == 'local') { + connection.detachStreams.push(stream.streamid); + onStreamEndedHandler(stream, connection); + } else onStreamEndedHandler(stream, connection); + } + } + + if (response.message.renegotiate) { + // renegotiate; so "peer.removeStream" happens. + connection.renegotiate(); + } + } else if (connection.onCustomMessage) { + connection.onCustomMessage(response.message); + } + } + + if (connection.isInitiator && response.searchingForRooms) { + defaultSocket && defaultSocket.send({ + sessionDescription: connection.sessionDescription, + responseFor: response.userid + }); + } + + if (response.sessionDescription && response.responseFor == connection.userid) { + var sessionDescription = response.sessionDescription; + if (!connection.sessionDescriptions[sessionDescription.sessionid]) { + connection.numberOfSessions++; + connection.sessionDescriptions[sessionDescription.sessionid] = sessionDescription; + } + } + + if (connection.isInitiator && response.askToShareParticipants && defaultSocket) { + connection.shareParticipants({ + shareWith: response.userid + }); + } + + // participants are shared with single user + if (response.shareWith == connection.userid && response.dontShareWith != connection.userid && response.joinUsers) { + joinParticipants(response.joinUsers); + } + + // participants are shared with all users + if (!response.shareWith && response.joinUsers) { + if (response.dontShareWith) { + if (connection.userid != response.dontShareWith) { + joinParticipants(response.joinUsers); + } + } else joinParticipants(response.joinUsers); + } + + if (response.messageFor == connection.userid && response.presenceState) { + if (response.presenceState == 'checking') { + defaultSocket.send({ + messageFor: response.userid, + presenceState: 'available', + _config: response._config + }); + log('participant asked for availability'); + } + + if (response.presenceState == 'available') { + rtcMultiSession.presenceState = 'available'; + + connection.onstatechange({ + userid: 'browser', + extra: {}, + name: 'room-available', + reason: 'Initiator is available and room is active.' + }); + + joinSession(response._config); + } + } + + if (response.donotJoin && response.messageFor == connection.userid) { + log(response.userid, 'is not joining your room.'); + } + + // if initiator disconnects sockets, participants should also disconnect + if (response.isDisconnectSockets) { + log('Disconnecting your sockets because initiator also disconnected his sockets.'); + connection.disconnect(); + } + }, + callback: function(socket) { + socket && this.onopen(socket); + }, + onopen: function(socket) { + if (socket) defaultSocket = socket; + if (onSignalingReady) onSignalingReady(); + + rtcMultiSession.defaultSocket = defaultSocket; + + if (!defaultSocket.__push) { + defaultSocket.__push = defaultSocket.send; + defaultSocket.send = function(message) { + message.userid = message.userid || connection.userid; + message.extra = message.extra || connection.extra || {}; + + defaultSocket.__push(message); + }; + } + } + }); + } + + // default-socket is a common socket shared among all users in a specific channel; + // to share participation requests; room descriptions; and other stuff. + var defaultSocket = getDefaultSocketRef(); + + rtcMultiSession.defaultSocket = defaultSocket; + + if (defaultSocket && onSignalingReady) setTimeout(onSignalingReady, 2000); + + if (connection.session.screen) { + loadScreenFrame(); + } + // CUSTOM CODE // + + /* Commenting this + connection.getExternalIceServers && loadIceFrame(function(iceServers) + { + connection.iceServers = connection.iceServers.concat(iceServers); + }); + */ + + // CUSTOM CODE // + + if (connection.log == false) connection.skipLogs(); + if (connection.onlog) { + log = warn = error = function() { + var log = {}; + var index = 0; + Array.prototype.slice.call(arguments).forEach(function(argument) { + log[index++] = toStr(argument); + }); + toStr = function(str) { + return str; + }; + connection.onlog(log); + }; + } + + function setDirections() { + var userMaxParticipantsAllowed = 0; + + // if user has set a custom max participant setting, remember it + if (connection.maxParticipantsAllowed != 256) { + userMaxParticipantsAllowed = connection.maxParticipantsAllowed; + } + + if (connection.direction == 'one-way') connection.session.oneway = true; + if (connection.direction == 'one-to-one') connection.maxParticipantsAllowed = 1; + if (connection.direction == 'one-to-many') connection.session.broadcast = true; + if (connection.direction == 'many-to-many') { + if (!connection.maxParticipantsAllowed || connection.maxParticipantsAllowed == 1) { + connection.maxParticipantsAllowed = 256; + } + } + + // if user has set a custom max participant setting, set it back + if (userMaxParticipantsAllowed && connection.maxParticipantsAllowed != 1) { + connection.maxParticipantsAllowed = userMaxParticipantsAllowed; + } + } + + // open new session + this.initSession = function(args) { + rtcMultiSession.isOwnerLeaving = false; + + setDirections(); + participants = {}; + + rtcMultiSession.isOwnerLeaving = false; + + if (!isNull(args.transmitRoomOnce)) { + connection.transmitRoomOnce = args.transmitRoomOnce; + } + + function transmit() { + if (defaultSocket && getLength(participants) < connection.maxParticipantsAllowed && !rtcMultiSession.isOwnerLeaving) { + defaultSocket.send(connection.sessionDescription); + } + + if (!connection.transmitRoomOnce && !rtcMultiSession.isOwnerLeaving) + setTimeout(transmit, connection.interval || 3000); + } + + // todo: test and fix next line. + if (!args.dontTransmit /* || connection.transmitRoomOnce */ ) transmit(); + }; + + function joinSession(_config, skipOnStateChange) { + if (rtcMultiSession.donotJoin && rtcMultiSession.donotJoin == _config.sessionid) { + return; + } + + // dontOverrideSession allows you force RTCMultiConnection + // to not override default session for participants; + // by default, session is always overridden and set to the session coming from initiator! + if (!connection.dontOverrideSession) { + connection.session = _config.session || {}; + } + + // make sure that inappropriate users shouldn't receive onNewSession event + rtcMultiSession.broadcasterid = _config.userid; + + if (_config.sessionid) { + // used later to prevent external rooms messages to be used by this user! + connection.sessionid = _config.sessionid; + } + + connection.isAcceptNewSession = false; + + var channel = getRandomString(); + newPrivateSocket({ + channel: channel, + extra: _config.extra || {}, + userid: _config.userid + }); + + var offers = {}; + if (connection.attachStreams.length) { + var stream = connection.attachStreams[connection.attachStreams.length - 1]; + if (!!stream.getAudioTracks && stream.getAudioTracks().length) { + offers.audio = true; + } + if (stream.getVideoTracks().length) { + offers.video = true; + } + } + + if (!isEmpty(offers)) { + log(toStr(offers)); + } else log('Seems data-only connection.'); + + connection.onstatechange({ + userid: _config.userid, + extra: {}, + name: 'connecting-with-initiator', + reason: 'Checking presence of the initiator; and the room.' + }); + + defaultSocket.send({ + participant: true, + channel: channel, + targetUser: _config.userid, + session: connection.session, + offers: { + audio: !!offers.audio, + video: !!offers.video + } + }); + + connection.skipOnNewSession = false; + invokeMediaCaptured(connection); + } + + // join existing session + this.joinSession = function(_config) { + if (!defaultSocket) + return setTimeout(function() { + warn('Default-Socket is not yet initialized.'); + rtcMultiSession.joinSession(_config); + }, 1000); + + _config = _config || {}; + participants = {}; + + rtcMultiSession.presenceState = 'checking'; + + connection.onstatechange({ + userid: _config.userid, + extra: _config.extra || {}, + name: 'detecting-room-presence', + reason: 'Checking presence of the room.' + }); + + function contactInitiator() { + defaultSocket.send({ + messageFor: _config.userid, + presenceState: rtcMultiSession.presenceState, + _config: { + userid: _config.userid, + extra: _config.extra || {}, + sessionid: _config.sessionid, + session: _config.session || false + } + }); + } + contactInitiator(); + + function checker() { + if (rtcMultiSession.presenceState == 'checking') { + warn('Unable to reach initiator. Trying again...'); + contactInitiator(); + setTimeout(function() { + if (rtcMultiSession.presenceState == 'checking') { + connection.onstatechange({ + userid: _config.userid, + extra: _config.extra || {}, + name: 'room-not-available', + reason: 'Initiator seems absent. Waiting for someone to open the room.' + }); + + connection.isAcceptNewSession = true; + setTimeout(checker, 2000); + } + }, 2000); + } + } + + setTimeout(checker, 3000); + }; + + connection.donotJoin = function(sessionid) { + rtcMultiSession.donotJoin = sessionid; + + var session = connection.sessionDescriptions[sessionid]; + if (!session) return; + + defaultSocket.send({ + donotJoin: true, + messageFor: session.userid, + sessionid: sessionid + }); + + participants = {}; + connection.isAcceptNewSession = true; + connection.sessionid = null; + }; + + // send file/data or text message + this.send = function(message, _channel) { + if (!(message instanceof ArrayBuffer || message instanceof DataView)) { + message = str2ab({ + extra: connection.extra, + userid: connection.userid, + data: message + }); + } + + if (_channel) { + if (_channel.readyState == 'open') { + _channel.send(message); + } + return; + } + + for (var dataChannel in connection.channels) { + var channel = connection.channels[dataChannel].channel; + if (channel.readyState == 'open') { + channel.send(message); + } + } + }; + + // leave session + this.leave = function() { + clearSession(); + }; + + // renegotiate new stream + this.addStream = function(e) { + var session = e.renegotiate; + + if (!connection.renegotiatedSessions[JSON.stringify(e.renegotiate)]) { + connection.renegotiatedSessions[JSON.stringify(e.renegotiate)] = { + session: e.renegotiate, + stream: e.stream + }; + } + + if (e.socket) { + if (e.socket.userid != connection.userid) { + addStream(connection.peers[e.socket.userid]); + } + } else { + for (var peer in connection.peers) { + if (peer != connection.userid) { + addStream(connection.peers[peer]); + } + } + } + + function addStream(_peer) { + var socket = _peer.socket; + + if (!socket) { + warn(_peer, 'doesn\'t has socket.'); + return; + } + + updateSocketForLocalStreams(socket); + + if (!_peer || !_peer.peer) { + throw 'No peer to renegotiate.'; + } + + var peer = _peer.peer; + + if (e.stream) { + if (!peer.attachStreams) { + peer.attachStreams = []; + } + + peer.attachStreams.push(e.stream); + } + + // detaching old streams + detachMediaStream(connection.detachStreams, peer.connection); + + if (e.stream && (session.audio || session.video || session.screen)) { + peer.addStream(e.stream); + } + + peer.recreateOffer(session, function(sdp, streaminfo) { + sendsdp({ + sdp: sdp, + socket: socket, + renegotiate: session, + labels: connection.detachStreams, + streaminfo: streaminfo + }); + connection.detachStreams = []; + }); + } + }; + + // www.RTCMultiConnection.org/docs/request/ + connection.request = function(userid, extra) { + connection.captureUserMedia(function() { + // open private socket that will be used to receive offer-sdp + newPrivateSocket({ + channel: connection.userid, + extra: extra || {}, + userid: userid + }); + + // ask other user to create offer-sdp + defaultSocket.send({ + participant: true, + targetUser: userid + }); + }); + }; + + function acceptRequest(response) { + if (!rtcMultiSession.requestsFrom) rtcMultiSession.requestsFrom = {}; + if (rtcMultiSession.requestsFrom[response.userid]) return; + + var obj = { + userid: response.userid, + extra: response.extra, + channel: response.channel || response.userid, + session: response.session || connection.session + }; + + // check how participant is willing to join + if (response.offers) { + if (response.offers.audio && response.offers.video) { + log('target user has both audio/video streams.'); + } else if (response.offers.audio && !response.offers.video) { + log('target user has only audio stream.'); + } else if (!response.offers.audio && response.offers.video) { + log('target user has only video stream.'); + } else { + log('target user has no stream; it seems one-way streaming or data-only connection.'); + } + + var mandatory = connection.sdpConstraints.mandatory; + if (isNull(mandatory.OfferToReceiveAudio)) { + connection.sdpConstraints.mandatory.OfferToReceiveAudio = !!response.offers.audio; + } + if (isNull(mandatory.OfferToReceiveVideo)) { + connection.sdpConstraints.mandatory.OfferToReceiveVideo = !!response.offers.video; + } + + log('target user\'s SDP has?', toStr(connection.sdpConstraints.mandatory)); + } + + rtcMultiSession.requestsFrom[response.userid] = obj; + + // www.RTCMultiConnection.org/docs/onRequest/ + if (connection.onRequest && connection.isInitiator) { + connection.onRequest(obj); + } else _accept(obj); + } + + function _accept(e) { + if (rtcMultiSession.captureUserMediaOnDemand) { + rtcMultiSession.captureUserMediaOnDemand = false; + connection.captureUserMedia(function() { + _accept(e); + + invokeMediaCaptured(connection); + }); + return; + } + + log('accepting request from', e.userid); + participants[e.userid] = e.userid; + newPrivateSocket({ + isofferer: true, + userid: e.userid, + channel: e.channel, + extra: e.extra || {}, + session: e.session || connection.session + }); + } + + // www.RTCMultiConnection.org/docs/accept/ + connection.accept = function(e) { + // for backward compatibility + if (arguments.length > 1 && isString(arguments[0])) { + e = {}; + if (arguments[0]) e.userid = arguments[0]; + if (arguments[1]) e.extra = arguments[1]; + if (arguments[2]) e.channel = arguments[2]; + } + + connection.captureUserMedia(function() { + _accept(e); + }); + }; + + var isRMSDeleted = false; + this.disconnect = function() { + this.isOwnerLeaving = true; + + if (!connection.keepStreamsOpened) { + for (var streamid in connection.localStreams) { + connection.localStreams[streamid].stop(); + } + connection.localStreams = {}; + + currentUserMediaRequest = { + streams: [], + mutex: false, + queueRequests: [] + }; + } + + if (connection.isInitiator) { + defaultSocket.send({ + isDisconnectSockets: true + }); + } + + connection.refresh(); + + rtcMultiSession.defaultSocket = defaultSocket = null; + isRMSDeleted = true; + + connection.ondisconnected({ + userid: connection.userid, + extra: connection.extra, + peer: connection.peers[connection.userid], + isSocketsDisconnected: true + }); + + // if there is any peer still opened; close it. + connection.close(); + + window.removeEventListener('beforeunload', rtcMultiSession.leaveHandler); + window.removeEventListener('keyup', rtcMultiSession.leaveHandler); + + // it will not work, though :) + delete this; + + log('Disconnected your sockets, peers, streams and everything except RTCMultiConnection object.'); + }; + } + + var webAudioMediaStreamSources = []; + + function convertToAudioStream(mediaStream) { + if (!mediaStream) throw 'MediaStream is mandatory.'; + + if (mediaStream.getVideoTracks && !mediaStream.getVideoTracks().length) { + return mediaStream; + } + + var context = new AudioContext(); + var mediaStreamSource = context.createMediaStreamSource(mediaStream); + + var destination = context.createMediaStreamDestination(); + mediaStreamSource.connect(destination); + + webAudioMediaStreamSources.push(mediaStreamSource); + + return destination.stream; + } + + var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; + var isFirefox = typeof window.InstallTrigger !== 'undefined'; + var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; + var isChrome = !!window.chrome && !isOpera; + var isIE = !!document.documentMode; + + var isPluginRTC = isSafari || isIE; + + var isMobileDevice = !!navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i); + + // detect node-webkit + var isNodeWebkit = !!(window.process && (typeof window.process == 'object') && window.process.versions && window.process.versions['node-webkit']); + + window.MediaStream = window.MediaStream || window.webkitMediaStream; + window.AudioContext = window.AudioContext || window.webkitAudioContext; + + function getRandomString() { + // suggested by @rvulpescu from #154 + if (window.crypto && crypto.getRandomValues && navigator.userAgent.indexOf('Safari') == -1) { + var a = window.crypto.getRandomValues(new Uint32Array(3)), + token = ''; + for (var i = 0, l = a.length; i < l; i++) { + token += a[i].toString(36); + } + return token; + } else { + return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, ''); + } + } + + var chromeVersion = 50; + var matchArray = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); + if (isChrome && matchArray && matchArray[2]) { + chromeVersion = parseInt(matchArray[2], 10); + } + + var firefoxVersion = 50; + matchArray = navigator.userAgent.match(/Firefox\/(.*)/); + if (isFirefox && matchArray && matchArray[1]) { + firefoxVersion = parseInt(matchArray[1], 10); + } + + function isData(session) { + return !session.audio && !session.video && !session.screen && session.data; + } + + function isNull(obj) { + return typeof obj == 'undefined'; + } + + function isString(obj) { + return typeof obj == 'string'; + } + + function isEmpty(session) { + var length = 0; + for (var s in session) { + length++; + } + return length == 0; + } + + // this method converts array-buffer into string + function ab2str(buf) { + var result = ''; + try { + result = String.fromCharCode.apply(null, new Uint16Array(buf)); + } catch (e) {} + return result; + } + + // this method converts string into array-buffer + function str2ab(str) { + if (!isString(str)) str = JSON.stringify(str); + + var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char + var bufView = new Uint16Array(buf); + for (var i = 0, strLen = str.length; i < strLen; i++) { + bufView[i] = str.charCodeAt(i); + } + return buf; + } + + function swap(arr) { + var swapped = [], + length = arr.length; + for (var i = 0; i < length; i++) + if (arr[i] && arr[i] !== true) + swapped.push(arr[i]); + return swapped; + } + + function forEach(obj, callback) { + for (var item in obj) { + callback(obj[item], item); + } + } + + var console = window.console || { + log: function() {}, + error: function() {}, + warn: function() {} + }; + + function log() { + console.log(arguments); + } + + function error() { + console.error(arguments); + } + + function warn() { + console.warn(arguments); + } + + if (isChrome || isFirefox || isSafari) { + var log = console.log.bind(console); + var error = console.error.bind(console); + var warn = console.warn.bind(console); + } + + function toStr(obj) { + return JSON.stringify(obj, function(key, value) { + if (value && value.sdp) { + log(value.sdp.type, '\t', value.sdp.sdp); + return ''; + } else return value; + }, '\t'); + } + + function getLength(obj) { + var length = 0; + for (var o in obj) + if (o) length++; + return length; + } + + // Get HTMLAudioElement/HTMLVideoElement accordingly + + function createMediaElement(stream, session) { + var mediaElement = document.createElement(stream.isAudio ? 'audio' : 'video'); + mediaElement.id = stream.streamid; + + if (isPluginRTC) { + var body = (document.body || document.documentElement); + body.insertBefore(mediaElement, body.firstChild); + + setTimeout(function() { + Plugin.attachMediaStream(mediaElement, stream) + }, 1000); + + return Plugin.attachMediaStream(mediaElement, stream); + } + + // "mozSrcObject" is always preferred over "src"!! + mediaElement[isFirefox ? 'mozSrcObject' : 'src'] = isFirefox ? stream : (window.URL || window.webkitURL).createObjectURL(stream); + + mediaElement.controls = true; + mediaElement.autoplay = !!session.remote; + mediaElement.muted = session.remote ? false : true; + + // http://goo.gl/WZ5nFl + // Firefox don't yet support onended for any stream (remote/local) + isFirefox && mediaElement.addEventListener('ended', function() { + stream.onended(); + }, false); + + mediaElement.play(); + + return mediaElement; + } + + var onStreamEndedHandlerFiredFor = {}; + + function onStreamEndedHandler(streamedObject, connection) { + if (streamedObject.mediaElement && !streamedObject.mediaElement.parentNode) return; + + if (onStreamEndedHandlerFiredFor[streamedObject.streamid]) return; + onStreamEndedHandlerFiredFor[streamedObject.streamid] = streamedObject; + connection.onstreamended(streamedObject); + } + + var onLeaveHandlerFiredFor = {}; + + function onLeaveHandler(event, connection) { + if (onLeaveHandlerFiredFor[event.userid]) return; + onLeaveHandlerFiredFor[event.userid] = event; + connection.onleave(event); + } + + function takeSnapshot(args) { + var userid = args.userid; + var connection = args.connection; + + function _takeSnapshot(video) { + var canvas = document.createElement('canvas'); + canvas.width = video.videoWidth || video.clientWidth; + canvas.height = video.videoHeight || video.clientHeight; + + var context = canvas.getContext('2d'); + context.drawImage(video, 0, 0, canvas.width, canvas.height); + + connection.snapshots[userid] = canvas.toDataURL('image/png'); + args.callback && args.callback(connection.snapshots[userid]); + } + + if (args.mediaElement) return _takeSnapshot(args.mediaElement); + + for (var stream in connection.streams) { + stream = connection.streams[stream]; + if (stream.userid == userid && stream.stream && stream.stream.getVideoTracks && stream.stream.getVideoTracks().length) { + _takeSnapshot(stream.mediaElement); + continue; + } + } + } + + function invokeMediaCaptured(connection) { + // to let user know that media resource has been captured + // now, he can share "sessionDescription" using sockets + if (connection.onMediaCaptured) { + connection.onMediaCaptured(); + delete connection.onMediaCaptured; + } + } + + function merge(mergein, mergeto) { + if (!mergein) mergein = {}; + if (!mergeto) return mergein; + + for (var item in mergeto) { + mergein[item] = mergeto[item]; + } + return mergein; + } + + function loadScript(src, onload) { + var script = document.createElement('script'); + script.src = src; + script.onload = function() { + log('loaded resource:', src); + if (onload) onload(); + }; + document.documentElement.appendChild(script); + } + + function capturePartOfScreen(args) { + var connection = args.connection; + var element = args.element; + + if (!window.html2canvas) { + return loadScript(connection.resources.html2canvas, function() { + capturePartOfScreen(args); + }); + } + + if (isString(element)) { + element = document.querySelector(element); + if (!element) element = document.getElementById(element); + } + if (!element) throw 'HTML DOM Element is not accessible!'; + + // todo: store DOM element somewhere to minimize DOM querying issues + + // html2canvas.js is used to take screenshots + html2canvas(element, { + onrendered: function(canvas) { + args.callback(canvas.toDataURL()); + } + }); + } + + function initFileBufferReader(connection, callback) { + if (!window.FileBufferReader) { + loadScript(connection.resources.FileBufferReader, function() { + initFileBufferReader(connection, callback); + }); + return; + } + + function _private(chunk) { + chunk.userid = chunk.extra.userid; + return chunk; + } + + var fileBufferReader = new FileBufferReader(); + fileBufferReader.onProgress = function(chunk) { + connection.onFileProgress(_private(chunk), chunk.uuid); + }; + + fileBufferReader.onBegin = function(file) { + connection.onFileStart(_private(file)); + }; + + fileBufferReader.onEnd = function(file) { + connection.onFileEnd(_private(file)); + }; + + callback(fileBufferReader); + } + + var screenFrame, loadedScreenFrame; + + function loadScreenFrame(skip) { + if (DetectRTC.screen.extensionid != ReservedExtensionID) { + return; + } + + if (loadedScreenFrame) return; + if (!skip) return loadScreenFrame(true); + + loadedScreenFrame = true; + + var iframe = document.createElement('iframe'); + iframe.onload = function() { + iframe.isLoaded = true; + log('Screen Capturing frame is loaded.'); + }; + //iframe.src = 'https://www.webrtc-experiment.com/getSourceId/'; + // CUSTOM CODE // + iframe.src = 'app/fusion/scripts/webrtc/getSourceId.html'; + // CUSTOM CODE // + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); + + screenFrame = { + postMessage: function() { + if (!iframe.isLoaded) { + setTimeout(screenFrame.postMessage, 100); + return; + } + iframe.contentWindow.postMessage({ + captureSourceId: true + }, '*'); + } + }; + } + + var iceFrame, loadedIceFrame; + + function loadIceFrame(callback, skip) { + if (loadedIceFrame) return; + if (!skip) return loadIceFrame(callback, true); + + loadedIceFrame = true; + + var iframe = document.createElement('iframe'); + iframe.onload = function() { + iframe.isLoaded = true; + + listenEventHandler('message', iFrameLoaderCallback); + + function iFrameLoaderCallback(event) { + if (!event.data || !event.data.iceServers) return; + callback(event.data.iceServers); + + // this event listener is no more needed + window.removeEventListener('message', iFrameLoaderCallback); + } + + iframe.contentWindow.postMessage('get-ice-servers', '*'); + }; + iframe.src = 'https://cdn.webrtc-experiment.com/getIceServers/'; + iframe.style.display = 'none'; + (document.body || document.documentElement).appendChild(iframe); + } + + function muteOrUnmute(e) { + var stream = e.stream, + root = e.root, + session = e.session || {}, + enabled = e.enabled; + + if (!session.audio && !session.video) { + if (!isString(session)) { + session = merge(session, { + audio: true, + video: true + }); + } else { + session = { + audio: true, + video: true + }; + } + } + + // implementation from #68 + if (session.type) { + if (session.type == 'remote' && root.type != 'remote') return; + if (session.type == 'local' && root.type != 'local') return; + } + + log(enabled ? 'Muting' : 'UnMuting', 'session', toStr(session)); + + // enable/disable audio/video tracks + + if (root.type == 'local' && session.audio && !!stream.getAudioTracks) { + var audioTracks = stream.getAudioTracks()[0]; + if (audioTracks) + audioTracks.enabled = !enabled; + } + + if (root.type == 'local' && (session.video || session.screen) && !!stream.getVideoTracks) { + var videoTracks = stream.getVideoTracks()[0]; + if (videoTracks) + videoTracks.enabled = !enabled; + } + + root.sockets.forEach(function(socket) { + if (root.type == 'local') { + socket.send({ + streamid: root.streamid, + mute: !!enabled, + unmute: !enabled, + session: session + }); + } + + if (root.type == 'remote') { + socket.send({ + promptMuteUnmute: true, + streamid: root.streamid, + mute: !!enabled, + unmute: !enabled, + session: session + }); + } + }); + + if (root.type == 'remote') return; + + // According to issue #135, onmute/onumute must be fired for self + // "fakeObject" is used because we need to keep session for renegotiated streams; + // and MUST pass exact session over onStreamEndedHandler/onmute/onhold/etc. events. + var fakeObject = merge({}, root); + fakeObject.session = session; + + fakeObject.isAudio = !!fakeObject.session.audio && !fakeObject.session.video; + fakeObject.isVideo = !!fakeObject.session.video; + fakeObject.isScreen = !!fakeObject.session.screen; + + if (!!enabled) { + // if muted stream is negotiated + stream.preMuted = { + audio: stream.getAudioTracks().length && !stream.getAudioTracks()[0].enabled, + video: stream.getVideoTracks().length && !stream.getVideoTracks()[0].enabled + }; + root.rtcMultiConnection.onmute(fakeObject); + } + + if (!enabled) { + stream.preMuted = {}; + root.rtcMultiConnection.onunmute(fakeObject); + } + } + + var Firefox_Screen_Capturing_Warning = 'Make sure that you are using Firefox Nightly and you enabled: media.getusermedia.screensharing.enabled flag from about:config page. You also need to add your domain in "media.getusermedia.screensharing.allowed_domains" flag. If you are using WinXP then also enable "media.getusermedia.screensharing.allow_on_old_platforms" flag. NEVER forget to use "only" HTTPs for screen capturing!'; + var SCREEN_COMMON_FAILURE = 'HTTPs i.e. SSL-based URI is mandatory to use screen capturing.'; + // CUSTOM CODE // + var ReservedExtensionID = 'icgmlogfeajbfdffajhoebcfbibfhaen'; + //var ReservedExtensionID = 'ajhifddimkapgcifgcodmmfdlknahffk'; + + // if application-developer deployed his own extension on Google App Store + var useCustomChromeExtensionForScreenCapturing = document.domain.indexOf('webrtc-experiment.com') != -1; + + function initHark(args) { + if (!window.hark) { + loadScript(args.connection.resources.hark, function() { + initHark(args); + }); + return; + } + + var connection = args.connection; + var streamedObject = args.streamedObject; + var stream = args.stream; + + var options = {}; + var speechEvents = hark(stream, options); + + speechEvents.on('speaking', function() { + if (connection.onspeaking) { + connection.onspeaking(streamedObject); + } + }); + + speechEvents.on('stopped_speaking', function() { + if (connection.onsilence) { + connection.onsilence(streamedObject); + } + }); + + speechEvents.on('volume_change', function(volume, threshold) { + if (connection.onvolumechange) { + connection.onvolumechange(merge({ + volume: volume, + threshold: threshold + }, streamedObject)); + } + }); + } + + attachEventListener = function(video, type, listener, useCapture) { + video.addEventListener(type, listener, useCapture); + }; + + var Plugin = window.PluginRTC || {}; + window.onPluginRTCInitialized = function(pluginRTCObject) { + Plugin = pluginRTCObject; + MediaStreamTrack = Plugin.MediaStreamTrack; + RTCPeerConnection = Plugin.RTCPeerConnection; + RTCIceCandidate = Plugin.RTCIceCandidate; + RTCSessionDescription = Plugin.RTCSessionDescription; + + log(isPluginRTC ? 'Java-Applet' : 'ActiveX', 'plugin has been loaded.'); + }; + if (!isEmpty(Plugin)) window.onPluginRTCInitialized(Plugin); + + // if IE or Safari + if (isPluginRTC) { + loadScript('https://cdn.webrtc-experiment.com/Plugin.EveryWhere.js'); + // loadScript('https://cdn.webrtc-experiment.com/Plugin.Temasys.js'); + } + + var MediaStream = window.MediaStream; + + if (typeof MediaStream === 'undefined' && typeof webkitMediaStream !== 'undefined') { + MediaStream = webkitMediaStream; + } + + /*global MediaStream:true */ + if (typeof MediaStream !== 'undefined' && !('stop' in MediaStream.prototype)) { + MediaStream.prototype.stop = function() { + this.getAudioTracks().forEach(function(track) { + track.stop(); + }); + + this.getVideoTracks().forEach(function(track) { + track.stop(); + }); + }; + } + + var defaultConstraints = { + mandatory: {}, + optional: [] + }; + + /* by @FreCap pull request #41 */ + var currentUserMediaRequest = { + streams: [], + mutex: false, + queueRequests: [] + }; + + function getUserMedia(options) { + if (isPluginRTC) { + if (!Plugin.getUserMedia) { + setTimeout(function() { + getUserMedia(options); + }, 1000); + return; + } + + return Plugin.getUserMedia(options.constraints || { + audio: true, + video: true + }, options.onsuccess, options.onerror); + } + + if (currentUserMediaRequest.mutex === true) { + currentUserMediaRequest.queueRequests.push(options); + return; + } + currentUserMediaRequest.mutex = true; + + var connection = options.connection; + + // tools.ietf.org/html/draft-alvestrand-constraints-resolution-00 + var mediaConstraints = options.mediaConstraints || {}; + var videoConstraints = typeof mediaConstraints.video == 'boolean' ? mediaConstraints.video : mediaConstraints.video || mediaConstraints; + var audioConstraints = typeof mediaConstraints.audio == 'boolean' ? mediaConstraints.audio : mediaConstraints.audio || defaultConstraints; + + var n = navigator; + var hints = options.constraints || { + audio: defaultConstraints, + video: defaultConstraints + }; + + if (hints.video && hints.video.mozMediaSource) { + // "mozMediaSource" is redundant + // need to check "mediaSource" instead. + videoConstraints = {}; + } + + if (hints.video == true) hints.video = defaultConstraints; + if (hints.audio == true) hints.audio = defaultConstraints; + + // connection.mediaConstraints.audio = false; + if (typeof audioConstraints == 'boolean' && hints.audio) { + hints.audio = audioConstraints; + } + + // connection.mediaConstraints.video = false; + if (typeof videoConstraints == 'boolean' && hints.video) { + hints.video = videoConstraints; + } + + // connection.mediaConstraints.audio.mandatory = {prop:true}; + var audioMandatoryConstraints = audioConstraints.mandatory; + if (!isEmpty(audioMandatoryConstraints)) { + hints.audio.mandatory = merge(hints.audio.mandatory, audioMandatoryConstraints); + } + + // connection.media.min(320,180); + // connection.media.max(1920,1080); + var videoMandatoryConstraints = videoConstraints.mandatory; + if (videoMandatoryConstraints) { + var mandatory = {}; + + if (videoMandatoryConstraints.minWidth) { + mandatory.minWidth = videoMandatoryConstraints.minWidth; + } + + if (videoMandatoryConstraints.minHeight) { + mandatory.minHeight = videoMandatoryConstraints.minHeight; + } + + if (videoMandatoryConstraints.maxWidth) { + mandatory.maxWidth = videoMandatoryConstraints.maxWidth; + } + + if (videoMandatoryConstraints.maxHeight) { + mandatory.maxHeight = videoMandatoryConstraints.maxHeight; + } + + if (videoMandatoryConstraints.minAspectRatio) { + mandatory.minAspectRatio = videoMandatoryConstraints.minAspectRatio; + } + + if (videoMandatoryConstraints.maxFrameRate) { + mandatory.maxFrameRate = videoMandatoryConstraints.maxFrameRate; + } + + if (videoMandatoryConstraints.minFrameRate) { + mandatory.minFrameRate = videoMandatoryConstraints.minFrameRate; + } + + if (mandatory.minWidth && mandatory.minHeight) { + // http://goo.gl/IZVYsj + var allowed = ['1920:1080', '1280:720', '960:720', '640:360', '640:480', '320:240', '320:180']; + + if (allowed.indexOf(mandatory.minWidth + ':' + mandatory.minHeight) == -1 || + allowed.indexOf(mandatory.maxWidth + ':' + mandatory.maxHeight) == -1) { + error('The min/max width/height constraints you passed "seems" NOT supported.', toStr(mandatory)); + } + + if (mandatory.minWidth > mandatory.maxWidth || mandatory.minHeight > mandatory.maxHeight) { + error('Minimum value must not exceed maximum value.', toStr(mandatory)); + } + + if (mandatory.minWidth >= 1280 && mandatory.minHeight >= 720) { + warn('Enjoy HD video! min/' + mandatory.minWidth + ':' + mandatory.minHeight + ', max/' + mandatory.maxWidth + ':' + mandatory.maxHeight); + } + } + + hints.video.mandatory = merge(hints.video.mandatory, mandatory); + } + + if (videoMandatoryConstraints) { + hints.video.mandatory = merge(hints.video.mandatory, videoMandatoryConstraints); + } + + // videoConstraints.optional = [{prop:true}]; + if (videoConstraints.optional && videoConstraints.optional instanceof Array && videoConstraints.optional.length) { + hints.video.optional = hints.video.optional ? hints.video.optional.concat(videoConstraints.optional) : videoConstraints.optional; + } + + // audioConstraints.optional = [{prop:true}]; + if (audioConstraints.optional && audioConstraints.optional instanceof Array && audioConstraints.optional.length) { + hints.audio.optional = hints.audio.optional ? hints.audio.optional.concat(audioConstraints.optional) : audioConstraints.optional; + } + + if (hints.video.mandatory && !isEmpty(hints.video.mandatory) && connection._mediaSources.video) { + hints.video.optional.forEach(function(video, index) { + if (video.sourceId == connection._mediaSources.video) { + delete hints.video.optional[index]; + } + }); + + hints.video.optional = swap(hints.video.optional); + + hints.video.optional.push({ + sourceId: connection._mediaSources.video + }); + } + + if (hints.audio.mandatory && !isEmpty(hints.audio.mandatory) && connection._mediaSources.audio) { + hints.audio.optional.forEach(function(audio, index) { + if (audio.sourceId == connection._mediaSources.audio) { + delete hints.audio.optional[index]; + } + }); + + hints.audio.optional = swap(hints.audio.optional); + + hints.audio.optional.push({ + sourceId: connection._mediaSources.audio + }); + } + + if (hints.video && !hints.video.mozMediaSource && hints.video.optional && hints.video.mandatory) { + if (!hints.video.optional.length && isEmpty(hints.video.mandatory)) { + hints.video = true; + } + } + + if (isMobileDevice) { + // Android fails for some constraints + // so need to force {audio:true,video:true} + hints = { + audio: !!hints.audio, + video: !!hints.video + }; + } + + // connection.mediaConstraints always overrides constraints + // passed from "captureUserMedia" function. + // todo: need to verify all possible situations + log('invoked getUserMedia with constraints:', toStr(hints)); + + // easy way to match + var idInstance = JSON.stringify(hints); + + function streaming(stream, returnBack, streamid) { + if (!streamid) streamid = getRandomString(); + + // localStreams object will store stream + // until it is removed using native-stop method. + connection.localStreams[streamid] = stream; + + var video = options.video; + if (video) { + video[isFirefox ? 'mozSrcObject' : 'src'] = isFirefox ? stream : (window.URL || window.webkitURL).createObjectURL(stream); + video.play(); + } + + options.onsuccess(stream, returnBack, idInstance, streamid); + currentUserMediaRequest.streams[idInstance] = { + stream: stream, + streamid: streamid + }; + currentUserMediaRequest.mutex = false; + if (currentUserMediaRequest.queueRequests.length) + getUserMedia(currentUserMediaRequest.queueRequests.shift()); + } + + if (currentUserMediaRequest.streams[idInstance]) { + streaming(currentUserMediaRequest.streams[idInstance].stream, true, currentUserMediaRequest.streams[idInstance].streamid); + } else { + n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia; + + // http://goo.gl/eETIK4 + n.getMedia(hints, streaming, function(error) { + options.onerror(error, hints); + }); + } + } + + var RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription; + var RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate; + + var RTCPeerConnection; + if (typeof mozRTCPeerConnection !== 'undefined') { + RTCPeerConnection = mozRTCPeerConnection; + } else if (typeof webkitRTCPeerConnection !== 'undefined') { + RTCPeerConnection = webkitRTCPeerConnection; + } else if (typeof window.RTCPeerConnection !== 'undefined') { + RTCPeerConnection = window.RTCPeerConnection; + } else { + console.error('WebRTC 1.0 (RTCPeerConnection) API seems NOT available in this browser.'); + } + + function setSdpConstraints(config) { + var sdpConstraints; + + var sdpConstraints_mandatory = { + OfferToReceiveAudio: !!config.OfferToReceiveAudio, + OfferToReceiveVideo: !!config.OfferToReceiveVideo + }; + + sdpConstraints = { + mandatory: sdpConstraints_mandatory, + optional: [{ + VoiceActivityDetection: false + }] + }; + + if (!!navigator.mozGetUserMedia && firefoxVersion > 34) { + sdpConstraints = { + OfferToReceiveAudio: !!config.OfferToReceiveAudio, + OfferToReceiveVideo: !!config.OfferToReceiveVideo + }; + } + + return sdpConstraints; + } + + function PeerConnection() { + return { + create: function(type, options) { + merge(this, options); + + var self = this; + + this.type = type; + this.init(); + this.attachMediaStreams(); + + if (isFirefox && this.session.data) { + if (this.session.data && type == 'offer') { + this.createDataChannel(); + } + + this.getLocalDescription(type); + + if (this.session.data && type == 'answer') { + this.createDataChannel(); + } + } else self.getLocalDescription(type); + + return this; + }, + getLocalDescription: function(createType) { + log('(getLocalDescription) peer createType is', createType); + + if (this.session.inactive && isNull(this.rtcMultiConnection.waitUntilRemoteStreamStartsFlowing)) { + // inactive session returns blank-stream + this.rtcMultiConnection.waitUntilRemoteStreamStartsFlowing = false; + } + + var self = this; + + if (createType == 'answer') { + this.setRemoteDescription(this.offerDescription, createDescription); + } else createDescription(); + + function createDescription() { + self.connection[createType == 'offer' ? 'createOffer' : 'createAnswer'](function(sessionDescription) { + sessionDescription.sdp = self.serializeSdp(sessionDescription.sdp, createType); + self.connection.setLocalDescription(sessionDescription); + + if (self.trickleIce) { + self.onSessionDescription(sessionDescription, self.streaminfo); + } + + if (sessionDescription.type == 'offer') { + log('offer sdp', sessionDescription.sdp); + } + + self.prevCreateType = createType; + }, self.onSdpError, self.constraints); + } + }, + serializeSdp: function(sdp, createType) { + // it is "connection.processSdp=function(sdp){return sdp;}" + sdp = this.processSdp(sdp); + + if (isFirefox) return sdp; + + if (this.session.inactive && !this.holdMLine) { + this.hold = true; + if ((this.session.screen || this.session.video) && this.session.audio) { + this.holdMLine = 'both'; + } else if (this.session.screen || this.session.video) { + this.holdMLine = 'video'; + } else if (this.session.audio) { + this.holdMLine = 'audio'; + } + } + + sdp = this.setBandwidth(sdp); + if (this.holdMLine == 'both') { + if (this.hold) { + this.prevSDP = sdp; + sdp = sdp.replace(/a=sendonly|a=recvonly|a=sendrecv/g, 'a=inactive'); + } else if (this.prevSDP) { + if (!this.session.inactive) { + // it means that DTSL key exchange already happened for single or multiple media lines. + // this block checks, key-exchange must be happened for all media lines. + sdp = this.prevSDP; + + // todo: test it: makes sense? + if (chromeVersion <= 35) { + return sdp; + } + } + } + } else if (this.holdMLine == 'audio' || this.holdMLine == 'video') { + sdp = sdp.split('m='); + + var audio = ''; + var video = ''; + + if (sdp[1] && sdp[1].indexOf('audio') == 0) { + audio = 'm=' + sdp[1]; + } + if (sdp[2] && sdp[2].indexOf('audio') == 0) { + audio = 'm=' + sdp[2]; + } + + if (sdp[1] && sdp[1].indexOf('video') == 0) { + video = 'm=' + sdp[1]; + } + if (sdp[2] && sdp[2].indexOf('video') == 0) { + video = 'm=' + sdp[2]; + } + + if (this.holdMLine == 'audio') { + if (this.hold) { + this.prevSDP = sdp[0] + audio + video; + sdp = sdp[0] + audio.replace(/a=sendonly|a=recvonly|a=sendrecv/g, 'a=inactive') + video; + } else if (this.prevSDP) { + sdp = this.prevSDP; + } + } + + if (this.holdMLine == 'video') { + if (this.hold) { + this.prevSDP = sdp[0] + audio + video; + sdp = sdp[0] + audio + video.replace(/a=sendonly|a=recvonly|a=sendrecv/g, 'a=inactive'); + } else if (this.prevSDP) { + sdp = this.prevSDP; + } + } + } + + if (!this.hold && this.session.inactive) { + // transport.cc&l=852 - http://goo.gl/0FxxqG + // dtlstransport.h&l=234 - http://goo.gl/7E4sYF + // http://tools.ietf.org/html/rfc4340 + + // From RFC 4145, SDP setup attribute values. + // http://goo.gl/xETJEp && http://goo.gl/3Wgcau + if (createType == 'offer') { + sdp = sdp.replace(/a=setup:passive|a=setup:active|a=setup:holdconn/g, 'a=setup:actpass'); + } else { + sdp = sdp.replace(/a=setup:actpass|a=setup:passive|a=setup:holdconn/g, 'a=setup:active'); + } + + // whilst doing handshake, either media lines were "inactive" + // or no media lines were present + sdp = sdp.replace(/a=inactive/g, 'a=sendrecv'); + } + // this.session.inactive = false; + return sdp; + }, + init: function() { + this.setConstraints(); + this.connection = new RTCPeerConnection(this.iceServers, this.optionalArgument); + + if (this.session.data) { + log('invoked: createDataChannel'); + this.createDataChannel(); + } + + this.connection.onicecandidate = function(event) { + if (!event.candidate) { + if (!self.trickleIce) { + returnSDP(); + } + + return; + } + + if (!self.trickleIce) return; + + self.onicecandidate(event.candidate); + }; + + function returnSDP() { + if (self.returnedSDP) { + self.returnedSDP = false; + return; + }; + self.returnedSDP = true; + + self.onSessionDescription(self.connection.localDescription, self.streaminfo); + } + + this.connection.onaddstream = function(e) { + log('onaddstream', isPluginRTC ? e.stream : toStr(e.stream)); + + self.onaddstream(e.stream, self.session); + }; + + this.connection.onremovestream = function(e) { + self.onremovestream(e.stream); + }; + + this.connection.onsignalingstatechange = function() { + self.connection && self.oniceconnectionstatechange({ + iceConnectionState: self.connection.iceConnectionState, + iceGatheringState: self.connection.iceGatheringState, + signalingState: self.connection.signalingState + }); + }; + + this.connection.oniceconnectionstatechange = function() { + if (!self.connection) return; + + self.oniceconnectionstatechange({ + iceConnectionState: self.connection.iceConnectionState, + iceGatheringState: self.connection.iceGatheringState, + signalingState: self.connection.signalingState + }); + + if (self.trickleIce) return; + + if (self.connection.iceGatheringState == 'complete') { + log('iceGatheringState', self.connection.iceGatheringState); + returnSDP(); + } + }; + + var self = this; + }, + setBandwidth: function(sdp) { + if (isMobileDevice || isFirefox || !this.bandwidth) return sdp; + + var bandwidth = this.bandwidth; + + if (this.session.screen) { + if (!bandwidth.screen) { + warn('It seems that you are not using bandwidth for screen. Screen sharing is expected to fail.'); + } else if (bandwidth.screen < 300) { + warn('It seems that you are using wrong bandwidth value for screen. Screen sharing is expected to fail.'); + } + } + + // if screen; must use at least 300kbs + if (bandwidth.screen && this.session.screen) { + sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, ''); + sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + bandwidth.screen + '\r\n'); + } + + // remove existing bandwidth lines + if (bandwidth.audio || bandwidth.video || bandwidth.data) { + sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, ''); + } + + if (bandwidth.audio) { + sdp = sdp.replace(/a=mid:audio\r\n/g, 'a=mid:audio\r\nb=AS:' + bandwidth.audio + '\r\n'); + } + + if (bandwidth.video) { + sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + (this.session.screen ? bandwidth.screen : bandwidth.video) + '\r\n'); + } + + if (bandwidth.data && !this.preferSCTP) { + sdp = sdp.replace(/a=mid:data\r\n/g, 'a=mid:data\r\nb=AS:' + bandwidth.data + '\r\n'); + } + + return sdp; + }, + setConstraints: function() { + var sdpConstraints = setSdpConstraints({ + OfferToReceiveAudio: !!this.session.audio, + OfferToReceiveVideo: !!this.session.video || !!this.session.screen + }); + + if (this.sdpConstraints.mandatory) { + sdpConstraints = setSdpConstraints(this.sdpConstraints.mandatory); + } + + this.constraints = sdpConstraints; + + if (this.constraints) { + log('sdp-constraints', toStr(this.constraints)); + } + + this.optionalArgument = { + optional: this.optionalArgument.optional || [], + mandatory: this.optionalArgument.mandatory || {} + }; + + if (!this.preferSCTP) { + this.optionalArgument.optional.push({ + RtpDataChannels: true + }); + } + + log('optional-argument', toStr(this.optionalArgument)); + + if (!isNull(this.iceServers)) { + var iceCandidates = this.rtcMultiConnection.candidates; + + var stun = iceCandidates.stun; + var turn = iceCandidates.turn; + var host = iceCandidates.host; + + if (!isNull(iceCandidates.reflexive)) stun = iceCandidates.reflexive; + if (!isNull(iceCandidates.relay)) turn = iceCandidates.relay; + + if (!host && !stun && turn) { + this.rtcConfiguration.iceTransports = 'relay'; + } else if (!host && !stun && !turn) { + this.rtcConfiguration.iceTransports = 'none'; + } + + this.iceServers = { + iceServers: this.iceServers, + iceTransports: this.rtcConfiguration.iceTransports + }; + } else this.iceServers = null; + + log('rtc-configuration', toStr(this.iceServers)); + }, + onSdpError: function(e) { + var message = toStr(e); + + if (message && message.indexOf('RTP/SAVPF Expects at least 4 fields') != -1) { + message = 'It seems that you are trying to interop RTP-datachannels with SCTP. It is not supported!'; + } + error('onSdpError:', message); + }, + onSdpSuccess: function() { + log('sdp success'); + }, + onMediaError: function(err) { + error(toStr(err)); + }, + setRemoteDescription: function(sessionDescription, onSdpSuccess) { + if (!sessionDescription) throw 'Remote session description should NOT be NULL.'; + + if (!this.connection) return; + + log('setting remote description', sessionDescription.type, sessionDescription.sdp); + + var self = this; + this.connection.setRemoteDescription( + new RTCSessionDescription(sessionDescription), + onSdpSuccess || this.onSdpSuccess, + function(error) { + if (error.search(/STATE_SENTINITIATE|STATE_INPROGRESS/gi) == -1) { + self.onSdpError(error); + } + } + ); + }, + addIceCandidate: function(candidate) { + var self = this; + if (isPluginRTC) { + RTCIceCandidate(candidate, function(iceCandidate) { + onAddIceCandidate(iceCandidate); + }); + } else onAddIceCandidate(new RTCIceCandidate(candidate)); + + function onAddIceCandidate(iceCandidate) { + self.connection.addIceCandidate(iceCandidate, function() { + log('added:', candidate.sdpMid, candidate.candidate); + }, function() { + error('onIceFailure', arguments, candidate.candidate); + }); + } + }, + createDataChannel: function(channelIdentifier) { + // skip 2nd invocation of createDataChannel + if (this.channels && this.channels.length) return; + + var self = this; + + if (!this.channels) this.channels = []; + + // protocol: 'text/chat', preset: true, stream: 16 + // maxRetransmits:0 && ordered:false && outOfOrderAllowed: false + var dataChannelDict = {}; + + if (this.dataChannelDict) dataChannelDict = this.dataChannelDict; + + if (isChrome && !this.preferSCTP) { + dataChannelDict.reliable = false; // Deprecated! + } + + log('dataChannelDict', toStr(dataChannelDict)); + + if (this.type == 'answer' || isFirefox) { + this.connection.ondatachannel = function(event) { + self.setChannelEvents(event.channel); + }; + } + + if ((isChrome && this.type == 'offer') || isFirefox) { + this.setChannelEvents( + this.connection.createDataChannel(channelIdentifier || 'channel', dataChannelDict) + ); + } + }, + setChannelEvents: function(channel) { + var self = this; + + channel.binaryType = 'arraybuffer'; + + if (this.dataChannelDict.binaryType) { + channel.binaryType = this.dataChannelDict.binaryType; + } + + channel.onmessage = function(event) { + self.onmessage(event.data); + }; + + var numberOfTimes = 0; + channel.onopen = function() { + channel.push = channel.send; + channel.send = function(data) { + if (self.connection.iceConnectionState == 'disconnected') { + return; + } + + if (channel.readyState.search(/closing|closed/g) != -1) { + return; + } + + if (channel.readyState.search(/connecting|open/g) == -1) { + return; + } + + if (channel.readyState == 'connecting') { + numberOfTimes++; + return setTimeout(function() { + if (numberOfTimes < 20) { + channel.send(data); + } else throw 'Number of times exceeded to wait for WebRTC data connection to be opened.'; + }, 1000); + } + try { + channel.push(data); + } catch (e) { + numberOfTimes++; + warn('Data transmission failed. Re-transmitting..', numberOfTimes, toStr(e)); + if (numberOfTimes >= 20) throw 'Number of times exceeded to resend data packets over WebRTC data channels.'; + setTimeout(function() { + channel.send(data); + }, 100); + } + }; + self.onopen(channel); + }; + + channel.onerror = function(event) { + self.onerror(event); + }; + + channel.onclose = function(event) { + self.onclose(event); + }; + + this.channels.push(channel); + }, + addStream: function(stream) { + if (!stream.streamid && !isIE) { + stream.streamid = getRandomString(); + } + + // todo: maybe need to add isAudio/isVideo/isScreen if missing? + + log('attaching stream:', stream.streamid, isPluginRTC ? stream : toStr(stream)); + + this.connection.addStream(stream); + + this.sendStreamId(stream); + this.getStreamInfo(); + }, + attachMediaStreams: function() { + var streams = this.attachStreams; + for (var i = 0; i < streams.length; i++) { + this.addStream(streams[i]); + } + }, + getStreamInfo: function() { + this.streaminfo = ''; + var streams = this.connection.getLocalStreams(); + for (var i = 0; i < streams.length; i++) { + if (i == 0) { + this.streaminfo = JSON.stringify({ + streamid: streams[i].streamid || '', + isScreen: !!streams[i].isScreen, + isAudio: !!streams[i].isAudio, + isVideo: !!streams[i].isVideo, + preMuted: streams[i].preMuted || {} + }); + } else { + this.streaminfo += '----' + JSON.stringify({ + streamid: streams[i].streamid || '', + isScreen: !!streams[i].isScreen, + isAudio: !!streams[i].isAudio, + isVideo: !!streams[i].isVideo, + preMuted: streams[i].preMuted || {} + }); + } + } + }, + recreateOffer: function(renegotiate, callback) { + log('recreating offer'); + + this.type = 'offer'; + this.session = renegotiate; + + // todo: make sure this doesn't affect renegotiation scenarios + // this.setConstraints(); + + this.onSessionDescription = callback; + this.getStreamInfo(); + + // one can renegotiate data connection in existing audio/video/screen connection! + if (this.session.data) { + this.createDataChannel(); + } + + this.getLocalDescription('offer'); + }, + recreateAnswer: function(sdp, session, callback) { + // if(isFirefox) this.create(this.type, this); + + log('recreating answer'); + + this.type = 'answer'; + this.session = session; + + // todo: make sure this doesn't affect renegotiation scenarios + // this.setConstraints(); + + this.onSessionDescription = callback; + this.offerDescription = sdp; + this.getStreamInfo(); + + // one can renegotiate data connection in existing audio/video/screen connection! + if (this.session.data) { + this.createDataChannel(); + } + + this.getLocalDescription('answer'); + } + }; + } + + var FileSaver = { + SaveToDisk: invokeSaveAsDialog + }; + + + function invokeSaveAsDialog(fileUrl, fileName) { + /* + if (typeof navigator.msSaveOrOpenBlob !== 'undefined') { + return navigator.msSaveOrOpenBlob(file, fileFullName); + } else if (typeof navigator.msSaveBlob !== 'undefined') { + return navigator.msSaveBlob(file, fileFullName); + } + */ + + var hyperlink = document.createElement('a'); + hyperlink.href = fileUrl; + hyperlink.target = '_blank'; + hyperlink.download = fileName || fileUrl; + + if (!!navigator.mozGetUserMedia) { + hyperlink.onclick = function() { + (document.body || document.documentElement).removeChild(hyperlink); + }; + (document.body || document.documentElement).appendChild(hyperlink); + } + + var evt = new MouseEvent('click', { + view: window, + bubbles: true, + cancelable: true + }); + + hyperlink.dispatchEvent(evt); + + if (!navigator.mozGetUserMedia) { + URL.revokeObjectURL(hyperlink.href); + } + } + + var TextSender = { + send: function(config) { + var connection = config.connection; + + if (config.text instanceof ArrayBuffer || config.text instanceof DataView) { + return config.channel.send(config.text, config._channel); + } + + var channel = config.channel, + _channel = config._channel, + initialText = config.text, + packetSize = connection.chunkSize || 1000, + textToTransfer = '', + isobject = false; + + if (!isString(initialText)) { + isobject = true; + initialText = JSON.stringify(initialText); + } + + // uuid is used to uniquely identify sending instance + var uuid = getRandomString(); + var sendingTime = new Date().getTime(); + + sendText(initialText); + + function sendText(textMessage, text) { + var data = { + type: 'text', + uuid: uuid, + sendingTime: sendingTime + }; + + if (textMessage) { + text = textMessage; + data.packets = parseInt(text.length / packetSize); + } + + if (text.length > packetSize) + data.message = text.slice(0, packetSize); + else { + data.message = text; + data.last = true; + data.isobject = isobject; + } + + channel.send(data, _channel); + + textToTransfer = text.slice(data.message.length); + + if (textToTransfer.length) { + setTimeout(function() { + sendText(null, textToTransfer); + }, connection.chunkInterval || 100); + } + } + } + }; + + function TextReceiver(connection) { + var content = {}; + + function receive(data, userid, extra) { + // uuid is used to uniquely identify sending instance + var uuid = data.uuid; + if (!content[uuid]) content[uuid] = []; + + content[uuid].push(data.message); + if (data.last) { + var message = content[uuid].join(''); + if (data.isobject) message = JSON.parse(message); + + // latency detection + var receivingTime = new Date().getTime(); + var latency = receivingTime - data.sendingTime; + + var e = { + data: message, + userid: userid, + extra: extra, + latency: latency + }; + + if (message.preRecordedMediaChunk) { + if (!connection.preRecordedMedias[message.streamerid]) { + connection.shareMediaFile(null, null, message.streamerid); + } + connection.preRecordedMedias[message.streamerid].onData(message.chunk); + } else if (connection.autoTranslateText) { + e.original = e.data; + connection.Translator.TranslateText(e.data, function(translatedText) { + e.data = translatedText; + connection.onmessage(e); + }); + } else if (message.isPartOfScreen) { + connection.onpartofscreen(message); + } else connection.onmessage(e); + + delete content[uuid]; + } + } + + return { + receive: receive + }; + } + + // Last time updated at Sep 25, 2015, 08:32:23 + + // Latest file can be found here: https://cdn.webrtc-experiment.com/DetectRTC.js + + // Muaz Khan - www.MuazKhan.com + // MIT License - www.WebRTC-Experiment.com/licence + // Documentation - github.com/muaz-khan/DetectRTC + // ____________ + // DetectRTC.js + + // DetectRTC.hasWebcam (has webcam device!) + // DetectRTC.hasMicrophone (has microphone device!) + // DetectRTC.hasSpeakers (has speakers!) + + (function() { + + 'use strict'; + + var navigator = window.navigator; + + if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) { + // Firefox 38+ seems having support of enumerateDevices + // Thanks @xdumaine/enumerateDevices + navigator.enumerateDevices = function(callback) { + navigator.mediaDevices.enumerateDevices().then(callback); + }; + } + + if (typeof navigator !== 'undefined') { + if (typeof navigator.webkitGetUserMedia !== 'undefined') { + navigator.getUserMedia = navigator.webkitGetUserMedia; + } + + if (typeof navigator.mozGetUserMedia !== 'undefined') { + navigator.getUserMedia = navigator.mozGetUserMedia; + } + } else { + navigator = { + getUserMedia: function() {} + }; + } + + var isMobileDevice = !!navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i); + var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob); + + // this one can also be used: + // https://www.websocket.org/js/stuff.js (DetectBrowser.js) + + function getBrowserInfo() { + var nVer = navigator.appVersion; + var nAgt = navigator.userAgent; + var browserName = navigator.appName; + var fullVersion = '' + parseFloat(navigator.appVersion); + var majorVersion = parseInt(navigator.appVersion, 10); + var nameOffset, verOffset, ix; + + // In Opera, the true version is after 'Opera' or after 'Version' + if ((verOffset = nAgt.indexOf('Opera')) !== -1) { + browserName = 'Opera'; + fullVersion = nAgt.substring(verOffset + 6); + + if ((verOffset = nAgt.indexOf('Version')) !== -1) { + fullVersion = nAgt.substring(verOffset + 8); + } + } + // In MSIE, the true version is after 'MSIE' in userAgent + else if ((verOffset = nAgt.indexOf('MSIE')) !== -1) { + browserName = 'IE'; + fullVersion = nAgt.substring(verOffset + 5); + } + // In Chrome, the true version is after 'Chrome' + else if ((verOffset = nAgt.indexOf('Chrome')) !== -1) { + browserName = 'Chrome'; + fullVersion = nAgt.substring(verOffset + 7); + } + // In Safari, the true version is after 'Safari' or after 'Version' + else if ((verOffset = nAgt.indexOf('Safari')) !== -1) { + browserName = 'Safari'; + fullVersion = nAgt.substring(verOffset + 7); + + if ((verOffset = nAgt.indexOf('Version')) !== -1) { + fullVersion = nAgt.substring(verOffset + 8); + } + } + // In Firefox, the true version is after 'Firefox' + else if ((verOffset = nAgt.indexOf('Firefox')) !== -1) { + browserName = 'Firefox'; + fullVersion = nAgt.substring(verOffset + 8); + } + + // In most other browsers, 'name/version' is at the end of userAgent + else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) { + browserName = nAgt.substring(nameOffset, verOffset); + fullVersion = nAgt.substring(verOffset + 1); + + if (browserName.toLowerCase() === browserName.toUpperCase()) { + browserName = navigator.appName; + } + } + + if (isEdge) { + browserName = 'Edge'; + // fullVersion = navigator.userAgent.split('Edge/')[1]; + fullVersion = parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10); + } + + // trim the fullVersion string at semicolon/space if present + if ((ix = fullVersion.indexOf(';')) !== -1) { + fullVersion = fullVersion.substring(0, ix); + } + + if ((ix = fullVersion.indexOf(' ')) !== -1) { + fullVersion = fullVersion.substring(0, ix); + } + + majorVersion = parseInt('' + fullVersion, 10); + + if (isNaN(majorVersion)) { + fullVersion = '' + parseFloat(navigator.appVersion); + majorVersion = parseInt(navigator.appVersion, 10); + } + + return { + fullVersion: fullVersion, + version: majorVersion, + name: browserName + }; + } + + var isMobile = { + Android: function() { + return navigator.userAgent.match(/Android/i); + }, + BlackBerry: function() { + return navigator.userAgent.match(/BlackBerry/i); + }, + iOS: function() { + return navigator.userAgent.match(/iPhone|iPad|iPod/i); + }, + Opera: function() { + return navigator.userAgent.match(/Opera Mini/i); + }, + Windows: function() { + return navigator.userAgent.match(/IEMobile/i); + }, + any: function() { + return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows()); + }, + getOsName: function() { + var osName = 'Unknown OS'; + if (isMobile.Android()) { + osName = 'Android'; + } + + if (isMobile.BlackBerry()) { + osName = 'BlackBerry'; + } + + if (isMobile.iOS()) { + osName = 'iOS'; + } + + if (isMobile.Opera()) { + osName = 'Opera Mini'; + } + + if (isMobile.Windows()) { + osName = 'Windows'; + } + + return osName; + } + }; + + var osName = 'Unknown OS'; + + if (isMobile.any()) { + osName = isMobile.getOsName(); + } else { + if (navigator.appVersion.indexOf('Win') !== -1) { + osName = 'Windows'; + } + + if (navigator.appVersion.indexOf('Mac') !== -1) { + osName = 'MacOS'; + } + + if (navigator.appVersion.indexOf('X11') !== -1) { + osName = 'UNIX'; + } + + if (navigator.appVersion.indexOf('Linux') !== -1) { + osName = 'Linux'; + } + } + + + var isCanvasSupportsStreamCapturing = false; + var isVideoSupportsStreamCapturing = false; + ['captureStream', 'mozCaptureStream', 'webkitCaptureStream'].forEach(function(item) { + // asdf + if (item in document.createElement('canvas')) { + isCanvasSupportsStreamCapturing = true; + } + + if (item in document.createElement('video')) { + isVideoSupportsStreamCapturing = true; + } + }); + + // via: https://github.com/diafygi/webrtc-ips + function DetectLocalIPAddress(callback) { + getIPs(function(ip) { + //local IPs + if (ip.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/)) { + callback('Local: ' + ip); + } + + //assume the rest are public IPs + else { + callback('Public: ' + ip); + } + }); + } + + //get the IP addresses associated with an account + function getIPs(callback) { + var ipDuplicates = {}; + + //compatibility for firefox and chrome + var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; + var useWebKit = !!window.webkitRTCPeerConnection; + + // bypass naive webrtc blocking using an iframe + if (!RTCPeerConnection) { + var iframe = document.getElementById('iframe'); + if (!iframe) { + // + throw 'NOTE: you need to have an iframe in the page right above the script tag.'; + } + var win = iframe.contentWindow; + RTCPeerConnection = win.RTCPeerConnection || win.mozRTCPeerConnection || win.webkitRTCPeerConnection; + useWebKit = !!win.webkitRTCPeerConnection; + } + + //minimal requirements for data connection + var mediaConstraints = { + optional: [{ + RtpDataChannels: true + }] + }; + + //firefox already has a default stun server in about:config + // media.peerconnection.default_iceservers = + // [{"url": "stun:stun.services.mozilla.com"}] + var servers; + + //add same stun server for chrome + if (useWebKit) { + servers = { + iceServers: [{ + urls: 'stun:stun.services.mozilla.com' + }] + }; + + if (typeof DetectRTC !== 'undefined' && DetectRTC.browser.isFirefox && DetectRTC.browser.version <= 38) { + servers[0] = { + url: servers[0].urls + }; + } + } + + //construct a new RTCPeerConnection + var pc = new RTCPeerConnection(servers, mediaConstraints); + + function handleCandidate(candidate) { + //match just the IP address + var ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/; + var ipAddress = ipRegex.exec(candidate)[1]; + + //remove duplicates + if (ipDuplicates[ipAddress] === undefined) { + callback(ipAddress); + } + + ipDuplicates[ipAddress] = true; + } + + //listen for candidate events + pc.onicecandidate = function(ice) { + //skip non-candidate events + if (ice.candidate) { + handleCandidate(ice.candidate.candidate); + } + }; + + //create a bogus data channel + pc.createDataChannel(''); + + //create an offer sdp + pc.createOffer(function(result) { + + //trigger the stun server request + pc.setLocalDescription(result, function() {}, function() {}); + + }, function() {}); + + //wait for a while to let everything done + setTimeout(function() { + //read candidate info from local description + var lines = pc.localDescription.sdp.split('\n'); + + lines.forEach(function(line) { + if (line.indexOf('a=candidate:') === 0) { + handleCandidate(line); + } + }); + }, 1000); + } + + var MediaDevices = []; + + // ---------- Media Devices detection + var canEnumerate = false; + + /*global MediaStreamTrack:true */ + if (typeof MediaStreamTrack !== 'undefined' && 'getSources' in MediaStreamTrack) { + canEnumerate = true; + } else if (navigator.mediaDevices && !!navigator.mediaDevices.enumerateDevices) { + canEnumerate = true; + } + + var hasMicrophone = canEnumerate; + var hasSpeakers = canEnumerate; + var hasWebcam = canEnumerate; + + // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediadevices + // todo: switch to enumerateDevices when landed in canary. + function checkDeviceSupport(callback) { + // This method is useful only for Chrome! + + if (!navigator.enumerateDevices && window.MediaStreamTrack && window.MediaStreamTrack.getSources) { + navigator.enumerateDevices = window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack); + } + + if (!navigator.enumerateDevices && navigator.enumerateDevices) { + navigator.enumerateDevices = navigator.enumerateDevices.bind(navigator); + } + + if (!navigator.enumerateDevices) { + if (callback) { + callback(); + } + return; + } + + MediaDevices = []; + navigator.enumerateDevices(function(devices) { + devices.forEach(function(_device) { + var device = {}; + for (var d in _device) { + device[d] = _device[d]; + } + + var skip; + MediaDevices.forEach(function(d) { + if (d.id === device.id) { + skip = true; + } + }); + + if (skip) { + return; + } + + // if it is MediaStreamTrack.getSources + if (device.kind === 'audio') { + device.kind = 'audioinput'; + } + + if (device.kind === 'video') { + device.kind = 'videoinput'; + } + + if (!device.deviceId) { + device.deviceId = device.id; + } + + if (!device.id) { + device.id = device.deviceId; + } + + if (!device.label) { + device.label = 'Please invoke getUserMedia once.'; + if (!isHTTPs) { + device.label = 'HTTPs is required to get label of this ' + device.kind + ' device.'; + } + } + + if (device.kind === 'audioinput' || device.kind === 'audio') { + hasMicrophone = true; + } + + if (device.kind === 'audiooutput') { + hasSpeakers = true; + } + + if (device.kind === 'videoinput' || device.kind === 'video') { + hasWebcam = true; + } + + // there is no 'videoouput' in the spec. + + MediaDevices.push(device); + }); + + if (typeof DetectRTC !== 'undefined') { + DetectRTC.MediaDevices = MediaDevices; + DetectRTC.hasMicrophone = hasMicrophone; + DetectRTC.hasSpeakers = hasSpeakers; + DetectRTC.hasWebcam = hasWebcam; + } + + if (callback) { + callback(); + } + }); + } + + // check for microphone/camera support! + checkDeviceSupport(); + + var DetectRTC = {}; + + // ---------- + // DetectRTC.browser.name || DetectRTC.browser.version || DetectRTC.browser.fullVersion + DetectRTC.browser = getBrowserInfo(); + + // DetectRTC.isChrome || DetectRTC.isFirefox || DetectRTC.isEdge + DetectRTC.browser['is' + DetectRTC.browser.name] = true; + + var isHTTPs = location.protocol === 'https:'; + var isNodeWebkit = !!(window.process && (typeof window.process === 'object') && window.process.versions && window.process.versions['node-webkit']); + + // --------- Detect if system supports WebRTC 1.0 or WebRTC 1.1. + var isWebRTCSupported = false; + ['webkitRTCPeerConnection', 'mozRTCPeerConnection', 'RTCIceGatherer'].forEach(function(item) { + if (item in window) { + isWebRTCSupported = true; + } + }); + DetectRTC.isWebRTCSupported = isWebRTCSupported; + + //------- + DetectRTC.isORTCSupported = typeof RTCIceGatherer !== 'undefined'; + + // --------- Detect if system supports screen capturing API + var isScreenCapturingSupported = false; + if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 35) { + isScreenCapturingSupported = true; + } else if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 34) { + isScreenCapturingSupported = true; + } + + if (!isHTTPs) { + isScreenCapturingSupported = false; + } + DetectRTC.isScreenCapturingSupported = isScreenCapturingSupported; + + // --------- Detect if WebAudio API are supported + var webAudio = {}; + ['AudioContext', 'webkitAudioContext', 'mozAudioContext', 'msAudioContext'].forEach(function(item) { + if (webAudio.isSupported && webAudio.isCreateMediaStreamSourceSupported) { + return; + } + if (item in window) { + webAudio.isSupported = true; + + if ('createMediaStreamSource' in window[item].prototype) { + webAudio.isCreateMediaStreamSourceSupported = true; + } + } + }); + DetectRTC.isAudioContextSupported = webAudio.isSupported; + DetectRTC.isCreateMediaStreamSourceSupported = webAudio.isCreateMediaStreamSourceSupported; + + // ---------- Detect if SCTP/RTP channels are supported. + + var isRtpDataChannelsSupported = false; + if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 31) { + isRtpDataChannelsSupported = true; + } + DetectRTC.isRtpDataChannelsSupported = isRtpDataChannelsSupported; + + var isSCTPSupportd = false; + if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 28) { + isSCTPSupportd = true; + } else if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 25) { + isSCTPSupportd = true; + } else if (DetectRTC.browser.isOpera && DetectRTC.browser.version >= 11) { + isSCTPSupportd = true; + } + DetectRTC.isSctpDataChannelsSupported = isSCTPSupportd; + + // --------- + + DetectRTC.isMobileDevice = isMobileDevice; // "isMobileDevice" boolean is defined in "getBrowserInfo.js" + + // ------ + + DetectRTC.isWebSocketsSupported = 'WebSocket' in window && 2 === window.WebSocket.CLOSING; + DetectRTC.isWebSocketsBlocked = 'Checking'; + + if (DetectRTC.isWebSocketsSupported) { + /* CUSTOM CODE */ + var href = window.location.href; + var hostPatt = new RegExp(window.location.host +"/[^/]*"); + var res = hostPatt.exec(href); + var protocol = window.location.protocol.replace("http","ws"); + + var signalingServerPath = protocol + "//" + res + "/contact"; + var websocket = new WebSocket(signalingServerPath) + // var websocket = new WebSocket('wss://echo.websocket.org:443/'); + /* CUSTOM CODE */ + websocket.onopen = function() { + DetectRTC.isWebSocketsBlocked = false; + + if (DetectRTC.loadCallback) { + DetectRTC.loadCallback(); + } + }; + websocket.onerror = function() { + DetectRTC.isWebSocketsBlocked = true; + + if (DetectRTC.loadCallback) { + DetectRTC.loadCallback(); + } + }; + } + + // ------ + var isGetUserMediaSupported = false; + if (navigator.getUserMedia) { + isGetUserMediaSupported = true; + } else if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { + isGetUserMediaSupported = true; + } + if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 47 && !isHTTPs) { + DetectRTC.isGetUserMediaSupported = 'Requires HTTPs'; + } + DetectRTC.isGetUserMediaSupported = isGetUserMediaSupported; + + // ----------- + DetectRTC.osName = osName; // "osName" is defined in "detectOSName.js" + + // ---------- + DetectRTC.isCanvasSupportsStreamCapturing = isCanvasSupportsStreamCapturing; + DetectRTC.isVideoSupportsStreamCapturing = isVideoSupportsStreamCapturing; + + // ------ + DetectRTC.DetectLocalIPAddress = DetectLocalIPAddress; + + // ------- + DetectRTC.load = function(callback) { + this.loadCallback = callback; + + checkDeviceSupport(callback); + }; + + DetectRTC.MediaDevices = MediaDevices; + DetectRTC.hasMicrophone = hasMicrophone; + DetectRTC.hasSpeakers = hasSpeakers; + DetectRTC.hasWebcam = hasWebcam; + + // ------ + var isSetSinkIdSupported = false; + if ('setSinkId' in document.createElement('video')) { + isSetSinkIdSupported = true; + } + DetectRTC.isSetSinkIdSupported = isSetSinkIdSupported; + + // ----- + var isRTPSenderReplaceTracksSupported = false; + if (DetectRTC.browser.isFirefox /*&& DetectRTC.browser.version > 39*/ ) { + /*global mozRTCPeerConnection:true */ + if ('getSenders' in mozRTCPeerConnection.prototype) { + isRTPSenderReplaceTracksSupported = true; + } + } else if (DetectRTC.browser.isChrome) { + /*global webkitRTCPeerConnection:true */ + if ('getSenders' in webkitRTCPeerConnection.prototype) { + isRTPSenderReplaceTracksSupported = true; + } + } + DetectRTC.isRTPSenderReplaceTracksSupported = isRTPSenderReplaceTracksSupported; + + //------ + var isRemoteStreamProcessingSupported = false; + if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 38) { + isRemoteStreamProcessingSupported = true; + } + DetectRTC.isRemoteStreamProcessingSupported = isRemoteStreamProcessingSupported; + + //------- + var isApplyConstraintsSupported = false; + + /*global MediaStreamTrack:true */ + if (typeof MediaStreamTrack !== 'undefined' && 'applyConstraints' in MediaStreamTrack.prototype) { + isApplyConstraintsSupported = true; + } + DetectRTC.isApplyConstraintsSupported = isApplyConstraintsSupported; + + //------- + var isMultiMonitorScreenCapturingSupported = false; + if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 43) { + // version 43 merely supports platforms for multi-monitors + // version 44 will support exact multi-monitor selection i.e. you can select any monitor for screen capturing. + isMultiMonitorScreenCapturingSupported = true; + } + DetectRTC.isMultiMonitorScreenCapturingSupported = isMultiMonitorScreenCapturingSupported; + + window.DetectRTC = DetectRTC; + + })(); + + // DetectRTC extender + var screenCallback; + + DetectRTC.screen = { + chromeMediaSource: 'screen', + extensionid: ReservedExtensionID, + getSourceId: function(callback) { + if (!callback) throw '"callback" parameter is mandatory.'; + + // make sure that chrome extension is installed. + if (!!DetectRTC.screen.status) { + onstatus(DetectRTC.screen.status); + } else DetectRTC.screen.getChromeExtensionStatus(onstatus); + + function onstatus(status) { + if (status == 'installed-enabled') { + screenCallback = callback; + window.postMessage('get-sourceId', '*'); + return; + } + + DetectRTC.screen.chromeMediaSource = 'screen'; + callback('No-Response'); // chrome extension isn't available + } + }, + onMessageCallback: function(data) { + if (!(isString(data) || !!data.sourceId)) return; + + log('chrome message', data); + + // "cancel" button is clicked + if (data == 'PermissionDeniedError') { + DetectRTC.screen.chromeMediaSource = 'PermissionDeniedError'; + if (screenCallback) return screenCallback('PermissionDeniedError'); + else throw new Error('PermissionDeniedError'); + } + + // extension notified his presence + if (data == 'rtcmulticonnection-extension-loaded') { + DetectRTC.screen.chromeMediaSource = 'desktop'; + if (DetectRTC.screen.onScreenCapturingExtensionAvailable) { + DetectRTC.screen.onScreenCapturingExtensionAvailable(); + + // make sure that this event isn't fired multiple times + DetectRTC.screen.onScreenCapturingExtensionAvailable = null; + } + } + + // extension shared temp sourceId + if (data.sourceId) { + DetectRTC.screen.sourceId = data.sourceId; + if (screenCallback) screenCallback(DetectRTC.screen.sourceId); + } + }, + getChromeExtensionStatus: function(extensionid, callback) { + function _callback(status) { + DetectRTC.screen.status = status; + callback(status); + } + + if (isFirefox) return _callback('not-chrome'); + + if (arguments.length != 2) { + callback = extensionid; + extensionid = this.extensionid; + } + + var image = document.createElement('img'); + image.src = 'chrome-extension://' + extensionid + '/icon.png'; + image.onload = function() { + DetectRTC.screen.chromeMediaSource = 'screen'; + window.postMessage('are-you-there', '*'); + setTimeout(function() { + if (DetectRTC.screen.chromeMediaSource == 'screen') { + _callback( + DetectRTC.screen.chromeMediaSource == 'desktop' ? 'installed-enabled' : 'installed-disabled' /* if chrome extension isn't permitted for current domain, then it will be installed-disabled all the time even if extension is enabled. */ + ); + } else _callback('installed-enabled'); + }, 2000); + }; + image.onerror = function() { + _callback('not-installed'); + }; + } + }; + + // if IE + if (!window.addEventListener) { + window.addEventListener = function(el, eventName, eventHandler) { + if (!el.attachEvent) return; + el.attachEvent('on' + eventName, eventHandler); + }; + } + + function listenEventHandler(eventName, eventHandler) { + window.removeEventListener(eventName, eventHandler); + window.addEventListener(eventName, eventHandler, false); + } + + window.addEventListener('message', function(event) { + if (event.origin != window.location.origin) { + return; + } + + DetectRTC.screen.onMessageCallback(event.data); + }); + + function setDefaults(connection) { + var DetectRTC = window.DetectRTC || {}; + + // www.RTCMultiConnection.org/docs/userid/ + connection.userid = getRandomString(); + + // www.RTCMultiConnection.org/docs/session/ + connection.session = { + audio: true, + video: true + }; + + // www.RTCMultiConnection.org/docs/maxParticipantsAllowed/ + connection.maxParticipantsAllowed = 256; + + // www.RTCMultiConnection.org/docs/direction/ + // 'many-to-many' / 'one-to-many' / 'one-to-one' / 'one-way' + connection.direction = 'many-to-many'; + + // www.RTCMultiConnection.org/docs/mediaConstraints/ + connection.mediaConstraints = { + mandatory: {}, // kept for backward compatibility + optional: [], // kept for backward compatibility + audio: { + mandatory: {}, + optional: [] + }, + video: { + mandatory: {}, + optional: [] + } + }; + + // www.RTCMultiConnection.org/docs/candidates/ + connection.candidates = { + host: true, + stun: true, + turn: true + }; + + connection.sdpConstraints = {}; + + // as @serhanters proposed in #225 + // it will auto fix "all" renegotiation scenarios + connection.sdpConstraints.mandatory = { + OfferToReceiveAudio: true, + OfferToReceiveVideo: true + }; + + connection.privileges = { + canStopRemoteStream: false, // user can stop remote streams + canMuteRemoteStream: false // user can mute remote streams + }; + + connection.iceProtocols = { + tcp: true, + udp: true + }; + + // www.RTCMultiConnection.org/docs/preferSCTP/ + connection.preferSCTP = isFirefox || chromeVersion >= 32 ? true : false; + connection.chunkInterval = isFirefox || chromeVersion >= 32 ? 100 : 500; // 500ms for RTP and 100ms for SCTP + connection.chunkSize = isFirefox || chromeVersion >= 32 ? 13 * 1000 : 1000; // 1000 chars for RTP and 13000 chars for SCTP + + // www.RTCMultiConnection.org/docs/fakeDataChannels/ + connection.fakeDataChannels = false; + + connection.waitUntilRemoteStreamStartsFlowing = null; // NULL == true + + // auto leave on page unload + connection.leaveOnPageUnload = true; + + // get ICE-servers from XirSys + connection.getExternalIceServers = isChrome; + + // www.RTCMultiConnection.org/docs/UA/ + connection.UA = { + isFirefox: isFirefox, + isChrome: isChrome, + isMobileDevice: isMobileDevice, + version: isChrome ? chromeVersion : firefoxVersion, + isNodeWebkit: isNodeWebkit, + isSafari: isSafari, + isIE: isIE, + isOpera: isOpera + }; + + // file queue: to store previous file objects in memory; + // and stream over newly connected peers + // www.RTCMultiConnection.org/docs/fileQueue/ + connection.fileQueue = {}; + + // this array is aimed to store all renegotiated streams' session-types + connection.renegotiatedSessions = {}; + + // www.RTCMultiConnection.org/docs/channels/ + connection.channels = {}; + + // www.RTCMultiConnection.org/docs/extra/ + connection.extra = {}; + + // www.RTCMultiConnection.org/docs/bandwidth/ + connection.bandwidth = { + screen: 300 // 300kbps (dirty workaround) + }; + + // www.RTCMultiConnection.org/docs/caniuse/ + connection.caniuse = { + RTCPeerConnection: DetectRTC.isWebRTCSupported, + getUserMedia: !!navigator.webkitGetUserMedia || !!navigator.mozGetUserMedia, + AudioContext: DetectRTC.isAudioContextSupported, + + // there is no way to check whether "getUserMedia" flag is enabled or not! + ScreenSharing: DetectRTC.isScreenCapturingSupported, + RtpDataChannels: DetectRTC.isRtpDataChannelsSupported, + SctpDataChannels: DetectRTC.isSctpDataChannelsSupported + }; + + // www.RTCMultiConnection.org/docs/snapshots/ + connection.snapshots = {}; + + // www.WebRTC-Experiment.com/demos/MediaStreamTrack.getSources.html + connection._mediaSources = {}; + + // www.RTCMultiConnection.org/docs/devices/ + connection.devices = {}; + + // www.RTCMultiConnection.org/docs/language/ (to see list of all supported languages) + connection.language = 'en'; + + // www.RTCMultiConnection.org/docs/autoTranslateText/ + connection.autoTranslateText = false; + + // please use your own Google Translate API key + // Google Translate is a paid service. + connection.googKey = 'AIzaSyCgB5hmFY74WYB-EoWkhr9cAGr6TiTHrEE'; + + connection.localStreamids = []; + connection.localStreams = {}; + + // this object stores pre-recorded media streaming uids + // multiple pre-recorded media files can be streamed concurrently. + connection.preRecordedMedias = {}; + + // www.RTCMultiConnection.org/docs/attachStreams/ + connection.attachStreams = []; + + // www.RTCMultiConnection.org/docs/detachStreams/ + connection.detachStreams = []; + + connection.optionalArgument = { + optional: [{ + DtlsSrtpKeyAgreement: true + }, { + googImprovedWifiBwe: true + }, { + googScreencastMinBitrate: 300 + }], + mandatory: {} + }; + + connection.dataChannelDict = {}; + + // www.RTCMultiConnection.org/docs/dontAttachStream/ + connection.dontAttachStream = false; + + // www.RTCMultiConnection.org/docs/dontCaptureUserMedia/ + connection.dontCaptureUserMedia = false; + + // this feature added to keep users privacy and + // make sure HTTPs pages NEVER auto capture users media + // isChrome && location.protocol == 'https:' + connection.preventSSLAutoAllowed = false; + + connection.autoReDialOnFailure = true; + connection.isInitiator = false; + + // access DetectRTC.js features directly! + connection.DetectRTC = DetectRTC; + + // you can falsify it to merge all ICE in SDP and share only SDP! + // such mechanism is useful for SIP/XMPP and XMLHttpRequest signaling + // bug: renegotiation fails if "trickleIce" is false + connection.trickleIce = true; + + // this object stores list of all sessions in current channel + connection.sessionDescriptions = {}; + + // this object stores current user's session-description + // it is set only for initiator + // it is set as soon as "open" method is invoked. + connection.sessionDescription = null; + + // resources used in RTCMultiConnection + connection.resources = { + // CUSTOM CODE // + /* Commenting this block as we do not wasnt external dependencies + * + RecordRTC: 'https://cdn.webrtc-experiment.com/RecordRTC.js', + PreRecordedMediaStreamer: 'https://cdn.webrtc-experiment.com/PreRecordedMediaStreamer.js', + customGetUserMediaBar: 'https://cdn.webrtc-experiment.com/navigator.customGetUserMediaBar.js', + html2canvas: 'https://cdn.webrtc-experiment.com/screenshot.js', + hark: 'https://cdn.webrtc-experiment.com/hark.js', + firebase: 'https://cdn.webrtc-experiment.com/firebase.js', + firebaseio: 'https://webrtc-signaling.firebaseio.com/', + + muted: 'static/fusion/images/ATT_Labs_Logo.png', + + getConnectionStats: 'https://cdn.webrtc-experiment.com/getConnectionStats.js', + FileBufferReader: 'https://cdn.webrtc-experiment.com/FileBufferReader.js' + */ + + // CUSTOM CODE // + + + }; + + // www.RTCMultiConnection.org/docs/body/ + connection.body = document.body || document.documentElement; + connection.screenbody = null;// document.body || document.documentElement; + connection.videobody = null;//document.body || document.documentElement; + + // www.RTCMultiConnection.org/docs/peers/ + connection.peers = {}; + + // www.RTCMultiConnection.org/docs/firebase/ + connection.firebase = 'chat'; + + connection.numberOfSessions = 0; + connection.numberOfConnectedUsers = 0; + + // by default, data-connections will always be getting + // FileBufferReader.js if absent. + connection.enableFileSharing = true; + + // www.RTCMultiConnection.org/docs/autoSaveToDisk/ + // to make sure file-saver dialog is not invoked. + connection.autoSaveToDisk = false; + + connection.processSdp = function(sdp) { + // process sdp here + return sdp; + }; + + // www.RTCMultiConnection.org/docs/onmessage/ + connection.onmessage = function(e) { + log('onmessage', toStr(e)); + }; + + // www.RTCMultiConnection.org/docs/onopen/ + connection.onopen = function(e) { + log('Data connection is opened between you and', e.userid); + }; + + // www.RTCMultiConnection.org/docs/onerror/ + connection.onerror = function(e) { + error(onerror, toStr(e)); + }; + + // www.RTCMultiConnection.org/docs/onclose/ + connection.onclose = function(e) { + warn('onclose', toStr(e)); + + // todo: should we use "stop" or "remove"? + // BTW, it is remote user! + connection.streams.remove({ + userid: e.userid + }); + }; + + var progressHelper = {}; + + // www.RTCMultiConnection.org/docs/onFileStart/ + connection.onFileStart = function(file) { + var div = document.createElement('div'); + div.title = file.name; + div.innerHTML = ' '; + connection.body.insertBefore(div, connection.body.firstChild); + progressHelper[file.uuid] = { + div: div, + progress: div.querySelector('progress'), + label: div.querySelector('label') + }; + progressHelper[file.uuid].progress.max = file.maxChunks; + }; + + // www.RTCMultiConnection.org/docs/onFileProgress/ + connection.onFileProgress = function(chunk) { + var helper = progressHelper[chunk.uuid]; + if (!helper) return; + helper.progress.value = chunk.currentPosition || chunk.maxChunks || helper.progress.max; + updateLabel(helper.progress, helper.label); + }; + + // www.RTCMultiConnection.org/docs/onFileEnd/ + connection.onFileEnd = function(file) { + if (progressHelper[file.uuid]) progressHelper[file.uuid].div.innerHTML = '' + file.name + ''; + + // for backward compatibility + if (connection.onFileSent || connection.onFileReceived) { + if (connection.onFileSent) connection.onFileSent(file, file.uuid); + if (connection.onFileReceived) connection.onFileReceived(file.name, file); + } + }; + + function updateLabel(progress, label) { + if (progress.position == -1) return; + var position = +progress.position.toFixed(2).split('.')[1] || 100; + label.innerHTML = position + '%'; + } + + // www.RTCMultiConnection.org/docs/onstream/ + connection.onstream = function(e) { + // CUSTOM CODE // + + if(e.isVideo || e.isAudio) + { + var videoTag = e.mediaElement; + var videoType = e.type; + var parentDiv = connection.videobody; + + if(videoType == "local") + { + videoTag.style.top = "auto"; + videoTag.style.position = "absolute"; + //videoTag.style.left = (parentDiv.offsetWidth - 160) + "px"; + videoTag.style.height = "150px"; + videoTag.style.width = "150px"; + videoTag.style.zIndex = 1; + + } + else if(videoType == "remote") + { + videoTag.style.top = "auto"; + videoTag.style.position = "absolute"; + videoTag.style.zIndex = -1; + } + + parentDiv.appendChild(videoTag); + } + else if(e.isScreen) + { + var screenTag = e.mediaElement; + var screenType = e.type; + var parentDiv = connection.screenbody; + + if(screenType == "local") + { + // no need to display this because the person sharing his/her screen doesn't have to see whats being shared + // enabled for demo purposes + parentDiv.appendChild(screenTag); + } + else if(screenType == "remote") + { + parentDiv.appendChild(screenTag); + } + + + } + + else + connection.body.insertBefore(e.mediaElement, connection.body.firstChild); + + // CUSTOM CODE // + }; + + // www.RTCMultiConnection.org/docs/onStreamEndedHandler/ + connection.onstreamended = function(e) { + log('onStreamEndedHandler:', e); + + if (!e.mediaElement) { + return warn('Event.mediaElement is undefined', e); + } + if (!e.mediaElement.parentNode) { + e.mediaElement = document.getElementById(e.streamid); + + if (!e.mediaElement) { + return warn('Event.mediaElement is undefined', e); + } + + if (!e.mediaElement.parentNode) { + return warn('Event.mediElement.parentNode is null.', e); + } + } + + e.mediaElement.parentNode.removeChild(e.mediaElement); + }; + + // todo: need to write documentation link + connection.onSessionClosed = function(session) { + if (session.isEjected) { + warn(session.userid, 'ejected you.'); + } else warn('Session has been closed.', session); + }; + + // www.RTCMultiConnection.org/docs/onmute/ + connection.onmute = function(e) { + if (e.isVideo && e.mediaElement) { + e.mediaElement.pause(); + e.mediaElement.setAttribute('poster', e.snapshot || connection.resources.muted); + } + if (e.isAudio && e.mediaElement) { + e.mediaElement.muted = true; + } + }; + + // www.RTCMultiConnection.org/docs/onunmute/ + connection.onunmute = function(e) { + if (e.isVideo && e.mediaElement) { + e.mediaElement.play(); + e.mediaElement.removeAttribute('poster'); + } + if (e.isAudio && e.mediaElement) { + e.mediaElement.muted = false; + } + }; + + // www.RTCMultiConnection.org/docs/onleave/ + connection.onleave = function(e) { + log('onleave', toStr(e)); + }; + + connection.token = getRandomString; + + connection.peers[connection.userid] = { + drop: function() { + connection.drop(); + }, + renegotiate: function() {}, + addStream: function() {}, + hold: function() {}, + unhold: function() {}, + changeBandwidth: function() {}, + sharePartOfScreen: function() {} + }; + + connection._skip = ['stop', 'mute', 'unmute', '_private', '_selectStreams', 'selectFirst', 'selectAll', 'remove']; + + // www.RTCMultiConnection.org/docs/streams/ + connection.streams = { + mute: function(session) { + this._private(session, true); + }, + unmute: function(session) { + this._private(session, false); + }, + _private: function(session, enabled) { + if (session && !isString(session)) { + for (var stream in this) { + if (connection._skip.indexOf(stream) == -1) { + _muteOrUnMute(this[stream], session, enabled); + } + } + + function _muteOrUnMute(stream, session, isMute) { + if (session.local && stream.type != 'local') return; + if (session.remote && stream.type != 'remote') return; + + if (session.isScreen && !stream.isScreen) return; + if (session.isAudio && !stream.isAudio) return; + if (session.isVideo && !stream.isVideo) return; + + if (isMute) stream.mute(session); + else stream.unmute(session); + } + return; + } + + // implementation from #68 + for (var stream in this) { + if (connection._skip.indexOf(stream) == -1) { + this[stream]._private(session, enabled); + } + } + }, + stop: function(type) { + var _stream; + for (var stream in this) { + if (connection._skip.indexOf(stream) == -1) { + _stream = this[stream]; + + if (!type) _stream.stop(); + + else if (isString(type)) { + // connection.streams.stop('screen'); + var config = {}; + config[type] = true; + _stopStream(_stream, config); + } else _stopStream(_stream, type); + } + } + + function _stopStream(_stream, config) { + // connection.streams.stop({ remote: true, userid: 'remote-userid' }); + if (config.userid && _stream.userid != config.userid) return; + + if (config.local && _stream.type != 'local') return; + if (config.remote && _stream.type != 'remote') return; + + if (config.screen && !!_stream.isScreen) { + _stream.stop(); + } + + if (config.audio && !!_stream.isAudio) { + _stream.stop(); + } + + if (config.video && !!_stream.isVideo) { + _stream.stop(); + } + + // connection.streams.stop('local'); + if (!config.audio && !config.video && !config.screen) { + _stream.stop(); + } + } + }, + remove: function(type) { + var _stream; + for (var stream in this) { + if (connection._skip.indexOf(stream) == -1) { + _stream = this[stream]; + + if (!type) _stopAndRemoveStream(_stream, { + local: true, + remote: true + }); + + else if (isString(type)) { + // connection.streams.stop('screen'); + var config = {}; + config[type] = true; + _stopAndRemoveStream(_stream, config); + } else _stopAndRemoveStream(_stream, type); + } + } + + function _stopAndRemoveStream(_stream, config) { + // connection.streams.remove({ remote: true, userid: 'remote-userid' }); + if (config.userid && _stream.userid != config.userid) return; + + if (config.local && _stream.type != 'local') return; + if (config.remote && _stream.type != 'remote') return; + + if (config.screen && !!_stream.isScreen) { + endStream(_stream); + } + + if (config.audio && !!_stream.isAudio) { + endStream(_stream); + } + + if (config.video && !!_stream.isVideo) { + endStream(_stream); + } + + // connection.streams.remove('local'); + if (!config.audio && !config.video && !config.screen) { + endStream(_stream); + } + } + + function endStream(_stream) { + onStreamEndedHandler(_stream, connection); + delete connection.streams[_stream.streamid]; + } + }, + selectFirst: function(args) { + return this._selectStreams(args, false); + }, + selectAll: function(args) { + return this._selectStreams(args, true); + }, + _selectStreams: function(args, all) { + if (!args || isString(args) || isEmpty(args)) throw 'Invalid arguments.'; + + // if userid is used then both local/remote shouldn't be auto-set + if (isNull(args.local) && isNull(args.remote) && isNull(args.userid)) { + args.local = args.remote = true; + } + + if (!args.isAudio && !args.isVideo && !args.isScreen) { + args.isAudio = args.isVideo = args.isScreen = true; + } + + var selectedStreams = []; + for (var stream in this) { + if (connection._skip.indexOf(stream) == -1 && (stream = this[stream]) && ((args.local && stream.type == 'local') || (args.remote && stream.type == 'remote') || (args.userid && stream.userid == args.userid))) { + if (args.isVideo && stream.isVideo) { + selectedStreams.push(stream); + } + + if (args.isAudio && stream.isAudio) { + selectedStreams.push(stream); + } + + if (args.isScreen && stream.isScreen) { + selectedStreams.push(stream); + } + } + } + + return !!all ? selectedStreams : selectedStreams[0]; + } + }; + + var iceServers = []; + + // CUSTOM CODE // + // these servers are provided by research + iceServers.push({ + url: '' /*TODO To test this WebRTC with some open stun and turn test servers*/ + }); + + iceServers.push({ + url: 'turn:207.140.168.120:3478', + credential: 'xxx', + username: 'xxx' + }); + + iceServers.push({ + url: 'turn:207.140.168.120:443?transport=tcp', + credential: 'harmfulmustard', + username: 'ambient' + }); + + /* CHANGED: Fusion: These are non-att servers for testing purposes + + iceServers.push({ + url: 'stun:stun.l.google.com:19302' + }); + + iceServers.push({ + url: 'stun:stun.anyfirewall.com:3478' + }); + + iceServers.push({ + url: 'turn:turn.bistri.com:80', + credential: 'homeo', + username: 'homeo' + }); + + iceServers.push({ + url: 'turn:turn.anyfirewall.com:443?transport=tcp', + credential: 'webrtc', + username: 'webrtc' + }); + + */ + // CUSTOM CODE // + connection.iceServers = iceServers; + + connection.rtcConfiguration = { + iceServers: null, + iceTransports: 'all', // none || relay || all - ref: http://goo.gl/40I39K + peerIdentity: false + }; + + // www.RTCMultiConnection.org/docs/media/ + connection.media = { + min: function(width, height) { + if (!connection.mediaConstraints.video) return; + + if (!connection.mediaConstraints.video.mandatory) { + connection.mediaConstraints.video.mandatory = {}; + } + connection.mediaConstraints.video.mandatory.minWidth = width; + connection.mediaConstraints.video.mandatory.minHeight = height; + }, + max: function(width, height) { + if (!connection.mediaConstraints.video) return; + + if (!connection.mediaConstraints.video.mandatory) { + connection.mediaConstraints.video.mandatory = {}; + } + + connection.mediaConstraints.video.mandatory.maxWidth = width; + connection.mediaConstraints.video.mandatory.maxHeight = height; + } + }; + + connection._getStream = function(event) { + var resultingObject = merge({ + sockets: event.socket ? [event.socket] : [] + }, event); + + resultingObject.stop = function() { + var self = this; + + self.sockets.forEach(function(socket) { + if (self.type == 'local') { + socket.send({ + streamid: self.streamid, + stopped: true + }); + } + + if (self.type == 'remote') { + socket.send({ + promptStreamStop: true, + streamid: self.streamid + }); + } + }); + + if (self.type == 'remote') return; + + var stream = self.stream; + if (stream) self.rtcMultiConnection.stopMediaStream(stream); + }; + + resultingObject.mute = function(session) { + this.muted = true; + this._private(session, true); + }; + + resultingObject.unmute = function(session) { + this.muted = false; + this._private(session, false); + }; + + function muteOrUnmuteLocally(session, isPause, mediaElement) { + if (!mediaElement) return; + var lastPauseState = mediaElement.onpause; + var lastPlayState = mediaElement.onplay; + mediaElement.onpause = mediaElement.onplay = function() {}; + + if (isPause) mediaElement.pause(); + else mediaElement.play(); + + mediaElement.onpause = lastPauseState; + mediaElement.onplay = lastPlayState; + } + + resultingObject._private = function(session, enabled) { + if (session && !isNull(session.sync) && session.sync == false) { + muteOrUnmuteLocally(session, enabled, this.mediaElement); + return; + } + + muteOrUnmute({ + root: this, + session: session, + enabled: enabled, + stream: this.stream + }); + }; + + resultingObject.startRecording = function(session) { + var self = this; + + if (!session) { + session = { + audio: true, + video: true + }; + } + + if (isString(session)) { + session = { + audio: session == 'audio', + video: session == 'video' + }; + } + + if (!window.RecordRTC) { + return loadScript(self.rtcMultiConnection.resources.RecordRTC, function() { + self.startRecording(session); + }); + } + + log('started recording session', session); + + self.videoRecorder = self.audioRecorder = null; + + if (isFirefox) { + // firefox supports both audio/video recording in single webm file + if (session.video) { + self.videoRecorder = RecordRTC(self.stream, { + type: 'video' + }); + } else if (session.audio) { + self.audioRecorder = RecordRTC(self.stream, { + type: 'audio' + }); + } + } else if (isChrome) { + // chrome supports recording in two separate files: WAV and WebM + if (session.video) { + self.videoRecorder = RecordRTC(self.stream, { + type: 'video' + }); + } + + if (session.audio) { + self.audioRecorder = RecordRTC(self.stream, { + type: 'audio' + }); + } + } + + if (self.audioRecorder) { + self.audioRecorder.startRecording(); + } + + if (self.videoRecorder) self.videoRecorder.startRecording(); + }; + + resultingObject.stopRecording = function(callback, session) { + if (!session) { + session = { + audio: true, + video: true + }; + } + + if (isString(session)) { + session = { + audio: session == 'audio', + video: session == 'video' + }; + } + + log('stopped recording session', session); + + var self = this; + + if (session.audio && self.audioRecorder) { + self.audioRecorder.stopRecording(function() { + if (session.video && self.videoRecorder) { + self.videoRecorder.stopRecording(function() { + callback({ + audio: self.audioRecorder.getBlob(), + video: self.videoRecorder.getBlob() + }); + }); + } else callback({ + audio: self.audioRecorder.getBlob() + }); + }); + } else if (session.video && self.videoRecorder) { + self.videoRecorder.stopRecording(function() { + callback({ + video: self.videoRecorder.getBlob() + }); + }); + } + }; + + resultingObject.takeSnapshot = function(callback) { + takeSnapshot({ + mediaElement: this.mediaElement, + userid: this.userid, + connection: connection, + callback: callback + }); + }; + + // redundant: kept only for backward compatibility + resultingObject.streamObject = resultingObject; + + return resultingObject; + }; + + // new RTCMultiConnection().set({properties}).connect() + connection.set = function(properties) { + for (var property in properties) { + this[property] = properties[property]; + } + return this; + }; + + // www.RTCMultiConnection.org/docs/onMediaError/ + connection.onMediaError = function(event) { + error('name', event.name); + error('constraintName', toStr(event.constraintName)); + error('message', event.message); + error('original session', event.session); + }; + + // www.RTCMultiConnection.org/docs/takeSnapshot/ + connection.takeSnapshot = function(userid, callback) { + takeSnapshot({ + userid: userid, + connection: connection, + callback: callback + }); + }; + + connection.saveToDisk = function(blob, fileName) { + if (blob.size && blob.type) FileSaver.SaveToDisk(URL.createObjectURL(blob), fileName || blob.name || blob.type.replace('/', '-') + blob.type.split('/')[1]); + else FileSaver.SaveToDisk(blob, fileName); + }; + + // www.RTCMultiConnection.org/docs/selectDevices/ + connection.selectDevices = function(device1, device2) { + if (device1) select(this.devices[device1]); + if (device2) select(this.devices[device2]); + + function select(device) { + if (!device) return; + connection._mediaSources[device.kind] = device.id; + } + }; + + // www.RTCMultiConnection.org/docs/getDevices/ + connection.getDevices = function(callback) { + // if, not yet fetched. + if (!DetectRTC.MediaDevices.length) { + return setTimeout(function() { + connection.getDevices(callback); + }, 1000); + } + + // loop over all audio/video input/output devices + DetectRTC.MediaDevices.forEach(function(device) { + connection.devices[device.deviceId] = device; + }); + + if (callback) callback(connection.devices); + }; + + connection.getMediaDevices = connection.enumerateDevices = function(callback) { + if (!callback) throw 'callback is mandatory.'; + connection.getDevices(function() { + callback(connection.DetectRTC.MediaDevices); + }); + }; + + // www.RTCMultiConnection.org/docs/onCustomMessage/ + connection.onCustomMessage = function(message) { + log('Custom message', message); + }; + + // www.RTCMultiConnection.org/docs/ondrop/ + connection.ondrop = function(droppedBy) { + log('Media connection is dropped by ' + droppedBy); + }; + + // www.RTCMultiConnection.org/docs/drop/ + connection.drop = function(config) { + config = config || {}; + connection.attachStreams = []; + + // "drop" should detach all local streams + for (var stream in connection.streams) { + if (connection._skip.indexOf(stream) == -1) { + stream = connection.streams[stream]; + if (stream.type == 'local') { + connection.detachStreams.push(stream.streamid); + onStreamEndedHandler(stream, connection); + } else onStreamEndedHandler(stream, connection); + } + } + + // www.RTCMultiConnection.org/docs/sendCustomMessage/ + connection.sendCustomMessage({ + drop: true, + dontRenegotiate: isNull(config.renegotiate) ? true : config.renegotiate + }); + }; + + // www.RTCMultiConnection.org/docs/Translator/ + connection.Translator = { + TranslateText: function(text, callback) { + // if(location.protocol === 'https:') return callback(text); + + var newScript = document.createElement('script'); + newScript.type = 'text/javascript'; + + var sourceText = encodeURIComponent(text); // escape + + var randomNumber = 'method' + connection.token(); + window[randomNumber] = function(response) { + if (response.data && response.data.translations[0] && callback) { + callback(response.data.translations[0].translatedText); + } + + if (response.error && response.error.message == 'Daily Limit Exceeded') { + warn('Text translation failed. Error message: "Daily Limit Exceeded."'); + + // returning original text + callback(text); + } + }; + + var source = 'https://www.googleapis.com/language/translate/v2?key=' + connection.googKey + '&target=' + (connection.language || 'en-US') + '&callback=window.' + randomNumber + '&q=' + sourceText; + newScript.src = source; + document.getElementsByTagName('head')[0].appendChild(newScript); + } + }; + + // you can easily override it by setting it NULL! + connection.setDefaultEventsForMediaElement = function(mediaElement, streamid) { + mediaElement.onpause = function() { + if (connection.streams[streamid] && !connection.streams[streamid].muted) { + connection.streams[streamid].mute(); + } + }; + + // todo: need to make sure that "onplay" EVENT doesn't play self-voice! + mediaElement.onplay = function() { + if (connection.streams[streamid] && connection.streams[streamid].muted) { + connection.streams[streamid].unmute(); + } + }; + + var volumeChangeEventFired = false; + mediaElement.onvolumechange = function() { + if (!volumeChangeEventFired) { + volumeChangeEventFired = true; + connection.streams[streamid] && setTimeout(function() { + var root = connection.streams[streamid]; + connection.streams[streamid].sockets.forEach(function(socket) { + socket.send({ + streamid: root.streamid, + isVolumeChanged: true, + volume: mediaElement.volume + }); + }); + volumeChangeEventFired = false; + }, 2000); + } + }; + }; + + // www.RTCMultiConnection.org/docs/onMediaFile/ + connection.onMediaFile = function(e) { + log('onMediaFile', e); + connection.body.appendChild(e.mediaElement); + }; + + // www.RTCMultiConnection.org/docs/shareMediaFile/ + // this method handles pre-recorded media streaming + connection.shareMediaFile = function(file, video, streamerid) { + streamerid = streamerid || connection.token(); + + if (!PreRecordedMediaStreamer) { + loadScript(connection.resources.PreRecordedMediaStreamer, function() { + connection.shareMediaFile(file, video, streamerid); + }); + return streamerid; + } + + return PreRecordedMediaStreamer.shareMediaFile({ + file: file, + video: video, + streamerid: streamerid, + connection: connection + }); + }; + + // www.RTCMultiConnection.org/docs/onpartofscreen/ + connection.onpartofscreen = function(e) { + var image = document.createElement('img'); + image.src = e.screenshot; + connection.body.appendChild(image); + }; + + connection.skipLogs = function() { + log = error = warn = function() {}; + }; + + // www.RTCMultiConnection.org/docs/hold/ + connection.hold = function(mLine) { + for (var peer in connection.peers) { + connection.peers[peer].hold(mLine); + } + }; + + // www.RTCMultiConnection.org/docs/onhold/ + connection.onhold = function(track) { + log('onhold', track); + + if (track.kind != 'audio') { + track.mediaElement.pause(); + track.mediaElement.setAttribute('poster', track.screenshot || connection.resources.muted); + } + if (track.kind == 'audio') { + track.mediaElement.muted = true; + } + }; + + // www.RTCMultiConnection.org/docs/unhold/ + connection.unhold = function(mLine) { + for (var peer in connection.peers) { + connection.peers[peer].unhold(mLine); + } + }; + + // www.RTCMultiConnection.org/docs/onunhold/ + connection.onunhold = function(track) { + log('onunhold', track); + + if (track.kind != 'audio') { + track.mediaElement.play(); + track.mediaElement.removeAttribute('poster'); + } + if (track.kind != 'audio') { + track.mediaElement.muted = false; + } + }; + + connection.sharePartOfScreen = function(args) { + var lastScreenshot = ''; + + function partOfScreenCapturer() { + // if stopped + if (connection.partOfScreen && !connection.partOfScreen.sharing) { + return; + } + + capturePartOfScreen({ + element: args.element, + connection: connection, + callback: function(screenshot) { + // don't share repeated content + if (screenshot != lastScreenshot) { + lastScreenshot = screenshot; + + for (var channel in connection.channels) { + connection.channels[channel].send({ + screenshot: screenshot, + isPartOfScreen: true + }); + } + } + + // "once" can be used to share single screenshot + !args.once && setTimeout(partOfScreenCapturer, args.interval || 200); + } + }); + } + + partOfScreenCapturer(); + + connection.partOfScreen = merge({ + sharing: true + }, args); + }; + + connection.pausePartOfScreenSharing = function() { + for (var peer in connection.peers) { + connection.peers[peer].pausePartOfScreenSharing = true; + } + + if (connection.partOfScreen) { + connection.partOfScreen.sharing = false; + } + }; + + connection.resumePartOfScreenSharing = function() { + for (var peer in connection.peers) { + connection.peers[peer].pausePartOfScreenSharing = false; + } + + if (connection.partOfScreen) { + connection.partOfScreen.sharing = true; + } + }; + + connection.stopPartOfScreenSharing = function() { + for (var peer in connection.peers) { + connection.peers[peer].stopPartOfScreenSharing = true; + } + + if (connection.partOfScreen) { + connection.partOfScreen.sharing = false; + } + }; + + connection.takeScreenshot = function(element, callback) { + if (!element || !callback) throw 'Invalid number of arguments.'; + + if (!window.html2canvas) { + return loadScript(connection.resources.html2canvas, function() { + connection.takeScreenshot(element); + }); + } + + if (isString(element)) { + element = document.querySelector(element); + if (!element) element = document.getElementById(element); + } + if (!element) throw 'HTML Element is inaccessible!'; + + // html2canvas.js is used to take screenshots + html2canvas(element, { + onrendered: function(canvas) { + callback(canvas.toDataURL()); + } + }); + }; + + // this event is fired when RTCMultiConnection detects that chrome extension + // for screen capturing is installed and available + connection.onScreenCapturingExtensionAvailable = function() { + log('It seems that screen capturing extension is installed and available on your system!'); + }; + + if (!isPluginRTC && DetectRTC.screen.onScreenCapturingExtensionAvailable) { + DetectRTC.screen.onScreenCapturingExtensionAvailable = function() { + connection.onScreenCapturingExtensionAvailable(); + }; + } + + connection.changeBandwidth = function(bandwidth) { + for (var peer in connection.peers) { + connection.peers[peer].changeBandwidth(bandwidth); + } + }; + + connection.convertToAudioStream = function(mediaStream) { + convertToAudioStream(mediaStream); + }; + + connection.onstatechange = function(state) { + log('on:state:change (' + state.userid + '):', state.name + ':', state.reason || ''); + }; + + connection.onfailed = function(event) { + if (!event.peer.numOfRetries) event.peer.numOfRetries = 0; + event.peer.numOfRetries++; + + error('ICE connectivity check is failed. Renegotiating peer connection.'); + event.peer.numOfRetries < 2 && event.peer.renegotiate(); + + if (event.peer.numOfRetries >= 2) event.peer.numOfRetries = 0; + }; + + connection.onconnected = function(event) { + // event.peer.addStream || event.peer.getConnectionStats + log('Peer connection has been established between you and', event.userid); + }; + + connection.ondisconnected = function(event) { + error('Peer connection seems has been disconnected between you and', event.userid); + + if (isEmpty(connection.channels)) return; + if (!connection.channels[event.userid]) return; + + // use WebRTC data channels to detect user's presence + connection.channels[event.userid].send({ + checkingPresence: true + }); + + // wait 5 seconds, if target peer didn't response, simply disconnect + setTimeout(function() { + // iceConnectionState == 'disconnected' occurred out of low-bandwidth + // or internet connectivity issues + if (connection.peers[event.userid].connected) { + delete connection.peers[event.userid].connected; + return; + } + + // to make sure this user's all remote streams are removed. + connection.streams.remove({ + remote: true, + userid: event.userid + }); + + connection.remove(event.userid); + }, 3000); + }; + + connection.onstreamid = function(event) { + // event.isScreen || event.isVideo || event.isAudio + log('got remote streamid', event.streamid, 'from', event.userid); + }; + + connection.stopMediaStream = function(mediaStream) { + if (!mediaStream) throw 'MediaStream argument is mandatory.'; + + if (connection.keepStreamsOpened) { + if (mediaStream.onended) mediaStream.onended(); + return; + } + + // remove stream from "localStreams" object + // when native-stop method invoked. + if (connection.localStreams[mediaStream.streamid]) { + delete connection.localStreams[mediaStream.streamid]; + } + + if (isFirefox) { + // Firefox don't yet support onended for any stream (remote/local) + if (mediaStream.onended) mediaStream.onended(); + } + + // Latest firefox does support mediaStream.getAudioTrack but doesn't support stop on MediaStreamTrack + var checkForMediaStreamTrackStop = Boolean( + (mediaStream.getAudioTracks || mediaStream.getVideoTracks) && ( + (mediaStream.getAudioTracks()[0] && !mediaStream.getAudioTracks()[0].stop) || + (mediaStream.getVideoTracks()[0] && !mediaStream.getVideoTracks()[0].stop) + ) + ); + + if (!mediaStream.getAudioTracks || checkForMediaStreamTrackStop) { + if (mediaStream.stop) { + mediaStream.stop(); + } + return; + } + + if (mediaStream.getAudioTracks().length && mediaStream.getAudioTracks()[0].stop) { + mediaStream.getAudioTracks().forEach(function(track) { + track.stop(); + }); + } + + if (mediaStream.getVideoTracks().length && mediaStream.getVideoTracks()[0].stop) { + mediaStream.getVideoTracks().forEach(function(track) { + track.stop(); + }); + } + }; + + connection.changeBandwidth = function(bandwidth) { + if (!bandwidth || isString(bandwidth) || isEmpty(bandwidth)) { + throw 'Invalid "bandwidth" arguments.'; + } + + forEach(connection.peers, function(peer) { + peer.peer.bandwidth = bandwidth; + }); + + connection.renegotiate(); + }; + + // www.RTCMultiConnection.org/docs/openSignalingChannel/ + // http://goo.gl/uvoIcZ + + // CUSTOM CODE + var href = window.location.href; + var hostPatt = new RegExp(window.location.host +"/[^/]*"); + var res = hostPatt.exec(href); + var protocol = window.location.protocol.replace("http","ws"); + + var signalingServerPath = protocol + "//" + res + "/webrtc"; + var SIGNALING_SERVER = signalingServerPath; //"ws://localhost:80/quantum/webrtc"; //"wss://localhost:80/quantum/webrtc"; --> ws for http and wss for https + + connection.openSignalingChannel = function(config) { + + + config.channel = config.channel || this.channel; + var websocket = new WebSocket(SIGNALING_SERVER); + websocket.channel = config.channel; + websocket.onopen = function() { + websocket.push(JSON.stringify({ + open: true, + channel: config.channel + })); + if (config.callback) + config.callback(websocket); + }; + websocket.onmessage = function(event) { + config.onmessage(JSON.parse(event.data)); + }; + websocket.push = websocket.send; + websocket.send = function(data) { + websocket.push(JSON.stringify({ + data: data, + channel: config.channel + })); + }; + + /* + // make sure firebase.js is loaded + if (!window.Firebase) { + return loadScript(connection.resources.firebase, function() { + connection.openSignalingChannel(config); + }); + } + + var channel = config.channel || connection.channel; + + if (connection.firebase) { + // for custom firebase instances + connection.resources.firebaseio = connection.resources.firebaseio.replace('//chat.', '//' + connection.firebase + '.'); + } + + var firebase = new Firebase(connection.resources.firebaseio + channel); + firebase.channel = channel; + firebase.on('child_added', function(data) { + config.onmessage(data.val()); + }); + + firebase.send = function(data) { + // a quick dirty workaround to make sure firebase + // shouldn't fail for NULL values. + for (var prop in data) { + if (isNull(data[prop]) || typeof data[prop] == 'function') { + data[prop] = false; + } + } + + this.push(data); + }; + + if (!connection.socket) + connection.socket = firebase; + + firebase.onDisconnect().remove(); + + setTimeout(function() { + config.callback(firebase); + }, 1); + + */ + // CUSTOM CODE // + + }; + + connection.Plugin = Plugin; + } + +})(); \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/webrtc/getSourceId.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/webrtc/getSourceId.html similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/webrtc/getSourceId.html rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/scripts/webrtc/getSourceId.html diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/att_angular_gridster/sandbox-gridster.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/att_angular_gridster/sandbox-gridster.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/att_angular_gridster/sandbox-gridster.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/att_angular_gridster/sandbox-gridster.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/att_angular_gridster/ui-gridster.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/att_angular_gridster/ui-gridster.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/att_angular_gridster/ui-gridster.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/att_angular_gridster/ui-gridster.css diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/ecomp.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/ecomp.css new file mode 100644 index 00000000..7b659e9c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/ecomp.css @@ -0,0 +1,135 @@ +.menu-icon { + line-height: 40px; +} + +.menu-icon-collapse { + line-height: 40px; + margin-top:10px; + margin-bottom:10px; +} + +.header-container { + width: 100%; + float: left; +} +.menu-container { + float: left; + position:fixed; + background-color:#f2f2f2 +} +.content-container { + min-height: 650px; + width: calc(100% - 250px); +} +.footer-container { + float:left; + position: relative; + z-index: 2; + width: 100%; + position:relative; + z-index:2; +} + +.footer-global i { + font-size:40px; +} + +.b2b-header-tabs .header__item.profile .profile-info{ + border: 1px solid #d3d3d3; + max-width:400px; + width:300px; + padding: 20px; + pointer-events: auto; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + font-size: 16px; + -webkit-transition: opacity .2s ease-out; + -moz-transition: opacity .2s ease-out; + transition: opacity .2s ease-out; + background: #fff; + border-radius: 5px; + box-shadow: 0 5px 6px 0 rgba(0,0,0,.25); + color: #333; + line-height: 20px; + position: absolute; + left:-123px; + top:38px; + display:none; +} + + +/* .icon-accordion-plus, .icon-accordion-minus { + float: right; + line-height: 40px; +} + */ + .b2b-ln-icon-fix-pos{ + margin-top:10px; + } +.left-menu-collapsed { + width: 22px !important; +} + +.b2b-subnav-content > li > a { + display: inline; +} + +#page-content{ + margin-left:250px; +} + +.leftmenu-arrow-expand{ + margin-left:200px +} +.leftmenu-arrow-collapse{ + margin-left:0px; +} + +.leftment-items{ + margin-left:40px; +} + +.error-popup-body{ + word-wrap: break-word; +} + +.build_number{ + color:white +} + + +/*popup modal sizes*/ +.b2b-footer-wrapper .divider-bottom-footer{ + padding: 30px 0 50px 0; +} + +.b2b-modal-header{ + font-size: 24px; +} + +.b2b-modal-body{ + font-size: 14px; +} + +/* applying default styles */ + +p,a{ + font-size:14px; +} + +.b2b-footer-wrapper .copyright-text-sdk { + color: #fff; + font-size: 11px; + text-align: left; + font-family: "Omnes-ECOMP-W02", Arial; +} +.b2b-footer-wrapper .copyright-text-sdk a { + color: #fff; + font-size: 11px; + text-decoration: underline; + display: inline-block; +} +.b2b-footer-wrapper .copyright-text-sdk a:hover { + text-decoration: none; +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/fusion-sunny.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/fusion-sunny.css new file mode 100644 index 00000000..f9154a1c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/fusion-sunny.css @@ -0,0 +1,362 @@ + input, textarea, select, div { + font-family: Arial; + font-size: 11px; + font-weight: normal; + } + + form { + margin-top: 5px; + } + + + .applicationWindow { border-width: 0px 0px 1px 0px; + border-style: solid; + border-color: #959595; + box-shadow: inset 0 0 10px #000000; + margin-top: 10px; + margin-bottom: 10px; + margin-left: 10px; + margin-right: 10px; + } + + .feedbackMessage { width: 99%; + font-family: Arial; + font-size: 11px; + color: #1f1f1f; + padding: 3px; + border: 1px #eeb420 solid; + margin: 3px; + background: #fff9e5; + } + + .menubar { + border-width: 0px 0px 0px 1px; border-style: solid; border-color: #959595; + } + + .footer { + /*clear: both;*/ + border-width: 0px 1px 0px 1px; border-style: solid; border-color: #959595; + font-family: Verdana,Arial,Helvetica, sans-serif; + font-size: 9px; + padding: 10px 10px 30px 10px; + background: white; + } + + .pageTitle { + font-family: Arial; + font-size: 18px; + font-weight: bold; + margin-top: 5px; + } + + .content { + border-width: 0px 1px 0px 1px; + border-style: solid; + border-color: #959595; + font-family: Arial; + font-size: 11px; + padding: 5px; + background: white; + /*height: 600px;*/ + } + + .popupContent { + font-family: Arial; + font-size: 11px; + padding: 3px; + } + + .logo { + border-width: 0px 1px 0px 1px; + border-style: solid; + border-color: #959595; + text-align: right; + } + + .sep { + border: 1px solid black + } + + .logo { /*position: relative;*/ + float:left; + padding-top: 25px; + padding-left: 25px; + } + + .applicationLogo { float:right; + padding-top: 25px; + padding-right: 25px; + } + + .applinkWhite { font-family: Arial; + font-size: 13px; + font-weight: 900; + color: #FFFFFF; + text-decoration: none; } + + .terms { font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 9px; + } + + .broadcastMessage { color: red; } + .broadcastMessageList { color: red; } + + .button { + margin: 5px 1px 5px 1px; + padding: 3px; } + + .toolbarbutton:hover { + color:#005491; + } + + .headerText { font-family: Arial; + font-size: 15px; + font-weight: 700; + color: #000000; } + + .headerBackground { background: #336699; } + + .errorMessageText { font-family: Arial; + font-size: 11px; + font-weight: bold; + color: red; } + + + .normalText { font-family: Arial; + font-size: 11px; + color: #000000; } + + .normalTextRed { font-family: Arial; + font-size: 11px; + color: red; } + + + .smallNormalText { font-family: Arial; + font-size: 9px; + color: #000000; } + + .tableBorder { border:1px outset teal } + + .validationError { background: #b9eaff; } + + .templatebody { + background: url(../images/body_graphic.jpg) repeat-x; + /*margin: 40px 80px 40px 80px;*/ + } + + /*--------------------- General Content ------------------------------------*/ + + .relative { + position:relative; + } + + .clear{ + clear:both; + } + + .left { + float: left; + } + + .leftCentered{ + float: left; + text-align: center; + } + + .right { + float: right; + } + + .rightAligned{ + text-align: right; + } + + .centered { + text-align: center; + align: center; + } + + + .noWrap{ + white-space:nowrap; + } + + .disabled { + color:gray; + cursor:hand; + } + + /*--------------------- Tab styles -------------------------------------*/ + + .current { + font-weight: bold; + border-width: 1px 1px 1px 1px; + border-color: silver; + border-style: solid; + } + + .subTab { + font-weight:bold; + font-family: Arial; + font-size: 11px; + color: #0F3B82; + } + + + /*--------------------- Grid styles ------------------------------------*/ + + /* Grid navigation and header styles */ + .gridFilterLabel {font-size: 7pt; + font-align: justify; + font-weight: bold; + display: block;} + + .gridFilterText {height: 17px; + font-size: 8pt; + width: 60%; + font-align: justify;} + + .gridNavigationBar { font-family:Arial,Verdana; + font-size:11px; + font-weight:normal; + color:#000; + margin: 0px; + width: 100%; + vertical-align: middle; + } + + .gridNavigationBar .navLinks { float: left; + margin-right:15px; + padding-top: 2px; + height: 19px; + line-height: 19px; + } + + .gridNavigationBar .pageControls { float: left; + margin-right: 15px; + height: 19px; + line-height: 19px; + } + + .gridNavigationBar .pageControls input { font-size: 8pt; + height: 17px; + vertical-align: middle; + } + + .gridNavigationBar .pageInfo { float: right; + vertical-align: middle; + height: 19px; + line-height: 19px; + } + + .gridNavigationBar .pageInfo input { font-size: 8pt; + height: 17px; + vertical-align: middle; + } + + + .gridNavigationBar span { padding: 3px; } + + .gridNavigationBar a { + text-decoration:underline; + color:#000; + font-weight:normal; + } + + .gridNavigationBar img { vertical-align: middle; } + + .gridBulkUpdateRow { + height: 35px; + line-height: 35px; + } + + .gridBulkUpdateRow input { + vertical-align: middle; + } + + + /* dummy class used to lock the form elements of a grid - ex. bulk transaction processing */ + .alwaysEnabled {} + + .hidden { + display: none; + } + + .selectedPage { + background-color:#C4DFFB; + color: white; + border-style: solid; + border-width: 1px; + border-color: gray; + padding-left: 3px; + padding-right: 3px; + vertical-align: middle; + } + + .selectedRow{ + /*background-color:#C4DFFB;*/ + } + + /* Action Item styles */ + .actionList { + margin-left: -20px; + margin-right: -10px; + padding-left: 5px; + } + + .actionList li { + float:left; + padding-left: 3px; + padding-right: 3px; + } + + .actionList li a { + text-decoration:none; + color:#000; + } + + /* Filter Operator List styles */ + + .filterList { + margin: 0px; + } + + .filterList li { + list-style-type: none; + padding:3px 3px 3px 2px; + cursor:hand; + font-size:11px; + } + + .filterList li:hover { + background: #404040; + } + + .filterList li a { + color: #000; + text-decoration: none; + } + + .filterList li:hover a { + color: white; + } + + .filterList li a:hover { + text-decoration: none; + color: white; + } + + .filterListItem a { + text-decoration:none; + padding:3px 2px 3px 2px; + } + + + /*---------------------- Customized ZK Styles ------------------------------*/ + + .z-datebox input, .z-timebox input { + font-family: Arial; + font-size: 11px; + height: 15px; + margin-top:1px; + } diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/global.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/global.css new file mode 100644 index 00000000..25d1c578 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/global.css @@ -0,0 +1,178 @@ +body{ + margin: 0; + padding: 0; + padding-bottom: 0 !important; + min-width: 980px; +} +label { + display: inline-block; + margin-bottom: 5px; + font-weight: 700; +} +.footer-columns label { + color: #009fdb; + font-size: 18px; +} + +.b2b-header-tabs .header__item.profile .profile-info{ + border: 1px solid #d3d3d3; + max-width:400px; + width:300px; + padding: 20px; + pointer-events: auto; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + font-size: 16px; + -webkit-transition: opacity .2s ease-out; + -moz-transition: opacity .2s ease-out; + transition: opacity .2s ease-out; + background: #fff; + border-radius: 5px; + box-shadow: 0 5px 6px 0 rgba(0,0,0,.25); + color: #333; + line-height: 20px; + position: absolute; + left:-123px; + top:38px; + display:none; +} +.b2b-header-tabs .header__item.profile .profile-info.open{ + display:block; +} +.b2b-header-tabs .header__item.profile .profile-info label{ + font-family:Omnes-ATT-W02; + display:block; + margin-top:20px; + font-size: 16px; +} +.b2b-header-tabs .header__item.profile .profile-info span{ + font-family:Omnes_ATTW02Medium; + display:block; +} + +.b2b-header-tabs .selectWrap button.awd-select{ + height:36px; + line-height:31px; + font-size:1rem; + display:inline-block; +} +/* @font-face { + font-family: atticons; + src: url(../fonts/atticons.eot?#iefix) format("embedded-opentype"), url(../fonts/atticons.woff) format("woff"), url(../fonts/atticons.ttf) format("truetype"), url(../fonts/atticons.svg#atticons) format("svg"); + font-weight: normal; + font-style: normal; +} */ +[class*=" icon-"], [class^=icon-] { + font-family: atticons; + speak: none; + font-style: normal; + font-weight: 400; + font-variant: normal; + text-transform: none; + line-height: 40px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-user-small { + display: inline-block; + vertical-align: middle; + width: 20px; + font-size: 56px; + margin-right: 16px; + float: left; +} +.icon-user-small:before { + content: "\e60b"; +} +.icon-local-search { + content: "\e685"; +} +.header-container { + width: 100%; + float: left; +} +.menu-container { + width: 250px; + float: left; +} +.content-container { + float: left; + min-height: 650px; + width: calc(100% - 250px); +} +.footer-container { + float:left; + width: 100%; +} +.profile-info { + font-size: 16px; + color: #333; + line-height: 20px; +} +h6 { + font-weight: bold; + font-size: 1.125em; + line-height: 1.3333333333; +} + +.icon-primary-accordion-plus, .icon-primary-accordion-minus { + float: right; + line-height: 20px; +} +.left-menu-collapsed { + width: 0px !important; +} +.menu-icon { + float: left; + line-height: 20px; + width: 25px; + height: 20px; + margin-top: -10px; +} +.b2b-footer-wrapper { + width: 100%; + background-color: #222; + height: 88px; +} +.icon-primary-right { + margin-left: -11px; +} +@media (max-width: 768px) { + .divider-bottom-footer .footerLogo { + margin: 10px 0 0 0px; + } + .b2b-header-tabs .header__items { + width: 700px; + } +} +@media screen and (min-device-width: 769px) and (max-width: 1200px) { + .b2b-header-tabs .header__items { + width: 700px; + } +} +@media screen and (max-width: 1100px) { + .b2b-header-tabs .header__item.profile { + float: right; + } +} +@media screen and (min-width: 768px) and (max-width: 1105px) { + table th, table td{ + padding: 19px 10px; + } +} +.icon-spinner { + animation: spinner 1s linear infinite; + background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2036%2036%22%3E%0A%20%20%3Cpath%20fill%3D%22%230569AE%22%20d%3D%22M18%2036c-2.7%200-4.8-.6-6.2-1C8%2033.6%205.4%2031.1%204%2029.3%202.7%2027.6.9%2024.7.3%2020.8c-.3-2.1-.5-5.4.9-9.1C3%206.8%206.4%204.1%208.3%202.8%2011.8.5%2015.4%200%2017.8%200l.1%204.3c-1.8%200-4.6.4-7.3%202.2-1.4.9-4%203-5.4%206.7-1%202.8-.9%205.3-.7%206.9.5%203%201.8%205.1%202.9%206.4%201.1%201.4%203%203.2%206%204.3%201.5.5%204.6%201.3%208.3.3%203-.8%205-2.5%206.2-3.7%201.4-1.4%202.4-3.2%203.1-5%20.4-1.3.9-3.3.6-5.8-.5-4.2-2.8-7.1-4.2-8.5L30.5%205c1.8%201.8%204.8%205.6%205.4%2011.1.3%203.2-.3%205.9-.9%207.6-.8%202.4-2.2%204.8-4%206.7-1.5%201.6-4.2%203.8-8.1%204.9-1.8.5-3.4.7-4.9.7z%22%2F%3E%0A%20%20%3Cpath%20fill%3D%22%23FFF%22%20d%3D%22M17.8%202.2c1.8%200%204.9.3%208.2%202.2%201.2.7%202.2%201.5%203%202.3%22%2F%3E%0A%20%20%3Cpath%20fill%3D%22%23F2F2F3%22%20d%3D%22M27.5%208.1c-.8-.8-1.7-1.4-2.6-1.9-2.1-1.2-4.5-1.9-7.1-1.9V0c3.3%200%206.5.9%209.3%202.4%201.2.8%202.3%201.6%203.4%202.6l-3%203.1z%22%2F%3E%0A%3C%2Fsvg%3E"); + height: 50px; + width: 50px; +} +.loader-container { + position: fixed; + top: calc(50vh - 25px); + left: calc(50vw - 25px); +} +.loader-container i { + float: left; +} \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/jquery-ui.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/jquery-ui.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/jquery-ui.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/jquery-ui.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/layout/layout-default-latest.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/layout/layout-default-latest.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/layout/layout-default-latest.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/layout/layout-default-latest.css diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/workflows/bs-workflow.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/workflows/bs-workflow.css new file mode 100644 index 00000000..09e0a927 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/workflows/bs-workflow.css @@ -0,0 +1,134 @@ +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 99999; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; + background-color: transparent; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 9997; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + min-height: 16.42857143px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/workflows/workflows.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/workflows/workflows.css new file mode 100644 index 00000000..2a740ec5 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusion/styles/workflows/workflows.css @@ -0,0 +1,31 @@ +.scrolling-table{ + width: 1200px; +} +.scrolling-table .scroll-viewport { + height: 200px !important; + width: 99.5% !important; + background-color:white; +} + +.scrolling-table .scroll-overview{ + margin-top:-14px !important; +} + +.scrolling-table .scroll-viewport:hover{ + background-color:white; +} + +.scrolling-table #att-scroll-table-content{ + height:200px; + position: absolute !important; + width:700px; + padding-left: 0px; + padding-top: 0px; + padding-bottom: 0px; + padding-right:5px; +} + +.workflow-popup-body{ + position: relative; + padding: 30px; +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/drools-list-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/drools-list-controller.js new file mode 100644 index 00000000..c8a363c9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/drools-list-controller.js @@ -0,0 +1,43 @@ +app.controller("droolsListController", function ($scope,$http,droolsService, modalService, $modal) { + // Table Data + droolsService.getDrools().then(function(data){ + + var j = data; + $scope.tableData = JSON.parse(j.data); + //$scope.resetMenu(); + + },function(error){ + console.log("failed"); + reloadPageOnce(); + }); + + $scope.viewPerPage = 20; + $scope.scrollViewsPerPage = 2; + $scope.currentPage = 1; + $scope.totalPage; + $scope.searchCategory = ""; + $scope.searchString = ""; + /* modalService.showSuccess('','Modal Sample') ; */ + for(x in $scope.tableData){ + if($scope.tableData[x].active_yn=='Y') + $scope.tableData[x].active_yn=true; + else + $scope.tableData[x].active_yn=false; + } + $scope.openDialog = function(droolFile){ + droolsService.setSelectedFile(droolFile); + $modal.open({ + templateUrl: 'app/fusionapp/drools/view-models/droolsView.html', + controller: 'droolsViewController' + + }) + } + + + +}); + +function openInNewTab(url) { + var win = window.open(url, '_blank'); + win.focus(); +}; \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/drools-view-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/drools-view-controller.js new file mode 100644 index 00000000..0412718f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/drools-view-controller.js @@ -0,0 +1,45 @@ +app.controller('droolsViewController', function ($scope,modalService,droolsService){ + + + $scope.resultsString = ""; + // Table Data + droolsService.getDroolDetails(droolsService.getSelectedFile()).then(function(data){ + + var j = data; + $scope.postDroolsBean = JSON.parse(j.data); + //execute($scope.postDroolsBean); + + },function(error){ + console.log("failed"); + //reloadPageOnce(); + }); + + + + $scope.execute = function(postDroolsBean) { + console.log(postDroolsBean); + var uuu = "post_drools/execute"; + var postData={postDroolsBean:postDroolsBean}; + $.ajax({ + type : 'POST', + url : uuu, + dataType: 'json', + contentType: 'application/json', + data: JSON.stringify(postData), + success : function(data){ + $scope.$apply(function(){ + $scope.resultsString=data.resultsString; + console.log($scope.resultsString); + }); + }, + error : function(data){ + console.log(data); + modalService.showFailure("Fail","Error while executing: "+ data.responseText); + } + }); + + }; + + + + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/droolsController.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/droolsController.js new file mode 100644 index 00000000..c5c4e708 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/droolsController.js @@ -0,0 +1,11 @@ +app.config(function($routeProvider) { + $routeProvider + .when('/view', { + templateUrl: 'app/fusionapp/drools/view-models/droolsView.html', + controller : "droolsViewController" + }) + .otherwise({ + templateUrl: 'app/fusionapp/drools/view-models/droolsList.html', + controller : "droolsListController" + }); +}); \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/controller/dummy.txt diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/external/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/directives/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/external/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/directives/dummy.txt diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/services/droolsService.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/services/droolsService.js new file mode 100644 index 00000000..3b4ba3eb --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/services/droolsService.js @@ -0,0 +1,57 @@ +app.factory('droolsService', function ($http, $q) { + return { + getDrools: function() { + return $http.get('getDrools') + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getDroolDetails: function(selectedFile) { + return $http.get('getDroolDetails'+'?selectedFile=' + selectedFile ) + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getRole: function(roleId) { + + return $http.get('get_role?role_id=' + roleId) + .then(function(response) { + if (typeof response.data === 'object') { + return response.data; + } else { + return $q.reject(response.data); + } + + }, function(response) { + // something went wrong + return $q.reject(response.data); + }); + }, + + getSelectedFile: function() { + return this.selectedFile; + }, + + setSelectedFile: function(_selectedFile) { + this.selectedFile = _selectedFile; + } + }; +}); \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/fonts/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/utils/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/fonts/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/utils/dummy.txt diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsList.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsList.html new file mode 100644 index 00000000..91e68a15 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsList.html @@ -0,0 +1,28 @@ +
    +
    +

    Drools List

    +
    + + + + + + + + + + + + + + + + + + +
    Drools File NameClass NameRun Rule
    {{rowData.droolsFile}}{{rowData.className}} +
    +
    +
    +
    + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsSinglePage.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsSinglePage.html new file mode 100644 index 00000000..a1d0a5ba --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsSinglePage.html @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsView.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsView.html new file mode 100644 index 00000000..bcc80b73 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/droolsView.html @@ -0,0 +1,42 @@ + + diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/images/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/images/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/drools/view-models/dummy.txt diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/external/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/external/dummy.txt diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/directives/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/fonts/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/directives/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/fonts/dummy.txt diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7450-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7450-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..52ab2b54c3fc7277c1686de3ffa379100462702b GIT binary patch literal 465 zcmV;?0WSWDP)nA3K5i6$_kWVe}vt?!LWQiPz z{K0HJS|%#()JEDoTN2~{Tr6-mBm-dYO7SbrC^^>;?hq6IDh z>S(neYL&zmu`4SCHd!TlA&8Z`7A~DGneEMWGh$@tbwx&2lME+J3o9%0&5|y=Tc$8sB7ZP@wMu#rX)OoyL@pi761~#H&2zp0*$I31TPo&r00000NkvXX Hu0mjfnX|^h literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7450-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7450-text.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3c3325148e4b876953a48281deb0b21e73eed6 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^Q$U!J8A$qnnlv3qu?6^qxc&!&(3-C~KoQ20AirP+ zhi5m^fSmK5E{-7;jBhU(`mrcVv_0$(2>9pzK;!?}Ii5N?-#Ow~^P8r=y^+{d!#6or ztZa?1PsQowHHNd#rv0}`ZS?+acQXEEz2?nrR1;U6 zZC3mjyTeIGM}lkRWMy4R>DPP-6kaJ7pibJ@YVw{G`uXW5^B##j9|r*V(E z^z_LyL)|~;b51Qc)I$ztaD0e0swz2hGPH# literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7750-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7750-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9ee5499a9b46f35fa26098851f626d52c0116d84 GIT binary patch literal 565 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7SuK)l42Qq;qNg#MX`%|Dc z!IB`qUg`*e z{{NrT&k_}`EWM~x%=kJ>9nX}Eg%dtJlm7MP<>lr7m;ceYKl$+FiSrlw&$p`ui~0Yr z|Jlu>D(Ci3FZpKApGoaMq}Bv&5?;@`tmQ{e0#5kK9()ggW2ypCV6B z*@&E1?0jif|E|5QvUgw6%y4ZE4(dRzBgnH5rVHZG5gV zt?HBXnZ50__1`(cTp39(ybteLsn7dynO#)(B#B=;8bow!Vj4b`+37v#NP6-3YSzT| znn=IDLh_%I3+3v+zpr1;(0_k_n(=q@=RfaP|835+d%Zu+@b>>2i}(N4-q&A#@^}5R zUvK`K&cA%#{^svL=HLI^UUP1LRKw|?@xjl&+9wsg`+w$bedz6f)731${EzuP-{R=@ z|IwR*|KHyK|9$=ci81f%|GeKn&C&kjzp1croNxDcrsePd+`zav%=4Ukj_#YMXTNVx Q0LCJNr>mdKI;Vst0Q6iq*#H0l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7750-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/7750-text.png new file mode 100644 index 0000000000000000000000000000000000000000..aeb2dd002fa857bf4e0901fd52e290eeef36a4a2 GIT binary patch literal 632 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+Wp4EyINygy&i(0|`xeSpH_QoZdA42%yvT^vIy;@%u!-sq@SuAGRL}bsimH+?EvTeojo1)AgC+g%adAg*p_vyzUmH$u9 z=CkPFe;e3-uYdZ^`+tM=FWY?ziaJx4&#}#Kw(_IIyaV^8x1D`7=gavjRpYyP@j16& zat1Bkq2rO4b|{@I-fy}NpMTRl|L-i1=j2OW-BfOS)$X>Z>C4Ac&P#V5Uj29;->)cv z_n)t=|8hE^EOL&<^3|2PWFdJjlvb>X={x{wT|u#*}44czaM|f7i-mAIPRy__J8XZ zmfw!|=T$#C>dgGee{0I`bMX^-IwTHuygGQ)_1~`*`|Vz>Ucc`bcH%#;{I}`bq!MlZ Pg5uND)z4*}Q$iB}`({;g literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/apn-dns-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/apn-dns-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba5c5235ad4857ed999c596c47e0a2a52f63d89 GIT binary patch literal 1065 zcmb7@=`))N0LG)b)n!bugSKd_V@hYLj%Bx0Qmu?D%^D%C7-3{fv5T%F=@74Dcd@3F zj=VMx77oSC`Pcrq+lCk!#R>T-ojP)(9Y4`pD zU3T2|#j|uvHTHJbC99)|T*5kX@z0Q)>T&8FdY>XYJ$w)+mi<9HSGR#q^qo)1$;4QS zk*CDn{(<^!oLq2FGP?Bn5D0Y}s3N4AnQ?j6YLuolIy1Y`GpB7f3E%O$nPcX1Ge%yF zj+CoJr#N)xb|D;lL^h^UpehmweR$>4>$tloAp(#2Ykr7eT3ep* zH0{{v$(fPgFYg(NfcPFm5WZl!3I=1uS9gwoY9-4st1;XGEsb)uP>|HR$y`UopTwId z365j4@z|706Sxi}ajWZ9hij0Wc@S=qoteyyLt+%S>VWRU-<)eACRArlItG9|oB~qe zb3ZCoMbJzcE_#)3gQKnl^sg*1*ySWIQ4{f?f6iLGSig}T@~(3jT;qS|P!&f5mG6j& zKD)zlUBWT`V_q@{DCguUD$AS4v9CYyx(8P-+7}5m1_8A$sR}R24WT+mk@g0W#y5*( zkJm?K*~P(NfSQk$+$d(YyP8&;LC_?pw1kPXBJWVvX_HjX>}L|LWO`C&YRImJf3=A) zuLGR3k{y+%m$$4O|;PsbgP@vuVD+^dXv;Y3gLdy@EmC$GsyO-xc zu!Edf6SljDm3Q;Y37!M{2HN}e0!5ZJR2JDbAuDCQpTR+8fkrVZ-;>M+(_R&Pz5pv2 zwNf9Q=ka7d1w8D7DuF=sQRaJ~>XlvbnjQLvEL7Xu|Ghaf+azI z!3+)z{R#KyH|&3Z-XK6hV12jo8!>`|C@sy!W?Gxcy8yPydlm{!PkEG#@&Y!RsSsi^Uz-@sPB#1 zww9c(P>1IeA9S2dc6)f6>FwWWenY-Gs~5GEhVR}fUpu&c-mUg!YVtQ9syn~^-FCy^ z$1aUGYf{_in`~UqJx$Q^x5R;V&!_o2_bm*q{MNtv)rZ^#pFVz@INj)XzFqVEqM%=^ z4jE}bnm>QPS)0f6_NcqJSl*b&e|^2adzQ>hd1F;+<#c<#@B8`8HdinBo672I`REwng0i#Tlea3O7`tO+f?zW+WV2X z!9Bg_o#*+v{yQA}{d9tVjULAz;j``Kr?cdKCjLKr{J8D1^^5Bt6{pvK<^O#0rtrZh zE_$EjD?h8M?cVtNp!&)BXZrO&PsjiJG=2Y{r`5-1T$yihow;XYof1#-`7PHb1^!rh zUh{Y*$Kjg|NA9KfHy(30yY}1c%)awhNvsq5Pt@J>sas*QNb^r@eNr3uj)scw$*JYZ zS+X{*@!fJJU3~UCXXkgtT~Y82nses(JNGaD#N6ud7#jM&c$~2O`{kck-823&A8t8u z@P1%@k-YQWKT&+_^1Jg^^Hs_J&c9d_e}3l!{{Pw*$qT-p-Ei)D6~~Y5%*Idee~sSR zf9`qC>)lsZ*F_6R>&e?Qbkr38Ej*X{;QEgndIzh#?0df3@0-L~>bPgyiwpU+{|g=F zGS}NQSjE4oPe_wrYS^-G*Vps(j6U0H7Ew0Z0QU7P+qMG9IF^FQ}=nZ3FPpDc(3CT|8$S3j3^P65 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atcf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atcf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..1566d5be0a846d8da4a59f332c94fe92213116e3 GIT binary patch literal 650 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+ZX*E2XYB=o=kKVPB1;Qal7uDCD-1_s8Do-U3d6^w7MpDkLWAkg-(LAPG%#ozmH zR&GkpX8mAc^z>DAx#t!4jVD#?ITTw2oDf9*(l6H>E@fmz-U_~!DerV)a_Etx*FIk2 zH=V^iJ>z^!RMm1d`MzZ*w%@V%*EavV_TA6AuP4p_{YOPSsQizn2=A)n_IerlKd#C@ zmAgM*|8V44-937DNZD$vGqa|3?4q%s#Q12ejiqb9a_3NqhBirpFVYbdBh$(^npTF4q5T^&-1I zHRaDF{qT}c(He2TmbqB{^?X)0%{uc(QAytK=Vy51KR&Z&yBPoL*Pqhu`ut~wZBDT4 zdw$w``rftozf9h9KDqd)cx}1P{yhxWP5(a*{ImbP^UVDpo)>jieVfm__1ZN36Mt0e zSNw85J)QOR{g25j#Bcu->GEB*rS`?_w*07l8g>`sPAM)){})s<<0E(EExXL0vx~K* z{@wU@XS#8a<%I0p{dNU$(vOQCd=jpI)V?<7#KO0iqhuq$?p&W$eexvBwwkEg+yuL? zscS>u);In&i2K#+01y`>knvzopr02v2faR2}S literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atgw-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atgw-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2904d2770551ffc743b9e62859713385f74b6839 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_0wi;`T%Ezd!07Gi;uuoF`1Xz??_&djwm@eN z6=%&BhX}Pc5sk(V?{|Jm)n0pd<)?j$2J2sGZn~@DISGVbHa_*xw|2jke)-eQIXi>5 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atgw-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/atgw-text.png new file mode 100644 index 0000000000000000000000000000000000000000..f7c50c602c842834c15008e3881a55b1a9d25219 GIT binary patch literal 780 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+it4EyIN2o#)eP*@-EzW@H82Di@)3``}SE{-7;ac>S7G6IzzQuw`m+cCZfZXg>7 z=3F+4o+jMZnDM6Kxb*-3n@_HIE4UzFm9%ZI#w~ZJUWw$jfB)|P`1(H6ch3FBk6ld#GHV{4JhkJ7udUj56zvg>&g>-@7v()gY& zvg6l!74xw2Pu$bPTPB{9eE+A%hs|H_!k!CXg5krV?cv6rwfFMlExsA@)~@`s^OxCyy&opuCl{d4v|T^TG7 zT8!F`weN`P>g-(kPx@W{le6p_n0K6B9Uwh*{?VZ6HF3+{KAe3hU4sAPr9jcxzyIWy zcQ}8joc)8{{$p>VQv7?yoVB0YpYWf2ZY%%Z>-18KdHl6rE7YdmSKaSz$G?E0%L!3(ec__|SfZiJ;@#MP-rABx@L`eH0+YiZVG zzB<4+<Y#d)@D(=6xW=`a;pD7{@?vu zEl$~PWuVo+E%EJU3>*ApigX literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/bgcf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/bgcf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2904d2770551ffc743b9e62859713385f74b6839 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_0wi;`T%Ezd!07Gi;uuoF`1Xz??_&djwm@eN z6=%&BhX}Pc5sk(V?{|Jm)n0pd<)?j$2J2sGZn~@DISGVbHa_*xw|2jke)-eQIXi>5 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/bgcf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/bgcf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..b1e0869eca40dd406454f224177ddc7bbfd6583b GIT binary patch literal 645 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+it3Je7e0_XqVpTB;8LjU`K#AUOeF)%Q`@pN$vsbGA2?QYm>1%b9i#lzuvjMo^o)>UOvTR{6D0D#=*gYFPRJ1Z`pV)%YCtHbawBu_#X@2Yn=D( z*wwvWCurI3H<2g!KRo#Vdsg*o<%e>m6GcL`KAe5F?AuN2lhyC0?BzReyMNEU?=J&> zOqTqtbn1%@m;U$3GFtcbwjIBarnt!V?l)DNSvLiDo-YoV@}+m5&GqRwUu-D(-cWhVe${@RY3I4WZ-2m2nY+jM`&O;Vh`aysVEjyvcnwRXy^*zt*{gH^`zhb7 zGvE3CtLE|7^ImWJYkRug>HfFHYwNDQcP&qi=!;lown*i+>4STp|4zw#vwYi+Yx_7} zo&R0*|NGhx3oVpB2iMQN`+oj@1^$M8vM+M@C-P_SH~c)`{?sS-10OZ{@29=~y!_tP z>!mjOpTlR+z2nT(g4ddI$yNGbaq;i3N3=YM9@YeS3u_QJnjEbh0%LD=87 Y@0q&NrX$?+7$^=sUHx3vIVCg!0Bo#YB>(^b literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/com-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/com-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..59463a91779bfb5f18ff47a0f8e86d4963902df1 GIT binary patch literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZM#sNMdu0Z-fiD3KGM@>L&f+azI z!3+)W|1%gk>_6Wxkg$G!!2N<($Gs zb|yP)Du~T}Zm(Rc-ftEZ$D!CF;FKYzG*`3j%hvE;VatkBTjTkDvD(%Ah??KLtm+iM z=k?NK{hrY_k2c?WzWm3Bhlktw?XRC*zHhDmM6P|r|({$dr^|3H6WKr(o``njxgN@xNA+^XKg7@r+fJHTJ~jd@3djmv|>A4Gnz zf3n$hKz@RQttZp}4O~1{)BARbOt~YO`R>yHEgZoL?sC2l80~j4SnIOEL7Xu|Ghaf+azI z!3+ux0t^Z3@6R{r-~ax6K|q7t-CvU#7#Np$x;TbZFuuKdv2TfjKl`rBWkzPM*zu@`eT>s~dlZO_*C2llM+m|U57;XY5L>OptagZh&f{pFMwv--fJ z`>0Mk-rVjT`)dbY#VchCVt4IlU!V3_tH%1{bpIcc^Iu*)R&Jl2|Bm~|v@4U1-aHnN zzNXoI=)Lbg4e@&Moa`I%XNC8&?Y|!TqjtAc?v3Ld>woQy|JCBh+O2qh&*y9QH5>m| zZ#N4sx?L{!xv=@p&!+l`l~#`*bo2avcr4y8U$1rcGYtOzuV@wfeqWcFavx9o-?vYXcE2R|$82k${KwxW_s`llt&hsRmi{LrE=1%h zcYJu|iRn%Ezh8T{x$OPoLixpEtF|20x8q&^Yg4rT^PIiEmi6;4&{_XWYjdpD@>kw= zTsICDb?tk(SfKE#jr5=LMgH^cYJYusd3iZHWB&#DR)Jlj*&>tY10$2c)78&qol`;+ E0FtCHoB#j- literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/default-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/default-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..296a6f5c22c4e67a21280a8b92690ce63a86e9d4 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^^+4Rg!3-pSemT+rqznRlLR^7#BV#QPeZ2A!gsy#j z^Xm%`z5Mh6h@QQE3q+5eygV}Z#I<9$Uw;1B!hO#is7IhA$S;`TKM3+Lh%iVoC}lVZ zX$gFp50u;C>EaktaqI1^-F!_33~d*coLZ|Y|8L*wCYGq6Hbuxb{u94XdbXt0l2fKj zt=5Wv`te6;>)Xn;6OKRMpS`{J{Qpz$`5wNnly9-In}6PZUi?23zREw!zwefP-JH~; znE$T6uH1K}-eH55JyHK=1aVc?0F^!e{1cV>6aV%1kF5OvRkL?p|1kX{SoZ$S_&@w# yTK{hS0aE+l-Tve2U;P^cF8_XB1yoRXbY86N#?6Hy$L<6Dz~JfX=d#Wzp$P!f)2eI$ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-epc-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-epc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..74bfcfcec12c94c1d58181b42ffe2c4297d890ec GIT binary patch literal 700 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)s4fFT+Com}d7g&GZ;Qsr7HMQSM7#Nt8JzX3_Dj45hzu5O!fv4@FRm%}WPQ~~C zH?6+txAx}0mOl4+v#0L&j`|wlqEz9c?;0qAj4n=jHs|xCut)R1KbXJ8H*(*!Db{pU`_(^u*&UB|ldB zYd&@Um-+R>)almybeBB7e&>uZgM7t@_4>b}eq^hfUR-t8UGDGN-fxvNpGIn@$ya_U z-5~fqsKMzgL?O~QXQC)JQ_G#>`H~ZA}SKs~qBz4>GNSV`V^N*Nrj{jD3{o|dh zKWp3X)=$^-HLRH)Q+v4nmwfHvU)STm=>FE{-_>K+o!@>ne_!3EUpJ@Dzxhf%{@$DL z@O$q*zdUvO@0YWm!>hH(Iv?usic&;6P1J<0xDe(t`gyaAJ3&21)`r~jD|eq?o$>tFubY~; zj=oUN|6VERdoJ_x$6a%_tJgE#dvVx##azqUDYsuday(`I!)E4t+a-J2&xcFD`cbCz zG`8m6r-u97&HQ^Vwyz8RHTTF3wmmo7uQ_knQ)I66?c3MR%Y92XsqW^_4WISdy?7T_ lHs8MNhwbupKhTJJ2Iuw|JwB~Z{lLV;;OXk;vd$@?2>_N=ff)b* literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-epc-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-epc-text.png new file mode 100644 index 0000000000000000000000000000000000000000..00f2a2e45e571fb29122d8c61fecb46ddf3416e1 GIT binary patch literal 820 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)a_uv1&-he^jeZN40LqNg#^Rv`0GcYjC_H=O!sbG9N^KRKv1s*qU$2z42`~IIk zH?fX2)#^Fdn>91vXrCxt>uWkA!JfrY0ET|N51iF;=2O#}qJP~BUa(HLP>hRwsgm?< z9{>M&Pun~>p6l)V=@!BDJHmd!jh~L6L|aXHzcnkD)lK*-zRb<-=l4Z1JAGFC{G2Y6 zxIx!}|MO%0PWPF)SL=dlF2FlA9Gfnd;f|hxp&Tm=D#~Ge|y&7sjpYtCmVLEuxtK< z{STwsX6>5rWy<_SujeUi`5(=w{;w^vZvXCWns=}KSzWN_4gX|ru}H&9@9XZ@UsNdB zq$ex0e1H8n?~TUZ{!%Z?@9(Ww)^k*RVZrvxxIVhxq)14AFQ55={m;c;IjsAA?)^SF zuLGa*Qa%0O*sq(N=c-n4ouhEh)%wu-rsD~+wOeOhtG{=TOY^a%35TS`k$ewDerx-@ zEf-JpxjB8?_x-&4pGV^Re;n1X``GJc#S+h#^F6P<vHXR8%30NOWztXn zKl4_;(-8XQKy1C`of>4o$0Cg^jdpPj^wVu ze{ZBeXs7Hx$P&+<d3YCIj1N8>%04ZMf~q)^*aBxk6&y0W@*3DN%yPR@AnV? z#@`I&s5>Q}rNuCP{ukw2S#^&ZzowrT{jOf`c9uWY>4kUOclj&7wWY#kTzd9B3A7ix zVDK)`K59Z&-#EL7Xu|GhaLM1_d z!3+)s4fFT+Com}d7g&GZ;Qsr7HMQSM7#Nt8JzX3_Dj45hzu5O!fv4@FRm%}WPQ~~C zH?6+txAx}0mOl4+v#0L&j`|wlqEz9c?;0qAj4n=jHs|xCut)R1KbXJ8H*(*!Db{pU`_(^u*&UB|ldB zYd&@Um-+R>)almybeBB7e&>uZgM7t@_4>b}eq^hfUR-t8UGDGN-fxvNpGIn@$ya_U z-5~fqsKMzgL?O~QXQC)JQ_G#>`H~ZA}SKs~qBz4>GNSV`V^N*Nrj{jD3{o|dh zKWp3X)=$^-HLRH)Q+v4nmwfHvU)STm=>FE{-_>K+o!@>ne_!3EUpJ@Dzxhf%{@$DL z@O$q*zdUvO@0YWm!>hH(Iv?usic&;6P1J<0xDe(t`gyaAJ3&21)`r~jD|eq?o$>tFubY~; zj=oUN|6VERdoJ_x$6a%_tJgE#dvVx##azqUDYsuday(`I!)E4t+a-J2&xcFD`cbCz zG`8m6r-u97&HQ^Vwyz8RHTTF3wmmo7uQ_knQ)I66?c3MR%Y92XsqW^_4WISdy?7T_ lHs8MNhwbupKhTJJ2Iuw|JwB~Z{lLV;;OXk;vd$@?2>_N=ff)b* literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-ims-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/dra-ims-text.png new file mode 100644 index 0000000000000000000000000000000000000000..1d54d9aa9e412850ae9f5428b42161b07ea49cc5 GIT binary patch literal 851 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+ux3A`?mc5e_n2Tan|x#Z_XZwne!p;&8)U3j!hZIe;R-AdGIU!C-Z(b z@kuT*cU6@$m#n+FW1iKIl*!x$HaBy`I^JCWXLnR#pKl$z&|aacpB2Y^4%olqGzmIA zx8{87w?$%K8!wCLX+KzZRO@byUs~zjp8^uW*~^XpsDJ(H`0mQDfYb?nt6Iww((MhU z-`Pp+-z)ZVf$_Ta@iSuI|4UkN=0of=IN-p{#7hTb75{g2B3NIm$QXme)Ui?`{IS1;eK|1vt`^{dG@>noN`+Id>2lBIpQ z(C?pz%s!TSmK8hASkhOQwoT%`UG0w#8@tzwq#D?{?Da1A()0Ss^tl!fpB3+H%G=o? zH1F28jq|@7ub6Ljt=!5zp&->^`R9fClOMiw-uLRP&JG{l(l6x|zy1aBTk@QlExG&W zP0369ramdV{n-0L?T5d$s_)}YH+nBJu_=C0@B6Uu_4|K6{+$2!Wx4&|m;Uv?F3;ch z{a)$!@|R2gEMBbfb*<h&>af%)#4(+n=PFX>w!^h zXW{~Vc7Nutma4MXxu#64i+qwP9KXEbh$nOHzNoHWYV)?c%e^Q*+x*L{v%UALV&m7n zmD>H^5B}0SmSX3%?foxy!J}uz8RqZ2w(phsuBC^EL7Xu|GhaLM1_d z!3+Wh3=R9=|G&S!;Cw>Bd6DgSn~-tu|#gYwIJb}X-r zQoC~0#s8OQfzPF6JJuSl3|Yy9Tyz5i*h^p8!?OPSm3IM>ZOabter-JI9!e*~{y zX}?f!dGFm>f##9FI75pc&d+eWn)Ranl&AXdS#SRoJ=w}Cb>fWwb9c!FYt!o5!uY)T zW|@CJeAKmXm)MybnX!p8AeJl4su9(-|%Yg#)}Ow~x4GATv9_jJom)Kj>>qn;(zxd{{pu_Eu|OQ z+iSM_|90%`+^@};D|{VDSz*AWcuJo{&9>aEX@-u&UnwU7OnW;eJ0EMJtt=k49ya~970 zDJK=%^ZV#M{_yK*)rX(|zoXy(YeDz)-lx6)_e)ZvK9Ar04yI z(mQ#lzyFkeFTZT6Y4&{YY0d9C-EL7Xu|Ghaf+azI z!3+)!`|tNB2r#TaZ!llseL%qhFW(;w3{2jhE{-7;ac>SV@&c6}Quw`m+i`YoCLo)E zp`kcx88=^(15eyJ$91QE?|&1fbb8^UcYk~q$8#N4c>E~(Wpt2+?=sCx-G5(|J>+Y; zx8@X2XuZ&yzz4P!cl7?eQSy)dnc(#?B6a1;ildtGX}2$FL|*89u<6jVKO(1+KEG#7GB>uHI%QLqv(hxR zKa+yeyYC(ckm`1I)3fc1ZSBa(=Pb-|LAymJZ@!`J~DOQ2hnSlcNwye_urV@u>J1mk9}84zAQSdYp-OiSbaL) zczRKC^~Z+u-{v`{Oo_=nb$w=t+03mq9)|3Tm)FdglhY-InD zUwV7LYD=q@o4(3)R`YZH|35Fbd%H@)@8^e`A5DIJ|MT(pbvc<>jfBDtL87vGuOpI&Z->84&rPFp;g?q{WPL-{XuBz^@ jZ@&Nj`|rPX`;jR7SR)r{{q@Y7KxxO*)z4*}Q$iB}&n$=h literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/eatf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/eatf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..59463a91779bfb5f18ff47a0f8e86d4963902df1 GIT binary patch literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZM#sNMdu0Z-fiD3KGM@>L&f+azI z!3+)W|1%gk>_6Wxkg$G!!2N<($Gs zb|yP)Du~T}Zm(Rc-ftEZ$D!CF;FKYzG*`3j%hvE;VatkBTjTkDvD(%Ah??KLtm+iM z=k?NK{hrY_k2c?WzWm3Bhlktw?XRC*zHhDmM6P|r|({$dr^|3H6WKr(o``njxgN@xNA+^XL&0wqCy z!3_Hw9264P8@!({a6jODe}SF!e|H83MrBVI$B>G+x7Tjx9WoGLxcIdptnmO)zAIEW@dz+_4nSrpVxnRD!6`b_px=Kg7t2tt-5z@ zf7bEin;H-Q-c|eidu)#Ui~L!ZDW{ef6#c*WD>iTT_UG51|2-=D+WYUSn|6YhMei#2 z7rlQKJ=baHM2kK0rBUzMH}byQy{k-dzwK82xvK7SZcX}>{%-!3YgaZo&;LImsxYJ8 ze{OCHuJ~kUw`MFwURk2uV}qSep1xz<%WGPrysghn=O6i`(ORY hD_xbBe?mvv4FO#pa%=3xK; literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ecscf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ecscf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dafbe9e0a17dbbe9a16debf0023eb9916cb1d63b GIT binary patch literal 855 zcmb7??@v;D0LDpEl&mTUZp3mpi^X}1z1P5YR z2`mPK5yL;2TM#n*y;0#I`XqC|g|thQU&IR;{Cs>8I~iK8swxl^GPaAVQ6!t81;r+B za@?OzS6o?V8G{jK<>&4#k}aEiGhu8^j*ED|CAp?1NT>DkSI=NwBl&_8?AL?MNV$h8 z7BMfz*V@iJIKDN$mgn4&Ipd8U+E%E@=nn3metFL!>n7`v?u8BVMmbS3uF;uIZLLtw z^VKYDDQoJc9?N6oTV!`BEFTtB3IsyGwVv)3Yl(h+w{WV=;(eHYJ$ zo-5Uum7kcW#f9W?P8KU`J_DrK?in=oT;Bkjs&nI)ydT2R%2R=>k--3U<+kGSIsN-# z1?5pk5tXf}BG*EAqP-nTyzmF6uPV7#Exh?L7)BTfwmYjSI{YJ!A*3Xr!%LH|1{Pij zA0PJ88?>qMe>bzsg4HzpKUaO%n%S_q9>j)azLdJ7`#VuzhnDapb>3CAHB4Ho;*Y@A zm4@~-sU(uRAy|jy=_@0s{hZim+y=)wGproTM*h`#(tPQ)o{?%B$^W&dM>x{Id@-X* zA%bqzoPDy%F=73Z*XUiZJ*J$E8Vk(wioj9J;&c;NMQRaXcY;YTEWtn!7h-_SpcgAh zydp3Imb87~7Z`Mmzk`_;pl18E9a3u^wa)~0&&k_}Y-+_<-_qJsU}KUIO!$Rkv4tlQ(W^6ZyWS3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ecscf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ecscf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..ca98a51d2a619445c58c0d8b7ce3d711e0fdfd50 GIT binary patch literal 604 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+lb83Ov>|G&S!K*3?YK*RY2(Y*}q3=E8iJzX3_Dj45hxj1Q#fD=|l?$c+NZx>!k)syInuaow*&RUb0cJ%*>_#e9sw$=osUzOnd5*l~fMOr(FXa0BZeG|783EyHb zHQk~)@$oV>rI}pChV8%Jy*X2-+RS2?SpggC$DSi zb93&rPI|L&-|hY{rjb9yzWu-R{M_p7tua5Qwg28%wrjopYPD+4ny$n5_XjQieWiYW zV*ecr+b!?@Io|)As5W^{^QyMRe{a3L9xUBrrSA6ValxOzo@?%H)y#Rm*L#=$j}20X zKiZwWQ{m3OeUGrv@A_&lY56&ZHP@~iX$t)m*~?!OwX$fl?$)ZjMW!+@%k?$|Etxtc zhll;wvFPK4S?Z=ArcYS=&>_CC_{rr>ms9nxPmDh*XZOILg1da} fmy6hmzwzJMw~Dl?7<>}-1I3M}tDnm{r-UW|@(@B& literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/emsc-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/emsc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2904d2770551ffc743b9e62859713385f74b6839 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_0wi;`T%Ezd!07Gi;uuoF`1Xz??_&djwm@eN z6=%&BhX}Pc5sk(V?{|Jm)n0pd<)?j$2J2sGZn~@DISGVbHa_*xw|2jke)-eQIXi>5 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enb-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enb-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e03be510de2ca17e373aa3d7ecd1e08e0fd48ad3 GIT binary patch literal 1127 zcmb7@`#0MM0L9}G)Z+wI^<3h#oqFtqO1(~ZB1TaaiqTH16m4ys*{WV4-;^Mv8jV+v zSfVR6q8@cdYvemQ-lbVfF(zpnk0_CnkorcFS^tCGbMO89bbq`hVfX+eeJgz!3}zG* z=ofxK;J@f;9rRX$*zN%CVdo?L52*hC+DaJSKUkWkhvOq)C?6MCoEl7%kc|*^V6`F7=Lqaayb$v2O2z?KEh%p9i{gcq@ zyUzkjJ6{5{u3@B9h&TlMRb8!zx-5&}J>;*`wpFy8uF3MF{Bq|dKSYs zONpaI{d5HXb?laP>)pE1`kmVO>zt?B@p#4Bn2o_PD#75^;{FfB6D#@H{^-sNV;EGj z)d<}uMKRr%c`u#+;~oTe!UbT<+AE96?z0+Bg&H09O2g%e@0j0Sz%Z!IH-&DuCMPBa zgMeHfHqFP}B5AOpTa%pJb$8qWJH;c>azd(88_E~JQn@p!f{4eq6jo-;RK10}HE^r}5=z$?$_aHmgHO0ocpO(&D#vdI5w|BCsU_9fwI)y=qmx z>r5WglHH|{phuih71+lh_RgPtNi-vEAF*#~w2}e(2R~m#K6LR=*kXi}D$Njjj8cbe z*aO`#rb}eO&=hBJ17r9N&W!2pccNrlu0p@CYQ-^`S*vY9p(#0FZOfcATFu$h-tf(f zL*On}#!@=wwmWh8vT!n7^aN=w(jvgP*JRho{x!g<0&Vf7Zd*I&KnZku*_s3ifB;p9 zp=sBRcFf6m)+`e`V z$gw@>dgNb(d9Y{`pNAD8k2(9bXWB`cUa+h-%j7Y;o<5#p-I%^a>vA~)n?Q8W1_vxi z9mf4C-RdR<11maAE?i5}GkCqOyQHI}#Oi8`SNj&v>ha|~Llg5yM^P!zM%D7wMh;J` zp+}vf8b|f*!#69}D*QFbRZ|B1#sXs6QdM3HyaSdc&7ugy0u|6k31VNw79 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enb-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enb-text.png new file mode 100644 index 0000000000000000000000000000000000000000..9fbf8c298b26cbeb3134ba77feef6d10102869d9 GIT binary patch literal 627 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+it3Jm|>C+t6ee|>>KLw~^hxl0$cGB7aS@^oAq69B+etF_Ens}l&P_#f}uQzVvB$if>^Jb;>UZ|u5J6`IbrS7HS#52XH1u0{-MMF z+nxRrjaK!VF5daY4>{+j9De>rc^}{OecLqaQf;Rm5w^RjJ-^>)*6~%B!;Ow<9PacF zzAP{FzWnF0z>{a)=et~xU^nRY`UX_Uksjf6{dFmv4&JHIce;+iLWWsqlL}mH$-q;?wl3 zslro&dvZgvet1j#`eRh`b=}S6Y1f`r&oAMMt+SonCHDQF8S9mu=XYLs=xvpmGT*;2 z{ImUuR{h_?_cxuF(iOMUSA4`dfBAvd^XW&v*E(9}uD-+{|8kmqCBv`h^2h5k>&|YM z-M2XAuzb*A`Q3kCK0mSY)cvCE`xb1y@^JMp#pG>PbAEco|2C?VH_889Q~uKMSjK1R zqo?lA%Koo&_xtbnEBxB$o?p7m{`=2^L33~Zp0oS=)|Ykv%;xO~cmL0~ ze7f*^nPHa3(XCZ$do1rgO4+ySp}lm?j}H$IxAV)}p)>yP|2hBd!ey3g)%NND(*T2~ LtDnm{r-UW|%ehT^ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enum-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enum-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..daee75ac845c72c81c4077652946c2ec71c151b1 GIT binary patch literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)s4gLG?|7Q@G|K1=#Az}UbMCR643=E8KJzX3_Dj471I-3`x$kX;v;VNz8FRL?R!sGB% zj^Lng-IE2vxgK>*i?6?J&ARe=-9(x1r-S-xoNRcvyft^}z3}bNyv2Sy-~X_Eb@lpR zDbv-b>jJ(WUKPJ6FZH5&>ioQ4&z^64p`P(+aqb-ZU~l%fbN{PwRZQDt|365+y~6gM z{i^xZ7BjYd(|=?*J)>~R-uivhPsx4emN;`|%J=*3y&XT4ANI>!EPj3W`}g3_!Iwig zUO!(yVOreA@_+u<&wYG$_~4(J>*hRo^8DkU(}yokJFC3n>ajoazugZk{-gX&|MOY%`!%1tSIxWo>0ji66{50u6-B(D>U78 zzLS4d)jiAl%_6*ePyPETZ!`DN&w_tXHdeE$v|ant{CG$hn>i!pf|9k%KcmMGF z^|AH;zcJtYZ@cT$zd(D42l7+){d_h%|DS$NP3L((6-H-ZvS9FZ^>bP0l+XkK#JF+s literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enum-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/enum-text.png new file mode 100644 index 0000000000000000000000000000000000000000..f04e3d5c5e95c6eecb935773f308fed2e7b8d5f3 GIT binary patch literal 551 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+lb8Tu0h);s(^-!MNw;eEk<&3Rf$3=E8Yo-U3d6^w7MKFnLAAaL|!YQGY*)~|p1 zxBYf0AE|5Pt)6{n&j0qVS!eazIBN}#NhJ3eB8YGC&*yDt@Tn@@vFZ7{^u)7O<~I*5 zJf*)re7oEZ@h8)&s(R(7+43(s=vDQ7i|ZE+-EXgIUUp* zSN^Dc|9SKF%87CEVSlSTYxn7VtC^r5JYRpaU769D=@;JJ?)zzR?EJQ+y>)eOZ={&N zKYRbF{5Rg-ehF^$zdkAReAw9WEb6Zj8+Y4}e^*|=jIMRD zW8v-+obEzV_Fb imzS6O&$mNk{Aac2>bmS2%2EW3HwI5vKbLh*2~7YayC+Ei literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/esmlc-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/esmlc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2904d2770551ffc743b9e62859713385f74b6839 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_0wi;`T%Ezd!07Gi;uuoF`1Xz??_&djwm@eN z6=%&BhX}Pc5sk(V?{|Jm)n0pd<)?j$2J2sGZn~@DISGVbHa_*xw|2jke)-eQIXi>5 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/esmlc-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/esmlc-text.png new file mode 100644 index 0000000000000000000000000000000000000000..0a29e736f2410bd5f0312fe20dbfc518322d09a6 GIT binary patch literal 701 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+Wp3aUZOeAM5= zAH;2#y6$F`$$s6q^BuKXpCoR&#ZXh{{@g z`0G%y>plNJh7vv?tkoGc6ItzxwA#D(pOHsd-cfon!Q%CKayq?TYR5v zr}g&Kb+MIGe;&>kZnXH;%zXd#WUFtF%WDeOH<$m+J!7_G$+7dt|GnPA9sgMIR>`^< zd;J}&j>-HE+U#H3+m$i#%60McpW?qRzVgLLxU@?7>&@@EKa%b1%zv$&v&}A~%x>?! zgEg<(t?ja#@1M?`7#22v`990DM}Ldgzk2Og_G){4D}U|X`iGtSkIhS7tDpMa?zn^a zzR9<0?#thb&9wiU^W%`ZWLr$tqw||)ZeQOMS$j6--~Wm_*L`}1zru{?&zJW$I%DF# z^5Rzcr2MP@@1GU?oZ>upK3lx>{hgt0Vf(&qU6FraU(s!U$9uP4>^z_MZK1hfy;Bq^t!N91hfy;Bq^t!N95 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/gmlc-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/gmlc-text.png new file mode 100644 index 0000000000000000000000000000000000000000..43cf74d9bd1a09c5dc7fc4f98c378f733f650de1 GIT binary patch literal 755 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+ux1`Pe@6ZQwJzu)j)pkV%vlMh1~7?`3xT^vIyZoR#JchX`7fwqT?Q4WGz-v3YA z&Nlh4K*UnBYi|yItDd5GO1R#Azl!H1RP@U~C`!7@;_lqf-LKB1Sf;D@20q^(T#|Qg zapf(|`jXn)x({ua@BFs)xzg&FS5Muqv|5@Zca~fB^;+B7-k2w6TkQ+4PV$;>?sRj{ z_o+`;eeM5u&NpnTowSoQ{|~jI$^IX-_nn6%=f>H<(Pq+A?!}ZO*@# zbDaO)-2VPWBk=X-rn#lhwbwLS@|M-#j`tfJ^nY0VJ~OpGr^IJ{Yx0hd z-;)h@eO5Gx{rURSuDZt?*Z*nlceH=K&y_cFN{n+Wzzwf9~*Sw0^y3-@2Njz=QI8{x81r^*+n%XFmepPF`j> zKgW7`^7ZfczncZm74m+4dByu3vy6Rztp1c~ZLg#9W;ClIW3RdTb@J0?GweQ{ER4QVJO9$T(1RD!?OxufS-9fUMVTEr zUSC%FXLiMiJbV4!esBAC7U{YbulL>aefm58Zp+=S@B3qgo8nWqT$ i_4ob2LHzUo!fmARaQ5OC6?1@TkipZ{&t;ucLK6TQbf($> literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hlr-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hlr-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..daee75ac845c72c81c4077652946c2ec71c151b1 GIT binary patch literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)s4gLG?|7Q@G|K1=#Az}UbMCR643=E8KJzX3_Dj471I-3`x$kX;v;VNz8FRL?R!sGB% zj^Lng-IE2vxgK>*i?6?J&ARe=-9(x1r-S-xoNRcvyft^}z3}bNyv2Sy-~X_Eb@lpR zDbv-b>jJ(WUKPJ6FZH5&>ioQ4&z^64p`P(+aqb-ZU~l%fbN{PwRZQDt|365+y~6gM z{i^xZ7BjYd(|=?*J)>~R-uivhPsx4emN;`|%J=*3y&XT4ANI>!EPj3W`}g3_!Iwig zUO!(yVOreA@_+u<&wYG$_~4(J>*hRo^8DkU(}yokJFC3n>ajoazugZk{-gX&|MOY%`!%1tSIxWo>0ji66{50u6-B(D>U78 zzLS4d)jiAl%_6*ePyPETZ!`DN&w_tXHdeE$v|ant{CG$hn>i!pf|9k%KcmMGF z^|AH;zcJtYZ@cT$zd(D42l7+){d_h%|DS$NP3L((6-H-ZvS9FZ^>bP0l+XkK#JF+s literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hlr-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hlr-text.png new file mode 100644 index 0000000000000000000000000000000000000000..b2762502b069ca30cb4087e49d8c1ff377c42b55 GIT binary patch literal 376 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZM#sNMdu0Z-fiD3KGM@>L&0wqCy z!3+%!``_PBP!I?xn7_W?;Jk;@FK(dR6Hgb%kczmsSI>4GHsE1My!p}pj>_75|1-ti z6Q=#zG9{{g?t78MiH!~$*02DTgMol^c*=^0W^;Krwie_*<5+siy{T+APhkG#n+x(k zC6~XR{pZWu?5bbiO!eQ}CtY8ck{o%rKPl_lyDzW2FY8%fh_%E>nA}{d=>bP0l+XkKn6$yz literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-epc-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-epc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..daee75ac845c72c81c4077652946c2ec71c151b1 GIT binary patch literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)s4gLG?|7Q@G|K1=#Az}UbMCR643=E8KJzX3_Dj471I-3`x$kX;v;VNz8FRL?R!sGB% zj^Lng-IE2vxgK>*i?6?J&ARe=-9(x1r-S-xoNRcvyft^}z3}bNyv2Sy-~X_Eb@lpR zDbv-b>jJ(WUKPJ6FZH5&>ioQ4&z^64p`P(+aqb-ZU~l%fbN{PwRZQDt|365+y~6gM z{i^xZ7BjYd(|=?*J)>~R-uivhPsx4emN;`|%J=*3y&XT4ANI>!EPj3W`}g3_!Iwig zUO!(yVOreA@_+u<&wYG$_~4(J>*hRo^8DkU(}yokJFC3n>ajoazugZk{-gX&|MOY%`!%1tSIxWo>0ji66{50u6-B(D>U78 zzLS4d)jiAl%_6*ePyPETZ!`DN&w_tXHdeE$v|ant{CG$hn>i!pf|9k%KcmMGF z^|AH;zcJtYZ@cT$zd(D42l7+){d_h%|DS$NP3L((6-H-ZvS9FZ^>bP0l+XkK#JF+s literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-epc-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-epc-text.png new file mode 100644 index 0000000000000000000000000000000000000000..9739214fb407ff52edc0d21c66cf4a9141a23e21 GIT binary patch literal 726 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+ux4FC5xB&@$LVDP@b;C#URMGTXe7#NsrJzX3_Dj471INP_{fT!(Y=Uagj{EFY} zH$Ru?5)53DXJE{2KYP{vXSzYFo$7iFk4YqhiG2kO4Rf=9zhmFem{jrUPu`)}8JXM9 zC@S@t@2!h^F{xWRKkKhcdETCtU&VLLEZmd%^>Uy`&DCsGCYk)GzfQ9+}rX? zcz@NNm*!{d6sCPpn(Zd<_w{o57VYr0_vPM{@93Y$=Y3OYQ(f@8r$N(8{lUJ2! zc0Bf7eg2TsqK669>)!iE{?ZXWxpuMd=l||SGjAB(`|?Z4EGchK=J%)d?8jz@*)!d9 ze_?*NZsE;`ibCCseZT*|-rn+}Z+?s{&>3EHbN6U|O@0}~>puI@`}13Uls+5Xkb9wi z{zJ%*SO>A~kF*27`Q~li{kCymll{Hz`@XKtuYDbT|JSv4zdte?{j3Wro`>yo&Cae` zwbIUdfqzEjr%Lgaw_*(!hc`>am016yq){s&mS#I zeu+=`_rhht-n;&vf397eedT?*&A%*r>$i2Y{rr9{QnUP^{o~U2_#fM1l`Ct0e^=+) z_#^voZ^Qxbnyvjaud90P-CF)zc;l-A_Nf_FYvT86#Ks@-(b>+M@b$)W2dma$tRfa^Bq6b;Ub&?f?8I8RB`QaQM$2$T_>L$@Y^H QFqtuUy85}Sb4q9e0IDa5X#fBK literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-ims-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-ims-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..daee75ac845c72c81c4077652946c2ec71c151b1 GIT binary patch literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)s4gLG?|7Q@G|K1=#Az}UbMCR643=E8KJzX3_Dj471I-3`x$kX;v;VNz8FRL?R!sGB% zj^Lng-IE2vxgK>*i?6?J&ARe=-9(x1r-S-xoNRcvyft^}z3}bNyv2Sy-~X_Eb@lpR zDbv-b>jJ(WUKPJ6FZH5&>ioQ4&z^64p`P(+aqb-ZU~l%fbN{PwRZQDt|365+y~6gM z{i^xZ7BjYd(|=?*J)>~R-uivhPsx4emN;`|%J=*3y&XT4ANI>!EPj3W`}g3_!Iwig zUO!(yVOreA@_+u<&wYG$_~4(J>*hRo^8DkU(}yokJFC3n>ajoazugZk{-gX&|MOY%`!%1tSIxWo>0ji66{50u6-B(D>U78 zzLS4d)jiAl%_6*ePyPETZ!`DN&w_tXHdeE$v|ant{CG$hn>i!pf|9k%KcmMGF z^|AH;zcJtYZ@cT$zd(D42l7+){d_h%|DS$NP3L((6-H-ZvS9FZ^>bP0l+XkK#JF+s literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-ims-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/hss-ims-text.png new file mode 100644 index 0000000000000000000000000000000000000000..ec69f2599a89ad45dba8e58d50d846e7e090f5d7 GIT binary patch literal 757 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+lb8Tu0x3hvK;FW}G+aDKfq@6l2Q2Bug~7srr_xHktHfhrjq7W`c)z7oXBJAN-r zk3CU?p}#YVKQs5<|5SF@GgJOt=$h3oUdRNT)oILrbzssPp1-qx2)<&NdOT)jnVrqgYmL92+*~|U zo_zwJl2u+BpDc%StAk5=^0SQR?e^cd&&y?~{2<(6xp;0pSL>@4N6y&S?b??YIc4kn z9qO?fGrN-t{$B}~v{RGQ{5i?D!{*S*$vf*$N-&+Pn0Y4Ub+Sg&Qg8i+gEN0g7<(UL z;Ye9$5iD;gmz$`fzu?Qk&*8cYITgG=l6-9w5#{Zv9WSUU%WQzYHmVkUEtT0%XeSz|FV?%(YyvB^}EYo#jX7#bTnW8?&{X_8!FD9 zzJ7Q0%=6E!6!yJ}0MwdZyP*If09`1R&^UpG+g-uPW5i8|R1tE#tt zN&m`o_q0LHRiLtp^|2nMzd(Xd!^$;)My#!QInQ4tzI1(?-LJ1QEz{p!J+^)=ci_)e z)ux{=o;?)}HoW3P@2PP08$V~fJ{*2`^-_Jo`11Alf9S+&^>bP0l+XkK8&;t# literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/icscf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/icscf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dafbe9e0a17dbbe9a16debf0023eb9916cb1d63b GIT binary patch literal 855 zcmb7??@v;D0LDpEl&mTUZp3mpi^X}1z1P5YR z2`mPK5yL;2TM#n*y;0#I`XqC|g|thQU&IR;{Cs>8I~iK8swxl^GPaAVQ6!t81;r+B za@?OzS6o?V8G{jK<>&4#k}aEiGhu8^j*ED|CAp?1NT>DkSI=NwBl&_8?AL?MNV$h8 z7BMfz*V@iJIKDN$mgn4&Ipd8U+E%E@=nn3metFL!>n7`v?u8BVMmbS3uF;uIZLLtw z^VKYDDQoJc9?N6oTV!`BEFTtB3IsyGwVv)3Yl(h+w{WV=;(eHYJ$ zo-5Uum7kcW#f9W?P8KU`J_DrK?in=oT;Bkjs&nI)ydT2R%2R=>k--3U<+kGSIsN-# z1?5pk5tXf}BG*EAqP-nTyzmF6uPV7#Exh?L7)BTfwmYjSI{YJ!A*3Xr!%LH|1{Pij zA0PJ88?>qMe>bzsg4HzpKUaO%n%S_q9>j)azLdJ7`#VuzhnDapb>3CAHB4Ho;*Y@A zm4@~-sU(uRAy|jy=_@0s{hZim+y=)wGproTM*h`#(tPQ)o{?%B$^W&dM>x{Id@-X* zA%bqzoPDy%F=73Z*XUiZJ*J$E8Vk(wioj9J;&c;NMQRaXcY;YTEWtn!7h-_SpcgAh zydp3Imb87~7Z`Mmzk`_;pl18E9a3u^wa)~0&&k_}Y-+_<-_qJsU}KUIO!$Rkv4tlQ(W^6ZyWS3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/icscf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/icscf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..6dbfc819cc612b6c1148c4882c1b114cdf5cedc5 GIT binary patch literal 657 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+lb6BrZ<)}R01AK>u*zQFv3-Wk8j85kIUc)B=-R4~3d*a%e0(6Hd|O7WFUASMID zvZZ`w%Iu8_Jo*7Q^ky%6_&2`na*|`F=4STpn(b3u>UwR@tmpjbeTe^4VVuh2zX@99 zBAfa$FI`bOxmvZ=^P*?LzXRHTEID zKXOI?+Lx+SaPi{Ia+mTiTQAMwU*NBz$=J9oeYVui1ix9@ngLS#ReJsfF8j0Sex^`c zN~O$`6;f|2W#f_smR0UZsJyt|?B0x^8UME(&fFF|!|Bkpx&ZD=H}{|8!aeV*&$@9&-2ct8V2)&3+#hBSlgx8-bN%hR*A}g~I(dT7g3`F^C)s=I zA1vCLdn~zriEgcoOp*+1*jtn9H>+h%|6<){>Bg7nEpINX8TGQ)Nyv)*+n0|VJ55-( z)W@f=9dgw(ObC~s<#*|db+X6Wq7uHNpG+1`42!$7|No^Ru03z2t(>x`VB44agZIBZ vivY!6!i4=_Rm!G0)a}3j{`>F0C{#V8*XETGu?$}~gH(FD`njxgN@xNA_B&Qs literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ipag-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ipag-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6f15bdbf4793415b578edba7d857b391ea3f0279 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^^&rd$BpBWuQ`iTjm`Z~Df*BafCZDwc@+3T6978G? qlNabpur5vz>1hfy;Bq^t!N91hfy;Bq^t!N9mTUZp3mpi^X}1z1P5YR z2`mPK5yL;2TM#n*y;0#I`XqC|g|thQU&IR;{Cs>8I~iK8swxl^GPaAVQ6!t81;r+B za@?OzS6o?V8G{jK<>&4#k}aEiGhu8^j*ED|CAp?1NT>DkSI=NwBl&_8?AL?MNV$h8 z7BMfz*V@iJIKDN$mgn4&Ipd8U+E%E@=nn3metFL!>n7`v?u8BVMmbS3uF;uIZLLtw z^VKYDDQoJc9?N6oTV!`BEFTtB3IsyGwVv)3Yl(h+w{WV=;(eHYJ$ zo-5Uum7kcW#f9W?P8KU`J_DrK?in=oT;Bkjs&nI)ydT2R%2R=>k--3U<+kGSIsN-# z1?5pk5tXf}BG*EAqP-nTyzmF6uPV7#Exh?L7)BTfwmYjSI{YJ!A*3Xr!%LH|1{Pij zA0PJ88?>qMe>bzsg4HzpKUaO%n%S_q9>j)azLdJ7`#VuzhnDapb>3CAHB4Ho;*Y@A zm4@~-sU(uRAy|jy=_@0s{hZim+y=)wGproTM*h`#(tPQ)o{?%B$^W&dM>x{Id@-X* zA%bqzoPDy%F=73Z*XUiZJ*J$E8Vk(wioj9J;&c;NMQRaXcY;YTEWtn!7h-_SpcgAh zydp3Imb87~7Z`Mmzk`_;pl18E9a3u^wa)~0&&k_}Y-+_<-_qJsU}KUIO!$Rkv4tlQ(W^6ZyWS3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/isbc-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/isbc-text.png new file mode 100644 index 0000000000000000000000000000000000000000..a842e9ffde944cfb18270e2469d46eb8d5821e99 GIT binary patch literal 649 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+it4E_5P0_Oj}-=Oebpy2#^t{FE)85kHpc)B=-R4~51c02E}g23^Ihh`iuFsl4N z{jO|=g2uhDsV|Ru{eQnoHL$M2E6@&T8Up-N_R98+|FOWk{paaR*3Ws3*@b0IJ@3to zWO49T#?ARQrAI$3nzsAz_G!Cc zZJs-S!-h9E(`{Rq$8ByKjeIFET6p!dtq|Hhp$o zp1oC8*YrPc?YMorm-_2Gd+fb$^SpQ8i=+RnlRvgXYwf#l@;ZHA&hM-KHl*NR(So~wlPW$vU6e1>xnp(y*~^ZH+Mc@Y-u3^~ zxw@2%a}4L-e|KNtXkg@(`)}4q7i^hVfA`wkVy&#=dac^OGydw;{aY4sBmVXIOSi7; z%nQGo{QKu}$NIb9b%c1Ix7Bf~>Bh7EdHUz`4G-PV^4IUbcb~aZIdS^rv}4PT-Qewh z5M_I6_uISs9<7r)?5j8bZ;n)6m51l1{UJMp&3{kZ|NozH`$D7jeYZdR&x=p-4*$D2 zV7bBVO!_z8&9WzBGS{<&t;ucLK6T4vu1Aq literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/iwf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/iwf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a82e73c193297eabbdb8f1f862ddac30d78454cf GIT binary patch literal 696 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+ZH6&M`;zYpl&-%v0=;l9Cnw=G%53=B;2o-U3d6^w6Z-pzZWz|+cY*se19!{>kc zyUnegs!bewUbRZsPY+$mHcCY4gQ{yK+t2rI{E)w%d>O6hqxw@qIC z?>E84PZm8`e)x^nu};s!{Yt$3>ouhQy;%{X_WR*eeb#uv^4>qux;uOFS6Dq?|Fq(P zbl%)w+3pGdwSF(TP%r(x;%V@=H|kzL&hXha%{v$N{@=%U*T27iEr0vi%jNg}R%hP% zuP!CN{Qc9L^Sd*CY`@`o-*?9TZ)uOelvjS)|K-{F$GMNcoPYk)x?|q`tLHwJngSn?|BCk?F8*s% zlsozFRPXy&BcA=_FZi|Z`u{zbzrKHPY&OG!U7COAd-GratzLKPulm$W`9~|xRMhXZ z{2SKe@#{1H<33)IXfq{l)yRZCUTn=_-FkpR^vE@?AXY;Fs_73;(;ypTGS- z>fr8OS^v-WiGA>Vum6WD{L!25{88p!F%SGplzA6Vu79-7VqN%$<5zM|Gqi&em%+o!(Qhiw1!U;cw%*suJFQ~yoZ`KliIvfnf8SMtQtx=a3F`rpTE t8}9#^o>2FB_WeK4%=iC1n-5|BXHMLFRZ#Tv8&JAr@O1TaS?83{1OQX&h#vp| literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/iwf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/iwf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..4d0092eb0ba59affba0db2a4cabc1192a8e2b20a GIT binary patch literal 595 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+%w3=ReX3IFF8>=)?2e}4V@K=rl985kIMdAc};R4~4sdbV$|fdJcalNkwT{O|ow z4PT^b$#W`h)7-O-P{NX<$7Qfe7dhOrNw&IT7vHIK(#Zt#FxfvPP7XEAHJ#xM5@O%4d9`$+B z88-H1t|`)cJN_Sf{_l0AmA2u;FQ*EQ{H)AR{AFYuc=D{!Yki$Pjnl*2lnOh(@T=_n zVXN`G>5|i5oxSH+k7oRS`{!oeNB`Q#^MBmjxN}?F`@e3sr}c~eWo%d7|7BPAXTt1oqc{=S)*Z#W0_qV1Tem3#uqrYqKx*2=OX)^v}_*cLG&!^M+xQPGk*Lu2B UHc!1-0gPh?Pgg&ebxsLQ0N7YT!vFvP literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/lrf-rdf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/lrf-rdf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..82b5c473bee9504bc5d5d9044a3f5a992502516f GIT binary patch literal 953 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+Wo=l?VG&wsDruz!8R{Q`pkTNC$H3=GT)o-U3d6^w6h{4ZLfA#(I%!*eD3mTTYZ zZ?3(WvHYy$E2G;1D`!3Zz5QGJ3XLbp-1m?@9R$-zZ(C(U84EjXU^K1$qWa!{yxU&U^Mqnt6cHX`ycYX-D4Pn99o!q|ZODJb{(de|uI>n!U~Xm*CC^ zTC4XR4u4rEt9{${X@~7Y?d89u*I1ZUo4OLc(s17PDbX!;Mp~Md$w&Vu&wFe zwny?&deI$06`8(cQ{8`*d|z9+&Z=O2&xi85GwU;w-Z0mkt|?_GYncC{IV9d}DdWDP zcJ8>>@7ecEn|f1l*Kfh~A9>6xbo;(`7o=`jZyW!z{)w{%&$p@KckFJ6$EDsaYJR?7 zx9^tij!jwPf3YfihW+1{{`J2u&;R#jIf!Ym zS^e)~-Lde>CF|oGRO}zle*47S_*D3*+xoWMJRjQ4AgcefD>_KB1TDM1449J`JYD@< J);T3K0RVwr0!07- literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/lrf-rdf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/lrf-rdf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..14daba85503440b4f70fed21c83123b3e5d15a72 GIT binary patch literal 638 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+it4FC5RC^YoXPYAewUf}(D@rlv$3=E7Gl60GlBdjdvTleo)SR&t<)~x@0PVqTQ5b-yY+vLYA{Te=x2j<=j{vXnP)am&+ zvsNM3^xfsOOZ>k1Z`o>XWIJb>{F2lwtc%xC@p{jG<=J<`VCJ&F33vRjxNQFC=X>;? zzs-R+b{)ye8|T%wKL0i~%I9~b&!hTg{ zoqbG+{iKGSwXWX_7pHB0)$eHXI(bps^RLqv^oDP+b}DwiCa(0d)JEFW38R{{Q~5_;kj<>9^ANU;VYcchx)nug;EG8 f{XHZY{EL7Xu|GhaLM1_d z!3+)t3<(VZ3jg#&IYaem)}*%#hc?nr4` zee|ZloSUk<_Ai}U_4CE7ML+-e&0_lzGxNZsTN{?k@BRMN?Zzo{)>luihi5$fz4ySq zCp&zZ8_pGXO6~e}=ae{C^~qS@xfM6=s!v}%J%53Vl-rMhnti`HZ~gkcZ9`}Nzk>Pt z)q3{q#%K7o(rq>iH#}-=n)7k1U)}8XSNHuT9-jZQYQK{o|F^~Wy{DU&-~1^0?8lmY z`~Qoa@8&C2wtKXB*RRsAPq*FvDs+DN^7!|=Y}>V`@W_{aJ2-#$ynMTQjgM#KJ}uVI zU7PNShQQr^vn0RsrMOo@7R3v zknp~bzPCS~3VZ(iyFlL?EB1Y?+OPS4%oUEW`FK&j$1@vmo}n@K(W%(5z;`^r^*X{B=$kMH|Y=y*i+Drd%BHFhpNcjlV1jUQhhUjEfoo=KkX!}A)0t#z?{e`^o3 zZ~OZCaK6=_C*Hp_>kq~}_{g)izV_FP_ovq%{+As8b#JTrUzZ8hPye~cJ)Qq2_r&}C zE6>lm7x`bL|LXs1|F(y0{a7lq<$tu??Q7d5+H3!PwBLW{KYs(a$$|MZmY%;~&-UX$ z`0l#Tf7gG1p15 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgc8-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgc8-text.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba933a74015951a442990285b1e467031a5d58f GIT binary patch literal 771 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+it3B=3=B+Jo-U3d6^w5V8ZrXa9#Z(d-0YZK0+0y= z0anXXx8$gEIA5IAAmDJ}|Noo!UKbXB^I%`TPF>dEv_prU(xL{ziLUB8N`CDBG#=JR zOy&I7E_cl}UtLo?_0+DLo&0wXdK|4N5#Ik-=*Qf*;!mV!*PiriT>Wk7TdM<)b1OfX zd+8qR*Kj$sC)GH4)xC(`%+z=0_4NU6wr7ja=BcP|=-5`7uYSDwzERoP6Y}fZn>*I@ ze%i6!w0He_a((aj#_j*EHXD4ge=ql^;=pTfd;gQRQRjYUWb_yB_qMp~ z{8w?Ozwg4GXaBIq%d%{%eRbTD)9YVS#f0i&x5R0k_66SY7j&Q1^_B(fcY3_Wy#B~> zRlh%yin|Wk|K4i#X|c+z;0>R;3%v^+C2JqEKhghDa>;$WqRrYfo9^y@vg6;^*8i&> z9j-m3!s5F9Lwe&>tA7uBzKY-bVJdm<;;)@|WIi4Ke>BbJfZ>lnrr%GUj}_7U$lW75 z&3o#JU#Hg3lHR`2_29i683iZfq^sq1|NiHdh97!*?*aeCi9xq5`2N=ix%^u>VNS8g zavsI%bCwr=ME}44?O6mUy(CQ7|5c@InuGEF`|rR1{#ys9{(t`c_a6h}k)CTmoEh~% ON5 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgcf-emsc-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgcf-emsc-text.png new file mode 100644 index 0000000000000000000000000000000000000000..74bf8f2c66fe26d5285c68efaddebcbe1efab21c GIT binary patch literal 1140 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+)s4FU`b``;(5KR@5#et*E`(?4f2FfiZoba4!+h&@k# ziSmyH4K1{VK8pErovbl?tA%=+1K8Ej?%-|^Y$#;A#BGG)TFrI zxPswqu#{u`ZyAfnw~yt|{eJX#enbkNY0~l5bz9Gz72u z*^)n7;mMTq%pOPUj%x~O-l#m|}-`g6WjrfOd5|2Hi|)Ae^(M_u=^Qx5Ce=S_Jy z?-A$!DuxATPCWl>dHwHG{raD$jsie%>P7EGtsZM}DzMP%;Y@4CBA|9iY_ zLFb|+>nt|8vL(5m3cL4^{jkl0yX_51r9B5!r(C>VyYs8b)IaTO*=zPH-aJz}|NA}Z zN&ftMzfb+v9J7M=-fzQ6e>a^k{n_!R`_l5@Ql3EhUl(s=%m31}PwSuY>D;~>?{*%r z`xE#3HP2Pvmyw$V|1a4ee((51f2Hkd^A|sB;=f^B=i;ZK(^u5&_E37>|DA2WUj5o! zu8}$S*Ztk~U$VG@n!Al6q6Hlmh{u0&|J$IZG>L!iDcLJk0ydGR$N35tzA~+U&y~OT z_1*HuH7aILEAN#DFMQ`}U+z7ng6C)0#K$f9p%dCqyVgfsv55KfGD%qX=N^U+40^vT z+&AVQ+QB#3U$eJu!jJYQ^PjV7xwr65Jg@n)uIpcJC zjye0jucu8K&fH(*(-8c+KEZBxer>km`SSU;NBv(P`uSV_i>1`RoyR@pzvv#|eZM!X rl~M1?GTmAKtNw5OgA~nR=6}vrdmXZmMzTHt=4J*@S3j3^P65 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgw-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mgw-text.png new file mode 100644 index 0000000000000000000000000000000000000000..a2470f5d133ece5544bcb9e7d2965cf5dbe3cfc6 GIT binary patch literal 823 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+%n3TRfe66;s zlsosxp?jmX!Y4}(TgyjIfA!;HJ8nJXXckiP7P&8wn6hf60e%T7D~?!~WzwmTjzUKVL57c=Rx{vCsP`QZgO zUw&mUh`$qAH(j^V?tjvXsps$PJ9?q|k+S4RPdky_&llTWKc3~z^hsGoc~R;l|H`_s z`zKoKwPOyNmCOkJraJ%q(3`=8rn zRuyfSo@*BE=3H~yKhP#_ol9r7S^3YOrt+_D3)hQ$x7wBF-g;|#&8w)?EBkIGTh4#w zAL{x3Pi3s`pTLyo=}&*|zdbvd5tQN_|6SXBBa~_GpSu0`-+%x8_g^!Zg7BEvTwfr= TogDZ9lpsA_{an^LB{Ts5Bd)Cb literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mind-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mind-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..daee75ac845c72c81c4077652946c2ec71c151b1 GIT binary patch literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)s4gLG?|7Q@G|K1=#Az}UbMCR643=E8KJzX3_Dj471I-3`x$kX;v;VNz8FRL?R!sGB% zj^Lng-IE2vxgK>*i?6?J&ARe=-9(x1r-S-xoNRcvyft^}z3}bNyv2Sy-~X_Eb@lpR zDbv-b>jJ(WUKPJ6FZH5&>ioQ4&z^64p`P(+aqb-ZU~l%fbN{PwRZQDt|365+y~6gM z{i^xZ7BjYd(|=?*J)>~R-uivhPsx4emN;`|%J=*3y&XT4ANI>!EPj3W`}g3_!Iwig zUO!(yVOreA@_+u<&wYG$_~4(J>*hRo^8DkU(}yokJFC3n>ajoazugZk{-gX&|MOY%`!%1tSIxWo>0ji66{50u6-B(D>U78 zzLS4d)jiAl%_6*ePyPETZ!`DN&w_tXHdeE$v|ant{CG$hn>i!pf|9k%KcmMGF z^|AH;zcJtYZ@cT$zd(D42l7+){d_h%|DS$NP3L((6-H-ZvS9FZ^>bP0l+XkK#JF+s literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mind-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mind-text.png new file mode 100644 index 0000000000000000000000000000000000000000..84f9d86d79fe9f3ef1c6301f65b46280dd308321 GIT binary patch literal 550 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3_KR84?WE3ph0Vzdv8${rP}`T6LSn3=E9Do-U3d6^w7MU0gRuL8SFzGdIh24&(R# zHyuqVzje%3ZAr}8U+<4KKNog=#Q(cZBDu%#7=oCQt^33HeH0_dJ09KZQH%LF_Mi8h zo$Z-j-rfJ>0)NkwGtSNvHnXT$UN)2r|I5#JK&^gif8c(Z3#%S>Z?9SV!!dr&zqlix zPAC4FCI2P$^8eglLHU2H7%cW&{@hl>Y0-W3OZ4fv?=O6=>UFN`%~+fCWAF5ruP=Kv z@6)kjzpa1q)7N`X1^0hBDZBLlj<4NGZT&iHYmd}_KWUknTK;~2>D;I~dBaD^S0&$F z{P0_XbKCr14TAC4_p(IP-TD31_DANCh<_imvwqgd`fdJOcjMo`8Sjz}|1SFDBmec`@8WIsB416X?_Imv-u~B@mzS6O j&$p{ZXZ-vAV?V=&?yfm)-Ty^_(Z=BE>gTe~DWM4f2ZA=y literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mme-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mme-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..58ab86c5933c0aad87db2d095076149b51d26484 GIT binary patch literal 232 zcmeAS@N?(olHy`uVBq!ia0vp^Q$U!J8A$qnnlv3qu?6^qxc&!&(3-C~KoQ20AirP+ zhi5m^fSd`QE{-7;ac{5LavfC=V0qxsHAPO*{bN#-Wz?bF9mgw&>^! b{%4GrcU^lEndM~xbQ^=GtDnm{r-UW|szqhQ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mme-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mme-text.png new file mode 100644 index 0000000000000000000000000000000000000000..e524f192c82bb73e202b79182d657927d32462d4 GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^Q$U!J8A$qnnlv3qu?6^qxc&!&(3-C~KoQ20AirP+ zhi5m^fSe_sE{-7;jBigEavcf~aJ?uVw4}#+M(&N&WG5!Q1G<0DUDEA|h)_%IGC0rZ zIOEX#pb0zgyi)jmc$3cStL6tL;%cnkW%3GdL26Qijr>mdKI;Vst046MJIsgCw literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mrf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/mrf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..59463a91779bfb5f18ff47a0f8e86d4963902df1 GIT binary patch literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZM#sNMdu0Z-fiD3KGM@>L&f+azI z!3+)W|1%gk>_6Wxkg$G!!2N<($Gs zb|yP)Du~T}Zm(Rc-ftEZ$D!CF;FKYzG*`3j%hvE;VatkBTjTkDvD(%Ah??KLtm+iM z=k?NK{hrY_k2c?WzWm3Bhlktw?XRC*zHhDmM6P|r|({$dr^|3H6WKr(o``njxgN@xNA+^XEL7Xu|Ghaf+azI z!3+%n3)0RwWCB6O z?~={QiX6-dB?}ttU6;K7zbW~$1&?`AxJllxTnAqZ?p3=#eb|3sy%NKcr?=MJzWUCl zX-Z6d)BC>%zISk6IOG#vqf;uYWcjMt_)pVW`xQTHm(TLIzBAY4%gNP0pE!2?JRD!^ zm1)_by?y@n{pT#}+&*f5wad5A=YMpWZLOu9?A?;mI_YlL)6+LAUN|9sUGtYE!?fvt z<}T&hl+#~#bx-}8JqA9Oc0YHVny~5q(`7&2K6=@5Z@sko4L+|r>u(L`-mhBmyxWVl zy)Mn`e1GJPjq^p&#HeAw(5ZGnf=pWUjMqWZ6bf`)!^&w zEfe*#0>34`S^Oscb7JbZiu3$Oj$W^s5dXpU|CIQGUGsOG5 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/msn-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/msn-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8386fcb44ff81ceba2217e0a5786ed2dcd66028b GIT binary patch literal 465 zcmV;?0WSWDP)mu^pozi}_9$E|65PaB z;V5)zkj95N2k926B-z_OyCyQi3 zsH-Hjh@vbL#4d}b3qdU3HGl4OPHZ2x+agA0zOHDIt4W3vrVA@6bIqbM+l(Hv zwOM%3zRGNwW=rHJi{y4@{#hkG2(;#%IU*Z(W{BSD>E<;**$I31z?A+@00000NkvXX Hu0mjfE4kN> literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/msn-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/msn-text.png new file mode 100644 index 0000000000000000000000000000000000000000..954982f15f8fc4958f47c0e4f54031c32d17df6e GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^Q$U!J8A$qnnlv3qu?6^qxc&!&(3-C~KoQ20AirP+ zhi5m^fShNZE{-7;ac@r<`Y}85v?i_(3h?uOt{o7h@HW(fQ`qmo)SjRvX9PFNs>Urn zA);(A!B^}0qc=OY z;F4sk|6J7&yK85|_PjjzHet5rq@Zo{r}f+yd~-B6UFYJwJ8B!AB=qN9xmkPZ`Rua? zYrKvfT6^=!G^yyu_&4h|atB0~{aycMndB*>tEaktaqI1^-F!_33~d*coLZ|Y|8L*wCYGq6Hbuxb{u94XdbXt0l2fKj zt=5Wv`te6;>)Xn;6OKRMpS`{J{Qpz$`5wNnly9-In}6PZUi?23zREw!zwefP-JH~; znE$T6uH1K}-eH55JyHK=1aVc?0F^!e{1cV>6aV%1kF5OvRkL?p|1kX{SoZ$S_&@w# yTK{hS0aE+l-Tve2U;P^cF8_XB1yoRXbY86N#?6Hy$L<6Dz~JfX=d#Wzp$P!f)2eI$ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7450-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7450-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed07db41f7397e45f5a3e07f37a819507c6ed13 GIT binary patch literal 464 zcmV;>0WbcEP)jq_gkv`UTL>yxGzV@17yFPllVf{q`WU0ahNh&XIl|R0}#oxqnuel{*?h`w9rj**TH)I#H27{<cXF4C_wH7ybMH9B+P|Q!{WD?~9Jqk9 z#A;jART4R3S5^pv@j=stAXaW#xHP)tZf~xc5hFWaS7hXBl2Hlj!ph1#TT9pzK;!?}Ii5N?-#Ow~^P8r=y^+{d!#6or ztZa?1PsQowHHNd#rv0}`ZS?+acQXEEz2?nrR1;U6 zZC3mjyTeIGM}lkRWMy4R>DPP-6kaJ7pibJ@YVw{G`uXW5^B##j9|r*V(E z^z_LyL)|~;b51Qc)I$ztaD0e0swz2hGPH# literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750a-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750a-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..79ba2fc22c19c1e00b8b2db4e31c1fb672e97d27 GIT binary patch literal 393 zcmeAS@N?(olHy`uVBq!ia0vp^^&rg13?%;)_Xhwewg8_H*Z*J;TJtprD8g70+xoA<<~gp)q&et1vY zTg>2Jva&jzQTbx{-QA1=5=qP^Tn*per$6?5-+oVFZ*mp)*Lkme-O}YEVw?Ag*9QK2 lwr>8*xAq$RJ9htKo%!lxj<4{MZeU0sTjZT6%3iV=L2t$*QjC9d91Y+mN+BkhIG-M9ze7c7io%WGRagR6t*M$@SWc8!q^g%&4I zO7cA~dfK4_SRxuEMoSdfJxKFrcd$JYD@<);T3K0RScB BXe9su literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750b-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750b-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bfce0b12d09a81a0549a77ce89416c673d555c85 GIT binary patch literal 393 zcmV;40e1e0P)mJ{XN5CzBVGV`z1*1t|Z4J_$sC6Y!(J2=D?fmWL)l&vJg`BLPStgEN44n9-{NMz0p6hy|n*tzWbQ zOanlQc)&O;zSW2XNdH6F!M8ANDdx1L*ae=q9$oDW2f=uPco8mVYLl< nU-U-lox8rKxBo+Vz}=l+ndsTjZT6%3iV=L2t$*QjC9d91Y+mN+BkhIG-M9ze7c7io%WGRagR6t*M$@SWc8!q^g%&4I zO7cA~dfK4_SRxuEMoSdfJxKFrcd$JYD@<);T3K0RScB BXe9su literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750c-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750c-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..47870bc53180e6bf810ccc4e9a5c113a94b6eca8 GIT binary patch literal 391 zcmeAS@N?(olHy`uVBq!ia0vp^^&rg13?%;)_Xhwewg8_H*Z*J;TJtprD8g70=t5HaJMNcpYcKV1GTTg=y{_uP(r#>JPMpmu_>^#b!Ba|Pi;LS`kZbBgco<`W1x zfBRmg!}?!Gr8JlXoNO2znJoVOebZ$2?Ql*&^6@uf|L$MDrlu@vE4BULo$1edH3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750c-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750c-text.png new file mode 100644 index 0000000000000000000000000000000000000000..afad34de6d70444900e634b801f1f06f37e48b61 GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^^&rg13?%;)_Xhwewg8_H*Z*J;TJtprD8g70sTjZT6%3iV=L2t$*QjC9d91Y+mN+BkhIG-M9ze7c7io%WGRagR6t*M$@SWc8!q^g%&4I zO7cA~dfK4_SRxuEMoSdfJxKFrcd$JYD@<);T3K0RScB BXe9su literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750d-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750d-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f407a0f6bf8c50669ea56ec445c792db4d42227f GIT binary patch literal 391 zcmV;20eJq2P)#Hsc*e4&Ai|al%YN`;UNa;1%jWjxQ8io}?%;Ht`65gW41m~x z1%x&PVA@$>`2(VwD?A(HRg*Dq1zwPg8t(;Ok&7B11wNS@`NGNj;l>Rf^7^oblvW62 z4G9Db5NHcN0U}`lxCt;3T!zN=k(uBX^Mjv65I`npf>v1As{v)N7Er_z(n$ajfrNP^ zpok+(O`A9LRBgJm;M2JVza>lTqWhr1V4J-tykO>}OzX6Hh*06EN z?wrcr4FIQl-uKP|yy_Qgpa?(+p#p*gQ2+g8oOb)sZ&1Hu{TB9n+HW$GdEo9g^!KH| lQT?5}d`++aLAk@t%`chi@oc66FbV(w002ovPDHLkV1n2JrN;mO literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750d-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/n7750d-text.png new file mode 100644 index 0000000000000000000000000000000000000000..6e25a269fdb09968c1f9aa673265ff9ffd1149ed GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^^&rg13?%;)_Xhwewg8_H*Z*J;TJtprD8g70E?OvGO%cnytE0LSkpoQof#;gVERf9J`Vx zt>V?3I^l-IpWM2~`9J1c^i9?lxT}#-RQ8ME6RVu06<73*HxDEePwqOVEihTrK%R-) zWkN=i!`=gm4R3TqA1w4OcpIJ}Wa0hY+^71&f?He$2LpRpUD$3koocv$;LL(7i<5%B zywA%%Y-IChZq+TR{$ToobP0l+XkKgJWZY literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/nb-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/nb-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e03be510de2ca17e373aa3d7ecd1e08e0fd48ad3 GIT binary patch literal 1127 zcmb7@`#0MM0L9}G)Z+wI^<3h#oqFtqO1(~ZB1TaaiqTH16m4ys*{WV4-;^Mv8jV+v zSfVR6q8@cdYvemQ-lbVfF(zpnk0_CnkorcFS^tCGbMO89bbq`hVfX+eeJgz!3}zG* z=ofxK;J@f;9rRX$*zN%CVdo?L52*hC+DaJSKUkWkhvOq)C?6MCoEl7%kc|*^V6`F7=Lqaayb$v2O2z?KEh%p9i{gcq@ zyUzkjJ6{5{u3@B9h&TlMRb8!zx-5&}J>;*`wpFy8uF3MF{Bq|dKSYs zONpaI{d5HXb?laP>)pE1`kmVO>zt?B@p#4Bn2o_PD#75^;{FfB6D#@H{^-sNV;EGj z)d<}uMKRr%c`u#+;~oTe!UbT<+AE96?z0+Bg&H09O2g%e@0j0Sz%Z!IH-&DuCMPBa zgMeHfHqFP}B5AOpTa%pJb$8qWJH;c>azd(88_E~JQn@p!f{4eq6jo-;RK10}HE^r}5=z$?$_aHmgHO0ocpO(&D#vdI5w|BCsU_9fwI)y=qmx z>r5WglHH|{phuih71+lh_RgPtNi-vEAF*#~w2}e(2R~m#K6LR=*kXi}D$Njjj8cbe z*aO`#rb}eO&=hBJ17r9N&W!2pccNrlu0p@CYQ-^`S*vY9p(#0FZOfcATFu$h-tf(f zL*On}#!@=wwmWh8vT!n7^aN=w(jvgP*JRho{x!g<0&Vf7Zd*I&KnZku*_s3ifB;p9 zp=sBRcFf6m)+`e`V z$gw@>dgNb(d9Y{`pNAD8k2(9bXWB`cUa+h-%j7Y;o<5#p-I%^a>vA~)n?Q8W1_vxi z9mf4C-RdR<11maAE?i5}GkCqOyQHI}#Oi8`SNj&v>ha|~Llg5yM^P!zM%D7wMh;J` zp+}vf8b|f*!#69}D*QFbRZ|B1#sXs6QdM3HyaSdc&7ugy0u|6k31VNw79 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/nb-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/nb-text.png new file mode 100644 index 0000000000000000000000000000000000000000..bbc1357baae8e44ed76bf861794a931631608e91 GIT binary patch literal 499 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+rv0t^Zc0qghAH+bKF{(eFH-Se>w42;p9E{-7;ac>S7G6IzzQuw{x?3i2x$bJTf z2XC(&>}yrvX}hTTM}w=W_W$&`8O}yK-CjQ`GyNOJq?R7Mpg`oK`b{r}OD6L3D=nj# zMfbdCUmx{DBYwLYL!lL$GzrAj@U*V#2=_!vs z*F4u}?kL)H>xXHkoyRpZJM*jaeQNKS)K9y=?|ryf@W*h;Der$*%Z9%`*q{8fwq8l@ z%GLF!Bhw!)Ztb6XzUk9H6DFTOH&`^f zEZ=Vbo_=eGs@gw^#;WJarvz{Q(9pU2>xN&w@u!X2|88vfG*PtP_*-)Qx2G1fe`@&G z$@DLo+yD2~cLm+4OH*Db*Z;U~r1STN=ziB=`KLGe1-IFKi>{CKyeN8q!T-m*-|zeV b4i~XM(eKFa5}mM9ps@6G^>bP0l+XkK18EIj literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pas-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pas-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..74bfcfcec12c94c1d58181b42ffe2c4297d890ec GIT binary patch literal 700 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)s4fFT+Com}d7g&GZ;Qsr7HMQSM7#Nt8JzX3_Dj45hzu5O!fv4@FRm%}WPQ~~C zH?6+txAx}0mOl4+v#0L&j`|wlqEz9c?;0qAj4n=jHs|xCut)R1KbXJ8H*(*!Db{pU`_(^u*&UB|ldB zYd&@Um-+R>)almybeBB7e&>uZgM7t@_4>b}eq^hfUR-t8UGDGN-fxvNpGIn@$ya_U z-5~fqsKMzgL?O~QXQC)JQ_G#>`H~ZA}SKs~qBz4>GNSV`V^N*Nrj{jD3{o|dh zKWp3X)=$^-HLRH)Q+v4nmwfHvU)STm=>FE{-_>K+o!@>ne_!3EUpJ@Dzxhf%{@$DL z@O$q*zdUvO@0YWm!>hH(Iv?usic&;6P1J<0xDe(t`gyaAJ3&21)`r~jD|eq?o$>tFubY~; zj=oUN|6VERdoJ_x$6a%_tJgE#dvVx##azqUDYsuday(`I!)E4t+a-J2&xcFD`cbCz zG`8m6r-u97&HQ^Vwyz8RHTTF3wmmo7uQ_knQ)I66?c3MR%Y92XsqW^_4WISdy?7T_ lHs8MNhwbupKhTJJ2Iuw|JwB~Z{lLV;;OXk;vd$@?2>_N=ff)b* literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pas-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pas-text.png new file mode 100644 index 0000000000000000000000000000000000000000..48b1e273bc3c98d26e86fec07def2773ac26a8e3 GIT binary patch literal 596 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)w4GabX1^?G8yuaVSfByM^8-HKVW?*34?djqeQo;E4+QDga6a-oyGJ5H-a@YQ! zezq~j`i9;l)-^@@LvOu2b3az>_|Jv^c?6Mw<@1^qdnW6zi+ZBD%e3XH>rZz3Pv(Br zvnQWh7g{yt&aw&pwJGvzR?FV1_}SrF9W8V3da&K4*Ib{>Cp*@z-el%@KwF22TP;6r z#+e0n@4nxx+wHLTaxROj!j{^Cpjg)TGS`nEI{NNt;Wz1wx04RMWBV>xaCdra*qNU< z+gJX*^X}-q_ct4V`oB(JbNg>IvplEz-$NTe7y9k554`a8@0ra_t+f^Qzpm_?8?tfk zpWpH??HWAo&-A|jJ|`si{WY_WI_C1r_NRL6+-j5l?0EUDhQUGdKEFhXxbF{*?Jvw* zvoq{(SEZkNf8Dog{;wCC!)~AW`+94d{>kZ0tAl^V#qY6kU90xhH-63AMf2~zpXcn} zu;|8t8CUdH7C7Yk{XbCrqmB2-*TdG^XNA3EL7Xu|GhaLM1_d z!3+Wo`vV*p=Knw6zdqr;f3}lTW4?&Gb>5eDcYDC#OHY9H)1ce!h9k^N066@t@D@ z4BRUZ`oE~#_dxy9&!+h|p2pgj00m?|t&@+6{~-J{)qc|ccwWYeU(7s=7QeQewg@EG zGaRm47RNqI#NA%`dN14R)$=ubIYQX}q;ovKc6jLz&zg7ZPw8JcAo+3f>y`0S#4ojL zuKaXHU$XwhrqaM3&mSA#z3t02Xt?$E`S%_CYy!Xk{^>E=p>sX2{^~L2H!=!A>*GaQ z=7kkk@A>jmwOPWiY4!Q}2W&i=PCP9C$vi{db3>Db^&eK>Qzy80y!p2(BbYtyK;k#< zm+X@qGS{3vA6&1)Ddf*EdA=L3+Ce90@!9{G3@5QTDK{VVH|$qGc-DKv!FbX53%?AQ z7a!C&-?u2~TYFr6Tcb|@pP#$!54u!6IUfF>Rr%o2{RezLen_7Y*#Cb0hR25gh0mn) z|C!G0mh?69f5)wPh3j71Up!NJ{lEOdp9T3Xm;cYdAziKi{4al?l>C9p|Lz`-w?E(e zU$v>)oZ~s>o{r{Q2xamgix%zL;UtZP!OBEB?{$u|CnbJod#{W;?n(-w5e`21& z?(Dy-=N@tSwEn*!yM)Teb@f8an;h5KeT}cyRq06oyZbL|$L^fmX&Zm--z!&Wev2un z=9hfvMWyzuEB`0kPkFwB{r|t|e^Z`a{jdFM!S)|-O9h|*%Rig(`2PQG^Uu}%{y+Ut z-|@fg#)rBt|Lre2+;ac#^n{KB-~ahP^r?9GFZgbL(7uBItJ_wn)II!nduLn05sSM2 i=jXqi{|^QIXVo?Eu@YT-js=)P89ZJ6T-G@yGywos*sXN{ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcef-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcef-text.png new file mode 100644 index 0000000000000000000000000000000000000000..23faa7d7fa5c4e7ffd648a74e1f06ea6405a9ceb GIT binary patch literal 539 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+it0S){66&MQU|9^j8VEz3BuP>}+3=E7-o-U3d6^w7M-R)a!z|;2dSmA*u>mUBh zFPq6KJ}WJ(JLJ&G?{deQ+&6U`VUCq^;!tc6fD=5CaYgpLIqoZ^)!#dDT;vVw@37C7 zpS({?_rDL)W_|hCACX)~@y4J}vlhuk4>0rPnfc94enS zO-;VP|K;yR^E;pAiuLj>vQ|6$_@{ks-TjJ*OA8;@-b>r_iOX_jmi+urqJI_t9_P~3 z`?GbQ%3r3>yWXp`_e@<~yL=yS{p_WyCa({VxB9*6)zKe!{kNp=d;0nHZ~dy<(RFjP zo)%x^lkTwnJK@1?)jzJotCVzbN2kl59b%3wE6nAwq|4EYMYt0KfnK%ufIQC(d1EH z9d}ol)i0-)v67ogKAC^!vig!rG$y(WhKQ=Z1;?oa>l@Nhf7yj{(Y4-da{fGIft aKV#n>yGxskw%i5A6@#a%pUXO@geCx3B_W0Y literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcrf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcrf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..17ed4a4a6411af3a73bbe20029cbded82ce90a02 GIT binary patch literal 785 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+Wo`vV*p=Knw6zdqr;f3}lTW4?&Gb>5eDcYDC#OHY9H)1ce!h9k^N066@t@D@ z4BRUZ`oE~#_dxy9&!+h|p2pgj00m?|t&@+6{~-J{)qc|ccwWYeU(7s=7QeQewg@EG zGaRm47RNqI#NA%`dN14R)$=ubIYQX}q;ovKc6jLz&zg7ZPw8JcAo+3f>y`0S#4ojL zuKaXHU$XwhrqaM3&mSA#z3t02Xt?$E`S%_CYy!Xk{^>E=p>sX2{^~L2H!=!A>*GaQ z=7kkk@A>jmwOPWiY4!Q}2W&i=PCP9C$vi{db3>Db^&eK>Qzy80y!p2(BbYtyK;k#< zm+X@qGS{3vA6&1)Ddf*EdA=L3+Ce90@!9{G3@5QTDK{VVH|$qGc-DKv!FbX53%?AQ z7a!C&-?u2~TYFr6Tcb|@pP#$!54u!6IUfF>Rr%o2{RezLen_7Y*#Cb0hR25gh0mn) z|C!G0mh?69f5)wPh3j71Up!NJ{lEOdp9T3Xm;cYdAziKi{4al?l>C9p|Lz`-w?E(e zU$v>)oZ~s>o{r{Q2xamgix%zL;UtZP!OBEB?{$u|CnbJod#{W;?n(-w5e`21& z?(Dy-=N@tSwEn*!yM)Teb@f8an;h5KeT}cyRq06oyZbL|$L^fmX&Zm--z!&Wev2un z=9hfvMWyzuEB`0kPkFwB{r|t|e^Z`a{jdFM!S)|-O9h|*%Rig(`2PQG^Uu}%{y+Ut z-|@fg#)rBt|Lre2+;ac#^n{KB-~ahP^r?9GFZgbL(7uBItJ_wn)II!nduLn05sSM2 i=jXqi{|^QIXVo?Eu@YT-js=)P89ZJ6T-G@yGywos*sXN{ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcrf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcrf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..e48c305e21622fb96a703c6dc7c582dce9dbe481 GIT binary patch literal 594 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)t4E_7x|3AOJK;eFZKtsU%o>hy?7#J9Ldb&77QFwz zN%}OF5 zee(1`zq#%2H;8X6xFvjfcb%NG?c?J*{^iem^}kD0ui|I?zHs)9HTT7SP5<`EyZ-QQ zqx0>vH>~`0YW-20`tMKbA6{<>?*0CuwZ7N8yX3yey^r3n?|x)FG=1OO8INw4{oJ_! zWR3mR`M-{yEZM*1{MjFO|9nv2Q@^xVum9}h-JiGH&!2ztxqRhY+4x^O6xM%Q`k=)2 z>g8WXeeu!H%xmsX)US&Ae?)rIiQ~`hf9yL^zJ1R}*85LH?Vd?b72v8{bxeN$^l3kf zR_V?w``2?+D}LPy4*x^HESg@|tX!*c%Q~xe$It2iUT?}?E4%L8|NqIgUtV5b?myqI g_7^(i@72GI5q}%?Hy)WV2N=Z+p00i_>zopr0Gy#yK>z>% literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcscf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcscf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dafbe9e0a17dbbe9a16debf0023eb9916cb1d63b GIT binary patch literal 855 zcmb7??@v;D0LDpEl&mTUZp3mpi^X}1z1P5YR z2`mPK5yL;2TM#n*y;0#I`XqC|g|thQU&IR;{Cs>8I~iK8swxl^GPaAVQ6!t81;r+B za@?OzS6o?V8G{jK<>&4#k}aEiGhu8^j*ED|CAp?1NT>DkSI=NwBl&_8?AL?MNV$h8 z7BMfz*V@iJIKDN$mgn4&Ipd8U+E%E@=nn3metFL!>n7`v?u8BVMmbS3uF;uIZLLtw z^VKYDDQoJc9?N6oTV!`BEFTtB3IsyGwVv)3Yl(h+w{WV=;(eHYJ$ zo-5Uum7kcW#f9W?P8KU`J_DrK?in=oT;Bkjs&nI)ydT2R%2R=>k--3U<+kGSIsN-# z1?5pk5tXf}BG*EAqP-nTyzmF6uPV7#Exh?L7)BTfwmYjSI{YJ!A*3Xr!%LH|1{Pij zA0PJ88?>qMe>bzsg4HzpKUaO%n%S_q9>j)azLdJ7`#VuzhnDapb>3CAHB4Ho;*Y@A zm4@~-sU(uRAy|jy=_@0s{hZim+y=)wGproTM*h`#(tPQ)o{?%B$^W&dM>x{Id@-X* zA%bqzoPDy%F=73Z*XUiZJ*J$E8Vk(wioj9J;&c;NMQRaXcY;YTEWtn!7h-_SpcgAh zydp3Imb87~7Z`Mmzk`_;pl18E9a3u^wa)~0&&k_}Y-+_<-_qJsU}KUIO!$Rkv4tlQ(W^6ZyWS3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcscf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pcscf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..b8d2c3dc8f5cb680d27b56cd945f1a02366afaf4 GIT binary patch literal 744 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+)t37 z&P7SSHRCxHP{Jp{k-+r-|K?yD?$f%fuWkBlQaSCsZ;}Rs%sc-I28ZvH^fg;%1WEaH zG1kwmNXxt=$FsE0FiTNbd&Wxbc_G)a2r;MSqXVKWsDNE;*iaq=GSK;%1iT zJGRed5O^1rV#}je&hR2MPQ9>GE#a@!$;4?j!m?4S)7G!~9>bE!dGmat)q>6cj?bTy z__jRpE8~vEKO;L5+oIHLOY?b;kEnS*HAbE&nE7$?aeI z-`Ml_rQ)9~D$jlXNAp_!jpdteNXjgE`&)O<^GI%q9X-bm{4YDvLD}FAp@V0)i`=gC^n;MI^pHNk~DG>H@t&Gv}dtX0irxtld{yU_%b;>J= z;D*v^lTE((?q>^#D)_kZ$y}BVDtA6{hYR=CaTQ@y{dl_ixvX5 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pgw-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/pgw-text.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f86b59a72535a341332d2e4cbd7c1324489964 GIT binary patch literal 807 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+it3Je7e3H$%wUoX)Ae*XD@?cEpM7#NuPJY5_^Dj44!G-qUB;9yV)|9>Xx5PwHG zP$LjTE>HK=-K=ZtsKC))8(;H(y022irV}S*UMKaLJi1FdipweEPzZD;f~Yl~3JdbgM7bA&!@xc*cqs?^@3N=s zXJ!97TU!(26G~>fu#|`nxFVvQ8IR3bZY1X?7vsvqfq__Pzmu~Ul&{oFs znRbU}&#p05y7yzp!;IR1@SBgPM%{YmZmL*tq+Qki%5$gB8)R3m4V?XF#*LmAfBT=k zcy`)-Zus`=xrPo-ZtMR|W{)xYbolU5mD~5T=9X&&GiK*a{BiE*=QGEbI;GiV>+=b{ zpAu3m&~^WlZElP9vh5T1c{j!X6g@PlWl#B!?4>Ii-s}rY*seE4aN{3oc@yD@4d*x9 z&)vT62IIsJ6Z_3S{^t)byAjFM>nmqv_xW~F+S-pkhHIZC9hd6-qb<+czUEL7Xu|GhaLM1_d z!3+Wo=l?VG&wsDruz!8R{Q`pkTNC$H3=GT)o-U3d6^w6h{4ZLfA#(I%!*eD3mTTYZ zZ?3(WvHYy$E2G;1D`!3Zz5QGJ3XLbp-1m?@9R$-zZ(C(U84EjXU^K1$qWa!{yxU&U^Mqnt6cHX`ycYX-D4Pn99o!q|ZODJb{(de|uI>n!U~Xm*CC^ zTC4XR4u4rEt9{${X@~7Y?d89u*I1ZUo4OLc(s17PDbX!;Mp~Md$w&Vu&wFe zwny?&deI$06`8(cQ{8`*d|z9+&Z=O2&xi85GwU;w-Z0mkt|?_GYncC{IV9d}DdWDP zcJ8>>@7ecEn|f1l*Kfh~A9>6xbo;(`7o=`jZyW!z{)w{%&$p@KckFJ6$EDsaYJR?7 zx9^tij!jwPf3YfihW+1{{`J2u&;R#jIf!Ym zS^e)~-Lde>CF|oGRO}zle*47S_*D3*+xoWMJRjQ4AgcefD>_KB1TDM1449J`JYD@< J);T3K0RVwr0!07- literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/plrf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/plrf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..72662ef42ceef27f9879f1e294f0e63235857ebd GIT binary patch literal 735 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+Wp1`PY(|3BZa(2%fxen7$f(^u!NWnf@(^K@|xsbGA2^Kag6E1rgjmKO8*8t?o+ z`|lZ7_^Cx-Czy)Jo_uc~oN>LK(@F97r9AJ;CcaQ~pn#k2YkU09Lw2wKY!(nM6WpJa zdgSSY`8!Pye{|e;cFyP8=*IuwPMYtux%i#&SdE_lms*>b*4b-iI==Mjzi-v8;Pd;j ziM8x_vr?Vm`Ghmi51f23=lok6jz_{~yuTzW9h~hd@+SE|wyS!#Z@>M=1%97i|M;kH z6LECA%F;slQwM&^^Gsj+d|TbWnS%Ba=j^o}UzhKG|09==<-r@t`qs+2*n%tf1=D{f zvI8ys9XoaM|FfU#^Ya+|es0^F;5V~AXj@Rt+tY7mzve&l|7h_`wfHL)JKxt?D@8tg zvvuE<`4gwI|J3_0apm_P75NYD_lvmy#clKbcthx8M}wdSuiy6zO#Iib zf7o92E6@1Cx~-p%hJDeup7RRZxa-feNdNg`LD6gF6G|Vy?pxDlW+!$2?e?D% zDHU7ye@b{=^Xbmlx^FSB{+ul?_;JHGdadF;LY-g(v^ z4g0_T@5}s=T^o7pZv6fKvH$)?*Z5akD)z4*}Q$iB}OH`Ux literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/psap-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/psap-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2145c5f6a35f9b6bd2d71f0c9d3020384919f2f2 GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf`3?xk^GbjKl{s5m4S0IfH{P~{u0{JW@L4Lsu z`|ItK1Ey~V^6z=NIEGZjy}g{s)oj4i_VB`2hU5wcUCWNk@BgLWQt`RirObBh*uL-n zg0GyHgq9`sn9j&P&mie-!Tg|~k!kuOhF`J@k2eH8JNWm&r%5aLSG1}z^=x}7VX#;4 zrd}^&t;_*_1{MyP=j1hfy;Bq^t!N91hfy;Bq^t!N95 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rg-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rg-text.png new file mode 100644 index 0000000000000000000000000000000000000000..ab93224c14ffd98aa3e8daac8ef436e97d869cef GIT binary patch literal 540 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)o4gLG)Cnzx7|NmZ~z+nCPy)G@+7#J9vJzX3_Dj45hJ-BJHfSf!hDm z=Q0L)tefrWyY=Rre9<$H)_X|Ry|C^;fD;kV#qO`wbGdWlXui@(eY3~R_CM4=o!+)T zbd$Hy64lq=X0J`y;CXLJ?0)@~4^&T_U3GtY?y370z5nvGcB^DEty0o|eQ#gzpTBIe zca~TMRA%;dsO_E>{`PR3bV7V3kLuchxBaI7td@8QPMNl!O6O^>wk2Ea?gM9zwa^q(+sm*+286Ff7!B-`Mah5lL2qjs16@aucNJH`C{ecQS@+iM!K?DvI# zQp!Kabl0vg-aV(}_6m8%AOHUyUvzVB@xcWbUuY-Hul;s29S0%$htc?L+!O07JzIg1 O#o+1c=d#Wzp$Pz literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rnc-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rnc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..733d3da5db77c25d591b3f49f5149a88809b97b8 GIT binary patch literal 591 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+Tn`|tl}aG3vIz#yStq2T=b4mORu3=E9hJY5_^Dj45hyV&*EfT#6g;UneSn;vg@ z|9{izO*$1Um5-Q7q7eNviQQ7r$40%V?t)_f9NB9`n^TC z`cKLJwG}$WfBq$yiwfpy`^0W%{;gY^cI<=pF|WC@tzI9>d)|K5 zJb2$gNYrkE6WX{aD`Vv}Y zj8O(#1pYK^%&nTkbnyDk^0dR-r#v|Q_9wr=A76=mjs@>OEw3}5?Dlc%fs*^dUc0Xb zPI+{?saW^W$E^>1Ts`-(%+cgHJ>9x*H~0DL(tW!$FHVm$SYML(E9mr`^-f>;!wP~E ze=m}rw{@jKO?20fl`~vC_N_hYzPIzjpU255rQ7EB%)e89zxMlGDDijt-+lU*H+}qU zl>7erpMVedymmct-?O{o==zHKuTAqg>Z~5_e!uVcJMDw-#cLuzz6;y=DEnCT>8dxM fi;+#Kzpbwsqx;<2`11!~{4#jD`njxgN@xNAS0hN3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rnc-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/rnc-text.png new file mode 100644 index 0000000000000000000000000000000000000000..24cab754a1f0a10c7de436fd8020a9d0af0d747b GIT binary patch literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+Wp2@Ui2_XjX2-2Z=meSyLI241HJ3=E8KJzX3_Dj45hbDXqVL8SFzjDrYk%isKO zp=T}%8RQG(xIdr2)n$K1{HZ+>$vuY05X3yMDQ0OK=DQhp-kyDS_sO@i?OUu(C3jc6 zcaBN_K0ofA_o?v6*mX;u9lrLqGxA*eDnI#1%k?ZjUoCfbUwr35vrSlA{=R({#-+a$ zx<&8)xPSi4=lp%QE;au*nZJJi<*E9Trw?i@^|9FZ)4%TP^Qb%VJ3f63-F)jh(+|D- zy*qk0zdwF${=x3slNoEK^Dp}H_sWlFdm4IvYulgSD*tEq(Wzg5@2dKD^RQ0s$LMEe z_rpG?vwKYEcfb4Q{Kk9rVN5FyU9a4C{iJMHwfenXS7z;Wt@!vo?~gCMd^~jeA@}T;-s{vI7JbiN-oN_QA@_|R z=4#d#cir;~t=%WB5c6Y`$Ubhln-?Xj_pJE+r{wD<$CY26zq#$S>*-(XDRxoZ_m^Jy z5cuxr--pjHxo@;lS$0MIs_}n~WbU}1n?l-Cc-!Tc$A7D@&oVmZb8_MFT9^5DwZFc+ hyu92Wol(E5equm!Cezca;=p9V;OXk;vd$@?2>=wmWxxOc literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sbc-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sbc-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dafbe9e0a17dbbe9a16debf0023eb9916cb1d63b GIT binary patch literal 855 zcmb7??@v;D0LDpEl&mTUZp3mpi^X}1z1P5YR z2`mPK5yL;2TM#n*y;0#I`XqC|g|thQU&IR;{Cs>8I~iK8swxl^GPaAVQ6!t81;r+B za@?OzS6o?V8G{jK<>&4#k}aEiGhu8^j*ED|CAp?1NT>DkSI=NwBl&_8?AL?MNV$h8 z7BMfz*V@iJIKDN$mgn4&Ipd8U+E%E@=nn3metFL!>n7`v?u8BVMmbS3uF;uIZLLtw z^VKYDDQoJc9?N6oTV!`BEFTtB3IsyGwVv)3Yl(h+w{WV=;(eHYJ$ zo-5Uum7kcW#f9W?P8KU`J_DrK?in=oT;Bkjs&nI)ydT2R%2R=>k--3U<+kGSIsN-# z1?5pk5tXf}BG*EAqP-nTyzmF6uPV7#Exh?L7)BTfwmYjSI{YJ!A*3Xr!%LH|1{Pij zA0PJ88?>qMe>bzsg4HzpKUaO%n%S_q9>j)azLdJ7`#VuzhnDapb>3CAHB4Ho;*Y@A zm4@~-sU(uRAy|jy=_@0s{hZim+y=)wGproTM*h`#(tPQ)o{?%B$^W&dM>x{Id@-X* zA%bqzoPDy%F=73Z*XUiZJ*J$E8Vk(wioj9J;&c;NMQRaXcY;YTEWtn!7h-_SpcgAh zydp3Imb87~7Z`Mmzk`_;pl18E9a3u^wa)~0&&k_}Y-+_<-_qJsU}KUIO!$Rkv4tlQ(W^6ZyWS3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sbc-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sbc-text.png new file mode 100644 index 0000000000000000000000000000000000000000..f71bfba57edc959609aea78340bc8206ba273f8a GIT binary patch literal 632 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+)t3<3%3&o|89-yfiG|9wHm%pWWa42%yvT^vIy;@%uEWCSWbr0{$Bwqtw|azHi^ z?76$^_EZ@bMut5Vf0l;c{$79ctiaS;rNwF!y?11JJXTLW$jI>dbLgL+&s1O6?09ee z<3?C(ONY7ZfyZ+iYNpI)nmhGl@?Lk5D3g1^A`jLsbKf^lXy5#eC+ym@8#IgUa({83 zUiZgZIN`Om{I=RvE94j+1m%jluH#j*6lc7#%8v1zOLgJyx@DpZRbx&b?$<4^k@2rq zwB6Eg!v4s-Ca(D0M*9$%r`K&7T>i|XB- zzO{SLCth3jcT?mO?Th`Vo?cfi^j1PdFrN^e$M=%9kdA{L1`rVqp zb)i$A&*c2EZ0q$G1>67p{hQH!q<44e{|~QBCAHN3;-lvL`xsO6S9$MT`=425e^>Wg z@Vs3p9wjhwlg+nS`6(SsZEyP8?{)WmXU8tzR=xl2w)65IUW#mL&f+azI z!3+)W|1%gk>_6Wxkg$G!!2N<($Gs zb|yP)Du~T}Zm(Rc-ftEZ$D!CF;FKYzG*`3j%hvE;VatkBTjTkDvD(%Ah??KLtm+iM z=k?NK{hrY_k2c?WzWm3Bhlktw?XRC*zHhDmM6P|r|({$dr^|3H6WKr(o``njxgN@xNA+^XEL7Xu|GhaLM1_d z!3+us4g32Y7z_#m1m>^*|Nj2@1BLcV3=B+1JY5_^Dj44!G-L#-Wi~re&c@5D{ z;p-vqAIV!-9X#%1+Tyn1#r$;FtB&ixi|l{>K=R3g<^zSCFHefGZ@B!>{%i2{nL_?5 zFI>)>m0q6d`-n;S^~Yte&V0N!JvO~e+D2sMHsK;2o()pv3nCf+U;DnTKJnYu)j>9# z&r*~1qUBGYP_kZrDQ_7=huMMOH;j!hFTBP2CHG)J?<4-1Hl4g-lgq_6ODF0+eHtEJ zzoBwl){13bGyV%|xj$&&NcyV$b8`LuN#@VL;kLRDZl|NrB_j%pDv%;tr;fM@@MnDg`vfD zuf>l^JzlN;&Zw=}|9N~3ZTnGmN4p&il$m??N8D z-2e8hAuli$GA;PG)^^QYv>I{QGa+{`>F0BT@GK6NQ^MB=0#0O0%A>elF{r G5}E+a#J+C; literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/scscf-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/scscf-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dafbe9e0a17dbbe9a16debf0023eb9916cb1d63b GIT binary patch literal 855 zcmb7??@v;D0LDpEl&mTUZp3mpi^X}1z1P5YR z2`mPK5yL;2TM#n*y;0#I`XqC|g|thQU&IR;{Cs>8I~iK8swxl^GPaAVQ6!t81;r+B za@?OzS6o?V8G{jK<>&4#k}aEiGhu8^j*ED|CAp?1NT>DkSI=NwBl&_8?AL?MNV$h8 z7BMfz*V@iJIKDN$mgn4&Ipd8U+E%E@=nn3metFL!>n7`v?u8BVMmbS3uF;uIZLLtw z^VKYDDQoJc9?N6oTV!`BEFTtB3IsyGwVv)3Yl(h+w{WV=;(eHYJ$ zo-5Uum7kcW#f9W?P8KU`J_DrK?in=oT;Bkjs&nI)ydT2R%2R=>k--3U<+kGSIsN-# z1?5pk5tXf}BG*EAqP-nTyzmF6uPV7#Exh?L7)BTfwmYjSI{YJ!A*3Xr!%LH|1{Pij zA0PJ88?>qMe>bzsg4HzpKUaO%n%S_q9>j)azLdJ7`#VuzhnDapb>3CAHB4Ho;*Y@A zm4@~-sU(uRAy|jy=_@0s{hZim+y=)wGproTM*h`#(tPQ)o{?%B$^W&dM>x{Id@-X* zA%bqzoPDy%F=73Z*XUiZJ*J$E8Vk(wioj9J;&c;NMQRaXcY;YTEWtn!7h-_SpcgAh zydp3Imb87~7Z`Mmzk`_;pl18E9a3u^wa)~0&&k_}Y-+_<-_qJsU}KUIO!$Rkv4tlQ(W^6ZyWS3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/scscf-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/scscf-text.png new file mode 100644 index 0000000000000000000000000000000000000000..fd3cab5370aafb46ce6c8adc33d0a688cf1027e4 GIT binary patch literal 704 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+)!^Y^b$P+;g62q-YPfByaS&LDXP1||(p7srr_xHktFd4Wm~Dg0i(?Kt~tCLkLK z{IVqVtofP}N*tBgOfP<~zxg(+)M@&cSv&8qH+%e0W11g>?8UZuhkb7-3%ul=?0%=Sglx}&foW2UzOMX%&{9c+gBgoEv>e#_Rs+%&xlXyq4DW*+L|{~ zVzT!+P5-lSOHy5k@$K~?T^E1%^#7^)v+dvV#83;7Y~#1q(Oa6!H@%#`xliWgzps}M z6(O<_E=cep;D|v>7!=CAa{0t?aJAoyg#S2M*C#!_1OQZTyo{__oa7TGmI1eON2yz zTkLaU$D1Y63`cMKtXsucv&+@~n$a;k$&!PI;vy-J57zEf7=KKin tVSFd+oxR}w{A>Sz|E=49|NVDls@{F6iAby3%N$U;@O1TaS?83{1OOW3ZIA!} literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sdg-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sdg-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b4c0288b594ffb937beab64aefa2550dd84e2216 GIT binary patch literal 491 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+Wo=l?S#%-`=|pzuDR|9-)G+nqk_3=E7xo-U3d6^w6hI_4c#5NUaMpt>P2xk{~c5x(T|S^w=(^H0Z&_Gv7g66E!Fx|2zIs-emS))@Y0XLNjiJ-d^0?)*7D z|DUbzrfb$O{yn?q=ld7a|9<2;*#Gk5qMDzdo}QkrAOG+8&)?pE6Y>%p`zzg<#eTH^ z^bd=FEPu8>`#6*Q=L&|C$897w95{dWcvSrB^!@t!9}M}~Ce)nie;R6MHRo5Fd}P>m zpOHUn?(6jVy2gKBeZI>7>9SnApTfMt41XQ@J2Fg1e*c0xZRg$V4fnVGK35t4|Nhg{ z{U!E(Kc~J6f3m)k;d)EWg{^{LrwM-vT<9+F?;qpW3D0U}>i$1?a(eoI$$z{*w!7Bl m|2WhCzId{J{64T>|FgxhGu^3=F}4SWJ%gvKpUXO@geCyM4+>lW literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sdg-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sdg-text.png new file mode 100644 index 0000000000000000000000000000000000000000..3881e6622916e0211231650c50afff82ad926842 GIT binary patch literal 696 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+is`~RQsPf%cRD3~80@c#b#-j%nt7#Nu3JzX3_Dj44!Yy>K0Xjt%frT9uF5R+lX z_oCP+nHI(uLWfkRMBo3PTK;PK&jU-=aX+r8+p1)Huq9!CCu6qY#YlN2Lp523dv+%R zwC)BtZ{yt!9Gg@;(H5xzfJQp*sgq-c7L&wmc6jc zjiwC`{a2h&`E%(&m2cGd&&B70I+ITF3Z8v({-x3rH6Hf+=JM+v{{6aJ-d0d}*V2>x ze+q3aPu86N=-I4sb#2TX#TR`{yv$8NZmhqIhuN&YT9gn zx4rmvdiKS-YuisOf7`6H`SJ9>PpdSJJeN71UhliF`&XHagQ#%$->LF%Y#27M%5IEL zbX}PAS#>Fs&Be>B|I<8`R7{o=?1aeg=!U<|QecjS@-U{=`4XuP)XB#k0YQ`&B~L k-U|EgzyJRGZygG?pFwzzn_Zx{!ak5nPgg&ebxsLQ0Aq7(b^rhX literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgsns4-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgsns4-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8df1aac1415f563dc7172d80f44e451c23364b72 GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^Q$U!J8A$qnnlv3qu?6^qxc&!&(3-C~KoQ20AirP+ zhi5m^fSf*07srr_xVP6f@-`@lumlKmd%G2gh$&yZXrgyWLhML>|y^}qI#e$h5bwbS5C_8n>x3ZZXJ1+`njfIX?Bj{?R8wIZq=o~o7)=j zzV^j}Wot#eGcIiYU48!T|GXbpiud|`Tp#t_M>BHSvSr`)@E^%dyzyjhldp2#{686f Ymv>!zV-^+@2y_{Pr>mdKI;Vst0A*!i)c^nh literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgsns4-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgsns4-text.png new file mode 100644 index 0000000000000000000000000000000000000000..92cbd290aa90b5a971a2d3d90130b5210402c7de GIT binary patch literal 469 zcmV;`0V@89P)b z_KsEh#mEvkc=9yN=0=M&X)UoTDK?uY^WExVCYg_>{RiP2)o$~ z&VZ}s+3L-PwXyigI9gfmv&n?Ly!4CF56TlwUWU7Yd>HM4RemfM`F*sGl(Sj7sq#Eo z{viR4H4I2}hTpDw%`rH^2x26n_ ztvP-pbAxHe;@8&R?U?RZ$mvUKk=*RNZ*^lz+nDFDF{F&6qrcv7NBCA1<&h*~00000 LNkvXXu0mjf;7jKY literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgw-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgw-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2904d2770551ffc743b9e62859713385f74b6839 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_0wi;`T%Ezd!07Gi;uuoF`1Xz??_&djwm@eN z6=%&BhX}Pc5sk(V?{|Jm)n0pd<)?j$2J2sGZn~@DISGVbHa_*xw|2jke)-eQIXi>5 zTd$w`$M|dY+DGy`gZEn>m#RCTf93jz^XZ@eKiJ>e-(SBpfBtGdd&$h`^pM}5`}h8k z`jh>O@!O;I??3&%ZIokqR(J$L>6e+Fm#jQd8L)=dnXd*3MR(d*CA$GmE4>*5c*w?B3q1ne*WuRM3? z&sXoIkFfyzKi=!#|M>v|=e}9od>S)9c<#9`Ru|ve?7uDZ?$eHwPvz!E&w2M@*TJ{{ z_Fb3$@bTl`TTjmF>2IrCe?Gfc_k7*z&Ho;tnQLDNRQ8`K@TE*sOZ?>rz|dvzboFyt I=akR{0BKp_ga7~l literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgw-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/sgw-text.png new file mode 100644 index 0000000000000000000000000000000000000000..0801d79747d29fd37b58f4f84bd0dc6af78aa875 GIT binary patch literal 884 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|Ghaf+azI z!3+)!0RjvP1qti#&+p%FaQ^*=$;vM|x&DU)F(rLZN@Zp00hwV$0 zV|bFR;-6Z6TEa5x%>H#OhyFcya&YCZ?8nlE5tlZ0s@A$as1(THJ|S?zX2Y!gW%oFj zEUbxqQ*o}@Wx@IFET?wt-}3AB3G0v1{I^yV{)xT(3n>Wt^#rv=R zrYFA??f(+Wx3l1p!S?;iFAIO&d$#}ibvc!u34X^J51TFMdB3r*>D~6Z;?v9DztvyD ziu~GlNhIPIKU>AKYkQ)7 zoE$IPR&D;>sIBv|)c@no{}0aZI49A%1GZQO+_~-0szkky9nf?}*^hX^*B1r7i+t0q z9{PQ;yY$6LZMp9!ZgbzbSBB$izm->#DywP4;=N~CwElanl5aUSX-NuyUpMR0d+~Nr zPJ+w}e>Z-Tl0(mI5YE7N@__(TCpJ1vK>CfB*gW g-@5(C)W7|Vb7uZqvMnYYl$#hlUHx3vIVCg!0O|YD+W-In literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/siad-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/siad-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b2a0585aa0aba2257ac8f6fb33c980ed8dc2d941 GIT binary patch literal 774 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+Wh3=R9=|G&S!;Cw>Bd6DgSn~-tu|#gYwIJb}X-r zQoC~0#s8OQfzPF6JJuSl3|Yy9Tyz5i*h^p8!?OPSm3IM>ZOabter-JI9!e*~{y zX}?f!dGFm>f##9FI75pc&d+eWn)Ranl&AXdS#SRoJ=w}Cb>fWwb9c!FYt!o5!uY)T zW|@CJeAKmXm)MybnX!p8AeJl4su9(-|%Yg#)}Ow~x4GATv9_jJom)Kj>>qn;(zxd{{pu_Eu|OQ z+iSM_|90%`+^@};D|{VDSz*AWcuJo{&9>aEX@-u&UnwU7OnW;eJ0EMJtt=k49ya~970 zDJK=%^ZV#M{_yK*)rX(|zoXy(YeDz)-lx6)_e)ZvK9Ar04yI z(mQ#lzyFkeFTZT6Y4&{YY0d9C-EL7Xu|Ghaf+azI z!3+)!0RjvL3JL4)&+p&={(J$Wh@>e415>1@i(^Pd+?xZ8j6kJL3;wOo>)0RyWHK;3 zSabbhU$cS$%LC>x2ZxsL^*6nDmucSop!YwF;}Bz0sKQ;`+pYrx#8Q zz5HvPSK+4o4F$K{cb2|Zzj%F<{LSV6e@1<3e!+fm`-%$-;)S+#&5x40A7bhDA@lf+ z4?ky{mM-6zRio#6;XTW{$4AxYYoD@w^7-wlix-M34{ZMXZDsvyS4EjWZ#S;qV(NZl z!unMcuKai!rP0o|>Hcy3k#s6;)4{d+Gf9kyS^OGk2@hJXZ z|3^=^UH)UR;1`p)Ke4-i{;yxR#=UpZ@n<_<=4t*CyqrI){bQs0%KP75U*KS1U`djA z_C0>4V8Dv=r429Q{{M`fdH(t5pEY*#QK))G)1p5?cRn~sgOZY`tDnm{r-UW|jIy4m literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7-gport-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7-gport-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..319bb37c9059a91ad924df29591ef434e45d2f9e GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMYymzYuK&RxwB~CLP=v80$S;_| z;n|HeAm^B;i(^Q|t+%%}a!91ZyXzrO0Uh|-~ZM-`rYao+I3a&lRKlVr|swN z505HtOI&hZj;H)z(#51X z`>Si_|97r_o4m(YuJYui&-+2D{eS+-+W-E&{?Gr6L2@A5qGY3hwmC`f;8q8^Zs!-) Y&1oX?Y-Jzb0)52b>FVdQ&MBb@0OSgW$N&HU literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7-gport-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7-gport-text.png new file mode 100644 index 0000000000000000000000000000000000000000..1ba8a76d722b69b39d64a9aa5547af7a510d2aaa GIT binary patch literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^^&rg13?%;)_Xhwewg8_H*Z*J;TJtprD8g70%(RZ4|C}aNBoMmPfA_V!4Q5^EUYUhSxG#vGj3uw zYvCcDPt3Pnz0BY1@Begs?f=r#Mx9)zMa|yjXjlAGi$APywlL1|#}Br5^)F<%88L2S zu=Do_vtGh^Gt5ElN7f9*84ib=3=)&mVhBf3d#T}e`N;+!Tf43YL{?x+m+U=vxQX@7?_><^`g>AVGE-wPkN@uXYQTJHKbRn~V z*~UMi-KgP~;wBdBgyfeBcbcyX>y%qsuo^Q6%K98`h~93uuil|lV&l&l=DNTjX7F_N Kb6Mw<&;$U2$*PP1 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7gport-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7gport-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..daee75ac845c72c81c4077652946c2ec71c151b1 GIT binary patch literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+)s4gLG?|7Q@G|K1=#Az}UbMCR643=E8KJzX3_Dj471I-3`x$kX;v;VNz8FRL?R!sGB% zj^Lng-IE2vxgK>*i?6?J&ARe=-9(x1r-S-xoNRcvyft^}z3}bNyv2Sy-~X_Eb@lpR zDbv-b>jJ(WUKPJ6FZH5&>ioQ4&z^64p`P(+aqb-ZU~l%fbN{PwRZQDt|365+y~6gM z{i^xZ7BjYd(|=?*J)>~R-uivhPsx4emN;`|%J=*3y&XT4ANI>!EPj3W`}g3_!Iwig zUO!(yVOreA@_+u<&wYG$_~4(J>*hRo^8DkU(}yokJFC3n>ajoazugZk{-gX&|MOY%`!%1tSIxWo>0ji66{50u6-B(D>U78 zzLS4d)jiAl%_6*ePyPETZ!`DN&w_tXHdeE$v|ant{CG$hn>i!pf|9k%KcmMGF z^|AH;zcJtYZ@cT$zd(D42l7+){d_h%|DS$NP3L((6-H-ZvS9FZ^>bP0l+XkK#JF+s literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7gport-text.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/ss7gport-text.png new file mode 100644 index 0000000000000000000000000000000000000000..8656f9f8476839743a5f361cc393ff43d7efed2f GIT binary patch literal 1011 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+uo`|tms&tM=B;BbC@Lc{z1TSWmY7#NtNJY5_^Dj46+xO-`-29N9P`2vO-KmO@k zM+x#T+c0b9qr6S)e%(HssOS>#U!!Xg92p$5;%Cr{XcnER>zDBH{hx!3Ne%LOe@}3* z9Y2|AEkGEnAY)zjp29rGi_mQMWFA&mWWf=Z`4uo<4K-`{Nql%wDDO#LQS(7yV}UE?@KPKNjcDe}29Bpz!8{ zo$u3nX1>4wZtXS8^Z!rX?OFKp-;4*ouhKvNnRM5=x%+R21j&OiIDIx$1? zHr~S-~u4B@87g2X}mj8~OdmqnHt^QiS?}a_P z&K?dn?e6At#szI+^OegL3vB-fEl_p+#$A?DHj(}1`n^5BTKDaH(AcsnPGHG=&*py> zueU#EwR`-S|K}6C!awhM1%m#v9C*9>e*DL(ig_Ch>l3Pv{0b5N@O*jMx#`cDJ6zki z&QGr}?O#{gxjFC$@9T|8%wF|Z-)&v5bMCIr9~$=Zk7iHp{C`(p?aSf)cR$C6$Lla~{SdG(8gxy1`F><^89UB2kw{^-wbU+&cl@fV%h z-~BiLp?v)h-Q|xy+>)w)dx`(oPWJD1ePIv9*9O;YWvlv~EV=%Fl!c<1_=~__uG#yq zsVi>V_HUO)-i7|Y-8Ny1=43T`@2}C-KX1o;)MNj{MKWKGU)gzi>HpoOkpaJU`W#*$ z|5!0U_GNyj^cIzC<>%x(nCp(UF!^wDd+l$TcWuL48BY6pp7Y6dX_3X}v`wdVchqK_ zx4ivq|IZIGRrRjBE_~Pjx*8bk;roAGU0;XH{9pg)KSREU^Y-AtjG4eZ$l&Sf=d#Wz Gp$Pz~M<@sY literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/switch-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/switch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6e512719d73e0cb9576cdca11e2161231904c0af GIT binary patch literal 877 zcmV-z1CsoSP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D03mcmSad^jWnpw_ zZ*Cw|X>DZyGB7bUIx#RhGC3eIG&(amIyE-q^PkNC00PxXL_t(YOTAWUPZLoTJ=2{o zl$I7KTV;t0;+D9@_y?dglhI{pJJwe_E)FCmxH3!f(_Yrp7ONYgZ2nYoX9i;u7{`v4ZLzh-oe z_6+zj;PlC}*B!u+Hw?SY3BP9;9`}%ljRd2Jgyx{BUpI6dhS1QYRG{lsoMny?@Qo_r zLFM5Kb!2iW^>>D#e@sL+_hZ=Fi%Gm0I#x97k4P0h_4Sh@7o|EwgwTYK1gBxMI$*Wh z5mq18t(_e`$5^;RqeJd;ZZ|FEU-a(~WuJLx53OVd9OpjfL#bOnn zIN8PO`ZL5nEhGMQRaSD^4QQ%`5y|U>Hldk`>$ttJgiv5gcuMWh`^}d)&z=aci<8q% zKM_{(%wxV8nuOTvNN5&*Z>ZL99ealx(kAlRi5s|cbxBro+UaK;IrEs$_q3w9B3;MX z`45!Jg&Ng=?F9#8Zt5n2gArND3HljFFz+;dB=2cOlMpv^ed`tWkK#282iFKGm5az1 zGV)v~=1{H_<=OBX)5yFJ+pkTBqPZdko&#e)bh!<9P6&SaT6`HFcUIIeJV!QfR4V64 z#W9|F_3B#DCgijaV01XDo{X;?56{a+6Kw1D{+e17!fB`9fF^m&H$$6{Lk0TPRZ|D~ z;@m@A7{3O$Yfwg*D>?1-*TK9--UyQ`NW=WpEw$-mu-P09qB`=$EGm_fOqI*wRyLz* zR#;Yhm`okWfo5zgOz%1wZPj;v{iWz#M8f8mrmlY96Pwuh@&?6HUKw;$`?>2F%%GI;-?uo4AwA0@UditM%t>h-> zi^e%3Tn>+FSFURnjre0l1Yg!DLXh_=Li8l`_W*tZ2i!}YA%PpB00000NkvXXu0mjf Dt;dng literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/tas-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/tas-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..59463a91779bfb5f18ff47a0f8e86d4963902df1 GIT binary patch literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZM#sNMdu0Z-fiD3KGM@>L&f+azI z!3+)W|1%gk>_6Wxkg$G!!2N<($Gs zb|yP)Du~T}Zm(Rc-ftEZ$D!CF;FKYzG*`3j%hvE;VatkBTjTkDvD(%Ah??KLtm+iM z=k?NK{hrY_k2c?WzWm3Bhlktw?XRC*zHhDmM6P|r|({$dr^|3H6WKr(o``njxgN@xNA+^XEL7Xu|GhaLM1_d z!3_QT84?@>)}R01U~vDv!u)`OXk(vv1_q{so-U3d6^w6h-tXJ2CDQhBBI}9M_3!_u z?O&k1He&WihP3z1U#+u(Cod0Xnfg=Ei9@kP07OJwVNZ%OZ9BInPL^T&F9-iW7xYE! z1iCZAtUhw;2i{&;+w8n-x~Q!E)_6NDIa})m=O6bUn|u6zlj|!s72RVJu|feE4)Yfp zmMmgSU~TYfzazUOdETvZhDY;ab_+LEZT`i`AXc=zkngW!@o#PhmRk%7i=CMow%mMK zo9AlB{W#Tajn(;g*&pujoo9D~Gof&E@Ncd?pE4fUUUoX-{Ym(@B*UHR3%asv{1bwo z@2{U<)*5fLI=ta$=3fqmt0w#6nRl;GQ2(mEj;Hif*D}9X;xSWizn(V#^7bDo-}zr0 z^?#GUO0>iXp0b`Q_i-=4PS?muU_Yul&K*}VNP zudL~s|AF2gm*rnrz4(`$_0nF$({Xy`w>Po+t~_?7EM$pcZQTRUsrN+})YR*IEiv%w zfA#zH`jy;Y|NcAs;ivfS=V$$<`!GCc|E??bx4PbS^OJ+MhbPAWmSW%DI`J>>*~z(@ z>}^|~B-Z}la$i6A=)ctYFDv3y{%<*-<(ZK6{+P@s0{PX%|xwA%#&c8nO zYs2|J2mWp^y6b&s-;_Q0Hf zR{!5@Q+spe!2kb-*=Fzep5&hww8rMYCotHiBSLWczyE9g^FNrrL2{DHd{9zn@O1Ta JS?83{1OWDC%_RT; literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/transcoder-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/transcoder-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b2a0585aa0aba2257ac8f6fb33c980ed8dc2d941 GIT binary patch literal 774 zcmeAS@N?(olHy`uVBq!ia0vp^^&rf_3?x4$zf}ZMW&u7Su0Z-f>EL7Xu|GhaLM1_d z!3+Wh3=R9=|G&S!;Cw>Bd6DgSn~-tu|#gYwIJb}X-r zQoC~0#s8OQfzPF6JJuSl3|Yy9Tyz5i*h^p8!?OPSm3IM>ZOabter-JI9!e*~{y zX}?f!dGFm>f##9FI75pc&d+eWn)Ranl&AXdS#SRoJ=w}Cb>fWwb9c!FYt!o5!uY)T zW|@CJeAKmXm)MybnX!p8AeJl4su9(-|%Yg#)}Ow~x4GATv9_jJom)Kj>>qn;(zxd{{pu_Eu|OQ z+iSM_|90%`+^@};D|{VDSz*AWcuJo{&9>aEX@-u&UnwU7OnW;eJ0EMJtt=k49ya~970 zDJK=%^ZV#M{_yK*)rX(|zoXy(YeDz)-lx6)_e)ZvK9Ar04yI z(mQ#lzyFkeFTZT6Y4&{YY0d9C-EL7Xu|GhaLM1_d z!3_QT865tenZ0f2ey5e7#LU_JzX3_Dj44!WMl-YWmNb#-^@i6$a>&@ zz3=9GtG+`4HOwt6ho1l5|K{GYFDGns&1bDKQSP<)@3UaWeBNW?$M&4uwYm83MDyEn zZ@P~tM7_9pM`_ma#d~|)PW5MYtvtE!m3+kd{7qlC=JKUVEXm(~;pVxFU6);6q_)=Z zmj7HG&ewCF>*Mur=k9Cv-2QXbUBb?}=*aiRpM7ecN3P%2j4SymR#(p=d%5gi(A$8h zcB7Bi&;8MPJgGQSGs5s0|K1}ZUyF2CDNg=%`L@TOQpLK9eb$%XeVACVSn&LWTi$G! zn40@F7e?2t{`vc4XVqTaRL&oAAMZa?PO+DY-FJS8#g>)roIfU6djFXJC)TuYVx{N5 z&}G(_ME-2+`c-%5dHX8=^15Shj~5*-aj9;w7xR8H{X=$5kYGqn0=G=&EctGpkUuN3 zz5BlZbQKE-D>>*^a(4QC0-2)np4dN{VybR>_ISL^v*csae_AZg z`v-;BNF1_=I&t@r@(WpSN2>$kl1KZGvaIfo*mwB;{O!F9ia7dGAG!1YvplW#`1Z}a z?>;ORUt{qo)4P@>{>cIRut0ORn^n#EpEE?}9*XF9tJ!VyGgno$y18HZ#TCzx>bo=Z ze_ysp@%_I2o&19*XC!TyO3v`hF+bjC`#G_H+K>I-?ZpYg|M{~%sn>s6m~5DSGh)s= z-rbtdtFtXHh{yb$_%m>wX2goC;g;F`?)R0Pqkr)4Gu94~sWDpp%1{1%+TPk~_wZLi z&NI(n_YIAkYQ!)0^>NpEV}trgPczl++Gt?OdNXNSI^UD8lz5lUauVUj->DxbrMSkW@dU}?zZmU2ktG(2je2!e7 z%13kGUCljve6B&v=eKq?sde(-tu>U?Yo44wCT*V(um7WlnQcDP)wrkIPrIe;({b2; z^7tXEXRGfnFMRO&aYyu|YAu8Mhkuvvh!bJ!wav<}iQ#^^A@tGvDz^_0?N8P|yslsK zy|rKY<;R#`duvvO)K8hexc0ev==2%W>{3`h-wyp3yT@MUzsjYnUcJ^c^w%r@fBNU( zQlH)DpW7SPCpWuVoSFV=Z|vOv9=})qkPhGV_;O)q98j$AZCAdryXRN?)lHWUye`o0 zwm&1DoUi}0?{d%of4LVQsg*p4nbIj!1V%Y0T9|QVhtM(c$ z>p8Db6DDUc=~@5OPiN%qCsu7JXjt9;jJf{k@y@JS{HFh3P7^WT_uMf4?FG~NgPlrt zfBhZ#UX)4p<$l`VGUtjP0 f?}mTrX{a{f^*Q5Ea(W|`MRgNrFEz7dCe4ue@ z$(7HKelD$?|9toKI;YQ{{Qf4UrKy%y9Oc(LdA021j9ROf^8VyyPbT8~(LjXLHPVR1)JuAflz z^V8GQ)8|VR2GuHGQu-jw-;p_2%KAdBm(e|%a#=TqPHJ(9#5D}4Xhg}>h3YM)Scxa`Aw z$rZr#ZvdAshun788eqQ>K@!yWiDo?G``{ks++;~3cPQ~nx?U|3vI_$kg zw!2I}m8&oCKXbPKq`e9&)R!du(w7sy5%t3Ikn%N-^@rt>^|TJ@OMIThmzI|H|3?0S X^go|3{B6($CJhEpS3j3^P6Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1UpGYK~z{r?U>h3 z8$l4p`Nt8xB$(b?z(PVG9ta%?4nh&8JOUCD?S)STnK?Q-imE>w4nlvNpylM`q^PJU--+DZ+}hgO zhldB(UKv3i;t?a{s@~bzDJ(4X`F!78XA72hqku1%F4=tfq~oGTSFs9Kik{eb#--wF@EC- znRo(PS3;C|d3npr%f@>$NK2kdN=llVntFPALZMKU5E4H_LqqlT^&cn1ln(>~w99QW zNK1&)(o$Rj2AUQ)#R#!*P?(VKAOs+^w6uiJ=jUh2WRUjo@Q~4`F9V0{PDrlbogs#7 zb#;~YbiisLLn5SbpPwP-L}zCw-hQS6Hhq14xblz??UZn$B^|KkV(%d#sVJ$Y3G6Ao z%}^wc4cqpus^&r;P37+Hj&`uHu+Z4pC>eBhb&ZdYOJ*Ocsj1PL2i_9me5D<5 zc@iOo;P4t99kn&#U@({sLbOvJ92^i2OifL393gOaQZim_Kei^wK~Y^@%?DubIU!Vn z8l#n0&(VrqmA&VLwzjr(<6(f9$OxQMl&!6;+%#;>@!sAZ^WF0dX%3k?*WBD({G?_M zu>d7=t;=i<;X0m>8V%4ILhI}6351v;w1dUP#e`KhF)<-I<5h-h-3Pe1xn_u6gtHn0 z2(i)0KtpC(7FQzB+uO^`Mc_h0$xRYYwkAOG@IVyoQxn23zydWH;*CL-&IW9_d>qRg zgU!uNGDI(Rq-<_(=57jbNHEC&2Jn-tyRz(469SyW`}_N-@9*#X`}^@lh7G8ae9}(G zwY4>qA-E#k+}zL(=I7^=ZH$kPkNC-8$oS~N!9iJIz_j@7M8vDD<@UpwrC$1ChLSFT zCndv#p!*?~BO@cWCdAH^***kF5_`WL*B!i*hKGkW&OOstpVsCqr#^KlA-pMTH$*dRvei{L+@w-FBi1=={BR?-T0F#rGn07*qoM6N<$ Ef*vt3kN^Mx literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/usp-dns-icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/icons/usp-dns-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba5c5235ad4857ed999c596c47e0a2a52f63d89 GIT binary patch literal 1065 zcmb7@=`))N0LG)b)n!bugSKd_V@hYLj%Bx0Qmu?D%^D%C7-3{fv5T%F=@74Dcd@3F zj=VMx77oSC`Pcrq+lCk!#R>T-ojP)(9Y4`pD zU3T2|#j|uvHTHJbC99)|T*5kX@z0Q)>T&8FdY>XYJ$w)+mi<9HSGR#q^qo)1$;4QS zk*CDn{(<^!oLq2FGP?Bn5D0Y}s3N4AnQ?j6YLuolIy1Y`GpB7f3E%O$nPcX1Ge%yF zj+CoJr#N)xb|D;lL^h^UpehmweR$>4>$tloAp(#2Ykr7eT3ep* zH0{{v$(fPgFYg(NfcPFm5WZl!3I=1uS9gwoY9-4st1;XGEsb)uP>|HR$y`UopTwId z365j4@z|706Sxi}ajWZ9hij0Wc@S=qoteyyLt+%S>VWRU-<)eACRArlItG9|oB~qe zb3ZCoMbJzcE_#)3gQKnl^sg*1*ySWIQ4{f?f6iLGSig}T@~(3jT;qS|P!&f5mG6j& zKD)zlUBWT`V_q@{DCguUD$AS4v9CYyx(8P-+7}5m1_8A$sR}R24WT+mk@g0W#y5*( zkJm?K*~P(NfSQk$+$d(YyP8&;LC_?pw1kPXBJWVvX_HjX>}L|LWO`C&YRImJf3=A) zuLGR3k{y+%m$$4O|;PsbgP@vuVD+^dXv;Y3gLdy@EmC$GsyO-xc zu!Edf6SljDm3Q;Y37!M{2HN}e0!5ZJR2JDbAuDCQpTR+8fkrVZ-;>M+(_R&Pz5pv2 zwNf9Q=ka7d1w8D7DuF=sQRaJ~>XlvbnjQLvEL7Xu|Ghaf+azI z!3_Hi82aBQ2q-k%cbI>EeL+Cq(OY~B3`~nWT^vIy;@%u+1gd0cSnzkH_(~9Km+bDF zg)%Hn410V(Cuhjqe*b@ybb;2fd9KAB(HFh0WFBbm7if!cRc(tmEbVAi-JaXGhQHLt zRmm&bb5X{R?;qs<=|*=Rm~M5a^j2R=bGy5TNo}F}8P*@Zd*;dCnYpQ=qAT!oE$fMH zk2&)%efhTZ$n#hBSN_CQ-ZOrB$8Jre!G(`2119#z)cPGYkNUSb;L6vHP8UCJ+?%rR zssHVHDNpa$t!Q5GbaSqr{LWt%3pz_{bQlzie{4Lm>~Fs7{MK2o&mYL2+_da`PR^@4 z`y-~TyRUaJu68=}>R%n@t+O8JgX=S*KMJCEng#UJ>(S6+)zo0+PY6ZUE5HZ`D%Z;nbuzt?2^oNWC$FDb3r z^T?)Y=he0b7>RORoLi~8KkDV$;|Ds|Mb?gc8YjrNIOtt@(nf*8^7e4 z@^hJt3rrSGgxegAc- zk(^)f**V#fvht}uZSVU&7pzSUt*Np3q0jSg>9ngKk`rZWBF&}*&y5N@djA2p{e|OS zvLaLMmxQ0a1yuN5{%y#!I^ES3|DM!7sNFwp@6~b*<%f^`UR~eR^}YYYPx0l!r|&&$ z|5@{&YsN8t-h$2cXMec)+qwUk8}%*O{`l>M50#5AT5WwJ{;NGt*ZNmGC{&;U^gad5`p=|Oc|U;F SKgA!EEInQQT-G@yGywpJ$GtKD literal 0 HcmV?d00001 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/utils/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/images/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/utils/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/images/dummy.txt diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/dummy.txt diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sample-page-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sample-page-controller.js new file mode 100644 index 00000000..ad4f777e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sample-page-controller.js @@ -0,0 +1,61 @@ +app.controller('samplePageController', function($scope, $http,ProfileService,modalService){ + $scope.tableData=[]; + $scope.viewPerPage=20; + $scope.scrollViewPerPage=2; + $scope.currentPage=1; + $scope.totalPage; + $scope.searchCategory; + $scope.searchString=""; + $scope.currentPageNum=1; + ProfileService.getProfilePagination(1,$scope.viewPerPage).then(function(data){ + var j = data; + $scope.data = JSON.parse(j.data); + $scope.tableData =JSON.parse($scope.data.profileList); + $scope.totalPages =JSON.parse($scope.data.totalPage); + for(x in $scope.tableData){ + if($scope.tableData[x].active_yn=='Y') + $scope.tableData[x].active_yn=true; + else + $scope.tableData[x].active_yn=false; + } + //$scope.resetMenu(); + },function(error){ + console.log("failed"); + reloadPageOnce(); + }); + + $scope.$watch('currentPageNum', function(val) { + + ProfileService.getProfilePagination(val,$scope.viewPerPage).then(function(data){ + var j = data; + $scope.data = JSON.parse(j.data); + $scope.tableData =JSON.parse($scope.data.profileList); + $scope.totalPages =JSON.parse($scope.data.totalPage); + for(x in $scope.tableData){ + if($scope.tableData[x].active_yn=='Y') + $scope.tableData[x].active_yn=true; + else + $scope.tableData[x].active_yn=false; + } + //$scope.resetMenu(); + },function(error){ + console.log("failed"); + }); + + }); + + $scope.editRow = function(profileId){ + window.location = 'userProfile#/profile/' + profileId; + } + + $scope.toggleProfileActive = function(rowData) { + modalService.popupConfirmWinWithCancel("Confirm","You are about to change user's active status. Do you want to continue?", + function(){ + $http.get("profile/toggleProfileActive?profile_id="+rowData.id).success(function(){}); + }, + function(){ + rowData.active=!rowData.active; + }) + }; + +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sample-page-iframe-controller.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sample-page-iframe-controller.js new file mode 100644 index 00000000..8ba4eb54 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sample-page-iframe-controller.js @@ -0,0 +1,4 @@ +app.controller('samplePageWithIframeController', function($scope, $http,ProfileService,modalService){ + + +}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sampleController.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sampleController.js new file mode 100644 index 00000000..518880c7 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/controller/sampleController.js @@ -0,0 +1,11 @@ +app.config(function($routeProvider) { + $routeProvider + .when('/iframe', { + templateUrl: 'app/fusionapp/scripts/view-models/sampleWithIframe.html', + controller : "samplePageWithIframeController" + }) + .otherwise({ + templateUrl: 'app/fusionapp/scripts/view-models/sample.html', + controller : "samplePageController" + }); +}); \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/styles/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/directives/dummy.txt similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/styles/dummy.txt rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/directives/dummy.txt diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/utils/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/utils/dummy.txt new file mode 100644 index 00000000..e69de29b diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/view-models/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/view-models/dummy.txt new file mode 100644 index 00000000..e69de29b diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/view-models/sampleWithIframe.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/view-models/sampleWithIframe.html new file mode 100644 index 00000000..dafdc6a9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/scripts/view-models/sampleWithIframe.html @@ -0,0 +1,3 @@ +
    + +
    \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/styles/dummy.txt b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/app/fusionapp/styles/dummy.txt new file mode 100644 index 00000000..e69de29b diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/index.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/index.jsp new file mode 100644 index 00000000..f6030c97 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/index.jsp @@ -0,0 +1,24 @@ +<%-- + ================================================================================ + eCOMP Portal SDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property + ================================================================================ + Licensed 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. + ================================================================================ + --%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +<%-- Redirected because we can't set the welcome page to a virtual URL. --%> +<%-- Forward to the intended start page to reduce frustration for new users. --%> + diff --git a/ecomp-sdk/sdk-app/src/main/webapp/manifest.jsp b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/manifest.jsp similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/manifest.jsp rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/manifest.jsp diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/att_angular_gridster/sandbox-gridster.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/att_angular_gridster/sandbox-gridster.css new file mode 100644 index 00000000..a9edba8f --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/att_angular_gridster/sandbox-gridster.css @@ -0,0 +1,173 @@ +.gridster { + position: relative; + margin: auto; + /* height: 0 + */} + +.gridster>ul { + margin: 0; + list-style: none; + padding: 0 +} + +.gridster-item { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + list-style: none; + z-index: 2; + position: absolute; + display: none +} + +.gridster-loaded { + -webkit-transition: height .3s; + -moz-transition: height .3s; + -o-transition: height .3s; + transition: height .3s +} + +.gridster-loaded .gridster-item { + display: block; + position: absolute; + -webkit-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s; + -moz-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s; + -o-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s; + transition: opacity .3s, left .3s, top .3s, width .3s, height .3s; + -webkit-transition-delay: 50ms; + -moz-transition-delay: 50ms; + -o-transition-delay: 50ms; + transition-delay: 50ms +} + +.gridster-loaded .gridster-preview-holder { + display: none; + z-index: 1; + position: absolute; + background-color: #067ab4; + /* + background-color: rgb(6, 122, 180); + -ms-filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#067ab4', endColorstr='#067ab4'); IE + opacity: 0.2; + */ + border-color: #fff; + -webkit-transition: width .2s, height .3s; + -moz-transition: width .2s, height .3s; + -o-transition: width .2s, height .3s; + transition: width .2s, height .3s; + -webkit-transition-delay: 50ms; + -moz-transition-delay: 50ms; + -o-transition-delay: 50ms; + transition-delay: 50ms +} + +.gridster-loaded .gridster-item.gridster-item-moving { + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; + opacity: 0.9; +} + +.gridster-mobile { + height: auto !important +} + +.gridster-mobile .gridster-item { + height: auto; + position: static; + float: none +} + +.gridster-item.ng-leave.ng-leave-active { + opacity: 0 +} + +.gridster-item.ng-enter { + opacity: 1 +} + +.gridster-item-moving { + z-index: 3 +} + +.gridster-item-resizable-handler { + position: absolute; + font-size: 1px; + display: block +} + +.handle-se { + cursor: se-resize; + width: 0; + height: 0; + right: 1px; + bottom: 1px; + border-style: solid; + border-width: 0 0 12px 12px; + border-color: transparent +} + +.handle-ne { + cursor: ne-resize; + width: 12px; + height: 12px; + right: 1px; + top: 1px +} + +.handle-nw { + cursor: nw-resize; + width: 12px; + height: 12px; + left: 1px; + top: 1px +} + +.handle-sw { + cursor: sw-resize; + width: 12px; + height: 12px; + left: 1px; + bottom: 1px +} + +.handle-e { + cursor: e-resize; + width: 12px; + bottom: 0; + right: 1px; + top: 0 +} + +.handle-s { + cursor: s-resize; + height: 12px; + right: 0; + bottom: 1px; + left: 0 +} + +.handle-n { + cursor: n-resize; + height: 12px; + right: 0; + top: 1px; + left: 0 +} + +.handle-w { + cursor: w-resize; + width: 12px; + left: 1px; + top: 0; + bottom: 0 +} + +.gridster .gridster-item:hover .gridster-box { + border: 1.5px solid #B3B2B3 +} + +.gridster .gridster-item:hover .handle-se { + border-color: transparent transparent #ccc +} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/att_angular_gridster/ui-gridster.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/att_angular_gridster/ui-gridster.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/att_angular_gridster/ui-gridster.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/att_angular_gridster/ui-gridster.css diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/fusion-sunny.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/fusion-sunny.css new file mode 100644 index 00000000..f9154a1c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/css/fusion-sunny.css @@ -0,0 +1,362 @@ + input, textarea, select, div { + font-family: Arial; + font-size: 11px; + font-weight: normal; + } + + form { + margin-top: 5px; + } + + + .applicationWindow { border-width: 0px 0px 1px 0px; + border-style: solid; + border-color: #959595; + box-shadow: inset 0 0 10px #000000; + margin-top: 10px; + margin-bottom: 10px; + margin-left: 10px; + margin-right: 10px; + } + + .feedbackMessage { width: 99%; + font-family: Arial; + font-size: 11px; + color: #1f1f1f; + padding: 3px; + border: 1px #eeb420 solid; + margin: 3px; + background: #fff9e5; + } + + .menubar { + border-width: 0px 0px 0px 1px; border-style: solid; border-color: #959595; + } + + .footer { + /*clear: both;*/ + border-width: 0px 1px 0px 1px; border-style: solid; border-color: #959595; + font-family: Verdana,Arial,Helvetica, sans-serif; + font-size: 9px; + padding: 10px 10px 30px 10px; + background: white; + } + + .pageTitle { + font-family: Arial; + font-size: 18px; + font-weight: bold; + margin-top: 5px; + } + + .content { + border-width: 0px 1px 0px 1px; + border-style: solid; + border-color: #959595; + font-family: Arial; + font-size: 11px; + padding: 5px; + background: white; + /*height: 600px;*/ + } + + .popupContent { + font-family: Arial; + font-size: 11px; + padding: 3px; + } + + .logo { + border-width: 0px 1px 0px 1px; + border-style: solid; + border-color: #959595; + text-align: right; + } + + .sep { + border: 1px solid black + } + + .logo { /*position: relative;*/ + float:left; + padding-top: 25px; + padding-left: 25px; + } + + .applicationLogo { float:right; + padding-top: 25px; + padding-right: 25px; + } + + .applinkWhite { font-family: Arial; + font-size: 13px; + font-weight: 900; + color: #FFFFFF; + text-decoration: none; } + + .terms { font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 9px; + } + + .broadcastMessage { color: red; } + .broadcastMessageList { color: red; } + + .button { + margin: 5px 1px 5px 1px; + padding: 3px; } + + .toolbarbutton:hover { + color:#005491; + } + + .headerText { font-family: Arial; + font-size: 15px; + font-weight: 700; + color: #000000; } + + .headerBackground { background: #336699; } + + .errorMessageText { font-family: Arial; + font-size: 11px; + font-weight: bold; + color: red; } + + + .normalText { font-family: Arial; + font-size: 11px; + color: #000000; } + + .normalTextRed { font-family: Arial; + font-size: 11px; + color: red; } + + + .smallNormalText { font-family: Arial; + font-size: 9px; + color: #000000; } + + .tableBorder { border:1px outset teal } + + .validationError { background: #b9eaff; } + + .templatebody { + background: url(../images/body_graphic.jpg) repeat-x; + /*margin: 40px 80px 40px 80px;*/ + } + + /*--------------------- General Content ------------------------------------*/ + + .relative { + position:relative; + } + + .clear{ + clear:both; + } + + .left { + float: left; + } + + .leftCentered{ + float: left; + text-align: center; + } + + .right { + float: right; + } + + .rightAligned{ + text-align: right; + } + + .centered { + text-align: center; + align: center; + } + + + .noWrap{ + white-space:nowrap; + } + + .disabled { + color:gray; + cursor:hand; + } + + /*--------------------- Tab styles -------------------------------------*/ + + .current { + font-weight: bold; + border-width: 1px 1px 1px 1px; + border-color: silver; + border-style: solid; + } + + .subTab { + font-weight:bold; + font-family: Arial; + font-size: 11px; + color: #0F3B82; + } + + + /*--------------------- Grid styles ------------------------------------*/ + + /* Grid navigation and header styles */ + .gridFilterLabel {font-size: 7pt; + font-align: justify; + font-weight: bold; + display: block;} + + .gridFilterText {height: 17px; + font-size: 8pt; + width: 60%; + font-align: justify;} + + .gridNavigationBar { font-family:Arial,Verdana; + font-size:11px; + font-weight:normal; + color:#000; + margin: 0px; + width: 100%; + vertical-align: middle; + } + + .gridNavigationBar .navLinks { float: left; + margin-right:15px; + padding-top: 2px; + height: 19px; + line-height: 19px; + } + + .gridNavigationBar .pageControls { float: left; + margin-right: 15px; + height: 19px; + line-height: 19px; + } + + .gridNavigationBar .pageControls input { font-size: 8pt; + height: 17px; + vertical-align: middle; + } + + .gridNavigationBar .pageInfo { float: right; + vertical-align: middle; + height: 19px; + line-height: 19px; + } + + .gridNavigationBar .pageInfo input { font-size: 8pt; + height: 17px; + vertical-align: middle; + } + + + .gridNavigationBar span { padding: 3px; } + + .gridNavigationBar a { + text-decoration:underline; + color:#000; + font-weight:normal; + } + + .gridNavigationBar img { vertical-align: middle; } + + .gridBulkUpdateRow { + height: 35px; + line-height: 35px; + } + + .gridBulkUpdateRow input { + vertical-align: middle; + } + + + /* dummy class used to lock the form elements of a grid - ex. bulk transaction processing */ + .alwaysEnabled {} + + .hidden { + display: none; + } + + .selectedPage { + background-color:#C4DFFB; + color: white; + border-style: solid; + border-width: 1px; + border-color: gray; + padding-left: 3px; + padding-right: 3px; + vertical-align: middle; + } + + .selectedRow{ + /*background-color:#C4DFFB;*/ + } + + /* Action Item styles */ + .actionList { + margin-left: -20px; + margin-right: -10px; + padding-left: 5px; + } + + .actionList li { + float:left; + padding-left: 3px; + padding-right: 3px; + } + + .actionList li a { + text-decoration:none; + color:#000; + } + + /* Filter Operator List styles */ + + .filterList { + margin: 0px; + } + + .filterList li { + list-style-type: none; + padding:3px 3px 3px 2px; + cursor:hand; + font-size:11px; + } + + .filterList li:hover { + background: #404040; + } + + .filterList li a { + color: #000; + text-decoration: none; + } + + .filterList li:hover a { + color: white; + } + + .filterList li a:hover { + text-decoration: none; + color: white; + } + + .filterListItem a { + text-decoration:none; + padding:3px 2px 3px 2px; + } + + + /*---------------------- Customized ZK Styles ------------------------------*/ + + .z-datebox input, .z-timebox input { + font-family: Arial; + font-size: 11px; + height: 15px; + margin-top:1px; + } diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/css/nv.d3.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/css/nv.d3.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/css/nv.d3.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/css/nv.d3.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/cie.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/cie.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/cie.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/cie.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/colorbrewer.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/colorbrewer.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/colorbrewer.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/colorbrewer.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/core.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/core.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/core.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/core.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/crossfilter.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/crossfilter.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/crossfilter.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/crossfilter.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/crossfilter.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/crossfilter.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/crossfilter.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/crossfilter.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.geom.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.geom.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.geom.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.geom.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.layout.cloud.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.layout.cloud.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.layout.cloud.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.layout.cloud.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.layout.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.layout.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.layout.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.layout.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.v2.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.v2.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.v2.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.v2.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.v2.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.v2.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.v2.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.v2.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.v3.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.v3.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/d3.v3.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/d3.v3.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/fisheye.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/fisheye.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/fisheye.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/fisheye.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/hive.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/hive.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/hive.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/hive.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/horizon.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/horizon.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/horizon.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/horizon.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/interactiveLayer.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/interactiveLayer.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/interactiveLayer.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/interactiveLayer.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/d3/js/intro.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/intro.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/d3/js/intro.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/intro.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/axis-min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/axis-min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/axis-min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/axis-min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/axis.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/axis.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/axis.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/axis.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/axis.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/axis.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/axis.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/axis.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/backup/bullet.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/backup/bullet.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/backup/bullet.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/backup/bullet.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/backup/bulletChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/backup/bulletChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/backup/bulletChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/backup/bulletChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/boilerplate.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/boilerplate.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/boilerplate.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/boilerplate.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/bullet.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/bullet.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/bullet.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/bullet.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/bulletChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/bulletChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/bulletChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/bulletChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/cumulativeLineChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/cumulativeLineChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/cumulativeLineChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/cumulativeLineChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/discreteBar.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/discreteBar.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/discreteBar.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/discreteBar.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/discreteBarChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/discreteBarChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/discreteBarChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/discreteBarChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/distribution.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/distribution.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/distribution.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/distribution.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/historicalBar.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/historicalBar.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/historicalBar.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/historicalBar.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/historicalBarChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/historicalBarChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/historicalBarChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/historicalBarChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/indentedTree.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/indentedTree.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/indentedTree.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/indentedTree.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/legend.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/legend.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/legend.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/legend.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/line.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/line.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/line.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/line.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/lineChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/lineChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/lineChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/lineChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/linePlusBarChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/linePlusBarChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/linePlusBarChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/linePlusBarChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/linePlusBarWithFocusChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/linePlusBarWithFocusChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/linePlusBarWithFocusChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/linePlusBarWithFocusChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/lineWithFisheye.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/lineWithFisheye.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/lineWithFisheye.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/lineWithFisheye.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/lineWithFisheyeChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/lineWithFisheyeChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/lineWithFisheyeChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/lineWithFisheyeChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/lineWithFocusChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/lineWithFocusChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/lineWithFocusChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/lineWithFocusChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBar.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBar.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBar.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBar.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontal.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontal.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontal.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontal.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontalChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontalChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontalChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarHorizontalChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeries.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeries.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeries.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeries.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeriesChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeriesChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeriesChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiBarTimeSeriesChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/multiChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/multiChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/ohlcBar.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/ohlcBar.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/ohlcBar.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/ohlcBar.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/parallelCoordinates.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/parallelCoordinates.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/parallelCoordinates.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/parallelCoordinates.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/pie.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/pie.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/pie.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/pie.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/pieChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/pieChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/pieChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/pieChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/scatter.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/scatter.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/scatter.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/scatter.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/scatterChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/scatterChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/scatterChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/scatterChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/scatterPlusLineChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/scatterPlusLineChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/scatterPlusLineChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/scatterPlusLineChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/sparkline.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/sparkline.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/sparkline.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/sparkline.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/sparklinePlus.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/sparklinePlus.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/sparklinePlus.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/sparklinePlus.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/stackedArea.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/stackedArea.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/stackedArea.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/stackedArea.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/stackedAreaChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/stackedAreaChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/models/stackedAreaChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/models/stackedAreaChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/nv.d3.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/nv.d3.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/nv.d3.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/nv.d3.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/nv.d3.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/nv.d3.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/nv.d3.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/nv.d3.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/outro.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/outro.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/outro.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/outro.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/sankey.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/sankey.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/sankey.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/sankey.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/tooltip.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/tooltip.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/tooltip.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/tooltip.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/utils.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/utils.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/utils.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/d3/js/utils.js diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/gis/js/local.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/gis/js/local.js new file mode 100644 index 00000000..5f4208a8 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/gis/js/local.js @@ -0,0 +1,178 @@ +var pointLayer= null; +var animateFlag = false; +var frame = 0; +var dates = []; +var delay = 1000; +var intervalId = null; +$( document ).ready(function() { + map(data2.map.lat,data2.map.lon,data2.map.zoom); + pointLayer = new L.layerGroup().addTo(map); + var point = getDates(data2.points); + drawPoints(data2,point); + + + $('#timeUp').bind('click',function(){ + delay += 500; + if ( animateFlag ) { + clearInterval(intervalId); + intervalId = window.setInterval(function(){animate(data2);},delay); + } + }); + $('#timeDown').bind('click',function(){ + if ( delay === 500 ) { return false; } + delay -= 500; + if ( animateFlag ) { + clearInterval(intervalId); + intervalId = window.setInterval(function(){animate(data2);},delay); + } + }); + + + $('#date').bind('change',function(){ + drawPoints(data2,$('#date').val()); + }); + $('#animate').bind('click',function(){ + if ( animateFlag ) { + animateFlag = false; + $('#animate_color').html('Off'); + $('#animate_color').removeClass('animateOn'); + $('#animate_color').addClass('animateOff'); + clearInterval(intervalId); + } else { + animateFlag = true; + $('#animate_color').html('On'); + $('#animate_color').removeClass('animateOff'); + $('#animate_color').addClass('animateOn'); + intervalId = window.setInterval(function(){animate(data2);},delay); + } + }); + + +}); + +function abc() { + var abc = 1; + var xyz = ""; + return nul; + +} + + + +function animate(obj){ + var point = dates[frame]; + drawPoints(obj,point); + frame++; + if ( frame >= dates.length ) { + frame = 0; + } + $('#currDate').val(point); + $('#showDelay').html(delay); +} + +function someFunction() { + + var self = this; + var x = 1; + var z = self + x; +} + + +/** +* drawPoints - Draw the points provided by point(date) +* obj JSON Object - Data for Map +* p String - Key (date) from the JSON object. +*/ +function drawPoints(obj,p){ + pointLayer.clearLayers(); + var lats = obj.points[p].lats; + var lons = obj.points[p].lons; + var txt = obj.points[p].text; + var fills = obj.points[p].colors; + points(lats, lons,txt,fills); +} + +/** +* Get dates from the list provided in pIn and put them in Select. +* then return the fist date. +* +*/ +function getDates(pIn) { + var html = ""; + var c = 0; + var ret = 0; + for (var d in pIn ) { + var val = d.replace('"',''); + if ( c === 0 ) { ret = val;}; + html += ""; + dates[c] = val; + c++; + } + $('#date').html(html); + return ret; +} + +/** +* Map - pass argumets to build map as specified Lat/Lon and zoom level +* String lat - Latitude +* String lon - Longitude +* String zoom - Zoom Level (1-18) +* +*/ +function map(lat,lon,zoom){ + var map = L.map('map').setView([lat,lon],zoom); + map.addControl(new L.control.scale()); + L.tileLayer('http://localhost/tiles-light/{z}/{x}/{y}.png', {maxZoom:18}).addTo(map); + window.L=L; + window.map=map; +} + +/** +* points - pass argumets to points specified Lat/Lon. Text and color for point is also passed. +* Input is either all singe values or all arrays. +* String[] lat - Latitude +* String[] lon - Longitude +* String[] text - Single/Array of Text for points +* String[] fill - Single/Array of Fill colors. +*/ +function points(lat,lon,text,fill){ + if(lat.length) { + for(i=0;i4 or + // undefined(indicating the use of another browser). + { + var isIE10 = (eval("/*@cc_on!@*/false") && document.documentMode === 10); + if (isIE10) { + return 10; + } + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + do { + div.innerHTML = ''; + } while (all[0]); + return v > 4 ? v : undefined; + }; + + var browserVersion = getInternetExplorerVersion(); + + if (browserVersion && browserVersion < 9) { + ie8 = true; + } + + // This returned angular module 'gridster' is what is exported. + return angular.module('attGridsterLib', []) + + .constant('gridsterConfig', { + columns: 6, // number of columns in the grid + pushing: true, // whether to push other items out of the way + floating: true, // whether to automatically float items up so they stack + swapping: true, // whether or not to have items switch places instead of push down if they are the same size + width: 'auto', // width of the grid. "auto" will expand the grid to its parent container + colWidth: 'auto', // width of grid columns. "auto" will divide the width of the grid evenly among the columns + rowHeight: 'match', // height of grid rows. 'match' will make it the same as the column width, a numeric value will be interpreted as pixels, '/2' is half the column width, '*5' is five times the column width, etc. + margins: [10, 10], // margins in between grid items + outerMargin: false, + isMobile: false, // toggle mobile view + mobileBreakPoint: 100, // width threshold to toggle mobile mode + mobileModeEnabled: true, // whether or not to toggle mobile mode when screen width is less than mobileBreakPoint + minColumns: 1, // minimum amount of columns the grid can scale down to + minRows: 1, // minimum amount of rows to show if the grid is empty + maxRows: 100, // maximum amount of rows in the grid + defaultSizeX: 1, // default width of an item in columns + defaultSizeY: 1, // default height of an item in rows + minSizeX: 1, // minimum column width of an item + maxSizeX: null, // maximum column width of an item + minSizeY: 1, // minumum row height of an item + maxSizeY: null, // maximum row height of an item + saveGridItemCalculatedHeightInMobile: false, // grid item height in mobile display. true- to use the calculated height by sizeY given + resizable: { // options to pass to resizable handler + enabled: false, + handles: ['s', 'e', 'n', 'w', 'se', 'ne', 'sw', 'nw'] + }, + draggable: { // options to pass to draggable handler + enabled: true, + scrollSensitivity: 20, // Distance in pixels from the edge of the viewport after which the viewport should scroll, relative to pointer + scrollSpeed: 15 // Speed at which the window should scroll once the mouse pointer gets within scrollSensitivity distance + } + }) + + .controller('GridsterCtrl', ['gridsterConfig', '$timeout', + function(gridsterConfig, $timeout) { + + var gridster = this; + + /** + * Create options from gridsterConfig constant + */ + angular.extend(this, gridsterConfig); + + this.resizable = angular.extend({}, gridsterConfig.resizable || {}); + this.draggable = angular.extend({}, gridsterConfig.draggable || {}); + + var flag = false; + this.layoutChanged = function() { + if (flag) { + return; + } + flag = true; + $timeout(function() { + flag = false; + if (gridster.loaded) { + gridster.floatItemsUp(); + } + gridster.updateHeight(gridster.movingItem ? gridster.movingItem.sizeY : 0); + }, 30); + }; + + /** + * A positional array of the items in the grid + */ + this.grid = []; + + /** + * Clean up after yourself + */ + this.destroy = function() { + // empty the grid to cut back on the possibility + // of circular references + if (this.grid) { + this.grid = []; + } + this.$element = null; + }; + + /** + * Overrides default options + * + * @param {Object} options The options to override + */ + this.setOptions = function(options) { + if (!options) { + return; + } + + options = angular.extend({}, options); + + // all this to avoid using jQuery... + if (options.draggable) { + angular.extend(this.draggable, options.draggable); + delete(options.draggable); + } + if (options.resizable) { + angular.extend(this.resizable, options.resizable); + delete(options.resizable); + } + + angular.extend(this, options); + + if (!this.margins || this.margins.length !== 2) { + this.margins = [0, 0]; + } else { + for (var x = 0, l = this.margins.length; x < l; ++x) { + this.margins[x] = parseInt(this.margins[x], 10); + if (isNaN(this.margins[x])) { + this.margins[x] = 0; + } + } + } + }; + + /** + * Check if item can occupy a specified position in the grid + * + * @param {Object} item The item in question + * @param {Number} row The row index + * @param {Number} column The column index + * @returns {Boolean} True if if item fits + */ + this.canItemOccupy = function(item, row, column) { + return row > -1 && column > -1 && item.sizeX + column <= this.columns && item.sizeY + row <= this.maxRows; + }; + + /** + * Set the item in the first suitable position + * + * @param {Object} item The item to insert + */ + this.autoSetItemPosition = function(item) { + // walk through each row and column looking for a place it will fit + for (var rowIndex = 0; rowIndex < this.maxRows; ++rowIndex) { + for (var colIndex = 0; colIndex < this.columns; ++colIndex) { + // only insert if position is not already taken and it can fit + var items = this.getItems(rowIndex, colIndex, item.sizeX, item.sizeY, item); + if (items.length === 0 && this.canItemOccupy(item, rowIndex, colIndex)) { + this.putItem(item, rowIndex, colIndex); + return; + } + } + } + throw new Error('Unable to place item!'); + }; + + /** + * Gets items at a specific coordinate + * + * @param {Number} row + * @param {Number} column + * @param {Number} sizeX + * @param {Number} sizeY + * @param {Array} excludeItems An array of items to exclude from selection + * @returns {Array} Items that match the criteria + */ + this.getItems = function(row, column, sizeX, sizeY, excludeItems) { + var items = []; + if (!sizeX || !sizeY) { + sizeX = sizeY = 1; + } + if (excludeItems && !(excludeItems instanceof Array)) { + excludeItems = [excludeItems]; + } + for (var h = 0; h < sizeY; ++h) { + for (var w = 0; w < sizeX; ++w) { + var item = this.getItem(row + h, column + w, excludeItems); + if (item && (!excludeItems || excludeItems.indexOf(item) === -1) && items.indexOf(item) === -1) { + items.push(item); + } + } + } + return items; + }; + + /** + * @param {Array} items + * @returns {Object} An item that represents the bounding box of the items + */ + this.getBoundingBox = function(items) { + + if (items.length === 0) { + return null; + } + if (items.length === 1) { + return { + row: items[0].row, + col: items[0].col, + sizeY: items[0].sizeY, + sizeX: items[0].sizeX + }; + } + + var maxRow = 0; + var maxCol = 0; + var minRow = 9999; + var minCol = 9999; + + for (var i = 0, l = items.length; i < l; ++i) { + var item = items[i]; + minRow = Math.min(item.row, minRow); + minCol = Math.min(item.col, minCol); + maxRow = Math.max(item.row + item.sizeY, maxRow); + maxCol = Math.max(item.col + item.sizeX, maxCol); + } + + return { + row: minRow, + col: minCol, + sizeY: maxRow - minRow, + sizeX: maxCol - minCol + }; + }; + + + /** + * Removes an item from the grid + * + * @param {Object} item + */ + this.removeItem = function(item) { + for (var rowIndex = 0, l = this.grid.length; rowIndex < l; ++rowIndex) { + var columns = this.grid[rowIndex]; + if (!columns) { + continue; + } + var index = columns.indexOf(item); + if (index !== -1) { + columns[index] = null; + break; + } + } + this.layoutChanged(); + }; + + /** + * Returns the item at a specified coordinate + * + * @param {Number} row + * @param {Number} column + * @param {Array} excludeItems Items to exclude from selection + * @returns {Object} The matched item or null + */ + this.getItem = function(row, column, excludeItems) { + if (excludeItems && !(excludeItems instanceof Array)) { + excludeItems = [excludeItems]; + } + var sizeY = 1; + while (row > -1) { + var sizeX = 1, + col = column; + while (col > -1) { + var items = this.grid[row]; + if (items) { + var item = items[col]; + if (item && (!excludeItems || excludeItems.indexOf(item) === -1) && item.sizeX >= sizeX && item.sizeY >= sizeY) { + return item; + } + } + ++sizeX; + --col; + } + --row; + ++sizeY; + } + return null; + }; + + /** + * Insert an array of items into the grid + * + * @param {Array} items An array of items to insert + */ + this.putItems = function(items) { + for (var i = 0, l = items.length; i < l; ++i) { + this.putItem(items[i]); + } + }; + + /** + * Insert a single item into the grid + * + * @param {Object} item The item to insert + * @param {Number} row (Optional) Specifies the items row index + * @param {Number} column (Optional) Specifies the items column index + * @param {Array} ignoreItems + */ + this.putItem = function(item, row, column, ignoreItems) { + // auto place item if no row specified + if (typeof row === 'undefined' || row === null) { + row = item.row; + column = item.col; + if (typeof row === 'undefined' || row === null) { + this.autoSetItemPosition(item); + return; + } + } + + // keep item within allowed bounds + if (!this.canItemOccupy(item, row, column)) { + column = Math.min(this.columns - item.sizeX, Math.max(0, column)); + row = Math.min(this.maxRows - item.sizeY, Math.max(0, row)); + } + + // check if item is already in grid + if (item.oldRow !== null && typeof item.oldRow !== 'undefined') { + var samePosition = item.oldRow === row && item.oldColumn === column; + var inGrid = this.grid[row] && this.grid[row][column] === item; + if (samePosition && inGrid) { + item.row = row; + item.col = column; + return; + } else { + // remove from old position + var oldRow = this.grid[item.oldRow]; + if (oldRow && oldRow[item.oldColumn] === item) { + delete oldRow[item.oldColumn]; + } + } + } + + item.oldRow = item.row = row; + item.oldColumn = item.col = column; + + this.moveOverlappingItems(item, ignoreItems); + + if (!this.grid[row]) { + this.grid[row] = []; + } + this.grid[row][column] = item; + + if (this.movingItem === item) { + this.floatItemUp(item); + } + this.layoutChanged(); + }; + + /** + * Trade row and column if item1 with item2 + * + * @param {Object} item1 + * @param {Object} item2 + */ + this.swapItems = function(item1, item2) { + this.grid[item1.row][item1.col] = item2; + this.grid[item2.row][item2.col] = item1; + + var item1Row = item1.row; + var item1Col = item1.col; + item1.row = item2.row; + item1.col = item2.col; + item2.row = item1Row; + item2.col = item1Col; + }; + + /** + * Prevents items from being overlapped + * + * @param {Object} item The item that should remain + * @param {Array} ignoreItems + */ + this.moveOverlappingItems = function(item, ignoreItems) { + // don't move item, so ignore it + if (!ignoreItems) { + ignoreItems = [item]; + } else if (ignoreItems.indexOf(item) === -1) { + ignoreItems = ignoreItems.slice(0); + ignoreItems.push(item); + } + + // get the items in the space occupied by the item's coordinates + var overlappingItems = this.getItems( + item.row, + item.col, + item.sizeX, + item.sizeY, + ignoreItems + ); + this.moveItemsDown(overlappingItems, item.row + item.sizeY, ignoreItems); + }; + + /** + * Moves an array of items to a specified row + * + * @param {Array} items The items to move + * @param {Number} newRow The target row + * @param {Array} ignoreItems + */ + this.moveItemsDown = function(items, newRow, ignoreItems) { + if (!items || items.length === 0) { + return; + } + items.sort(function(a, b) { + return a.row - b.row; + }); + + ignoreItems = ignoreItems ? ignoreItems.slice(0) : []; + var topRows = {}, + item, i, l; + + // calculate the top rows in each column + for (i = 0, l = items.length; i < l; ++i) { + item = items[i]; + var topRow = topRows[item.col]; + if (typeof topRow === 'undefined' || item.row < topRow) { + topRows[item.col] = item.row; + } + } + + // move each item down from the top row in its column to the row + for (i = 0, l = items.length; i < l; ++i) { + item = items[i]; + var rowsToMove = newRow - topRows[item.col]; + this.moveItemDown(item, item.row + rowsToMove, ignoreItems); + ignoreItems.push(item); + } + }; + + /** + * Moves an item down to a specified row + * + * @param {Object} item The item to move + * @param {Number} newRow The target row + * @param {Array} ignoreItems + */ + this.moveItemDown = function(item, newRow, ignoreItems) { + if (item.row >= newRow) { + return; + } + while (item.row < newRow) { + ++item.row; + this.moveOverlappingItems(item, ignoreItems); + } + this.putItem(item, item.row, item.col, ignoreItems); + }; + + /** + * Moves all items up as much as possible + */ + this.floatItemsUp = function() { + if (this.floating === false) { + return; + } + for (var rowIndex = 0, l = this.grid.length; rowIndex < l; ++rowIndex) { + var columns = this.grid[rowIndex]; + if (!columns) { + continue; + } + for (var colIndex = 0, len = columns.length; colIndex < len; ++colIndex) { + var item = columns[colIndex]; + if (item) { + this.floatItemUp(item); + } + } + } + }; + + /** + * Float an item up to the most suitable row + * + * @param {Object} item The item to move + */ + this.floatItemUp = function(item) { + if (this.floating === false) { + return; + } + var colIndex = item.col, + sizeY = item.sizeY, + sizeX = item.sizeX, + bestRow = null, + bestColumn = null, + rowIndex = item.row - 1; + + while (rowIndex > -1) { + var items = this.getItems(rowIndex, colIndex, sizeX, sizeY, item); + if (items.length !== 0) { + break; + } + bestRow = rowIndex; + bestColumn = colIndex; + --rowIndex; + } + if (bestRow !== null) { + this.putItem(item, bestRow, bestColumn); + } + }; + + /** + * Update gridsters height + * + * @param {Number} plus (Optional) Additional height to add + */ + this.updateHeight = function(plus) { + var maxHeight = this.minRows; + plus = plus || 0; + for (var rowIndex = this.grid.length; rowIndex >= 0; --rowIndex) { + var columns = this.grid[rowIndex]; + if (!columns) { + continue; + } + for (var colIndex = 0, len = columns.length; colIndex < len; ++colIndex) { + if (columns[colIndex]) { + maxHeight = Math.max(maxHeight, rowIndex + plus + columns[colIndex].sizeY); + } + } + } + this.gridHeight = this.maxRows - maxHeight > 0 ? Math.min(this.maxRows, maxHeight) : Math.max(this.maxRows, maxHeight); + }; + + /** + * Returns the number of rows that will fit in given amount of pixels + * + * @param {Number} pixels + * @param {Boolean} ceilOrFloor (Optional) Determines rounding method + */ + this.pixelsToRows = function(pixels, ceilOrFloor) { + if (ceilOrFloor === true) { + return Math.ceil(pixels / this.curRowHeight); + } else if (ceilOrFloor === false) { + return Math.floor(pixels / this.curRowHeight); + } + + return Math.round(pixels / this.curRowHeight); + }; + + /** + * Returns the number of columns that will fit in a given amount of pixels + * + * @param {Number} pixels + * @param {Boolean} ceilOrFloor (Optional) Determines rounding method + * @returns {Number} The number of columns + */ + this.pixelsToColumns = function(pixels, ceilOrFloor) { + if (ceilOrFloor === true) { + return Math.ceil(pixels / this.curColWidth); + } else if (ceilOrFloor === false) { + return Math.floor(pixels / this.curColWidth); + } + + return Math.round(pixels / this.curColWidth); + }; + } + ]) + + .directive('gridsterPreview', function() { + return { + replace: true, + scope: true, + require: '^gridster', + template: '
    ', + link: function(scope, $el, attrs, gridster) { + + /** + * @returns {Object} style object for preview element + */ + scope.previewStyle = function() { + + if (!gridster.movingItem) { + return { + display: 'none' + }; + } + + return { + display: 'block', + height: (gridster.movingItem.sizeY * gridster.curRowHeight - gridster.margins[0]) + 'px', + width: (gridster.movingItem.sizeX * gridster.curColWidth - gridster.margins[1]) + 'px', + top: (gridster.movingItem.row * gridster.curRowHeight + (gridster.outerMargin ? gridster.margins[0] : 0)) + 'px', + left: (gridster.movingItem.col * gridster.curColWidth + (gridster.outerMargin ? gridster.margins[1] : 0)) + 'px' + }; + }; + } + }; + }) + + /** + * The gridster directive + * + * @param {Function} $timeout + * @param {Object} $window + * @param {Object} $rootScope + * @param {Function} gridsterDebounce + */ + .directive('gridster', ['$timeout', '$window', '$rootScope', 'gridsterDebounce', + function($timeout, $window, $rootScope, gridsterDebounce) { + return { + scope: true, + restrict: 'EAC', + controller: 'GridsterCtrl', + controllerAs: 'gridster', + compile: function($tplElem) { + + $tplElem.prepend('
    '); + + return function(scope, $elem, attrs, gridster) { + gridster.loaded = false; + + gridster.$element = $elem; + + scope.gridster = gridster; + + $elem.addClass('gridster'); + + var isVisible = function(ele) { + return ele.style.visibility !== 'hidden' && ele.style.display !== 'none'; + }; + + function refresh(config) { + gridster.setOptions(config); + + if (!isVisible($elem[0])) { + return; + } + + // resolve "auto" & "match" values + if (gridster.width === 'auto') { + gridster.curWidth = $elem[0].offsetWidth || parseInt($elem.css('width'), 10); + } else { + gridster.curWidth = gridster.width; + } + + if (gridster.colWidth === 'auto') { + gridster.curColWidth = (gridster.curWidth + (gridster.outerMargin ? -gridster.margins[1] : gridster.margins[1])) / gridster.columns; + } else { + gridster.curColWidth = gridster.colWidth; + } + + gridster.curRowHeight = gridster.rowHeight; + if (typeof gridster.rowHeight === 'string') { + if (gridster.rowHeight === 'match') { + gridster.curRowHeight = Math.round(gridster.curColWidth); + } else if (gridster.rowHeight.indexOf('*') !== -1) { + gridster.curRowHeight = Math.round(gridster.curColWidth * gridster.rowHeight.replace('*', '').replace(' ', '')); + } else if (gridster.rowHeight.indexOf('/') !== -1) { + gridster.curRowHeight = Math.round(gridster.curColWidth / gridster.rowHeight.replace('/', '').replace(' ', '')); + } + } + + gridster.isMobile = gridster.mobileModeEnabled && gridster.curWidth <= gridster.mobileBreakPoint; + + // loop through all items and reset their CSS + for (var rowIndex = 0, l = gridster.grid.length; rowIndex < l; ++rowIndex) { + var columns = gridster.grid[rowIndex]; + if (!columns) { + continue; + } + + for (var colIndex = 0, len = columns.length; colIndex < len; ++colIndex) { + if (columns[colIndex]) { + var item = columns[colIndex]; + item.setElementPosition(); + item.setElementSizeY(); + item.setElementSizeX(); + } + } + } + + updateHeight(); + } + + var optionsKey = attrs.gridster; + if (optionsKey) { + scope.$parent.$watch(optionsKey, function(newConfig) { + refresh(newConfig); + }, true); + } else { + refresh({}); + } + + scope.$watch(function() { + return gridster.loaded; + }, function() { + if (gridster.loaded) { + $elem.addClass('gridster-loaded'); + } else { + $elem.removeClass('gridster-loaded'); + } + }); + + scope.$watch(function() { + return gridster.isMobile; + }, function() { + if (gridster.isMobile) { + $elem.addClass('gridster-mobile').removeClass('gridster-desktop'); + } else { + $elem.removeClass('gridster-mobile').addClass('gridster-desktop'); + } + $rootScope.$broadcast('gridster-mobile-changed', gridster); + }); + + scope.$watch(function() { + return gridster.draggable; + }, function() { + $rootScope.$broadcast('gridster-draggable-changed', gridster); + }, true); + + scope.$watch(function() { + return gridster.resizable; + }, function() { + $rootScope.$broadcast('gridster-resizable-changed', gridster); + }, true); + + function updateHeight() { + if(gridster.gridHeight){ //need to put this check, otherwise fail in IE8 + $elem.css('height', (gridster.gridHeight * gridster.curRowHeight) + (gridster.outerMargin ? gridster.margins[0] : -gridster.margins[0]) + 'px'); + } + } + + scope.$watch(function() { + return gridster.gridHeight; + }, updateHeight); + + scope.$watch(function() { + return gridster.movingItem; + }, function() { + gridster.updateHeight(gridster.movingItem ? gridster.movingItem.sizeY : 0); + }); + + var prevWidth = $elem[0].offsetWidth || parseInt($elem.css('width'), 10); + + var resize = function() { + var width = $elem[0].offsetWidth || parseInt($elem.css('width'), 10); + + if (!width || width === prevWidth || gridster.movingItem) { + return; + } + prevWidth = width; + + if (gridster.loaded) { + $elem.removeClass('gridster-loaded'); + } + + refresh(); + + if (gridster.loaded) { + $elem.addClass('gridster-loaded'); + } + + $rootScope.$broadcast('gridster-resized', [width, $elem[0].offsetHeight], gridster); + }; + + // track element width changes any way we can + var onResize = gridsterDebounce(function onResize() { + resize(); + $timeout(function() { + scope.$apply(); + }); + }, 100); + + scope.$watch(function() { + return isVisible($elem[0]); + }, onResize); + + // see https://github.com/sdecima/javascript-detect-element-resize + if (typeof window.addResizeListener === 'function') { + window.addResizeListener($elem[0], onResize); + } else { + scope.$watch(function() { + return $elem[0].offsetWidth || parseInt($elem.css('width'), 10); + }, resize); + } + var $win = angular.element($window); + $win.on('resize', onResize); + + // be sure to cleanup + scope.$on('$destroy', function() { + gridster.destroy(); + $win.off('resize', onResize); + if (typeof window.removeResizeListener === 'function') { + window.removeResizeListener($elem[0], onResize); + } + }); + + // allow a little time to place items before floating up + $timeout(function() { + scope.$watch('gridster.floating', function() { + gridster.floatItemsUp(); + }); + gridster.loaded = true; + }, 100); + }; + } + }; + } + ]) + + .controller('GridsterItemCtrl', function() { + this.$element = null; + this.gridster = null; + this.row = null; + this.col = null; + this.sizeX = null; + this.sizeY = null; + this.minSizeX = 0; + this.minSizeY = 0; + this.maxSizeX = null; + this.maxSizeY = null; + + this.init = function($element, gridster) { + this.$element = $element; + this.gridster = gridster; + this.sizeX = gridster.defaultSizeX; + this.sizeY = gridster.defaultSizeY; + }; + + this.destroy = function() { + // set these to null to avoid the possibility of circular references + this.gridster = null; + this.$element = null; + }; + + /** + * Returns the items most important attributes + */ + this.toJSON = function() { + return { + row: this.row, + col: this.col, + sizeY: this.sizeY, + sizeX: this.sizeX + }; + }; + + this.isMoving = function() { + return this.gridster.movingItem === this; + }; + + /** + * Set the items position + * + * @param {Number} row + * @param {Number} column + */ + this.setPosition = function(row, column) { + this.gridster.putItem(this, row, column); + + if (!this.isMoving()) { + this.setElementPosition(); + } + }; + + /** + * Sets a specified size property + * + * @param {String} key Can be either "x" or "y" + * @param {Number} value The size amount + * @param {Boolean} preventMove + */ + this.setSize = function(key, value, preventMove) { + key = key.toUpperCase(); + var camelCase = 'size' + key, + titleCase = 'Size' + key; + if (value === '') { + return; + } + value = parseInt(value, 10); + if (isNaN(value) || value === 0) { + value = this.gridster['default' + titleCase]; + } + var max = key === 'X' ? this.gridster.columns : this.gridster.maxRows; + if (this['max' + titleCase]) { + max = Math.min(this['max' + titleCase], max); + } + if (this.gridster['max' + titleCase]) { + max = Math.min(this.gridster['max' + titleCase], max); + } + if (key === 'X' && this.cols) { + max -= this.cols; + } else if (key === 'Y' && this.rows) { + max -= this.rows; + } + + var min = 0; + if (this['min' + titleCase]) { + min = Math.max(this['min' + titleCase], min); + } + if (this.gridster['min' + titleCase]) { + min = Math.max(this.gridster['min' + titleCase], min); + } + + value = Math.max(Math.min(value, max), min); + + var changed = (this[camelCase] !== value || (this['old' + titleCase] && this['old' + titleCase] !== value)); + this['old' + titleCase] = this[camelCase] = value; + + if (!this.isMoving()) { + this['setElement' + titleCase](); + } + if (!preventMove && changed) { + this.gridster.moveOverlappingItems(this); + this.gridster.layoutChanged(); + } + + return changed; + }; + + /** + * Sets the items sizeY property + * + * @param {Number} rows + * @param {Boolean} preventMove + */ + this.setSizeY = function(rows, preventMove) { + return this.setSize('Y', rows, preventMove); + }; + + /** + * Sets the items sizeX property + * + * @param {Number} columns + * @param {Boolean} preventMove + */ + this.setSizeX = function(columns, preventMove) { + return this.setSize('X', columns, preventMove); + }; + + /** + * Sets an elements position on the page + */ + this.setElementPosition = function() { + if (this.gridster.isMobile) { + this.$element.css({ + marginLeft: this.gridster.margins[0] + 'px', + marginRight: this.gridster.margins[0] + 'px', + marginTop: this.gridster.margins[1] + 'px', + marginBottom: this.gridster.margins[1] + 'px', + top: '', + left: '' + }); + } else { + this.$element.css({ + margin: 0, + top: (this.row * this.gridster.curRowHeight + (this.gridster.outerMargin ? this.gridster.margins[0] : 0)) + 'px', + left: (this.col * this.gridster.curColWidth + (this.gridster.outerMargin ? this.gridster.margins[1] : 0)) + 'px' + }); + } + }; + + /** + * Sets an elements height + */ + this.setElementSizeY = function() { + if (this.gridster.isMobile && !this.gridster.saveGridItemCalculatedHeightInMobile) { + this.$element.css('height', ''); + } else { + var computedHeight = (this.sizeY * this.gridster.curRowHeight - this.gridster.margins[0]) + 'px'; + //this.$element.css('height', computedHeight); + this.$element.attr('style', this.$element.attr('style') + '; ' + 'height: '+computedHeight+' !important;'); + } + }; + + /** + * Sets an elements width + */ + this.setElementSizeX = function() { + if (this.gridster.isMobile) { + this.$element.css('width', ''); + } else { + this.$element.css('width', (this.sizeX * this.gridster.curColWidth - this.gridster.margins[1]) + 'px'); + } + }; + + /** + * Gets an element's width + */ + this.getElementSizeX = function() { + return (this.sizeX * this.gridster.curColWidth - this.gridster.margins[1]); + }; + + /** + * Gets an element's height + */ + this.getElementSizeY = function() { + return (this.sizeY * this.gridster.curRowHeight - this.gridster.margins[0]); + }; + + }) + + .factory('GridsterTouch', [function() { + return function GridsterTouch(target, startEvent, moveEvent, endEvent) { + var lastXYById = {}; + + // Opera doesn't have Object.keys so we use this wrapper + var numberOfKeys = function(theObject) { + if (Object.keys) { + return Object.keys(theObject).length; + } + + var n = 0, + key; + for (key in theObject) { + ++n; + } + + return n; + }; + + // this calculates the delta needed to convert pageX/Y to offsetX/Y because offsetX/Y don't exist in the TouchEvent object or in Firefox's MouseEvent object + var computeDocumentToElementDelta = function(theElement) { + var elementLeft = 0; + var elementTop = 0; + var oldIEUserAgent = navigator.userAgent.match(/\bMSIE\b/); + + for (var offsetElement = theElement; offsetElement != null; offsetElement = offsetElement.offsetParent) { + // the following is a major hack for versions of IE less than 8 to avoid an apparent problem on the IEBlog with double-counting the offsets + // this may not be a general solution to IE7's problem with offsetLeft/offsetParent + if (oldIEUserAgent && + (!document.documentMode || document.documentMode < 8) && + offsetElement.currentStyle.position === 'relative' && offsetElement.offsetParent && offsetElement.offsetParent.currentStyle.position === 'relative' && offsetElement.offsetLeft === offsetElement.offsetParent.offsetLeft) { + // add only the top + elementTop += offsetElement.offsetTop; + } else { + elementLeft += offsetElement.offsetLeft; + elementTop += offsetElement.offsetTop; + } + } + + return { + x: elementLeft, + y: elementTop + }; + }; + + // cache the delta from the document to our event target (reinitialized each mousedown/MSPointerDown/touchstart) + var documentToTargetDelta = computeDocumentToElementDelta(target); + + // common event handler for the mouse/pointer/touch models and their down/start, move, up/end, and cancel events + var doEvent = function(theEvtObj) { + + if (theEvtObj.type === 'mousemove' && numberOfKeys(lastXYById) === 0) { + return; + } + + var prevent = true; + + var pointerList = theEvtObj.changedTouches ? theEvtObj.changedTouches : [theEvtObj]; + + for (var i = 0; i < pointerList.length; ++i) { + var pointerObj = pointerList[i]; + var pointerId = (typeof pointerObj.identifier !== 'undefined') ? pointerObj.identifier : (typeof pointerObj.pointerId !== 'undefined') ? pointerObj.pointerId : 1; + + // use the pageX/Y coordinates to compute target-relative coordinates when we have them (in ie < 9, we need to do a little work to put them there) + if (typeof pointerObj.pageX === 'undefined') { + + // initialize assuming our source element is our target + if(!ie8){ + pointerObj.pageX = pointerObj.offsetX + documentToTargetDelta.x; + pointerObj.pageY = pointerObj.offsetY + documentToTargetDelta.y; + } + else{ + pointerObj.pageX = pointerObj.clientX; + pointerObj.pageY = pointerObj.clientY; + } + + if (pointerObj.srcElement.offsetParent === target && document.documentMode && document.documentMode === 8 && pointerObj.type === 'mousedown') { + // source element is a child piece of VML, we're in IE8, and we've not called setCapture yet - add the origin of the source element + pointerObj.pageX += pointerObj.srcElement.offsetLeft; + pointerObj.pageY += pointerObj.srcElement.offsetTop; + } else if (pointerObj.srcElement !== target && !document.documentMode || document.documentMode < 8) { + // source element isn't the target (most likely it's a child piece of VML) and we're in a version of IE before IE8 - + // the offsetX/Y values are unpredictable so use the clientX/Y values and adjust by the scroll offsets of its parents + // to get the document-relative coordinates (the same as pageX/Y) + var sx = -2, + sy = -2; // adjust for old IE's 2-pixel border + for (var scrollElement = pointerObj.srcElement; scrollElement !== null; scrollElement = scrollElement.parentNode) { + sx += scrollElement.scrollLeft ? scrollElement.scrollLeft : 0; + sy += scrollElement.scrollTop ? scrollElement.scrollTop : 0; + } + + pointerObj.pageX = pointerObj.clientX + sx; + pointerObj.pageY = pointerObj.clientY + sy; + } + } + + + var pageX = pointerObj.pageX; + var pageY = pointerObj.pageY; + + if (theEvtObj.type.match(/(start|down)$/i)) { + // clause for processing MSPointerDown, touchstart, and mousedown + + // refresh the document-to-target delta on start in case the target has moved relative to document + documentToTargetDelta = computeDocumentToElementDelta(target); + + // protect against failing to get an up or end on this pointerId + if (lastXYById[pointerId]) { + if (endEvent) { + endEvent({ + target: theEvtObj.target, + which: theEvtObj.which, + pointerId: pointerId, + pageX: pageX, + pageY: pageY + }); + } + + delete lastXYById[pointerId]; + } + + if (startEvent) { + if (prevent) { + prevent = startEvent({ + target: theEvtObj.target, + which: theEvtObj.which, + pointerId: pointerId, + pageX: pageX, + pageY: pageY + }); + } + } + + // init last page positions for this pointer + lastXYById[pointerId] = { + x: pageX, + y: pageY + }; + + // IE pointer model + if (target.msSetPointerCapture) { + target.msSetPointerCapture(pointerId); + } else if (theEvtObj.type === 'mousedown' && numberOfKeys(lastXYById) === 1) { + if (useSetReleaseCapture) { + target.setCapture(true); + } else { + document.addEventListener('mousemove', doEvent, false); + document.addEventListener('mouseup', doEvent, false); + } + } + } else if (theEvtObj.type.match(/move$/i)) { + // clause handles mousemove, MSPointerMove, and touchmove + + if (lastXYById[pointerId] && !(lastXYById[pointerId].x === pageX && lastXYById[pointerId].y === pageY)) { + // only extend if the pointer is down and it's not the same as the last point + + if (moveEvent && prevent) { + prevent = moveEvent({ + target: theEvtObj.target, + which: theEvtObj.which, + pointerId: pointerId, + pageX: pageX, + pageY: pageY + }); + } + + // update last page positions for this pointer + lastXYById[pointerId].x = pageX; + lastXYById[pointerId].y = pageY; + } + } else if (lastXYById[pointerId] && theEvtObj.type.match(/(up|end|cancel)$/i)) { + // clause handles up/end/cancel + + if (endEvent && prevent) { + prevent = endEvent({ + target: theEvtObj.target, + which: theEvtObj.which, + pointerId: pointerId, + pageX: pageX, + pageY: pageY + }); + } + + // delete last page positions for this pointer + delete lastXYById[pointerId]; + + // in the Microsoft pointer model, release the capture for this pointer + // in the mouse model, release the capture or remove document-level event handlers if there are no down points + // nothing is required for the iOS touch model because capture is implied on touchstart + if (target.msReleasePointerCapture) { + target.msReleasePointerCapture(pointerId); + } else if (theEvtObj.type === 'mouseup' && numberOfKeys(lastXYById) === 0) { + if (useSetReleaseCapture) { + target.releaseCapture(); + } else { + document.removeEventListener('mousemove', doEvent, false); + document.removeEventListener('mouseup', doEvent, false); + } + } + } + } + + if (prevent) { + if (theEvtObj.preventDefault) { + theEvtObj.preventDefault(); + } + + if (theEvtObj.preventManipulation) { + theEvtObj.preventManipulation(); + } + + if (theEvtObj.preventMouseEvent) { + theEvtObj.preventMouseEvent(); + } + } + }; + + var useSetReleaseCapture = false; + // saving the settings for contentZooming and touchaction before activation + var contentZooming, msTouchAction; + + this.enable = function() { + + if (window.navigator.msPointerEnabled) { + // Microsoft pointer model + target.addEventListener('MSPointerDown', doEvent, false); + target.addEventListener('MSPointerMove', doEvent, false); + target.addEventListener('MSPointerUp', doEvent, false); + target.addEventListener('MSPointerCancel', doEvent, false); + + // css way to prevent panning in our target area + if (typeof target.style.msContentZooming !== 'undefined') { + contentZooming = target.style.msContentZooming; + target.style.msContentZooming = 'none'; + } + + // new in Windows Consumer Preview: css way to prevent all built-in touch actions on our target + // without this, you cannot touch draw on the element because IE will intercept the touch events + if (typeof target.style.msTouchAction !== 'undefined') { + msTouchAction = target.style.msTouchAction; + target.style.msTouchAction = 'none'; + } + } else if (target.addEventListener) { + // iOS touch model + target.addEventListener('touchstart', doEvent, false); + target.addEventListener('touchmove', doEvent, false); + target.addEventListener('touchend', doEvent, false); + target.addEventListener('touchcancel', doEvent, false); + + // mouse model + target.addEventListener('mousedown', doEvent, false); + + // mouse model with capture + // rejecting gecko because, unlike ie, firefox does not send events to target when the mouse is outside target + if (target.setCapture && !window.navigator.userAgent.match(/\bGecko\b/)) { + useSetReleaseCapture = true; + + target.addEventListener('mousemove', doEvent, false); + target.addEventListener('mouseup', doEvent, false); + } + } else if (target.attachEvent && target.setCapture) { + // legacy IE mode - mouse with capture + useSetReleaseCapture = true; + target.attachEvent('onmousedown', function() { + doEvent(window.event); + window.event.returnValue = false; + return false; + }); + target.attachEvent('onmousemove', function() { + doEvent(window.event); + window.event.returnValue = false; + return false; + }); + target.attachEvent('onmouseup', function() { + doEvent(window.event); + window.event.returnValue = false; + return false; + }); + } + }; + + this.disable = function() { + if (window.navigator.msPointerEnabled) { + // Microsoft pointer model + target.removeEventListener('MSPointerDown', doEvent, false); + target.removeEventListener('MSPointerMove', doEvent, false); + target.removeEventListener('MSPointerUp', doEvent, false); + target.removeEventListener('MSPointerCancel', doEvent, false); + + // reset zooming to saved value + if (contentZooming) { + target.style.msContentZooming = contentZooming; + } + + // reset touch action setting + if (msTouchAction) { + target.style.msTouchAction = msTouchAction; + } + } else if (target.removeEventListener) { + // iOS touch model + target.removeEventListener('touchstart', doEvent, false); + target.removeEventListener('touchmove', doEvent, false); + target.removeEventListener('touchend', doEvent, false); + target.removeEventListener('touchcancel', doEvent, false); + + // mouse model + target.removeEventListener('mousedown', doEvent, false); + + // mouse model with capture + // rejecting gecko because, unlike ie, firefox does not send events to target when the mouse is outside target + if (target.setCapture && !window.navigator.userAgent.match(/\bGecko\b/)) { + useSetReleaseCapture = true; + + target.removeEventListener('mousemove', doEvent, false); + target.removeEventListener('mouseup', doEvent, false); + } + } else if (target.detachEvent && target.setCapture) { + // legacy IE mode - mouse with capture + useSetReleaseCapture = true; + target.detachEvent('onmousedown'); + target.detachEvent('onmousemove'); + target.detachEvent('onmouseup'); + } + }; + + return this; + }; + }]) + + .factory('GridsterDraggable', ['$document', '$timeout', '$window', 'GridsterTouch', + function($document, $timeout, $window, GridsterTouch) { + function GridsterDraggable($el, scope, gridster, item, itemOptions) { + + var elmX, elmY, elmW, elmH, + + mouseX = 0, + mouseY = 0, + lastMouseX = 0, + lastMouseY = 0, + mOffX = 0, + mOffY = 0, + + minTop = 0, + maxTop = 9999, + minLeft = 0, + realdocument = $document[0]; + + var originalCol, originalRow; + var inputTags = ['select', 'input', 'textarea', 'button']; + + var gridsterItemDragElement = $el[0].querySelector('[gridster-item-drag]'); + //console.log(gridsterItemDragElement); + var isDraggableAreaDefined = gridsterItemDragElement?true:false; + //console.log(isDraggableAreaDefined); + + function mouseDown(e) { + + if(ie8){ + e.target = window.event.srcElement; + e.which = window.event.button; + } + + if(isDraggableAreaDefined && (!gridsterItemDragElement.contains(e.target))){ + return false; + } + + if (inputTags.indexOf(e.target.nodeName.toLowerCase()) !== -1) { + return false; + } + + var $target = angular.element(e.target); + + // exit, if a resize handle was hit + if ($target.hasClass('gridster-item-resizable-handler')) { + return false; + } + + // exit, if the target has it's own click event + if ($target.attr('onclick') || $target.attr('ng-click')) { + return false; + } + + // only works if you have jQuery + if ($target.closest && $target.closest('.gridster-no-drag').length) { + return false; + } + + switch (e.which) { + case 1: + // left mouse button + break; + case 2: + case 3: + // right or middle mouse button + return; + } + + lastMouseX = e.pageX; + lastMouseY = e.pageY; + + elmX = parseInt($el.css('left'), 10); + elmY = parseInt($el.css('top'), 10); + elmW = $el[0].offsetWidth; + elmH = $el[0].offsetHeight; + + originalCol = item.col; + originalRow = item.row; + + dragStart(e); + + return true; + } + + function mouseMove(e) { + if (!$el.hasClass('gridster-item-moving') || $el.hasClass('gridster-item-resizing')) { + return false; + } + + var maxLeft = gridster.curWidth - 1; + + // Get the current mouse position. + mouseX = e.pageX; + mouseY = e.pageY; + + // Get the deltas + var diffX = mouseX - lastMouseX + mOffX; + var diffY = mouseY - lastMouseY + mOffY; + mOffX = mOffY = 0; + + // Update last processed mouse positions. + lastMouseX = mouseX; + lastMouseY = mouseY; + + var dX = diffX, + dY = diffY; + if (elmX + dX < minLeft) { + diffX = minLeft - elmX; + mOffX = dX - diffX; + } else if (elmX + elmW + dX > maxLeft) { + diffX = maxLeft - elmX - elmW; + mOffX = dX - diffX; + } + + if (elmY + dY < minTop) { + diffY = minTop - elmY; + mOffY = dY - diffY; + } else if (elmY + elmH + dY > maxTop) { + diffY = maxTop - elmY - elmH; + mOffY = dY - diffY; + } + elmX += diffX; + elmY += diffY; + + // set new position + $el.css({ + 'top': elmY + 'px', + 'left': elmX + 'px' + }); + + drag(e); + + return true; + } + + function mouseUp(e) { + if (!$el.hasClass('gridster-item-moving') || $el.hasClass('gridster-item-resizing')) { + return false; + } + + mOffX = mOffY = 0; + + dragStop(e); + + return true; + } + + function dragStart(event) { + $el.addClass('gridster-item-moving'); + gridster.movingItem = item; + + gridster.updateHeight(item.sizeY); + scope.$apply(function() { + if (gridster.draggable && gridster.draggable.start) { + gridster.draggable.start(event, $el, itemOptions); + } + }); + } + + function drag(event) { + var oldRow = item.row, + oldCol = item.col, + hasCallback = gridster.draggable && gridster.draggable.drag, + scrollSensitivity = gridster.draggable.scrollSensitivity, + scrollSpeed = gridster.draggable.scrollSpeed; + + var row = gridster.pixelsToRows(elmY); + var col = gridster.pixelsToColumns(elmX); + + var itemsInTheWay = gridster.getItems(row, col, item.sizeX, item.sizeY, item); + var hasItemsInTheWay = itemsInTheWay.length !== 0; + + if (gridster.swapping === true && hasItemsInTheWay) { + var boundingBoxItem = gridster.getBoundingBox(itemsInTheWay), + sameSize = boundingBoxItem.sizeX === item.sizeX && boundingBoxItem.sizeY === item.sizeY, + sameRow = boundingBoxItem.row === oldRow, + sameCol = boundingBoxItem.col === oldCol, + samePosition = boundingBoxItem.row === row && boundingBoxItem.col === col, + inline = sameRow || sameCol; + + if (sameSize && itemsInTheWay.length === 1) { + if (samePosition) { + gridster.swapItems(item, itemsInTheWay[0]); + } else if (inline) { + return; + } + } else if (boundingBoxItem.sizeX <= item.sizeX && boundingBoxItem.sizeY <= item.sizeY && inline) { + var emptyRow = item.row <= row ? item.row : row + item.sizeY, + emptyCol = item.col <= col ? item.col : col + item.sizeX, + rowOffset = emptyRow - boundingBoxItem.row, + colOffset = emptyCol - boundingBoxItem.col; + + for (var i = 0, l = itemsInTheWay.length; i < l; ++i) { + var itemInTheWay = itemsInTheWay[i]; + + var itemsInFreeSpace = gridster.getItems( + itemInTheWay.row + rowOffset, + itemInTheWay.col + colOffset, + itemInTheWay.sizeX, + itemInTheWay.sizeY, + item + ); + + if (itemsInFreeSpace.length === 0) { + gridster.putItem(itemInTheWay, itemInTheWay.row + rowOffset, itemInTheWay.col + colOffset); + } + } + } + } + + if (gridster.pushing !== false || !hasItemsInTheWay) { + item.row = row; + item.col = col; + } + + if(($window.navigator.appName === 'Microsoft Internet Explorer' && !ie8) || $window.navigator.userAgent.indexOf("Firefox")!==-1){ + if (event.pageY - realdocument.documentElement.scrollTop < scrollSensitivity) { + realdocument.documentElement.scrollTop = realdocument.documentElement.scrollTop - scrollSpeed; + } else if ($window.innerHeight - (event.pageY - realdocument.documentElement.scrollTop) < scrollSensitivity) { + realdocument.documentElement.scrollTop = realdocument.documentElement.scrollTop + scrollSpeed; + } + } + else{ + if (event.pageY - realdocument.body.scrollTop < scrollSensitivity) { + realdocument.body.scrollTop = realdocument.body.scrollTop - scrollSpeed; + } else if ($window.innerHeight - (event.pageY - realdocument.body.scrollTop) < scrollSensitivity) { + realdocument.body.scrollTop = realdocument.body.scrollTop + scrollSpeed; + } + } + + + + if (event.pageX - realdocument.body.scrollLeft < scrollSensitivity) { + realdocument.body.scrollLeft = realdocument.body.scrollLeft - scrollSpeed; + } else if ($window.innerWidth - (event.pageX - realdocument.body.scrollLeft) < scrollSensitivity) { + realdocument.body.scrollLeft = realdocument.body.scrollLeft + scrollSpeed; + } + + if (hasCallback || oldRow !== item.row || oldCol !== item.col) { + scope.$apply(function() { + if (hasCallback) { + gridster.draggable.drag(event, $el, itemOptions); + } + }); + } + } + + function dragStop(event) { + $el.removeClass('gridster-item-moving'); + var row = gridster.pixelsToRows(elmY); + var col = gridster.pixelsToColumns(elmX); + if (gridster.pushing !== false || gridster.getItems(row, col, item.sizeX, item.sizeY, item).length === 0) { + item.row = row; + item.col = col; + } + gridster.movingItem = null; + item.setPosition(item.row, item.col); + + scope.$apply(function() { + if (gridster.draggable && gridster.draggable.stop) { + gridster.draggable.stop(event, $el, itemOptions); + } + }); + } + + var enabled = null; + var $dragHandles = null; + var unifiedInputs = []; + + this.enable = function() { + if (enabled === true) { + return; + } + + // disable and timeout required for some template rendering + $timeout(function() { + // disable any existing draghandles + for (var u = 0, ul = unifiedInputs.length; u < ul; ++u) { + unifiedInputs[u].disable(); + } + unifiedInputs = []; + + if (gridster.draggable && gridster.draggable.handle) { + $dragHandles = angular.element($el[0].querySelectorAll(gridster.draggable.handle)); + if ($dragHandles.length === 0) { + // fall back to element if handle not found... + $dragHandles = $el; + } + } else { + $dragHandles = $el; + } + + for (var h = 0, hl = $dragHandles.length; h < hl; ++h) { + unifiedInputs[h] = new GridsterTouch($dragHandles[h], mouseDown, mouseMove, mouseUp); + unifiedInputs[h].enable(); + } + + enabled = true; + }); + }; + + this.disable = function() { + if (enabled === false) { + return; + } + + // timeout to avoid race contition with the enable timeout + $timeout(function() { + + for (var u = 0, ul = unifiedInputs.length; u < ul; ++u) { + unifiedInputs[u].disable(); + } + + unifiedInputs = []; + enabled = false; + }); + }; + + this.toggle = function(enabled) { + if (enabled) { + this.enable(); + } else { + this.disable(); + } + }; + + this.destroy = function() { + this.disable(); + }; + } + + return GridsterDraggable; + } + ]) + + .factory('GridsterResizable', ['GridsterTouch', function(GridsterTouch) { + function GridsterResizable($el, scope, gridster, item, itemOptions) { + + function ResizeHandle(handleClass) { + + var hClass = handleClass; + + var elmX, elmY, elmW, elmH, + + mouseX = 0, + mouseY = 0, + lastMouseX = 0, + lastMouseY = 0, + mOffX = 0, + mOffY = 0, + + minTop = 0, + maxTop = 9999, + minLeft = 0; + + var getMinHeight = function() { + return (item.minSizeY ? item.minSizeY : 1) * gridster.curRowHeight - gridster.margins[0]; + }; + var getMinWidth = function() { + return (item.minSizeX ? item.minSizeX : 1) * gridster.curColWidth - gridster.margins[1]; + }; + + var originalWidth, originalHeight; + var savedDraggable; + + function mouseDown(e) { + switch (e.which) { + case 1: + // left mouse button + break; + case 2: + case 3: + // right or middle mouse button + return; + } + + // save the draggable setting to restore after resize + savedDraggable = gridster.draggable.enabled; + if (savedDraggable) { + gridster.draggable.enabled = false; + scope.$broadcast('gridster-draggable-changed', gridster); + } + + // Get the current mouse position. + lastMouseX = e.pageX; + lastMouseY = e.pageY; + + // Record current widget dimensions + elmX = parseInt($el.css('left'), 10); + elmY = parseInt($el.css('top'), 10); + elmW = $el[0].offsetWidth; + elmH = $el[0].offsetHeight; + + originalWidth = item.sizeX; + originalHeight = item.sizeY; + + resizeStart(e); + + return true; + } + + function resizeStart(e) { + $el.addClass('gridster-item-moving'); + $el.addClass('gridster-item-resizing'); + + gridster.movingItem = item; + + item.setElementSizeX(); + item.setElementSizeY(); + item.setElementPosition(); + gridster.updateHeight(1); + + scope.$apply(function() { + // callback + if (gridster.resizable && gridster.resizable.start) { + gridster.resizable.start(e, $el, itemOptions); // options is the item model + } + }); + } + + function mouseMove(e) { + var maxLeft = gridster.curWidth - 1; + + // Get the current mouse position. + mouseX = e.pageX; + mouseY = e.pageY; + + // Get the deltas + var diffX = mouseX - lastMouseX + mOffX; + var diffY = mouseY - lastMouseY + mOffY; + mOffX = mOffY = 0; + + // Update last processed mouse positions. + lastMouseX = mouseX; + lastMouseY = mouseY; + + var dY = diffY, + dX = diffX; + + if (hClass.indexOf('n') >= 0) { + if (elmH - dY < getMinHeight()) { + diffY = elmH - getMinHeight(); + mOffY = dY - diffY; + } else if (elmY + dY < minTop) { + diffY = minTop - elmY; + mOffY = dY - diffY; + } + elmY += diffY; + elmH -= diffY; + } + if (hClass.indexOf('s') >= 0) { + if (elmH + dY < getMinHeight()) { + diffY = getMinHeight() - elmH; + mOffY = dY - diffY; + } else if (elmY + elmH + dY > maxTop) { + diffY = maxTop - elmY - elmH; + mOffY = dY - diffY; + } + elmH += diffY; + } + if (hClass.indexOf('w') >= 0) { + if (elmW - dX < getMinWidth()) { + diffX = elmW - getMinWidth(); + mOffX = dX - diffX; + } else if (elmX + dX < minLeft) { + diffX = minLeft - elmX; + mOffX = dX - diffX; + } + elmX += diffX; + elmW -= diffX; + } + if (hClass.indexOf('e') >= 0) { + if (elmW + dX < getMinWidth()) { + diffX = getMinWidth() - elmW; + mOffX = dX - diffX; + } else if (elmX + elmW + dX > maxLeft) { + diffX = maxLeft - elmX - elmW; + mOffX = dX - diffX; + } + elmW += diffX; + } + + // set new position + $el.css({ + 'top': elmY + 'px', + 'left': elmX + 'px', + 'width': elmW + 'px', + 'height': elmH + 'px' + }); + + resize(e); + + return true; + } + + function mouseUp(e) { + // restore draggable setting to its original state + if (gridster.draggable.enabled !== savedDraggable) { + gridster.draggable.enabled = savedDraggable; + scope.$broadcast('gridster-draggable-changed', gridster); + } + + mOffX = mOffY = 0; + + resizeStop(e); + + return true; + } + + function resize(e) { + var oldRow = item.row, + oldCol = item.col, + oldSizeX = item.sizeX, + oldSizeY = item.sizeY, + hasCallback = gridster.resizable && gridster.resizable.resize; + + var col = item.col; + // only change column if grabbing left edge + if (['w', 'nw', 'sw'].indexOf(handleClass) !== -1) { + col = gridster.pixelsToColumns(elmX, false); + } + + var row = item.row; + // only change row if grabbing top edge + if (['n', 'ne', 'nw'].indexOf(handleClass) !== -1) { + row = gridster.pixelsToRows(elmY, false); + } + + var sizeX = item.sizeX; + // only change row if grabbing left or right edge + if (['n', 's'].indexOf(handleClass) === -1) { + sizeX = gridster.pixelsToColumns(elmW, true); + } + + var sizeY = item.sizeY; + // only change row if grabbing top or bottom edge + if (['e', 'w'].indexOf(handleClass) === -1) { + sizeY = gridster.pixelsToRows(elmH, true); + } + + if (gridster.pushing !== false || gridster.getItems(row, col, sizeX, sizeY, item).length === 0) { + item.row = row; + item.col = col; + item.sizeX = sizeX; + item.sizeY = sizeY; + } + var isChanged = item.row !== oldRow || item.col !== oldCol || item.sizeX !== oldSizeX || item.sizeY !== oldSizeY; + + if (hasCallback || isChanged) { + scope.$apply(function() { + if (hasCallback) { + gridster.resizable.resize(e, $el, itemOptions); // options is the item model + } + }); + } + } + + function resizeStop(e) { + $el.removeClass('gridster-item-moving'); + $el.removeClass('gridster-item-resizing'); + + gridster.movingItem = null; + + item.setPosition(item.row, item.col); + item.setSizeY(item.sizeY); + item.setSizeX(item.sizeX); + + scope.$apply(function() { + if (gridster.resizable && gridster.resizable.stop) { + gridster.resizable.stop(e, $el, itemOptions); // options is the item model + } + }); + } + + var $dragHandle = null; + var unifiedInput; + + this.enable = function() { + if (!$dragHandle) { + $dragHandle = angular.element('
    '); + $el.append($dragHandle); + } + + unifiedInput = new GridsterTouch($dragHandle[0], mouseDown, mouseMove, mouseUp); + unifiedInput.enable(); + }; + + this.disable = function() { + if ($dragHandle) { + $dragHandle.remove(); + $dragHandle = null; + } + + unifiedInput.disable(); + unifiedInput = undefined; + }; + + this.destroy = function() { + this.disable(); + }; + } + + var handles = []; + var handlesOpts = gridster.resizable.handles; + if (typeof handlesOpts === 'string') { + handlesOpts = gridster.resizable.handles.split(','); + } + var enabled = false; + + for (var c = 0, l = handlesOpts.length; c < l; c++) { + handles.push(new ResizeHandle(handlesOpts[c])); + } + + this.enable = function() { + if (enabled) { + return; + } + for (var c = 0, l = handles.length; c < l; c++) { + handles[c].enable(); + } + enabled = true; + }; + + this.disable = function() { + if (!enabled) { + return; + } + for (var c = 0, l = handles.length; c < l; c++) { + handles[c].disable(); + } + enabled = false; + }; + + this.toggle = function(enabled) { + if (enabled) { + this.enable(); + } else { + this.disable(); + } + }; + + this.destroy = function() { + for (var c = 0, l = handles.length; c < l; c++) { + handles[c].destroy(); + } + }; + } + return GridsterResizable; + }]) + + .factory('gridsterDebounce', function() { + return function gridsterDebounce(func, wait, immediate) { + var timeout; + return function() { + var context = this, + args = arguments; + var later = function() { + timeout = null; + if (!immediate) { + func.apply(context, args); + } + }; + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) { + func.apply(context, args); + } + }; + }; + }) + + /** + * GridsterItem directive + * @param $parse + * @param GridsterDraggable + * @param GridsterResizable + * @param gridsterDebounce + */ + .directive('gridsterItem', ['$parse', 'GridsterDraggable', 'GridsterResizable', 'gridsterDebounce', + function($parse, GridsterDraggable, GridsterResizable, gridsterDebounce) { + return { + scope: true, + restrict: 'EA', + controller: 'GridsterItemCtrl', + controllerAs: 'gridsterItem', + require: ['^gridster', 'gridsterItem'], + link: function(scope, $el, attrs, controllers) { + var optionsKey = attrs.gridsterItem, + options; + + var gridster = controllers[0], + item = controllers[1]; + + scope.gridster = gridster; + + + // bind the item's position properties + // options can be an object specified by gridster-item="object" + // or the options can be the element html attributes object + if (optionsKey) { + var $optionsGetter = $parse(optionsKey); + options = $optionsGetter(scope) || {}; + if (!options && $optionsGetter.assign) { + options = { + row: item.row, + col: item.col, + sizeX: item.sizeX, + sizeY: item.sizeY, + minSizeX: 0, + minSizeY: 0, + maxSizeX: null, + maxSizeY: null + }; + $optionsGetter.assign(scope, options); + } + } else { + options = attrs; + } + + item.init($el, gridster); + + $el.addClass('gridster-item'); + + var aspects = ['minSizeX', 'maxSizeX', 'minSizeY', 'maxSizeY', 'sizeX', 'sizeY', 'row', 'col'], + $getters = {}; + + var expressions = []; + var aspectFn = function(aspect) { + var expression; + if (typeof options[aspect] === 'string') { + // watch the expression in the scope + expression = options[aspect]; + } else if (typeof options[aspect.toLowerCase()] === 'string') { + // watch the expression in the scope + expression = options[aspect.toLowerCase()]; + } else if (optionsKey) { + // watch the expression on the options object in the scope + expression = optionsKey + '.' + aspect; + } else { + return; + } + expressions.push('"' + aspect + '":' + expression); + $getters[aspect] = $parse(expression); + + // initial set + var val = $getters[aspect](scope); + if (typeof val === 'number') { + item[aspect] = val; + } + }; + + for (var i = 0, l = aspects.length; i < l; ++i) { + aspectFn(aspects[i]); + } + + var watchExpressions = '{' + expressions.join(',') + '}'; + + // when the value changes externally, update the internal item object + scope.$watchCollection(watchExpressions, function(newVals, oldVals) { + for (var aspect in newVals) { + var newVal = newVals[aspect]; + var oldVal = oldVals[aspect]; + if (oldVal === newVal) { + continue; + } + newVal = parseInt(newVal, 10); + if (!isNaN(newVal)) { + item[aspect] = newVal; + } + } + }); + + function positionChanged() { + // call setPosition so the element and gridster controller are updated + item.setPosition(item.row, item.col); + + // when internal item position changes, update externally bound values + if ($getters.row && $getters.row.assign) { + $getters.row.assign(scope, item.row); + } + if ($getters.col && $getters.col.assign) { + $getters.col.assign(scope, item.col); + } + } + scope.$watch(function() { + return item.row + ',' + item.col; + }, positionChanged); + + function sizeChanged() { + var changedX = item.setSizeX(item.sizeX, true); + if (changedX && $getters.sizeX && $getters.sizeX.assign) { + $getters.sizeX.assign(scope, item.sizeX); + } + var changedY = item.setSizeY(item.sizeY, true); + if (changedY && $getters.sizeY && $getters.sizeY.assign) { + $getters.sizeY.assign(scope, item.sizeY); + } + + if (changedX || changedY) { + item.gridster.moveOverlappingItems(item); + gridster.layoutChanged(); + scope.$broadcast('gridster-item-resized', item); + } + } + + scope.$watch(function() { + return item.sizeY + ',' + item.sizeX + ',' + item.minSizeX + ',' + item.maxSizeX + ',' + item.minSizeY + ',' + item.maxSizeY; + }, sizeChanged); + + var draggable = new GridsterDraggable($el, scope, gridster, item, options); + var resizable = new GridsterResizable($el, scope, gridster, item, options); + + var updateResizable = function() { + resizable.toggle(!gridster.isMobile && gridster.resizable && gridster.resizable.enabled); + }; + updateResizable(); + + var updateDraggable = function() { + draggable.toggle(!gridster.isMobile && gridster.draggable && gridster.draggable.enabled); + }; + updateDraggable(); + + scope.$on('gridster-draggable-changed', updateDraggable); + scope.$on('gridster-resizable-changed', updateResizable); + scope.$on('gridster-resized', updateResizable); + scope.$on('gridster-mobile-changed', function() { + updateResizable(); + updateDraggable(); + }); + + function whichTransitionEvent() { + var el = document.createElement('div'); + var transitions = { + 'transition': 'transitionend', + 'OTransition': 'oTransitionEnd', + 'MozTransition': 'transitionend', + 'WebkitTransition': 'webkitTransitionEnd' + }; + for (var t in transitions) { + if (el.style[t] !== undefined) { + return transitions[t]; + } + } + } + + var debouncedTransitionEndPublisher = gridsterDebounce(function() { + scope.$apply(function() { + scope.$broadcast('gridster-item-transition-end', item); + }); + }, 50); + + if(whichTransitionEvent()){ //check for IE8, as it evaluates to null + $el.on(whichTransitionEvent(), debouncedTransitionEndPublisher); + } + + scope.$broadcast('gridster-item-initialized', item); + + return scope.$on('$destroy', function() { + try { + resizable.destroy(); + draggable.destroy(); + } catch (e) {} + + try { + gridster.removeItem(item); + } catch (e) {} + + try { + item.destroy(); + } catch (e) {} + }); + } + }; + } + ]) + + .directive('gridsterNoDrag', function() { + return { + restrict: 'A', + link: function(scope, $element) { + $element.addClass('gridster-no-drag'); + } + }; + }) + + ; + +})); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/att_angular_gridster/ui-gridster-tpls.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/att_angular_gridster/ui-gridster-tpls.js new file mode 100644 index 00000000..3ca3db7d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/att_angular_gridster/ui-gridster-tpls.js @@ -0,0 +1,168 @@ +/** +* FileName ui-gridster +* Version 0.0.1 +* Build number ad58c6f4f8f8fd7f04ac457f95d76f09 +* Date 08/17/2015 +*/ + + +(function(angular, window){ +angular.module("att.gridster", ["att.gridster.tpls", "att.gridster.utilities","att.gridster.gridster"]); +angular.module("att.gridster.tpls", ["template/gridster/gridster.html","template/gridster/gridsterItem.html","template/gridster/gridsterItemBody.html","template/gridster/gridsterItemFooter.html","template/gridster/gridsterItemHeader.html"]); +angular.module('att.gridster.utilities', []) + .factory('$extendObj', [function() { + var _extendDeep = function(dst) { + angular.forEach(arguments, function(obj) { + if (obj !== dst) { + angular.forEach(obj, function(value, key) { + if (dst[key] && dst[key].constructor && dst[key].constructor === Object) { + _extendDeep(dst[key], value); + } else { + dst[key] = value; + } + }); + } + }); + return dst; + }; + return { + extendDeep: _extendDeep + }; + }]); + +angular.module('att.gridster.gridster', ['attGridsterLib', 'att.gridster.utilities']) + .config(['$compileProvider', function($compileProvider) { + $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|javascript):/); + }]) + .constant('attGridsterConfig', + { + columns: 3, + margins: [10, 10], + outerMargin: true, + pushing: true, + floating: true, + swapping: true, + draggable: { + enabled: true + } + }) + .directive('attGridster', ['attGridsterConfig', '$extendObj', function(attGridsterConfig, $extendObj) { + return { + restrict: 'EA', + scope: { + attGridsterOptions: '=?' + }, + templateUrl: 'template/gridster/gridster.html', + replace: false, + transclude: true, + controller: [function() {}], + link: function(scope) { + if (angular.isDefined(scope.attGridsterOptions)) { + attGridsterConfig = $extendObj.extendDeep(attGridsterConfig, scope.attGridsterOptions); + } + scope.attGridsterConfig = attGridsterConfig; + } + }; + }]) + .directive('attGridsterItem', ['$timeout', function($timeout) { + return { + restrict: 'EA', + require: ['^attGridster'], + scope: { + attGridsterItem: '=' + }, + templateUrl: 'template/gridster/gridsterItem.html', + replace: false, + transclude: true, + controller: [function() {}] + }; + }]) + .directive('attGridsterItemHeader', [function() { + return { + restrict: 'EA', + require: ['^attGridsterItem'], + scope: { + headerText: '@', + subHeaderText: '@?' + }, + templateUrl: 'template/gridster/gridsterItemHeader.html', + replace: true, + transclude: true, + link: function(scope, element) { + if (angular.isDefined(scope.subHeaderText) && scope.subHeaderText) { + angular.element(element[0].querySelector('span.gridster-item-sub-header-content')).attr("tabindex", "0"); + angular.element(element[0].querySelector('span.gridster-item-sub-header-content')).attr("aria-label", scope.subHeaderText); + } + } + }; + }]) + .directive('attGridsterItemBody', [function() { + return { + restrict: 'EA', + require: ['^attGridsterItem'], + scope: {}, + templateUrl: 'template/gridster/gridsterItemBody.html', + replace: true, + transclude: true + }; + }]) + .directive('attGridsterItemFooter', ['$location', function($location) { + return { + restrict: 'EA', + require: ['^attGridsterItem'], + scope: { + attGridsterItemFooterLink: '@?' + }, + templateUrl: 'template/gridster/gridsterItemFooter.html', + replace: true, + transclude: true, + controller: ['$scope', function($scope) { + $scope.clickOnFooterLink = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + if ($scope.attGridsterItemFooterLink) { + $location.url($scope.attGridsterItemFooterLink); + } + }; + }], + link: function(scope, element) { + if (angular.isDefined(scope.attGridsterItemFooterLink) && scope.attGridsterItemFooterLink) { + element.attr("role", "link"); + } + } + }; + }]); +angular.module("template/gridster/gridster.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("template/gridster/gridster.html", + "
    "); +}]); + +angular.module("template/gridster/gridsterItem.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("template/gridster/gridsterItem.html", + "
    "); +}]); + +angular.module("template/gridster/gridsterItemBody.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("template/gridster/gridsterItemBody.html", + "
    "); +}]); + +angular.module("template/gridster/gridsterItemFooter.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("template/gridster/gridsterItemFooter.html", + "
    \n" + + " \n" + + "
    "); +}]); + +angular.module("template/gridster/gridsterItemHeader.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("template/gridster/gridsterItemHeader.html", + "
    \n" + + " \"||\"\n" + + " {{headerText}}\n" + + " {{subHeaderText}}\n" + + "
    \n" + + "
    "); +}]); + +return {} +})(angular, window); \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/jquery.resize.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/jquery.resize.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/jquery.resize.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/jquery.resize.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/layout/debug.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/layout/debug.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/layout/debug.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/layout/debug.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/layout/jquery-latest.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/layout/jquery-latest.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/layout/jquery-latest.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/layout/jquery-latest.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/layout/jquery-ui-latest.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/layout/jquery-ui-latest.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/layout/jquery-ui-latest.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/layout/jquery-ui-latest.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/layout/jquery.layout-latest.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/layout/jquery.layout-latest.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/layout/jquery.layout-latest.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/layout/jquery.layout-latest.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/moment.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/moment.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/js/moment.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/js/moment.min.js diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Entries b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Entries new file mode 100644 index 00000000..a4612779 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Entries @@ -0,0 +1,9 @@ +D/tree//// +/calendar.css/1.2/Tue Oct 01 18:58:02 2013/-ko/TQuantum_BD +/dashboard.css/1.2/Tue Oct 01 18:58:02 2013/-ko/TQuantum_BD +/form-field-tooltip.css/1.2/Tue Oct 01 18:58:02 2013/-ko/TQuantum_BD +/mobile_raptor.css/1.2/Tue Oct 01 18:58:02 2013/-ko/TQuantum_BD +/novamap.css/1.2/Tue Oct 01 18:58:02 2013/-ko/TQuantum_BD +/picker.css/1.2/Tue Oct 01 18:58:02 2013/-ko/TQuantum_BD +/ral.css/1.2/Tue Oct 01 18:58:02 2013/-ko/TQuantum_BD +/raptor.css/1.2/Wed Jul 03 21:16:48 2013/-ko/TQuantum_BD diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Repository b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Repository new file mode 100644 index 00000000..d4b93eab --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Repository @@ -0,0 +1 @@ +fusion/war/static/fusion/raptor/css diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Root b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Root new file mode 100644 index 00000000..e69de29b diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Tag b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Tag new file mode 100644 index 00000000..8f405b6d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/CVS/Tag @@ -0,0 +1 @@ +TQuantum_BD diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/Style.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/Style.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/Style.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/Style.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/bd_quantum_raptor.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/bd_quantum_raptor.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/bd_quantum_raptor.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/bd_quantum_raptor.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/calendar.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/calendar.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/calendar.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/calendar.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/dashboard.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/dashboard.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/dashboard.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/dashboard.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/drupal.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/drupal.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/drupal.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/drupal.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/form-field-tooltip.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/form-field-tooltip.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/form-field-tooltip.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/form-field-tooltip.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/mobile_raptor.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/mobile_raptor.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/mobile_raptor.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/mobile_raptor.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/novamap.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/novamap.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/novamap.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/novamap.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/picker.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/picker.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/picker.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/picker.css diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/ral.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/ral.css new file mode 100644 index 00000000..65fb6fd2 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/ral.css @@ -0,0 +1,1437 @@ +/* +Reusable Asset Library - CSS Positioning Version (v3.2) +Release Date: 1/26/07 +Core Styles +*/ + +/*------------------------General-----------------------------------*/ +body{ +background:#FFF; +font-family:Arial,Verdana,Geneva,Helvetica,sans-serif; +font-size:.71em; +padding:0; +margin:0px; +margin-right:1px; +border:0; +} +.nested{ +border:0; +padding:0; +margin:0; +} +.btm{ +vertical-align:bottom !important; +} +.nowrap{ +white-space:nowrap; +} +.top, .top td{ +vertical-align:top !important; +} +table{ /*IE5.5 hack*/ +font-size:100%; +} +td,tr,th{ /*IE5.5 hack*/ +font-size:inherit; +} +.hide{ +display:none !important; +} +.mid { +vertical-align:middle !important; +} +.value { +text-align:right; +} +.show{ +display:block !important; +} +ul{ +padding:0; +margin:0; +border:0; +} +.indent{ +margin-left:10px !important; +} +.code{ +font-family: Courier,serif; +} +p{ +padding:5px 0; +margin:0; +border:0; +} +h1{ +font-size:150%; +margin:2px 0px; +display:block; +position:relative; +clear:both; +} +h2{ +font-size:130%; +margin:2px 0px; +clear:both; +position:relative; +display:block; +} +h2.blue{ +position:relative; +top:0; +left:0; +font-size:100%; +background:#369; +color:#FFF; +margin:0; +margin-top:10px; +padding:2px 5px 2px 8px; +height:14px; +width:auto; +vertical-align:middle; +} +h3{ +font-size:120%; +clear:both; +margin:2px 0px; +position:relative; +display:block; +} +h4 { +font-size:100%; +clear:both; +margin:2px 0px; +position:relative; +display:block; +} + +/*----------------------Horizontal Rules----------------------------*/ +.hrule-blue { +height:1px; +border-top:1px #369 solid; +margin-top:6px; +margin-bottom:2px; +line-height:0px; +padding:0; +clear:both; +} +hr{ +border:0; +height:1px; +margin:10px 0; +background:#CCC; +width:100%; +clear:both; +} + +/*--------------Primay Window Banner--------------------------------*/ +#tBAN{ +padding:0; +border:0; +margin:0; +position:relative; +background:no-repeat url(../images/swoosh.gif) 100% 0; +min-width:800px; +display:table; /*For vertical centering in standards complaint browsers*/ +height:69px; +overflow-x:hidden; /*Remove horizonal scroll in IE*/ +} +#banner-spacer{ +display:block; +width:650px; +height:1px; +position:relative; +top:-1px; +} +#tBAN #logo{ +border:0; +padding:0; +margin:0; +top:10px; +position:absolute; +} +#tBAN #company { +color:#FFF; +font-weight:bold; +font-size:10pt; +padding-right:10px; +_position:absolute; /*IE Hack for vertical centering*/ +_top:48%; /*IE Hack for vertical centering*/ +display:table-cell; /*For standards complaint browsers*/ +vertical-align:middle; /*For standards complaint browsers*/ +text-align:right; +width:99%; +} +#tBAN #txt{ +_position:relative; /*IE Hack for vertical centering*/ +_top:-48%; /*IE Hack for vertical centering*/ +width:205px; +float:right; +overflow:hidden; +} +#appName{ +position:absolute; +left:112px; +top:45px; +color:#09C; +font-size:11pt; +font-weight:bold; +white-space:nowrap; +} + +/*---------------------Secondary Window Banner----------------------*/ +#tSWB{ +background:#FFF; +height:69px; +border-bottom:2px #369 solid; +} +#tSWB #appName{ +top:35px; +} + + +/*--------------------Secondary Windows (General)-------------------*/ +.pHW{ +background:#FFC; +} +.pSW{ +background:#FFF; +} +.pSW .tPH,.pHW .tPH{ +margin:0; +} +/*--------------------mIC: Introductory Copy------------------------*/ +p.mIC{ +padding:0; +margin:0; +} + +/*-----------------------mQH: Quick Help----------------------------*/ +.qh-link{ +float:right; +width:12px; +height:14px; +background:url(../images/quickhelp_lt.gif) no-repeat 0 50%; +cursor:pointer; +position:relative; +vertical-align:middle; +} +.qh-link-field{ +width:12px; +height:12px; +background:url(../images/quickhelp_lt.gif) no-repeat 0px 0px; +cursor:pointer; +position:relative; +top:0px; +} +.qh-element{ +margin-left:5px; +vertical-align:middle; +} +.icon-quick-help{ +display:inline; +} +.mQH { +clear:both !important; +display:none; +background:#9CF !important; +margin:0 !important; +border:0 !important; +height:auto !important; +padding:4px 8px !important; +position:relative !important; +z-index:0; +} +.mQH .label{ +font-weight:bold; +padding-right:5px; +} + +/*----------------------bPF: Footer---------------------------------*/ +#bPF{ +position:relative; +bottom:0px; +display:block; +/*float:none;*/ +height:60px; +clear:both; +padding:25px 0 20px 10px; +line-height:100%; +color:#333; +white-space:nowrap; +} +#bPF ul{ +position:relative; +top:0px; +left:0px; +margin:0 !important; +padding:0 !important; +margin-left:0px !important; +} +#bPF li{ +display:inline; +} +#bPF .pipe{ +padding-right:5px; +padding-left:5px; +} + +/*---------------------------LAYOUT---------------------------------*/ +#grid{ +display:block; +clear:both !important; +height:50%; +width:auto; +position:relative; +width:95%; +min-width:800px; +margin-left:10px; +z-index:10; +} +.grid-secondary{ +margin-top:10px; +margin-left:10px; +width:95%; +position:relative; +} + +/* One column-------------------------------------------------------*/ +.one-col .col1 { +width:95%; +} +.one-col .col2 { +display:none; +} +.one-col .col3 { +display:none; +} + +/* Two column, wide left:------------------------------------------*/ +.two-col-wl .col1 { +width:75%; +float:left; +} +.two-col-wl .col2 { +width:15%; +float:left; +margin-left:10px; +} +.two-col-wl .col3 { +display:none; +} + +/* Two column, wide right:------------------------------------------*/ +.two-col-wr .col1 { +width:15%; +float:left; +} +.two-col-wr .col2 { +width:75%; +float:left; +margin-left:10px; +} +.two-col-wr .col3 { +display:none; +} + +/* Three column-----------------------------------------------------*/ +.three-col .col1 { +width:15%; +float:left; +min-width:140px; +} +.three-col .col2 { +width:60%; +float:left; +margin-left:10px; +} +.three-col .col3 { +width:15%; +float:left; +margin-left:10px; +min-width:140px; +} + + +/*---------------------------Forms----------------------------------*/ +.first-row td{ +padding-top:5px !important; +} +.last-row td{ +padding-bottom:5px !important; +} +.checkbox{ +height:13px; +width:13px; +vertical-align:middle; +padding:0; +margin:0; +margin-right:10px; +text-align:center !important; +} +.col-ast{ +width:10px !important; +} +.col-ast div,.col-ast img{ +width:9px; +height:14px; +} +.form-grid td { +padding:5px 0; +vertical-align:middle; +} +.form-grid label.twoline, +label.br { +display:block; +} + + +.inline{ /*When multiple text input fields */ +margin-right:10px !important; /*are adjacent, space them out!!*/ +} +label{ +white-space:nowrap; +margin-right:15px; +vertical-align:middle; +} +.noborder{ +border:0 !important; +} +.rcb-spacer,.rcb-spacer img{ +width:20px; +} +p .ast{ +position:relative; +left:0px; +padding-right:3px; +} +.spacer-left { +padding:0 !important; +margin:0 !important; +width:5px; +} +.spacer-left img{ +margin:0; +padding:0; +border:0; +width:5px; +height:1px; +} +label span.br{ +display:block; +padding-left:5px; +} +label.text{ +vertical-align:top !important; +} +label.spacer{ +color:white; +} +form { +margin:0; +padding:0; +border:0; +} +.form-buttons{ +margin:10px 0; +white-space:nowrap; +margin-left:0px; +} +.top-border{ +border-top:1px #666 solid; +padding-top:10px; +margin-top:15px; +} +.form-buttons td { +vertical-align:middle; +padding:5px 0; +} +fieldset{ +border:0; +border-bottom:1px #000 solid; +padding:5px; +} +fieldset td{ +padding:3px 0; +} +fieldset .btm-row td{ +border-top:1px #CCC solid !important; +} +fieldset legend{ +color:#000; +font-weight:bold; +padding-bottom:5px; +margin-top:5px; +margin-left:-6px; +} +input.button{ +padding:1px 4px; +font-size:85%; +margin:0; +background:#ccc; +} +input.arrow-up{ +background:#CCC url(../images/button_arrow_up.gif) no-repeat 90% 50%; +padding-right:20px; +font-size:11px; +} +input.arrow-down{ +background:#CCC url(../images/button_arrow_down.gif) no-repeat 90% 50%; +padding-right:20px; +font-size:11px; +} +input.button-blue{ +padding:1px 4px; +font-size:85%; +margin:0; +color:#FFF; +background:#369; +} +input.button-sm{ +padding:1px; +font-size:78%; +margin:0; +} +textarea{ +font-size:100%; +font-family:sans-serif; +} +td.spacer{ +height:1px; +padding:0; +} +.disabled { +color:#CCC !important; +} +.abled { +color:#000 !important; +} +input.text, input.password{ +font-size:100%; +vertical-align:middle; +} +input.text:focus,textarea:focus{ +background:#FFC; +} +.radio{ +padding:0; +margin:0; +border:0; +height:12px; +width:12px; +vertical-align:middle; +margin-right:8px !important; +text-align:center !important; +} +.rcb { +line-height:120%; +} +select { +font-size:85%; +} +.tip{ +font-size:80%; +padding-left:5px; +display:inline; +position:relative; +} +td.tier2 label{ +padding-left:22px !important; +} +td.tier2 .checkbox{ +margin-left:-1px; +} +.col-radio{ +text-align:center; +} +/*---------------------------Help-----------------------------------*/ +.app-help{ +margin-right:auto; +margin-left:auto; +} +.nobullet li{ +list-style:none; +} +.plain{ +position:relative; +top:0px; +left:0px; +margin:0 !important; +padding:0 !important; +margin-left:1px !important; +} +.plain .list-label{ +padding-right:10px; +} +.plain li{ +list-style:none; +} +.index{ +clear:both; +padding:0; +margin:0; +border:0; +} +.index ul{ +padding:0px; +margin:0px; +border:0px; +height:15px; +} +.index ul li{ +float:left; +padding:4px; +list-style:none; +} +.index a{ +text-decoration:none !important; +} +.index a:hover{ +text-decoration:underline !important; +} + +/*--------------------------Glossary--------------------------------*/ +.glossary-index{ +height:12px; +display:block; +margin:0; +padding:0; +border:0; +padding-top:5px; +padding-bottom:5px; +margin-right:auto; +margin-left:auto; +text-transform:uppercase; +} +.glossary-index li{ +list-style:none; +display:inline; +padding-right:2px; +padding-left:2px; +font-weight:bold; +} +.glossary-index a{ +padding-left:2px; +padding-right:2px; +} +.glossary-index a:hover{ +background:#CCC; +} +dl{ +margin:0; +} +dt{ +font-weight:bold; +} +dd { +margin-left:20px; +} +.marker { +font-weight:bold; +color:#369; +width:100%; +text-transform:uppercase; +} +.section{ +border-bottom:1px #999 solid; +} +p.link{ +width:100%; +text-align:center; +margin-top:0px; +padding:0; +padding-bottom:5px; +} +.blocks { +padding:0; +margin:0; +border:0; +} +.blocks li{ +list-style:none; +float:left; +padding:10px; +} +.last{ +border-right:0 !important; +} +table { +clear:both; +} +.noline td { +border-bottom:0 !important; +} +.scroll{ +overflow:auto; +} +.ital{ +font-style:oblique; +} +.em{ +font-weight:bold !important; +} +.left{ +float:left; +} +.right{ +float:right; +} + +/*--------------------mTIE: Table of Interactive Elements-----------*/ +th{ +font-weight:bold !important; +} +th a{ +font-weight:bold !important; +} +.mTIE { +margin:10px 0; +border:0; +padding:0; +border-left:1px #CCC solid; +border-top:1px #CCC solid; +width:100%; +} +.date, .date-ss, .time { +text-align:right; +white-space:nowrap; + +} +.mTIE td{ +margin:0; +border:0; +border-bottom:1px #CCC solid; +border-right:1px #CCC solid; +padding:4px 6px; +vertical-align:middle; +} +.mTIE .headerRow td { +text-align:center; +} +.mTIE th { +margin:0; +border:0; +border-bottom:1px #CCC solid; +border-right:1px #CCC solid; +padding:3px 6px; +} +.mTIE a { +text-decoration:underline; +} +.headerRow{ +background:#369 !important; +color:#FFF; +font-weight:bold; +} +.button-mTIE{ /*Check All-Clear All button*/ +padding:1px 4px; +background:#CCC; +font-size:85%; +margin:0; +width:75px; +} +.decimal{ +text-align:right; +} +#totalRow { +background:#FFF !important; +} +#totalRow .decTotal { +text-align:right; +} +#totalRow .total{ +text-align:right; +} + +/*------------------------mTAB--------------------------------------*/ +.mTAB { +margin:0px 0; +border:0; +padding:0; +border-left:1px #CCC solid; +border-top:1px #CCC solid; +/*width:100%;*/ +} +.mTAB .date{ +text-align:right; +white-space:nowrap; +} +.mTAB td{ +margin:0; +border:0; +border-bottom:1px #CCC solid; +border-right:1px #CCC solid; +padding:4px 6px; +vertical-align:middle; +} +.mTAB .headerRow td { +text-align:center; +} +.mTAB th { +margin:0; +border:0; +border-bottom:1px #CCC solid; +border-right:1px #CCC solid; +padding:4px 6px; +} +/*.mTAB a { +text-decoration:underline; +}*/ +.headerRow{ +background:#369 !important; +color:#FFF; +font-weight:bold; +} +.button-mTAB{ /*Check All-Clear All button*/ +font-size:10px; +padding:1px 4px; +height:20px; +line-height:12px; +width:75px; +} + +/* LISTS and mTS */ +/*----------------------mIM: Inline Messages------------------------*/ +.mIM{ +background:#9CF; +margin:5px 0; +padding:5px; +background-position:9px 5px !important; +clear:both; +display:block; +} +.mIM p,.mIM ul,.mIM ol{ +position:relative; +top:0; +left:0; +padding:0; +margin:0; +padding-left:48px; +padding-bottom:5px; +border:0; +display:block; +} +.mIM ul{ +padding-left:65px; +width:80%; +} +.mIM ol{ +padding-left:70px; +width:80%; +} +* html .mIM { /*IE Hack*/ +height:35px; /*set the height in IE5.5*/ +voice-family:"\"}\""; +voice-family:inherit; +height:30px; /*set the height in IE6.0*/ +} +*+.mIM{ /*high end browser hack*/ +min-height:30px; +} +div.error { +background:#9CF url(../images/icon_error.gif) no-repeat; +} +.error .txt{ +font-size:100%; +color:#F00; +font-weight:bold; +text-align:right; +padding-right:10px; +padding-left:44px; +width:35px; +} +.error table{ +position:relative; +} +.error table td{ +vertical-align:top; +} +.error .list-errors { +padding:0; +display:block; +clear:both; +left:-1px; +position:relative; +} +.error .list-errors li { +list-style:none; +background:url(../images/dash.gif) no-repeat 0 50%; +padding-left:12px; +} +.error p, +.error ul{ +padding-left:0; +} +.error p{ +padding-top:0; +margin-top:0; +} +.info { +background:#9CF url(../images/icon_info.gif) no-repeat; +} +.confirmation { +background:#9CF url(../images/icon_confirmation.gif) no-repeat; +} +.alert { +background:#9CF url(../images/icon_alert.gif) no-repeat; +} +.help { +background:#9CF url(../images/icon_help.gif) no-repeat; +} + +/*---------------------mRT: Return to Top---------------------------*/ +.mRT { +margin:10px 0; +clear:both; +display:block; +} +.mRT a { +background:url(../images/return_to_top.gif) no-repeat 0 2px; +padding-left:15px; +} +/*---------------------mPW:Please Wait------------------------------*/ +.mPW { +border-top:1px #666 solid; +border-bottom:1px #666 solid; +background:#FFF; +padding:10px; +text-align:center; +height:auto; +width:auto; +clear:both; +display:block; +margin:10px 0px; +} +.icon-wait { +background:url(../images/please_wait.gif) no-repeat 50% 100%; +width:100px; +height:20px; +margin-left:auto; +margin-right:auto; +clear:both; +display:block; +} + +/*---------------------mDL: Data List-------------------------------*/ +.mDL{ +width:100%; +margin:10px 0; +} +.mDL td{ +padding:4px 0px 4px 10px; +} +.mDL th{ +background:#369; +color:#FFF; +text-align:left; +padding:2px 5px; +} +.mDL .label{ +text-align:right; +} +.mDL .total{ /*are these being duplicated?*/ +text-align:right; +font-weight:bold; +padding-right:10px; +} +.mDL .decimal{ +text-align:right; +padding-right:10px; +} + +/*------------------mDDL: Double Data List--------------------------*/ +.mDDL .plain{ +margin-bottom:10px !important; +} +.mDDL{ +width:100%; +margin:10px 0; +} +.mDDL td{ +padding:4px 0px 4px 10px; +} +.mDDL th{ +background:#369; +color:#FFF; +text-align:left; +padding:2px 5px; +} +.mDDL .label{ +text-align:right; +} +.mDDL .total{ +text-align:right; +font-weight:bold; +padding-right:10px; +} +.mDDL .decimal{ +text-align:right; +padding-right:10px; +} + +/*------------------------mCA: Contact -------------------------*/ +.mCA{ +position:relative; +width:50%; +height:auto; +margin:10px 0; +} +.mCA .number { +position:relative; +} +.mCA .mail{ +font-weight:bold; +position:relative; +background:inherit; +} +.mCA address{ +margin-left:150px; +font-weight:normal; +font-style:normal; +} + + +/*----------mDSR:Data Summary/Review Verification-------------------*/ +.mDSR { +border-bottom:1px #000 solid; +width:100%; +margin:10px 0; +} +.mDSR th { +text-align:left; +padding:4px 6px; +} +.mDSR td { +text-align:left; +padding:4px 4px; +vertical-align:top; +} +th a{ +font-weight:normal; +margin-left:5px; +} + +/*---------------------mLL: Link Listing----------------------------*/ +.mLL { +margin:10px 0; +width:100%; +display:block; +height:auto; +position:relative; +clear:both; +float:none; +} +.mLL ul{ +margin:0; +padding:10px 0px; +width:45%; +position:relative; +} +.mLL ul li{ +list-style:none; +border:0; +margin:0; +padding-bottom:2px; +} + + +/*-----------------mPN: Pagination/Navigation-----------------------*/ +.mPN{ +position:relative; +display:block; +clear:both; +height:45px; +margin:10px 0; +white-space:nowrap; +} +.mPN p, +.mPN label { +line-height:160% !important; +padding:0; +margin:0; +border:0; +vertical-align:top; +} +.mPN .current{ +font-weight:bold; +} +.mPN a{ +font-weight:bold; +} +.mPN .left,.mPN .right{ +float:left; +vertical-align:top; +height:100%; +color:#999; +font-weight:bold; +} +.mPN .left{ +padding-right:40px; +} +.mPN .right{ +padding-left:45px; +} +.mPN .middle{ +float:left; +text-align:left; +height:100%; +padding-top:0px; +} +.mPN input.text{ +vertical-align:top; +} + +/*-----------------mSN: Simple Navigation---------------------------*/ +.mSN{ +padding:5px 0 !important; +margin:0; +border:0; +width:90%; +} +.mSN *{ /*IE Hack to fix jumping*/ +position:relative; +top:0; +left:0; +} +.mSN ul{ +clear:both; +width:80%; +margin:0 !important; +left:15px; +} +.mSN li { +list-style:none; +padding-bottom:3px; +} + +/*----------------------mTC: Task Confirmation----------------------*/ +.mTC{ +border:1px #9CF solid; +border-top:0; +margin:10px 0; +min-width:300px; +} +.mTC ul{ +margin-left:65px; +} +.mTC p{ +margin-left:60px; +} +.mTC table{ +padding:0; +margin:0; +border:0; +margin-left:58px; +} +.mTC h2{ +position:relative; +top:0; +left:0; +width:auto; +background:#9CF url(../images/banner-confirmation.gif) repeat-x 0 0; +padding:12px 10px 12px 60px; +font-size:100%; +font-weight:normal; +margin-bottom:10px; +} + +/*--------------------mHL: Helpful Links (new)----------------------*/ +.mHL{ +border-top:1px #333 solid; +border-bottom:1px #333 solid; +padding:10px 0; +margin-bottom:10px; +} +.mHL h3{ +font-size:100%; +} +.mHL ul{ +margin-left:65px; +} + +/*--------------------mTI: Task Instructions------------------------*/ +.mTI{ +display:block; +clear:both; +margin:10px 0; +} +.mTI ul{ +position:relative; +display:block; +left:.1em; +padding:0; +border:0; +} +/*---------------bSWN: Secondary Window Navigation------------------*/ +.bSWN{ +padding:10px 0; +border-top:1px #369 solid; +} + +/*----------------mSD: Status Dashboard-----------------------------*/ +.mSD{ +border:1px #369 solid; +margin:10px 0; +width:100%; +} +.mSD th{ +background:#369; +color:#FFF; +text-align:left; +padding:2px 5px; +} + +/*----------------mSDL: Summary Data Listing-----------------------*/ +.mSDL{ +border:1px #369 solid; +margin:10px 0; +min-width:250px; +width:100%; +} +.mSDL td{ +border:0; +margin:0; +padding:2px 0 2px 8px; +vertical-align:middle; +} +.mSDL th{ +background:#369; +color:#FFF; +text-align:left; +padding:2px 5px; +} +.mSDL .value{ +text-align:right; +} + +/*----------------------mDEE: Data Entry/Edit ----------------------*/ +.mDEE{ +margin:10px 0; +width:100%; +} +table.mDEE{ +border:1px #369 solid; +} +.mDEE td{ +border:0; +margin:0; +padding:5px 0; +vertical-align:middle; +} +.mDEE th{ +background:#369; +color:#FFF; +text-align:left; +padding:2px 5px; +} +.nopad{ +padding:0 !important; +border:0; +margin:0; +width:100%; +} +.desc { +text-align:right; +} + +/*---------------------Supporting Text------------------------------*/ +.mST{ +margin:10px 0; +display:block; +clear:both; +} + +/*------------------------tPH: Page header--------------------------*/ +.tPH { +margin:10px 100px 1px 10px; +display:block; +clear:both; +} + +/*----------------Topic index found in pHW2.html--------------------*/ +.topic-index{ +padding:0; +margin:5px 0; +width:100%; +height:14px; +display:block; +clear:both; +position:relative; +top:0; +left:0; +} +.topic-index li{ +list-style:none; +float:left; +margin-right:25px; +padding:0; +border:0; +} +.topic-index li a{ +padding-left:10px; +background:url(../images/arrow_down_alt.gif) no-repeat 0 50%; +} +.alt li a{ +padding-left:10px; +background:url(../images/arrow_down_alt2.gif) no-repeat 0 50%; +} + +/*------------------Freezing header mods for NS7------------------- */ +div[class="class_float"] table { +padding:0; +margin:0; +border:1px #CCC solid !important; +background:#369; +width:100%; +} +div[class="class_float"] th { +margin:0; +border-right:0; +border-bottom:0; +vertical-align:middle; +} +.headerRow nobr{ +border-left:2px #369 solid; +} + +/*------------------mSD:Status Dashboard----------------------------*/ +.data-mSD{ +width:90%; +margin:0 10px; +} +.data-mSD td{ +padding:2px 0 !important; +margin:0 !important; +border:0 !important; +} +.data-mSD .value{ +text-align:right !important; +} +.wrap { +white-space:normal; +} +.input-error{ +color:#F00; +font-weight:bold; +} + + +/*-------------------mCC: Convenence Choices------------------------*/ +.mCC{ +margin:10px 0; +width:100%; +} +table.mCC{ +border:1px #369 solid; +} +.mCC td{ +border:0; +margin:0; +padding:5px 0; +vertical-align:middle; +} +.mCC th{ +background:#369; +color:#FFF; +text-align:left; +padding:2px 5px; +} + +/*-----------------------Layout sample pages------------------------*/ +.layout-template .col1, +.layout-template .col2, +.layout-template .col3{ +background:#efefef; +height:350px; +border:1px #CCC dotted; +text-align:center; +} +.layout-template #grid{ +padding-top:10px; +} +.center{ +text-align:center; +} + +/*----------------------Row Exchange Module-------------------------*/ +div.mREX{ +border:1px #999 solid; +padding:5px 10px; +margin-bottom:20px; +background:#efefef; +} +h1.mREX{ +background:#999; +color:#FFF; +padding:5px 10px; +margin:0; +font-size:100%; +margin-top:20px; +} + +/*---------------508 Complaint Skip Navigation Link-----------------*/ +#skip{ +display:inline; +color:#FFF !important; +text-decoration:none; +font-size:1px; +position:absolute; +top:0; +left:0; +z-index:10; +} +.cal-label{ +font-size:90%; +color:#999; +position: relative; +top:4px; +} +caption{ +font-weight:bold; +color:#369; +} +#grid a:visited{ +text-decoration:none; +border-bottom:1px dotted; +} +.clear{ +display:block !imporatn; +clear:both; +} + +/*---------------------mTS: Task Steps------------------------------*/ +.mTS { +border:1px #9CF solid; +width:140px; +background:#FFF; +margin:10px 0; +} +.mTS h2 { +text-transform:uppercase; +text-align:center; +color:#369; +padding:0px 4px; +margin:0; +border:0; +font-size:100%; +border-bottom:1px #9CF solid; +} +.mTS ul { +margin:0; +border:0; +padding:5px 0; +width:90%; +} +.mTS ul li { +list-style:none; +padding-bottom:8px; +padding-left:20px; +padding-right:5px; +} +.mTS li.current { +font-weight:bold; +background:url(../images/task_arrow_on.gif) no-repeat; +} +.mTS li.complete { +background:url(../images/check.gif) no-repeat; +} \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/raptor.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/raptor.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/css/raptor.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/raptor.css diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/tree/context-menu.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/tree/context-menu.css new file mode 100644 index 00000000..160c2a11 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/tree/context-menu.css @@ -0,0 +1,57 @@ +/************************************************************************************************************ + + DHTML Suite for Applications + (C) www.dhtmlgoodies.com, August 2006 + + CSS for the context menu class. + + Terms of use: + Look at the terms of use at http://www.dhtmlgoodies.com/index.html?page=termsOfUse + + Thank you! + + www.dhtmlgoodies.com + Alf Magne Kalleland + +************************************************************************************************************/ + +.DHTMLSuite_contextMenu{ /* The bar that is parent of the menu strip */ + position:absolute; + background-color:#FFF; + border:1px solid #000; + padding:1px; +} + +.DHTMLSuite_contextMenu li{ + list-style-type:none; + padding:1px; /* Equal to border + padding of .DHTMLSuite_item_mouseover */ + border:0px; + cursor: pointer; + background-repeat:no-repeat; + background-position:left center; +} +.DHTMLSuite_contextMenu .DHTMLSuite_item_mouseover{ + border:1px solid #000; + background-color:#EEE; + padding:0px; /* Padding + border of this element should be equal to padding of li element (see above ) */ +} +.DHTMLSuite_contextMenu ul{ + margin:0px; + padding:0px; +} + +.DHTMLSuite_contextMenu a{ + text-decoration:none; + color:#000; + padding-left:25px; +} + +.DHTMLSuite_contextMenu div.DHTMLSuite_contextMenu_separator{ /* Css for the separator line */ + height:1px; + line-height:1px; + padding:0px; + background-color: #AAA; + overflow:hidden; + margin-top:1px; + margin-bottom:1px; +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/tree/drag-drop-folder-tree.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/tree/drag-drop-folder-tree.css new file mode 100644 index 00000000..67afc894 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/css/tree/drag-drop-folder-tree.css @@ -0,0 +1,64 @@ + ul,ol{ + top:0; + left:0px; + margin:0px 0px; + position:static; + border:0; + padding:0; + } + + p{ + font-family:arial; + + } + a{ + color:#000; + font-family:arial; + } + + .dhtmlgoodies_tree,#floatingContainer{ + margin:0px; + padding:0px; + } + .dhtmlgoodies_tree ul{ /* Sub menu groups */ + margin-left:20px; /* Left spacing */ + padding-left:0px; + display:none; /* Initially hide sub nodes */ + } + + #floatingContainer ul{ + margin-left:20px; /* Left spacing */ + padding-left:0px; + } + .dhtmlgoodies_tree li,#floatingContainer li{ /* Nodes */ + list-style-type:none; + vertical-align:middle; + + } + .dhtmlgoodies_tree li a,#floatingContainer li a{ /* Node links */ + color:#000; + text-decoration:none; + font-family:arial; + font-size:0.8em; + padding-left:1px; + line-height:13px; + margin-left:2px; + + } + .dhtmlgoodies_tree li a.highlightedNodeItem{ + color:#FFF; + background-color:#009; + } + + + body{ + margin:0px; + padding:0px; + } + + .dhtmlgoodies_tree input.folderTreeTextBox{ /* Css for the text input - rename item */ + font-size:10px; + margin:0px; + padding:0px; + height:12px; + } \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/css/nv.d3.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/css/nv.d3.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/css/nv.d3.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/css/nv.d3.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/cie.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/cie.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/cie.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/cie.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/colorbrewer.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/colorbrewer.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/colorbrewer.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/colorbrewer.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/core.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/core.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/core.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/core.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/crossfilter.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.geom.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.geom.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.geom.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.geom.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.layout.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.layout.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.layout.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.layout.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.v2.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/d3.v3.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/fisheye.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/fisheye.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/fisheye.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/fisheye.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/hive.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/hive.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/hive.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/hive.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/horizon.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/horizon.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/horizon.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/horizon.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/interactiveLayer.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/interactiveLayer.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/interactiveLayer.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/interactiveLayer.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/intro.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/intro.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/d3/js/intro.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/intro.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/axis-min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/axis-min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/axis-min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/axis-min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/axis.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/axis.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/axis.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/axis.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/axis.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/axis.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/axis.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/axis.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/boilerplate.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/boilerplate.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/boilerplate.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/boilerplate.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/bullet.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/bullet.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/bullet.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/bullet.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/bulletChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/bulletChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/bulletChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/bulletChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/cumulativeLineChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/cumulativeLineChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/cumulativeLineChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/cumulativeLineChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBar.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBar.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBar.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBar.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBarChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBarChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBarChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/discreteBarChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/distribution.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/distribution.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/distribution.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/distribution.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBar.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBar.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBar.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBar.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBarChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBarChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBarChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/historicalBarChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/indentedTree.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/indentedTree.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/indentedTree.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/indentedTree.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/legend.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/legend.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/legend.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/legend.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/line.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/line.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/line.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/line.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/lineChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/lineChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/lineChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/lineChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarWithFocusChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarWithFocusChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarWithFocusChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/linePlusBarWithFocusChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheye.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheye.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheye.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheye.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheyeChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheyeChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheyeChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFisheyeChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFocusChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFocusChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFocusChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/lineWithFocusChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBar.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBar.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBar.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBar.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontal.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontal.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontal.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontal.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontalChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontalChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontalChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarHorizontalChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeries.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeries.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeries.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeries.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeriesChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeriesChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeriesChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiBarTimeSeriesChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/multiChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/multiChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/ohlcBar.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/ohlcBar.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/ohlcBar.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/ohlcBar.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/parallelCoordinates.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/parallelCoordinates.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/parallelCoordinates.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/parallelCoordinates.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js.bak b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js.bak similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js.bak rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/pie.js.bak diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/pieChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/pieChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/pieChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/pieChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/scatter.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/scatter.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/scatter.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/scatter.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/scatterChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/scatterChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/scatterChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/scatterChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/scatterPlusLineChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/scatterPlusLineChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/scatterPlusLineChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/scatterPlusLineChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/sparkline.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/sparkline.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/sparkline.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/sparkline.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/sparklinePlus.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/sparklinePlus.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/sparklinePlus.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/sparklinePlus.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/stackedArea.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/stackedArea.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/stackedArea.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/stackedArea.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/stackedAreaChart.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/stackedAreaChart.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/models/stackedAreaChart.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/models/stackedAreaChart.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/nv.d3.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/nv.d3.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/nv.d3.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/nv.d3.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/outro.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/outro.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/outro.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/outro.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/sankey.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/sankey.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/sankey.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/sankey.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/tooltip.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/tooltip.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/tooltip.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/tooltip.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/utils.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/utils.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/d3/js/utils.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/d3/js/utils.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dashed-canvas.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dashed-canvas.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dashed-canvas.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dashed-canvas.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/data.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/data.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/data.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/data.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-canvas.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-canvas.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-canvas.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-canvas.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined_bak_color.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined_bak_color.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined_bak_color.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-combined_bak_color.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-dev.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-dev.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-dev.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-dev.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-externs.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-externs.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-externs.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-externs.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-gviz.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-gviz.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-gviz.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-gviz.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-interaction-model.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-interaction-model.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-interaction-model.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-interaction-model.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-layout.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-layout.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-layout.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-layout.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options-reference.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options-reference.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options-reference.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options-reference.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-options.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-base.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-base.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-base.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-base.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-install.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-install.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-install.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-plugin-install.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-tickers.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-tickers.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-tickers.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-tickers.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-utils.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-utils.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-utils.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph-utils.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/dygraph.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/dygraph.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/excanvas.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/excanvas.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/excanvas.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/excanvas.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/interaction.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/interaction.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/interaction.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/interaction.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/interaction.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/interaction.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/interaction.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/interaction.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/interaction_sun.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/interaction_sun.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/interaction_sun.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/interaction_sun.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/moment.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/moment.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/moment.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/moment.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/phantom-driver.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/phantom-driver.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/phantom-driver.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/phantom-driver.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/phantom-perf.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/phantom-perf.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/phantom-perf.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/phantom-perf.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/README b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/README similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/README rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/README diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/annotations.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/annotations.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/annotations.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/annotations.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/axes.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/axes.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/axes.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/axes.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/chart-labels.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/chart-labels.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/chart-labels.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/chart-labels.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/grid.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/grid.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/grid.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/grid.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/legend.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/legend.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/legend.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/legend.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/range-selector.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/range-selector.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/plugins/range-selector.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/plugins/range-selector.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/rgbcolor/rgbcolor.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/rgbcolor/rgbcolor.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/rgbcolor/rgbcolor.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/rgbcolor/rgbcolor.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/stacktrace.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/stacktrace.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/stacktrace.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/stacktrace.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/strftime/Doxyfile b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/strftime/Doxyfile similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/strftime/Doxyfile rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/strftime/Doxyfile diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime-min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime-min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime-min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime-min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/dy3/js/strftime/strftime.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.css similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.css rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.css diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/date_time_picker.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/dynamicform.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/dynamicform.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/dynamicform.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/dynamicform.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/moment.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/moment.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/moment.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/moment.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/multiselect.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/multiselect.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/multiselect.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/multiselect.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/quick_links.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/quick_links.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/quick_links.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/quick_links.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.html similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.html rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.html diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_chart_wizard.js diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_run.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_run.html new file mode 100644 index 00000000..1041d8b1 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_run.html @@ -0,0 +1,72 @@ + + +
    + +

    {{reportData.reportHeading}} + + +     +     + + +

    + +

    {{reportData.reportSubTitle}}

    + +
    Loading...
    + +
    + +

    + +
    + Back + +
    +
    +
    +
    +
    + {{reportData.message}} +
    +
    +
    +
    + +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_run.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_run.js new file mode 100644 index 00000000..436dedd0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_run.js @@ -0,0 +1,322 @@ +app.controller("reportRunController", ['$scope','$rootScope','$routeParams','$http','dateFilter', '$window', '$timeout', 'rowSorter', + function ($scope,$rootScope,$routeParams,$http,dateFilter,$window,$timeout,rowSorter) { + $scope.dateformat = "MM/dd/yyyy"; + $scope.datetimeformat = "MM/dd/yyyy hh:mm a"; + $scope.showFormFields = false; + $scope.showGrid = false; + $scope.showChart = false; + $scope.showBackButton = false; + $scope.reportData = {}; + $scope.reportData.allowEdit = false; + $scope.formFieldSelectedValues = {}; + $scope.showFormFieldIds = false; + + $scope.isInProgress = true; + + if($routeParams.reportUrlParams.indexOf("parent___params===")>-1) { + $scope.showBackButton = true; + $scope.parentReportUrlParams = $routeParams.reportUrlParams.substring($routeParams.reportUrlParams.indexOf("parent___params===")+18); + $scope.currentReportUrlParams = $routeParams.reportUrlParams.substring(0,$routeParams.reportUrlParams.indexOf("parent___params===")); + } else { + $scope.currentReportUrlParams = $routeParams.reportUrlParams; + } + console.log($routeParams.reportUrlParams); + var parseQueryString = function( queryString ) { + var params = {}, queries, temp, i, l; + // Split into key/value pairs + queries = queryString.split("&"); + // Convert the array of strings into an object + for ( i = 0, l = queries.length; i < l; i++ ) { + temp = queries[i].split('='); + //console.log(temp[0]); + //console.log(temp[0] != "refresh"); + if(temp[0] && temp[0] != "refresh") + params[temp[0]] = temp[1]; + } + return params; + }; + + var convertQueryString = function(queryString) { + var keys = ""; var str = ""; + keys = Object.keys(queryString); + //console.log(keys); + for ( i = 0, l = keys.length; i < l; i++ ) { + str += keys[i]+"="+queryString[keys[i]] + "&"; + + } + return str; + //queryString = + } + + + + + $scope.urlParams = parseQueryString($scope.currentReportUrlParams); + + $scope.reportChartURL = 'report#/report_chart_wizard/'+$scope.urlParams.c_master; + + $scope.reportEditURL = 'report_wizard.htm?action=report.edit&c_master='+$scope.urlParams.c_master; + + + $http.get('raptor.htm?action=report.run.container&'+$scope.currentReportUrlParams).then( + function(response){ + console.log(response); + $scope.isInProgress = false; + $scope.reportData = response.data; + console.log('reportData report run container response',$scope.reportData); + if ($scope.reportData.reportTitle) { + $scope.reportData.reportHeading = $scope.reportData.reportTitle; + if ($scope.reportData.reportSubTitle) { + $scope.reportData.reportSubTitle = $scope.reportData.reportSubTitle; + } + } + else + $scope.reportData.reportHeading = $scope.reportData.reportName; + if(!$scope.urlParams.hideChart && $scope.reportData.chartAvailable && $scope.reportData.totalRows>1){ + console.log('raptor.htm?action=chart.run&'+convertQueryString($scope.urlParams)); + $http.get('raptor.htm?action=chart.run&'+convertQueryString($scope.urlParams)).then( + function(response){ + $scope.showChart = true; + document.getElementById('chartiframe').contentWindow.document.write(response.data); + document.getElementById('chartiframe').contentWindow.document.close(); + }); + } + + if($scope.reportData.displayForm && $scope.reportData.formFieldList && $scope.reportData.formFieldList.length>0 && !$scope.urlParams.hideFormFields){ + $scope.showFormFields = true; + } + }); + $scope.getFormFieldSelectedValuesAsURL = function(){ + var formFieldsUrl = ''; + $scope.reportData.formFieldList.forEach(function(formField) { + if(formField.fieldType==='LIST_BOX') { + if($scope.formFieldSelectedValues && $scope.formFieldSelectedValues[formField.fieldId] && $scope.formFieldSelectedValues[formField.fieldId].value != '') { + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId].value+'&'; + } + } else if(formField.fieldType==='LIST_MULTI_SELECT') { + if($scope.formFieldSelectedValues[formField.fieldId].length >0) { + for (var i = 0; i < $scope.formFieldSelectedValues[formField.fieldId].length; i++) { + if($scope.formFieldSelectedValues[formField.fieldId][i].defaultValue){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId][i].value+'&'; + } + } + } + } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && formField.validationType === 'DATE'){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+dateFilter($scope.formFieldSelectedValues[formField.fieldId],$scope.dateformat)+'&'; + } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && formField.validationType === 'TIMESTAMP_MIN'){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+dateFilter($scope.formFieldSelectedValues[formField.fieldId],$scope.datetimeformat)+'&'; + } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && $scope.formFieldSelectedValues[formField.fieldId] && $scope.formFieldSelectedValues[formField.fieldId] != ''){ + formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId]+'&'; + } + }); + return formFieldsUrl; + + } + + $scope.runReport = function(pagination){ + var formFieldsUrl = $scope.getFormFieldSelectedValuesAsURL(); + /*if ($scope.reportData.reportTitle) + $scope.reportData.reportHeading = $scope.reportData.reportTitle; + else + $scope.reportData.reportHeading = $scope.reportData.reportName;*/ + + console.log("pagination"); + if(!pagination) { + //console.log("refreshed ..."); + $scope.gridOptions.pageNumber = 1; + paginationOptions.pageNumber = 1; + paginationOptions.pageSize = $scope.reportData.pageSize; + //console.log($scope.gridOptions); + $scope.gridOptions.paginationCurrentPage = 1; + $scope.gridOptions.paginationPageSizes= [$scope.reportData.pageSize]; + $scope.gridOptions.paginationPageSize= $scope.reportData.pageSize; + if($scope.reportData.totalRows<14){ + $scope.gridHeight = ($scope.reportData.totalRows+7)*30+'px'; + } else{ + $scope.gridHeight = '400px'; + } + $scope.gridOptions.totalItems = $scope.reportData.totalRows; + $scope.gridOptions.data= $scope.reportData.reportDataRows; + $scope.gridOptions.exporterPdfHeader.text= $scope.reportData.reportName; + + } + $scope.currentReportUrlParams = 'c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'&display_content=Y&r_page='+(paginationOptions.pageNumber-1); + console.log('raptor.htm?action=report.run.container&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)); + $http.get('raptor.htm?action=report.run.container&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)).then( + function(response){ + $scope.reportData = response.data; + if ($scope.reportData.reportTitle) { + $scope.reportData.reportHeading = $scope.reportData.reportTitle; + if ($scope.reportData.reportSubTitle) { + $scope.reportData.reportSubTitle = $scope.reportData.reportSubTitle; + } + } + else + $scope.reportData.reportHeading = $scope.reportData.reportName; + + if($scope.reportData.errormessage) { + //console.log($scope.reportData); + var stacktraceFP = $scope.reportData.stacktrace.substring(0, $scope.reportData.stacktrace.indexOf(":")+1); + document.getElementById('errorDiv').innerHTML = stacktraceFP + " " + $scope.reportData.errormessage; + //console.log(document.getElementById('errorDiv').innerHtml); + //console.log(stacktraceFP + " " + $scope.reportData.errormessage); + } + if(!pagination) { + if(!$scope.urlParams.hideChart && $scope.reportData.chartAvailable && $scope.reportData.totalRows>1){ + console.log('raptor.htm?action=chart.run&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'display_content=Y&r_page='+(paginationOptions.pageNumber-1)); + $http.get('raptor.htm?action=chart.run&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'display_content=Y&r_page='+(paginationOptions.pageNumber-1)).then( + function(response) { + console.log(response.data); + $scope.showChart = true; + console.log('response.data',response.data); + document.getElementById('chartiframe').contentWindow.document.write(response.data); + document.getElementById('chartiframe').contentWindow.document.close(); + }); + } else { + $scope.showChart = false; + } + } + if($scope.reportData.displayForm && $scope.reportData.formFieldList && $scope.reportData.formFieldList.length>0 && !$scope.urlParams.hideFormFields && !$scope.reportData.hideFormFieldsAfterRun){ + $scope.showFormFields = true; + } else { + $scope.showFormFields = false; + } + }); + }; + + var paginationOptions = { + pageNumber: 1, + pageSize: 5, + sort: null + }; + + $scope.gridOptions = { + pageNumber: 1, + sort : null, + paginationPageSizes: [5], + paginationPageSize: 5, + useExternalPagination: true, + columnDefs: [], + data: [], + enableGridMenu: true, + enableSelectAll: true, + gridMenuCustomItems : [ + { title : 'All Reports', + action : function($event) { + $window.open('report.htm','_self'); + }, order : 210 }, + { title : 'Edit Report', + action : function($event) { + $window.open($scope.reportEditURL,'_self'); + }, order : 211 }, + { title : 'Export All data as Excel 2007', + action : function($event) { + $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.excel2007.session','_self'); + }, order : 212 }, + { title : 'Export All data as Excel', + action : function($event) { + $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.excel.session','_self'); + }, order : 213 }, + { title : 'Export All data as CSV', + action : function($event) { + $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.csv.session','_self'); + }, order : 214 }, + { title : 'Export All data as PDF', + action : function($event) { + $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.pdf.session','_self'); + }, order : 215 } ], + exporterMenuPdf: false, + exporterMenuCsv: false, + exporterCsvFilename: 'myFile.csv', + exporterPdfDefaultStyle: {fontSize: 9}, + exporterPdfTableStyle: {margin: [30, 30, 30, 30]}, + exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'}, + exporterPdfHeader: { text: "My Header", style: 'headerStyle' }, + exporterPdfFooter: function ( currentPage, pageCount ) { + return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' }; + }, + exporterPdfCustomFormatter: function ( docDefinition ) { + docDefinition.styles.headerStyle = { fontSize: 22, bold: true }; + docDefinition.styles.footerStyle = { fontSize: 10, bold: true }; + return docDefinition; + }, + exporterPdfOrientation: 'portrait', + exporterPdfPageSize: 'LETTER', + exporterPdfMaxGridWidth: 500, + exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")), + onRegisterApi: function(gridApi) { + $scope.gridApi = gridApi; + gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) { + paginationOptions.pageNumber = newPage; + paginationOptions.pageSize = pageSize; + $scope.runReport(true); + }); + } + }; + + $scope.uiGridRefresh = function(){ + var columnDefsArray = []; + var columnFreezeEndColumn = $scope.reportData.colIdxTobeFreezed; + var doColumnNeedToFreeze = false; + if(columnFreezeEndColumn && columnFreezeEndColumn.length>0) { + doColumnNeedToFreeze = true; + } + $scope.reportData.reportDataColumns.forEach(function(entry) { + var tempColumnDef = { displayName: entry.columnTitle, field: entry.colId, enableSorting: entry.sortable, + sortingAlgorithm: function(a, b) { + return rowSorter.sortAlpha(a.displayValue, b.displayValue); + }, + cellTemplate: '
    '+ + '
    {{COL_FIELD.displayValue}}
    ' + + ' {{COL_FIELD.displayValue}}' + + '
    '}; + if(entry.columnWidth && entry.columnWidth!='null' && entry.columnWidth!='pxpx' && entry.columnWidth!='nullpx' && entry.columnWidth!='nullpxpx'){ + tempColumnDef['minWidth'] = entry.columnWidth.substring(0, entry.columnWidth.length - 2); + } else { + tempColumnDef['minWidth'] = '100'; + } + if(doColumnNeedToFreeze) { + tempColumnDef['pinnedLeft']= true; + if(columnFreezeEndColumn === entry.colId){ + doColumnNeedToFreeze = false; + } + } + columnDefsArray.push(tempColumnDef); + }); + + $scope.gridOptions.paginationPageSizes= [$scope.reportData.pageSize]; + $scope.gridOptions.paginationPageSize= $scope.reportData.pageSize; + if($scope.reportData.totalRows<14){ + $scope.gridHeight = ($scope.reportData.totalRows+5)*30+'px'; + }else{ + $scope.gridHeight = '400px'; + } + $scope.gridOptions.totalItems = $scope.reportData.totalRows; + $scope.gridOptions.columnDefs= columnDefsArray; + $scope.gridOptions.data= $scope.reportData.reportDataRows; + $scope.gridOptions.exporterPdfHeader.text= $scope.reportData.reportName; + }; + + $scope.$watch("reportData",function(newValue,oldValue) { + if(!$scope.urlParams.hideGrid){ + if($scope.reportData){ + if($scope.reportData.displayData && $scope.reportData.reportDataColumns){ + $scope.showGrid = true; + $scope.uiGridRefresh(); + } + } + } + }); + + $scope.triggerOtherFormFields = function(){ + console.log("report_run"); + var formFieldsUrl = $scope.getFormFieldSelectedValuesAsURL(); + $http.get('raptor.htm?action=report.formfields.run.container&c_master='+$scope.reportData.reportID+'&'+formFieldsUrl).then( + function(response){ + $scope.reportData = response.data; + }); + }; + $timeout(function() { + $rootScope.isViewRendering = false; + }); +}]); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_search.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_search.html new file mode 100644 index 00000000..37b388ff --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_search.html @@ -0,0 +1,35 @@ + +

    Report search

    +
    +
    + +
    +
    +
    +
    + +
    + + +
    +
    +
    +
    + +
    + + +
    +
    +
    diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_search.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_search.js new file mode 100644 index 00000000..afea176c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/ebz/report_search.js @@ -0,0 +1,136 @@ +app.controller("reportSearchController", ['$scope','$rootScope','$http','$timeout',function ($scope,$rootScope,$http,$timeout) { + + $http.get('raptor.htm?action=report.search.execute&r_page=0').then( + function(result){$scope.searchdData = result.data; + }); + + $scope.runReport = function(){ + var searchParams = ''; + if($scope.reportId && $scope.reportId!=''){ + searchParams = '&rep_id='+$scope.reportId+'&rep_id_options='+$scope.operatorRepId.index; + } + if($scope.reportName && $scope.reportName!=''){ + searchParams = searchParams+'&rep_name='+$scope.reportName+'&rep_name_options='+$scope.operatorRepName.index; + } + + console.log('raptor.htm?action=report.search.execute&r_page='+(paginationOptions.pageNumber-1)+searchParams); + $http.get('raptor.htm?action=report.search.execute&r_page='+(paginationOptions.pageNumber-1)+searchParams).then( + function(result){$scope.searchdData = result.data; + }); + //quantum/raptor.htm?action=report.search.execute&rep_id=1000&rep_id_options=2&rep_name=cross&rep_name_options=2 + }; + + + var paginationOptions = { + pageNumber: 1, + pageSize: 5, + sort: null + }; + + $scope.gridOptions = { + paginationPageSizes: [5], + paginationPageSize: 5, + useExternalPagination: true, + columnDefs: [], + data: [], + enableGridMenu: true, + enableSelectAll: true, + exporterMenuPdf: false, + exporterMenuCsv: false, + exporterCsvFilename: 'myFile.csv', + exporterPdfDefaultStyle: {fontSize: 9}, + exporterPdfTableStyle: {margin: [30, 30, 30, 30]}, + exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'}, + exporterPdfHeader: { text: "My Header", style: 'headerStyle' }, + exporterPdfFooter: function ( currentPage, pageCount ) { + return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' }; + }, + exporterPdfCustomFormatter: function ( docDefinition ) { + docDefinition.styles.headerStyle = { fontSize: 22, bold: true }; + docDefinition.styles.footerStyle = { fontSize: 10, bold: true }; + return docDefinition; + }, + exporterPdfOrientation: 'portrait', + exporterPdfPageSize: 'LETTER', + exporterPdfMaxGridWidth: 500, + exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")), + onRegisterApi: function(gridApi) { + $scope.gridApi = gridApi; + gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) { + paginationOptions.pageNumber = newPage; + paginationOptions.pageSize = pageSize; + $scope.runReport(); + }); + } + }; + + + var getPage = function() { + $scope.gridOptions.columnDefs = []; + $scope.searchdData.columns[0].forEach(function(entry) { + if(entry.columnTitle=='Run'){ + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', enableSorting: false, + cellTemplate: '
    ' + }); + } else if(entry.columnTitle=='Edit'){ + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', enableSorting: false, + cellTemplate: '
    ' + }); + } else if(entry.columnTitle=='Delete'){ + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', enableSorting: false, + cellTemplate: '
    ' + }); + } else if(entry.columnTitle=='Copy'){ + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', enableSorting: false, + cellTemplate: '
    ' + }); + } else if(entry.columnTitle=='Schedule'){ + //$scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', + // cellTemplate: '
    ' + //}); + } else if(entry.columnTitle=='No'){ + } else { + $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==displayValue'}); + } + }); + $scope.gridOptions.data = $scope.searchdData.rows[0]; + $scope.gridOptions.paginationPageSizes= [$scope.searchdData.metaReport.pageSize]; + $scope.gridOptions.paginationPageSize= $scope.searchdData.metaReport.pageSize; + $scope.gridOptions.totalItems = $scope.searchdData.metaReport.totalSize; + }; + + $scope.$watch("searchdData",function(newValue,oldValue) { + if($scope.searchdData){ + getPage(); + } + }); + + $scope.operatorsRepId = [{index: 0, value: 'Equal To', title: 'Equal To', alias:'Equal To'}, + {index: 1, value: 'Less Than', title: 'Less Than', alias:'Less Than'}, + {index: 2, value: 'Greater Than', title: 'Greater Than', alias:'Greater Than'}]; + $scope.operatorsRepName = [{index: 0, value: 'Starts With', title: 'Starts With', alias:'Starts With'}, + {index:1, value: 'Ends With', title: 'Ends With', alias:'Ends With'}, + {index: 2, value: 'Contains', title: 'Contains', alias:'Contains'}]; + + $scope.deleteReport = function(reportDeleteUrl,row) { + if (confirm("Please confirm: Are you sure you want to delete report #" + reportDeleteUrl.substr(41) + "?")) { + $http.get(reportDeleteUrl).then( + function(result){ + if(result.data=='deleted:true'){ + var index = $scope.gridOptions.data.indexOf(row.entity); + $scope.gridOptions.data.splice(index, 1); + alert("Report deleted."); + } else { + alert("Report not deleted."); + } + } + ); + } + }; + + $timeout(function() { + $rootScope.isViewRendering = false; + }); + + +}]); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/ATT_Business_logo.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/ATT_Business_logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..56c4f8db300c852358caa3d1fc473bcaeca666f2 GIT binary patch literal 8203 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/addbtn.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/addbtn.png new file mode 100644 index 0000000000000000000000000000000000000000..8f746db6344f2d90f7f3b00b4fdb2bbaa6db7b95 GIT binary patch literal 662 zcmV;H0%`q;P)1CwVuy+|2CE&iCvZ zwrxYN*Rxlv6`W2dK>U9!!!RHi3_?Diheo4e80~i3-tYHNuh$`)&4Ou~f>AaA1(Ak- zS}G&ueZrs5Cu}ww=yto1OeVohBoaT(W)pI`oWm@Cuh&Zn`~70E7^Kr_7!HSE9gj!I zWHQ1comWKX9uiH3lRU=>MqQ}WI-k#iK%Thei0_w5C5JwpPL&FE@|Vj6to!{AkH^Dz zu|y&f2gYc5F_zZtb^{BAexsN#zw#Je3x&9#F2`;u@T>TGy@G|>G2E&)krm2DP$*@2 zF9ur}Z?u>fhAdF4)joPT91c5hwOaky9}EV{GZ7X!<~h@w~fvEfiy@ zRH4=NqSu0xJ>}tu;j_(CB$+; z&1N&ta~fA55ct}QdQ9sf*QnxY>*kpE+b{_Q;sJloS71)&(@kO!}mqf@1v(v;*8Y=G9S3kY~Cw# zY=t&c z;3~JK4HxB^lY(MD+sYeQ=t%XSSW;x^1M?dTvN=W^yNcAcy`HCte31C;)5xP%b~qs> zDP&4(%TBqBNGHwnryK;BdMI$fEg xd0mc!C@j^ZpLxYv4HmnPfI0THYuv<%+6iSmMn&w3dPGDfL1|=LY008wP(boU~ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_add.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_add.gif new file mode 100644 index 0000000000000000000000000000000000000000..f3cfc64e2301698ee8c32fec5d0537c06bbf15ce GIT binary patch literal 469 zcmZ?wbhEHbbZ3xZIKsfd;MH*L&XerPn`SKEW1Kc~=aEYlb9P9@^aM04J$d=wN;<5+q#1n)l(DHSKUf$N0$3TCf@-ow z(^QQGi&<)#f*bk*TCyX{R7_Zlco^8{1PU{WP4MGkV&j~g#oBIX>{~dYN6eq2W=1lF$gdUtjs!ixR8s1pK%2PCu76qD?4f)-Y>eb zu5jzN8sSGfJ~gepmUJLbc}DhqmjC=aSPd8$A{(Nb%6{H_l6_XI_P3ZukaGaj6hA%* zzZ=b~#TdDJq*kpgNq3VoWE2f@SZUV#n6c#^6WcEKV**DyxY^DuJd`j^guCv^l}cmh z=jRsZG%0FT39Y=Wo-$>cPsoF-mn}uOLUvU?>$tu?W_yFI^pbXiO&LpP#h%`__V#vL ICk6&<06hA`hyVZp literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_add_edge.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_add_edge.gif new file mode 100644 index 0000000000000000000000000000000000000000..ada0334cc1f1aaa745d87957ba9a8a9a268042d6 GIT binary patch literal 564 zcmV-40?YkJNk%w1VMhQQ0K@ldi=YT#QhF zrT_o`$imXC+pO~k-g{8jC)ZW9)*r2z| z@Avn%z|XqG(*OVeA^8La6aXIpEC2ui07n2E000I5;3tk`X`X1RuB^Dca4gSsZP)Gi z64@j;z@TtQEEIc+tfFfPrxu7eQiq1Y8#Zf{l)V0fi0%Oe70X4vUYQoNSRm9e5uL1VMhA7ytke za037XZmN$OL6xH!Ko6Y-s<3aazHG9Obq*PL3ll&FoDcvB&uth38^CH10|yMljs`#z z$Xscgz`Pr43aZbq6b%uo&;XmblgL4x&=9E#Y7GDp5FosRWdT413Kh6H3StikCjkF5wcTdks>FCF2rq0r%n}yi|kOb!s4b-5Iq6NlsRDLh+=`85+YJK0DvEb zbghie0(_8+a9URP30GQb0}#%87tY!h=;40G*ig zRZBp$fY=&^NmC~`5YD;Tz-rSc2caw_0%G^B;Xi*ViE^=ru-L7vL|Jdn5Vq1!O>8FrFfjU4O52J+~lCQ z%elnTGiI5Jo3lc9pOdb|yUN#vrM_K?tQuU5ovXjY%-GD--nzun|Ns900000000000 z000000000000000A^8La6aW|iEC2ui0B8Ul000I5ASRAvX`X1Ru59bRa4gSs+T3`q z?|kq7z+i4BEE}9@lMG#(mR%KbB{vjW zn~sdGSeaIniH`}b0Hd4^oCORLx}{xXgCsZ$Sr7md%ZHzhwh#gb0kTz-0|2540NJ?# z3I$aK3IVs31=$A$;NtB82h>%hRS*XP;#do)A~+UV(CAe$K#AF-0tgZ@%XKBx00apN z0FV$V)I3h4a51omEnzov^d5MGWyJzN3^=s^FoS@|z&HR1AV5g?h!-%53}}f|L?PNC54UD_PbOgsSEMLDrz#=t<_3bely|v;y0z zVsg)jV^`EN7@aMvPnQV@K1#Sq8Ck_bA5P@9R%n83L@`npI%z@`L=K)xjLS~nNt6v% zS@9X%N>tYo5V<0_v6UpDI3LiCsMM$K+yWjX1z_Mow!!q&0YzZW3Nb=A4Bh^Dg(5KN z6I6HdhUvN}pa7VY31ALPW(k0m@YaoKH>lB5z(NQNX2mI<88e3(5D3%IB6k#!&lVYS zSe7UXh?vD)?O7oR9~T1RVj66*u_6j)$oJxnS@`0W8gCp2pDM`UD5M<=5L00pPb8^i e6H6@VzC09q21lnM-lZgC|y6m<&*l#*JIrdO0% zj0O?{kOrHaT4RSKI0bbRjQ|H%3k?Dfs8tUF4GXJR2#pI?4FCiI3kVFs$yN`-vup*P zA~+UxkPrq2&(sQ(=aB&nq`j3_j15?%56uekjsfPF0@_#rhXF^O2aN(SnouPgfdvps z1&9DZLV!#2tQ5O~su_T5q$D}`xM1WUHUtgywz*_6qJk>rs;rYl>6x;OFx_#C)NEP+ zR15$p2vo04${XX@jKoA~(8glR0z|D+^a{S7IRi1J6mZSJJtK0liD-a;*^w40G7Kpts9VfTayn zhX4Qn$~{-n5Vp5imb!T*qy7t z@Avn%z|XqG(*OVeA^8La6aXIpEC2ui07n2E000I5;3tk`X`X1RuB^Dca4gSsZP)Gi z5|<@3z@TtQEEdD2ih9j%yWjBm#j_EL zv86>Ih|$FVfPrxu7(rrr1Y8&af{l)V0fh|$Oe70X4U2FSkDY>%Kpl7=3j{%aZxaA; z0|2hB5}chB00@5?L6xKzKpUH`tN;=e6a}ufkF>~fbqyDI3l=~IsjtBUYZ(C86$}#t z2N7%D1F{v$6%GjEZU#UW&|GP4s@89<+zbx@5Z%VF;vy(`RX~k01i~1+;WY_b5I6Pg zxoP#v)dMvU6kyx85x{|S065V)pg@6xI6)lh0)bd@)jeUvXoXzk;D9k~1Jy)eM{A(D zHz{4nV=1u>KAHd&q>}(^TLoZkWD1i5L;y5t4X6=yInk+3U>qwPWhxHA1CbuJeSG7t z0X!EBeO2RX6eh8O2`cPM0D&pCRu2#uLyLexNri5jJ#%3S2r8DrDk?~z5W&E001E1R zl^3L~0{}9(!39JYDNLGDdFr;#O@!8sKs69$DG`v=t8)jEO=*;iJ+~k09^QtKA>TTH z_cAb#c8eEK^x64p~ zrODIY|NsB4!O;y~{-U5c!otG}41yu-}c zw!qKt_xHNQ(*OVeA^8La6aXIpEC2ui07n2E000I5;3tk`X`X1RuB^zsa4gSsZP)Gi z5|<@Bz@TtQEEv%kdhpD9}EORer^o~ z0Id!XppOFp18y5Zm8BOz8E*>?00jfA0G_dev$bw@4;Oe07C;7X3IG^u7}jbF6$1wo zYMc`j0~Kry0|Ve|5akPM$!`Wg7SCL1ZU_MD6btYD5n8nZH;Whm1!}Shghjz10)n*O z?3(l}2%J`MAULQcA>u3q3ld;#005*&1QaU&0FXf8z(ES}-UO)#fdw;9kupbjkoXIn6Za%&ANyUHJh0h z886v?Fk+?JOs6@!<{K~U?Y}l{DyA zV&kp9{9Tdc#ywp!?!#0Afqc#h91Oh{FCGR63$_MG9ZU#)>?SCy9nf*aLWzaJ8UT(S Bm@@zX literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_left2.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_left2.gif new file mode 100644 index 0000000000000000000000000000000000000000..726d4227b460fcff2533ef1615d2ac33b24c0232 GIT binary patch literal 399 zcmZ?wbhEHblwpuzIKsfd;MH*L&Xb7?ceF0u_vqQ1okuSH`1yO$`a@@~-249HSJ&*# zTlb$kdiLgmbqD|d|Nrvs$7P$3?md15$OdX91}OeyVHIHzV$cC82HDBL`hS5+-{RzX z8Y|aL`e`s>fd#-xm?)6!#j)M5nZFJ81bB40qwh-<>cX=~O-8Z)Wc7cJPngVBDE@xI9iiVyQ` z+OmLgd(jM&<;E-1&z+yNW4+oOr&SAYL@d?ozrJH?#w9Kb-Ilh9j`Xe#O_j#gAJXfM z8=LaE9=%u{{ML_K)Be<#z{^ih^R?KonsM<^YMXeoDi1>plS-4bGGA4}8y6PkDQ*TS UJXd!Fx*X>cG4Sopts9Wfu;>p zhX4Qn$zo3p#h*IkONLU*6m+~lXU#+awPCuNe%)ZW9)*qy7t z@Avn%z|XqG(*OVeA^8La6aXIpEC2ui07n2E000I5;3tk`X`X1RuB^Dca4gSsZP)Gi z5}D;hz@TtQEEdD4ih9j%yWjA5#Ic+tfFfPrxu7eQiq1Y8#Zf{l)V0fi9`Oe70X5sQzTf(dYuKpl7=3j{%aaRLAj zYpMd95)^R&o^KjKm82O!8-S_+uNAJF3IMaTaCH$GcncOl2EG8(62ic03TRHoJP-MM>RI#h-`zoDUEWmhc)5XxZ4miG+Re)UIyUhcAde1G9ZUg v=;89ExpN?4dXpi5>ACeOR-~WU(S!N*>q(Z3$#J8+`SUb#s9(>%eFy+ME$$V3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_plus.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_plus.gif new file mode 100644 index 0000000000000000000000000000000000000000..7a402426d3a3f3e37f851897b18e67c25f0c71de GIT binary patch literal 67 zcmZ?wbhEHbG literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_reorder_all.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_reorder_all.gif new file mode 100644 index 0000000000000000000000000000000000000000..d67e1a63f64dd99a2bd9fe403429cf839a62f851 GIT binary patch literal 686 zcmV;f0#W@(Nk%w1VQ2sx0K@RfzEt45Zna>xk{e*+{v&vQ9vyOH~fS(qbVT1{{v$ zA)<%PfdU5GuowVf;3BC>_V7gjAR&N+M-?ysZaW7cf`KgB9z=SX@RheK4k4mypbY_o zDhD_ki^m{=fTIscF)|6@04!jL7&QwJ)WA>xMKfZ70DwS%W=j>`w371%xh#+1aa1SK zQa?+(3NEbY?9tmq#!6|~D3M+OvCghE+%v*fxumaxmMnJ7*s+*ZHqzVmF#xtyip`nR zi=~;U2JyW9wHeq7IKqV&d_wCir~}Ig+O0E%WgP(st{Lsx*dW0w*s}GWqkSc4ge%&9 z0@gB%&<#UZyv1uZL7#)4Sx(x+zDq5uOw|!x2T0sXyn$6tmRzpMp}0A0q#@iQ4Lg?v z)}k3ZwM7sg`1}PZpnoWs0iA#d+VO@fd(L@sOM(!lQNS#ymGQ)d7&fs)h8%Y20}&pE Uh+z#RmT2OMD5j`li6H<0I|8C72mk;8 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_reorder_all.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_reorder_all.png new file mode 100644 index 0000000000000000000000000000000000000000..bca729f2f423b6bdaa7d8f185b660a47494885cb GIT binary patch literal 29837 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 A8UO$Q literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_right2.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_right2.gif new file mode 100644 index 0000000000000000000000000000000000000000..302cb2915c8507736147f6cd77fe9e1a10571d7c GIT binary patch literal 399 zcmZ?wbhEHblwpuzIKsfd;MH*L&Xb7?cXZ9({OH-6z{X`ek6ilk^Y^0lht6EN_x;DO zt^3a%J$rM(x`Y4!|9|=RwiKDT;FEZuMMR%7Ge@TiQ=`j~@7Xf*mOL(L z+mUqs2Fs$?JnHG(TmI}xXo_x`pLmX6qRvH$FNPz7wKhH5$)AtkJ}rWwJ%fQEozvce zkH=V`XzJvN)6!#j)M5nZFG!!7kuRWT#5`fqYR0wGjhWQ!i>K~y-;r*=$9UiVN!u46 zHr{Bw<{*+#C z+}M=Q{OHB%;n)au@1YUl6nyMzW@LL literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_save.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/arrow_save.gif new file mode 100644 index 0000000000000000000000000000000000000000..2702547afbe40f69f5437ae13823cba5d657d663 GIT binary patch literal 606 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calendar_icon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calendar_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..caf77f9a9ceaf964ddc66b81e7beda42bc9c363a GIT binary patch literal 552 zcmV+@0@wXVNk%w1VITk@0K@pr4yNy~G*(GfvWjYJ4C>4>&ii_0Y= zQn4O`S2BVbEM6{#12<7PgTvx#q3L?P1E)fdb3yBDc%Sr%&thy`+ zsOzaH0D+30mae+Gx~`V7v7Vl>v9&d_8P@*~FbHxmNHRz=GYT>=2{JMZGX6gT+ zS%5OiK%1C>rm!%>&1Ym{7EBaT3=|Spax?^Lzs11A3^Z4eS&+e=;k)Ur784!**$WT& z#}>^#F?rjKE8F4|YR)=-3wx<+`Ri9r&w{I(ufKDwFH32@>vrlXd(Yl*x2qc^Cakb} zSedxHoZDXhw0i%;=S-ez*S^OdnkRH9xpkA+g9dBO*xak@+gJJ5{N;@eJ$=Y}VRGb3 zA1P*cmI#UO<)_xnF6{fHlQd=N9H~rp{z&gfQWyI@UwAUyiC%H)#-4jV**-5!EEDw% zuN1IHT|9R8EJH%-cg?x;*FV^I-$>fs;Z>!)&ZL=3s-4RPSex@4HrEGjU#!|JCgsBD M?Xb1Mh4KGQ0E+dO1ONa4 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calendar_icon_nav1.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calendar_icon_nav1.gif new file mode 100644 index 0000000000000000000000000000000000000000..093ef50a69d4767c1b1b7fabf6631680984a1bf2 GIT binary patch literal 1065 zcmdth?N1v89Ki9LRz{3Ej0=lK7f_L~_=1@jVLBZhZqCI4GZ^E;(#B+{!ypEt5wo;o zKwD@T^pOhe`f$DLBc;6_EqA@^T_5QaePDy|kbz}ocABVfChkRT{WJXhe#!Us@5S%z zxid}8+$!K{-~j*>i^ct7@wbP??ce{-0{!A{FN-bvhmdlbQ@l=dV?=58SQ>k1ck%-6R_;Q|D zzKbVwu~^KL%tfP7Z#+-Mx0aTcu=s8y5+S0y;cz4r3I&5fS7aj)47fr&3!yDEycq}t z{6WU=_s<76OJNv>E@ON?+DFrNdY$&+6h$#4}Id5}1tY$lEx6dK= z#d(|AX0utXR*ThAVzrt}G-j*W1e;9;1VLh;?51%JhG7IoOt5Bq`ih|h(m@8u2!Rj; zA<#{|UJvO(old9!Zw$IwF+ypzT1|O1B^z=s2!gcg#?0)@>cnN`tX@8&Q>)ce>Z$1| zxl*ajj&hX>xuT>Txk^6%{m-aWDiz7}g9=C{9q&;FCMU!LGP8b6$eBuht?)=BlKx3^ z_oVYjiD5tj_l?hWkGluNTA@(*!RC zt_eAO+ofv`4&U$r4|ROi0sQaO?z32jfg!Y^(K+*8!!t{Nk#n$*@-G(Lh~ei;q~aRe*VEj+Sghmb*+`JTpVrL zba&M7543%D^xXW;V;^Zr*2C`gR$;a6ovzG^dZ_D|;N?%gdug93C@kl%vUc7={6oD* tPTP0~boK2uXM6g-Y&rcxLiNUwqiy{uQR48}_VHxJvu#%|NO{1U{{r#?_MZR% literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calender_icon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/calender_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..caf77f9a9ceaf964ddc66b81e7beda42bc9c363a GIT binary patch literal 552 zcmV+@0@wXVNk%w1VITk@0K@pr4yNy~G*(GfvWjYJ4C>4>&ii_0Y= zQn4O`S2BVbEM6{#12<7PgTvx#q3L?P1E)f8z>~|<%z#rPa;rNXU z_g>`B+-{sUbHSbq4_GV#)IS76afZn055z*q5uE@ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columnblankup.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columnblankup.gif new file mode 100644 index 0000000000000000000000000000000000000000..f76975bd21b807ff54bee462429f3825c452b046 GIT binary patch literal 193 zcmZ?wbhEHblw@FMIKsfd;MK7I(*1zu6#}6h|NsA=zx%v#+RXP~zSl3=uaG$5{N3jT zGj}+YFIa!<`u!L0<9pXPEIpu@JO!u{sFfI?_>+ZIgh7Zw2c#HeCj+b90+qfcAv{hi z*CkEh;ht=wv)X{UM1bAIpzGF&k0;)8c+7iWm>?^_8C%r#Mpa;y(-)7o-*`+qxgGRo LpU+6(V6X-N?w&#z literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columndown.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columndown.gif new file mode 100644 index 0000000000000000000000000000000000000000..6c8d80e6f9dc705b88ad0f4beec12e89e5075ac9 GIT binary patch literal 124 zcmZ?wbhEHblw@FM*v!Dd;MLHu^ngS8f&-Tx2!wWQIDR9bdBuV~7ZegFT)6k*!OIT` zeH;G&{|{6M0g69aSVb6k7<52fkQodtngt3DtM^8z9OFBox!5RRTxh)I; literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columnup.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/columnup.gif new file mode 100644 index 0000000000000000000000000000000000000000..1c9b24f85c5c3535ff61ca55d517706025fdfcd0 GIT binary patch literal 126 zcmZ?wbhEHblw@FM*v!Dd;MEY{yMF(r`wEE@=I=i5P`*GQw4;8>{_}UA2Q;r(f9(4G z7w`Z7{|{6M0g69aSVb6k7<52fkQodt+7nKCN*b5(ej@)Wnk16ovB4k_?5Aj8p}8Pv3y|DXMuug^Hdojv*W~ zlT#7`b{{=(z(a3q*F%2p!=}dq1infgTYScc!Ty(I*mn!_Q$WQGp00i_>zopr0P9RV Ac>n+a literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/csv_icon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/csv_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..d73e93a6d078dee376a517a1f9462beca8f1176b GIT binary patch literal 447 zcmex=OP> z$SlZU&rqycaA6@!r;0!BN1YS34fTpD^R%o27eCqCZ?c?MVg3J` E0D=f~PXGV_ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/deleteicon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/deleteicon.gif new file mode 100644 index 0000000000000000000000000000000000000000..d544b59bb9ca365bf5f935dd1d6b40266d730678 GIT binary patch literal 80 zcmZ?wbhEHb>h; dQ<$_`$xvhKx5|`)?rR-$zPn^(YOyj{0{|cG7Z3md literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/excel2007.jpg b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/excel2007.jpg new file mode 100644 index 0000000000000000000000000000000000000000..77d7cc208b428f3deb5a834f8234a167bda328f7 GIT binary patch literal 761 zcmex=~;k+`^QRlZ%U&n^%&LPtsIH zPQ?@_&_t6lF*VUKG0`;re}F-dgF%5oftgW>fk}{&S&;Gn5e5mMGl75s0a#es*qMPc zx&jQ0%uKAz%uMW1Nk%4S7FIz9HX%hrVG&2Az(V#$BPZ912QOX%Di>#DU`93usE3&a zWP_9-NCw#oMxgaVip>9SG4KGjFbOgXGT1Y`V7>CJUAivXtIB#-k4MzCX;*GUXqFzC zFni4luO^Q#HFu`2nsuw*rT1G`^PdFERL4`hPPddizI=o253jGne};;ap~WV9R?bi{ z<*QzIS+y!?yGZDz`=2HsUFZ6z_ak>zW483BTH|H8(`DQKGl)tye&)1)&b=rkbD~y| z=G-F|o1R!qk8BZZu~_mYz|*^CV!_%2A8I!!UAgfy_4>>;<;Jp?mtIyVxuC~8$#c70 zph|dQ^4cMbTID8n%}>k{f9kL>K}dJQ<2w&Sf819HJTqBn zma(L4hp*(sMM|DtTum{N3h~8TkFS27UD$awEu#C&YC|dS^XFss%}H6vBd}@dS`ALl zoqNCb83wNpshag*ZLQUm(>kxpT_i8wv&nM`+A^u^0aNV;_SaXgWo|hkm?^p{YT301 iFI}Cu*D@{mouwSfYQBl@`iFv3myWh71nTJgzX;~W&4w15g)V^>YPRieDOt#tBn?fLO_!z(QP)wt@W5j=hD6b%9w8buqDd1K z6H!AvHYy%C&fvkQ>s2*)FwTev9`#rqMQ8B93lB_!`R?!k=FK?IH!&t|Ll^eR2gCSg z^85UM-~aK{!eSSfQ}HM7+m?Llb-ut-W+k^fz(cvF$WWQfePz9l9 zN`=*p6}+iyPXd20`BcIRPf=ZezOufI&F7m~U0cE2(j2Der!lV6{G#khz^3?cL2!dL zCg#WRZ1WlB7H2U$F@(YKf!(3mJFhLkijQb^#oERymR1(gJJOBr;m*A=)QPU`4DQTp z3E0RE7hG#_*<^2?rBQG1Yu!ehp8gkL__^qPtxz(0g|zj&m{%5HnP;(Cqe(hFuR~L3 zy@*(9TVvMp>b!y%M#isCJ3Td)Q|f zKaZ$pv~5w<%G07ir3tSjU`H&`c{Q0F`Hb33nh%py_%oi(-LdV9?IXGcEyu)+hE}EyBh^X;MM*)OS5WaecvPN_ ztg`go3s@Cd$}0N`(J`n*rXrb0L1sk?vKW;qSbwrco7gk6JQuO~+LDGZn9w`dM)y8% zWY7!ICP=pOUu-!ysOv$Ux(aC}@klF;$Ahv2j=Z{bD)cGG-10aS>SUBC@1e0*iXKff zy2qONpTBuQqX26YyNVlfaIZKP_hhlSFK5J|ytRmS;wK!NgtR#pUdf-qCH^oZu^-`F z3coBD zM3;nNd~U?pspg@2cr$@?CwM$`g!=;rxTe{|In^GHDR!{GFM-{CTR}AE=4VGl0+Csl z5t$u;8$?tNksClGzJRABupNaeT_kYy!n^QHJd1FtH$n=%aK$L#P9v@tNUe*<^7^7N zmW)z$5eYcKlM`@&n?OKfBCr+DDeXiTm3~?v5Ss3Tunb>>XA)VyxFZe4(`Rd9HuXg0 z*oy={_uLQf)bk|ZNdg`u;EsS?H%_3uQ!41Bfr7RyUO+$kOu&VTccRgENM-`I)XiYy zJY-BwjWdCx0)gN(H(Ys0q`Tv4hC5OfF?jN9)yPwhEs>?w892oLK_qa*`+XX9SIR$) zJ_&>t`k`aI&1@$bcPpZ}{BH@^^8ym1Kt%C16X_=y{`YXRNZ?Y6Juas@;BuM+0_cMj z?RixA3eT#D*_BB|Nxeh@mdypq0!_x-c* zNj?kh!U#5=E(>|KjGDfD+*0@>w%m^sh$!~N+3S`ffsY;E#i+J#$1ZMXCqYwq0ZV~^ z%iU9OO*jp=q|@+AJx2vE37Dmw_)&8VwcMWsE+CeQk1qAajS^o3W!sAc-al`FFFZb^ zZgpU6cED^WbxRt^Re6vR?W4`;nN(wBy8oq;;o+e{A_0fn$KZJP7@XseBdW+3>rWSr z4Cq>sQg?-7bI~XeV-S%0(5B@LmxNOyf&G88z=@zg(gx-X-z+CuZ5+`!SjBac(L1H0 z3G6@<*a7Yj?J56ua7mN!6PT?&fz;tJ4C(p=T@2L=91;lF#vOr8+!y%f#)n9&j-95! z;O%cLP|;Z|ilt1I%L~}?0usFdjlMk-pyF+ltmz!pE0~A-_U*G02^_upHdp-dYwuu` zjtgr~=67I0B&eCC!ArS7%nt3LK~6zlz+C_=?L|-I(Q2j+P^-`Xc4rpC<4H zn!tWEYJSxE8?>axLD7{(E0mIC^#Z!Z;g<-$SaObb_RjHEbZT0W-{6q7lAF$Lkz44OY+^--fA$q1P5PFgo7fWqg=16*x(we=2%Ex+fa2 zvN6q(+Y-$Q#FM}sRy+|$0x@Mwz?%~o(6({1{ZnnU61j5%A%(8ElJ82VQCB*Ry3q50 zGcM*h!T*sXJ)w1S@f@V@iB&gI)Sg8r)j}Hm7FumOUnZcK%D)w^7hlCS=~bx49`kcjFHl`qmTgwxYa0DakIv8ohn7P# z*Gc*3dYm*BaHNiS(!DbrQW|+v0cTFY znkFz4I8PJ!JZuxsBj<6taZWOk>bg=U@VQ9fRP+HPR9+GYp&zlH*PXdi5^Ku$Lga!ne7l=84rL~D|Ozt4GJHhUWCYrEKT=DF? z{&g)$x#|U|cus(dXQQvr|2f)$&%rwJJ4`Q)8e_`f1rCY?*u@^#`UgAFH`oEqR6nNY zM`-t*FeCOll2alyb3N3#MwF^^Y4dtWv5KJM^A%p;dsruYXY7~(XJ^}ghy+YI5%*jC zDePSVc8SN}k@gLeD#MXcABTp187AlZI5`7*7ZghBmWC-l^`fZqyYRu?{Mq0w{>DRm z=8o{|?-^5qL;Ztp$45pes*AFfo%R3vc~spsvox||D)-+Mnz{pO`|`z)-OTv}%0kLKmXf{Y>R?wb(U>3WZs zv*dp*!sJexlPi>Gq%b)qrkUyb|M%zL??1nP{{8vo|Ce8Xe*O6KgAi458gev`swPEmrtHPe|qcHt(&iJ-gtH6`pfILp5HqE>in&T zw=O@teD2A)^AFFTet3Gt(-ljeE?M?u*^);~=G>h#`}*uTr{-+iv2DY)4J$XTT)uI6 z`M&a5OJ^l-Po6$^de@w;&e@$YD`Vo9#+T15FPmAGv@oe?R#D;1!ng%-CDThvW|Sn( zPmGx#lQ=gqYJOC~l!BC*DN!?{!e)l~%<&1E5f(lzJak5A%A}N-DKWv*gERXw6DKBy zOb^22BQ*wU!3;23n0;`t|xAB_5iMnoea-rd6iSrOx`b`WBTI zCe`g+BB+Qr)HrRoL+2D*j1MtMexC5i@l20HmVdbxTE#R}4; z()zjjip7djB~l7S3UWnqibaZwg^Joa+B!Kpnz@?th4NCxQgVfIvPH78g|eDCnsNnl z+L_u6Ll7wbWML6u_|KpNayuwbFmU`~xG$5Gk{!G@h{O2rBazd7i=3*TsT@pta(bq5 za!bfZp%Z;eOvEiJ3>p=jSlHDKY))L_zA=HT&*b1OMur3Y@fA8gAD?KR;;`_Idbq36 zd4^nqYTK1nPgPj?rQC}mH(hx?ou4z&sxj!YLUW&_R|)5)Da;3&%oe$<3=B}!b)qDdy}i44Ywv_D6M8rIc5dnH-O$^$sjG2IWAB>Y_OzkX_H}$RVt6W>T zaNfe2RW$`G3Z_n-I%U$7$&)6hEJ;aToSe2WEo)v@;=;tl1&LiWA`P_yHI*zCs z$-*MS@Si~kWHu;IFmT*wIKAd!bNYEXo60{g77DX995#*hYI(r$n2noPcSerm1_p-( zJUm$sI0PCT_?g9*IQ(Q{INvUl%a$7WVA%x$j;ID1!!5^Kng!jy9I#AQcjVBv@6%vP zVRmTYb$W6oli>jC)Fqu?&PY5^J=da8e&WK037xpybXSP6iouujQF5(a^meB`M)(bbQmmjInd0Wenmrp!5RRJOg3-; literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/green-arrow-right.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/green-arrow-right.gif new file mode 100644 index 0000000000000000000000000000000000000000..d3e37e84d7a9f8de0831cb7fc4c86dcea0512f0e GIT binary patch literal 201 zcmZ?wbhEHb6krfxIKsg2_wT=7fByXV_516OpP#?~`0(}HyU$-=e)#nK-G@i7-`;-q z^4gWdi~D6OV@XvyRzl<#hGXRuRnfn)sZs`_8yzJ=g9y6{~2%t#h)y!A`D^- zIv^z=I~iEr7O3{6WV#9_tz(c1Jnki=XC=95>XmgNYk1<`8frMU>=D|O7PZKS>G`V- kQ*W~n^5|}w}MWl|) zt9fi&6!P~vTnOIH%GbL)_>g)wt8#<%#{v<-!oJ0iI<* K{H-EP4Aubq;7)J= literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/grnarrowdn.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/grnarrowdn.gif new file mode 100644 index 0000000000000000000000000000000000000000..4c312a350aa41f5ec28e735d36166bb1eac2f916 GIT binary patch literal 74 zcmZ?wbhEHb?&!2bXL{{xwdKUr8s7?>DzfNTbkJOh*Tl>W?vU5tyO a1$`J(lh&ApwBAzeOQ;B)o~X*oU=0A;;1q8F literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/grnarrowup.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/grnarrowup.gif new file mode 100644 index 0000000000000000000000000000000000000000..23442aafcb52f9cc141ff2f846fd60031f904583 GIT binary patch literal 106 zcmZ?wbhEHbxs+7jWJ` zGdnjbU7stlXkEob1-H~MimVKZ|K$A(N-}dZt5Q=Gk}4HKb5avi6oPXTi%NnM%TkLJ H85pbqX=5Oc literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/h.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/h.png new file mode 100644 index 0000000000000000000000000000000000000000..389eb08a630d9d5de4bc274707789cc5a7ed5ca6 GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^%0PUAg9%8!wK(q&q}Y|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfHD+-pLsP-+;j~}^OXbZpRuF9;E{&zc{m+V~a(cH7-mvv4Gul;h(6EACn6xHXvDQ{VP`Rs+vCDj%; z-+ww~^YKeX|BrjVD}H^M=xh@rzV%gwy~pZ>m!16NC!|TPyvVVuU04N(KfCx@{G1fG Y^I?wqnHzUj1H*~I)78&qol`;+0RLO0)c^nh literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/inactive.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/inactive.gif new file mode 100644 index 0000000000000000000000000000000000000000..bb0a71121a3ec33f59716eedbff6386dede3bbf6 GIT binary patch literal 352 zcmV-m0iXUyNk%w1VGsZi0M$DH|4~ueEG++!kn~1I{s;)$+uNU?pWWTv$jHc^o}TFF z=>NyZt*x!v+S)S4-dkIhTJJB@IpetO-;~EO~h4I@PUD^udm5kTKGyz>eJK5L`11=ZK|rO|KsE0 zFE7{E*Zc+s^bQW}?Cj^~=hoKNzfe&5`T6+x_`Oa}(_df4#>W2u0RR900000000000 z00000A^8LW0027xEC2ui01yBW000Jkz@2bNEDjd}qfoFIvIshjQJ^D0gcqDncOn9| zp-4?w5N!v-uP()q5ofKl`m@>?5tHo}lV~V+2pwB6eSbS@TOfvN0Rd-97Fz)Z3=dlp yMN~SI1v?IwIwV6CP&WphLJlK3FDODb9yBEiMF%D-IT=DR9JEFUE)<4;K>#~QjiP-3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/loader.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..32af9875a41d87a018252b23b87c2c985db35c9e GIT binary patch literal 958 zcmZ?wbhEHbv}539n8?6z=FFLyGiUz)|DS<@LGeGgpKD04vtxj(k)8oFBS`2c3o91` z6N3(r%>dHEz!cx3-+n;%twQxAC+Vd|nU6IY=S%dZ?O>f-6!!G>v4CBAMP&znp1rW8 zkGrWtrT4je&f95D4dH?`m2N-Jf@^-B`u< k`efaf1uZNJVwLXmH>Kt%%wMyKcFfdpH0M|h^@&Et; literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/loading.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..7ca73e934650c377f31bf2c86832459eba68de0e GIT binary patch literal 4176 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/lookup_arrow.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/lookup_arrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..84e1aaad407ad48a96cc14ca7314713befe1dcee GIT binary patch literal 645 zcmZ?wbhEHb6l4%&c*el+9|XSt{`=|MxBnl%{{Qgt>znugpFR8k?8&bO_r6@Y_W#1= zPnR$LzkKP@`HOc?U3z-v%>OfI-kmvf=EUiHr%rr0dHl_hW8Y4nxOw#0t)qwkA3F46 z|K2})_deXU^Y_l3x3_KnziZpg&09Zh*z#}V)^i)z{a>^0|N7NGR;>B9bk(0#tDme~ z{(I$$Z!4C6U%K@F%H`*mFTXu+>EF2vf6ZTbXWqPL)93wIIPdE0xu0gv{6A;L_n9-# z^iTRbx$i}P?}z@L|9umW_4Hrs={eEU{<^i}V|)9{j`k$4(TTykftmmmJS4Ih0*=rlfdl zcH!=<{KJ_ATXJ#_>at}928M<_os!y0O6scG^GwXm zwWlz!Pf*g(Fcg#5(lEDm5o;3AQdOU4EXB<&W^ChZ)+DVuPuD_IgilD$+tJH|nPIN3 zfw>{Skg|l2udiq1OX<~y=JLF*Np2Z4H?^FaSi)6s_XeZWq3QYo+gv(@+}f6kSylX* zQE>3&RK3s*9X$po4hbl_AL-awwDi<8?c^*G50OWmB6_ihVs<`a?Ga>|s>6_(bo7+7 Yy56Nwrho;9xaBP^R3f}eGZh%D0n}z9S^xk5 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/blue.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/blue.png new file mode 100644 index 0000000000000000000000000000000000000000..69590b92ab25dbd8fc82d7d6b0eb5b7f6a1ec1ce GIT binary patch literal 1309 zcmV+&1>*XNP)Z z5tfPI80dhNjXizOZ4M^WIE{~~m@T?2q8U@v=+tB;lFVdoCfj^0CPoPxa6GrfGHmPM zPMduB)As-G{r+>$J@;M$0K^@Zu3t!T_jO|IxJ0ryoF-|-FAsEUt5^S!`sb3c&QIwZ&OqhB(xN~U z(9rS)a5&uAB*VT8CIMZ;S&V}E6$C1Gx~YDiz-ZB73yLw|+bc$NxGpdWn6ZNC8$XHU zc?qsdwf039BYGc}Z!E|B-?eog#+o~?v91Nbk}|C2s^S-Qn8}mL1yA30M$rG2mLoLt zZ>AUz7MAwiaJ0iL;E=#Zl%~OAY!uenPI#OZbeQywV>s>{8iAV9zPW{neKFd6#Ysu; zB#B9D?Gp&aVClMw%kM%7E7rQQzCXb)FcQLLRr{&5x$9?Q-tvDc<`$Q6l|Ixsir{<9g4h` zbIt|I+7B3&YrtRT0|}bGTH0YQ-hV4h0-D-U7xYb^;u4*BGBja+jiA@WoSh)>37pW? zpB3mE#~oX^TVbvP|0K8hOOl-bl%B^IK+)#QbGcxj2H(JNh)QW{r;*atkGa4kkXbR} zO69wFeaCB=!0$q;=`h&#VdgiDYF}ud3)vvtSx)pEm>73$;t@Lv$WD} zcoOJ_1AGI*#xymfxE+7bEldJR^9ycK-FJ+vR&C1j_FaKFa1%EjDp(b3>Q-00P0~w_ zxrIppGu|yq^AVDi|AfR#ApApH_YwH`t%SI&?u_)3mkB+TxPwU`LA%WZb|TgF6K|pT zyV%T5xJxMdO;PZSD2+zQG~^aG0Zp$*WcnS%Ulj3yI5-u@KjeIB(eot5cnCS@7AAqH zltzzWStkDC=+~ABgt+O9J}uR4C-K=m9{FDc@XT<4Rz<(S@Z-4kB6uwG2$MjH@qkBY zVg<(*^-uvxlzu-R$2`s&3X_1RDMeA2zeS=`AFxpYJOQ<4R2(NNoCTivH-WzZfyOD! T^E$RX00000NkvXXu0mjfg)VJP literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/green.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/green.png new file mode 100644 index 0000000000000000000000000000000000000000..0f79315e427e3401061bd85d197b033ca24e5212 GIT binary patch literal 1190 zcmV;X1X=ruP)JW3b9v#cu@&% zgPs-gCf_VvQJ}>7Vh}Ht1H4zC=+AbXd{}-iNx+^c;KERq%DHSnxzrh1;U#&ipYYy1 z!rS~LW0Od^QvT-eL-=4YF8V61e*cev!!rRFOuLImJ0h>kCNWq|@J$oJ$rgg2TM{il zi=i6An|-7J&*1#L`_J{Ckbtim0K3ASY?OFv6V85UCOFYiqLOV>UwgKe4rxXF{Ciwh2Con+Xv6szH`rJ|M53 zVvX!S9be3;R>F=PQen>lu{WlS1mI)&O-f1<`)dfkZyuk3@0v**tRs~o2_FhxZ6rXI zdmoo&UN+V=_SD<)V>8K`3{nN@Pnrn;+$K4yt-u?va}D>y+XFf)dJP4@cAOjF^`C%% z`=*k%V<Ouq$au!f48cz<;KVpa&&wufXOfC~`^BqK!%D~% z4EkeXl`2o-k`Nb{ON<3wgjR-0Df~_Bt}HdKgm8%Wf};%}HWpvWW%V?!E*!fe@^|Dt zga7{v*A(5T`)fPq0{#`z9cgEyBz9IfX9X{lcs)jZJ|M9&+-W%I-?R7O*?gW-Z0ws0~UVPKIZaaw{$39`SZvQeQIx zyDO7iZ|3aLlGynxhX*B6|+siHq>9pOe}CSXspA+fIt@QK2!RH`EQFrJ77 z&U+bj6W$qEWQ~~f{$k7oyik_RcB@TM>8>wvZG_jG-4T1%6$7pc`<2J_hvK1jJf<%mge9IrB(9@bzrJtl}F{p8F6!TLkzFv&J4X0doV+bmjsdR(A0+ zkSs_a#HIPb!RUyYfI9-t+|2??y_@xoNlx?hVS5hX9G@d*Y4~)JGaHJ5BfpCeoFrSa zdc^Y_fSe&tmLg;7DQyaFjNVG5Pun-^DvUW%qZo}b;3OSJq5(xi6qP>+Y{n-nqlFFI{3w+uK>(-n}fmrbZH&n;Yli=T~QEXV=CU zYp2%5*SEnhBV$SA=FQUB-Md-xkt4!58c*|xtwCa+1-N~iWnaF`mYqDw!p!CfTdQ7!*)a;{~>bAmIN*U9s0kAM$_r3(LmADr%*UDGVR^dv3VyY(e8V6ot=C}WI!iO>FNrS zI5>=}tE;DNM$`}O8_+}k&>cUnGVnTK4puVqaxB9sm`HD<8ydcNBj|go8QA}CO=Dwr z{=Iv`Jlp`J0-Pjf=gvHw6q4H7py=5%QR7*5>J*(jL}CH^Scv$G(Y0$6%D;P;EnKzg zM@NMMa&F!f%J1aGh5Q&A0(_`IfWgp0(AbX|Zrl*W1(0>|;)LjNfe#Z2UdusT0E(@m zK%oy?w+u8gVf21Aj&iP z`-Mt6SzG{1j~)9&DW^|Uk?NgXBWU*#n>K;tym=$K6DJ(;<_J%?$>R0_Yo(q!!=mcz zQ}Jp-_SLIk932&2N6x;!5M(md&~EA8TZ;=I;qc*4)!Is}%wf))(U@JkpybUPz^H&k zB6*Ad_ooP1@18pXOAa2isYHu~dBw*!`y?mB>hW<{Y&L_lQh9}r2(PJ4aRJc#-j?F` z?`I23OP4#jxe2!G9vuzJl$1K{p+mxVw!{U1A+{-kh^njemdWLRe%H|fat{wsRaPd@ zLa}@H*c2Cldi{EFRadjG6pG={iVDE?ceH6Y0uzJg0>EEFq6*)*k)iAT;vNwJ&OScB z#q8L@G~2g}iVGmvWD*tHGMgI^(B&YP1GfEY1j1w#6&FB|(I~2~OG+5Nn13QybWtk1 z0}Td-<|Hb<7ZHX|OtDQ(OqrVc0|9tzwJrE_O!U@}xB$ei6iM6C!h(y6Rucd|Jk9hu fe&0S(eGcGXd0TozQ6I=600000NkvXXu0mjfKWb4+ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/map_iphone.jpg b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/map_iphone.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d6b996c5d08b06e1a55b213e88a977c4f6666548 GIT binary patch literal 712 zcmex=db3yBDc%Sr%&thy`+ zsOzaH0D+30mae+Gx~`V7v7Vl>v9&d_8P@*~FbHxmNHT~pGYT>=2{JMZGX6ipAP#aW zBLfm(VP#?lN@xl&FflQ*Ffucvut9SPkRKRQ|Bb1IEit&V2j$=FM$nd9b*?=^{g`?zBhoJGcLuaJ9cMWTKAWzGdO;OC&>|PO~`q z?dP$k4HH)@F6n>eRd87@{ySez`?j2~+jfho+)Hks>+v{a)uyLvUqwDnbk~uz)C@bJ zP*;+AY-L79x9dKy9Za)5i#zw+f1qvcQxtrAwaO}Ik7W+~xz60Fmwg@3Y$NfdiG!(F z_-)yiP4|~5h+Ar|=|vfA(Qz)TA?;((WXw%PPnR{duh0_xb(O v#oNF2Ey>#H7{C0-e}=Q!)?Fv=F3hR?&tQ7EHKnpX{Ojt=w^j!i{l5tS6IuQB literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/orange.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/orange.png new file mode 100644 index 0000000000000000000000000000000000000000..8bee9da397e37a094f7c7f4d1169d1282b0e41e1 GIT binary patch literal 3413 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/purple.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/purple.png new file mode 100644 index 0000000000000000000000000000000000000000..b57873893261255efa18f98e7c47dcc0473d9bb7 GIT binary patch literal 1324 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 P00000NkvXXu0mjfV_aiO literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/yellow.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/maps/yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..a9d65acca6b10c03c259ec547ba1f6bc85437e33 GIT binary patch literal 1309 zcmV+&1>*XNP)Pe%s z1_r!wnTrsT6YXJZx+A1)b^v#oIpFaLJm0u2;~DSf`XEmHkq8Xlj3V!5IBmu!9f=HI z30E$Kf@WBamn2M~`70KF=vWWxXd4`njK7)Y`0DL{?q8I^$dHO0%#|hMpio-qJsEI3 z4m9`FFn(7x#l$@oz*rofPlS`@et@qB_T)&@MuuY81%CZGf}E~i?Sa8Zj~Dykp(HNQ z%)tMJ6T$1MD&%w~G^Z-%ih;feHi3@T5aJ>coQ;ZD$vxS8!Dm9R$7F?7VzZWSThaKK&XJxFt&K1gk*VmSoYQ1h&5ZG##jnRiH33!g^5x z32}CGpduy#h5xb)vDgeIu;?r}2k3GfjRUDf0B$njb|!)R58U0bpo}y(1OrUOFYM_t z0l#k#r3FcIaKB8>ByizeFp>LPRx120IRVXm^}|0sPJgJ<3VVdGmi7fEfq`q0q_s)u zz~}P@cV|l`i_t?Cp+mVc;PLeDHhmT7bgM6tP2lz~*bDBcNO`eOFecJ)-XZsS6Ox|) z7<&d@KX&x6=Y~H;o{y+^6hGM|M-W1~1w)s^0_x?z7>-r>20@u1XOhGpn z{k`ElN3mHO2ADGo^mop7XAnHGXJVqKdj$R7ztQCj|Ic+cr z6c>1Dg-X2to|_eB{r&S_2f^}Xk3r_!PVx#2REB>_w812>D@&pk>wTcsWI+6D-R_ zEHeAd*vJq>4yN_^Cxl=!>V!$)rDO-4q@{|9)LBqKtD>!q$rrfwBC2Q`oiGU$pPz?^hl7Iy=sSkN4HSQ}u!=Bv zG3bDt35pX2_Vxy^rskH`CUJFhJp+A13+Xl)M>RP`1qEwo*;XlQK86JhN^Zsytj&@( z0t*?8JQN%?d7Gr{gxAQsxVw59Z?O|v!zLgiYGSqj;F^UhCMQoX;LtHUe}P@=ir3at zr?20XvK73*z^;9BCI4e)4bv_5VvL-hIC)r@RBy^SSt#r3>HZ7oVVI;Wz+epkGV`9T literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/pdficon_large.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/pdficon_large.gif new file mode 100644 index 0000000000000000000000000000000000000000..39673df7b48ee551318e9f366010e13f112df78e GIT binary patch literal 434 zcmZ?wbhEHbRA5kGI3mn&_wHQ=1_mH5FE2MXHvSI;Kr$`u%$YO0ckfP1OA{0n{6BN1 zi;K&DU-;TGc}&Bp7n8EH%*TDB64URjFg#116vJ z?>9r$*ETfP1i0qU%y}1Jv-CmzvfRn_l%6!%$t-;;B;w1&d84>FS#p zv9ZrLn4>dqF#{jZilvq-3>L0op1gc98{4KW>v>i!n!i?W{SJnWvp3IO!M^Xv!c+SW zC~Y-nh(nzR2N@8ZFG;}_9X@(zQZeo9vxq1%)x$T{lqux3R#Zuaeg=C_+9(u zAcKj*1cvL(^$frMGD+wvGO`K?XeboqGc+>(l4A1a0xTh*K!3hCCB>yKGRohoQqx;#L)m4U$;05EW; AqW}N^ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/pdficon_small.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/pdficon_small.gif new file mode 100644 index 0000000000000000000000000000000000000000..bb5edcac38153b483a4acf5861baed1c0b37ff73 GIT binary patch literal 361 zcmZ?wbhEHb6l4%&xT?(Xq^9xig-Z|Ctbgg?_GrqC`#W}j3XQI=shQi{^5MgWdq<8v zEhyb6D*e#K`?j5nxw(0;n|mw2$ZHLKYj)1_67tU@;+FUJm+=WjaPbz|IpilLKkn#x zmXi6xCur%?WqEn|Z)H>t95`_2?!Ev2|1;14DE?$&WMEKc&;gkZ@)HAF+kuN3f?87j ziVKZOK3L2@=ggwW61hGi;P~MM3PLwOh!xLlIdrox<1eQq53hUry@@G6N zVqj{h_EfHGkZEqHX|J#9YU%Bmz%r?AiV|ZnW6zBKMiy3CuByrXjH0XzGRz9hGRtSl iG*xj)%Sz2>sc2a?L#%w?{#pS^`4cBk@hdtqSOWm%P;emt literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/pen_paper.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/pen_paper.gif new file mode 100644 index 0000000000000000000000000000000000000000..ba562347cf8784be0d8aec404700a2edacd6ad30 GIT binary patch literal 618 zcmV-w0+szoNk%w1VG#fi0OkMy|NsB~|NsC0{{R2_{{H{{|NsB}`1$|;{QUg?{QCd< z`u_ay{`>U%`}_X;^X&is`T6gwt0?CI&~=H}+(QPO;Nalf+uPaM+47M)jEnprD}cnE*k#weFYzo}QlVmjIoeo$-_a{Ez_JnGo!g1Dl(hz?NN_ znwspA0GOJYnVFgFj{xhC0GODV_lf}PjsmxmQ{#>S=!*d8hyaa^jf{+pi;IgBtEPp8 zg#e?lB%Xe%ct9eUb^w}>0Gg1TXCazU0E#Q~82}G3Tvtmq4yY|yBpNDBs4rewW;zCsAX-{SLUOh)Q&nX< z36BUA(5%H)TNjk7dQ-lqe0toxr(hx-ifE8=> z1{~11vt$(8Lw095Ws@Fo!AwloFUSRg8e)%)3Qj!sy(o(@h`% EJ7w!p(f|Me literal 0 HcmV?d00001 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/plus.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/plus.gif similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/plus.gif rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/plus.gif diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/popupicon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/popupicon.gif new file mode 100644 index 0000000000000000000000000000000000000000..7babac50b12e0ef9cd8dce653acca4257e68b99f GIT binary patch literal 79 zcmZ?wbhEHb6l4%&XkY+=|Ns9h{$ybhVffFW1LA{Z7?{*r`YR82;Y;%0w#?z@b4jXL3FA8&5*Ro>yqwo69RTzQ4-{z4J< z;zol<7T=<|cQpnaT5h`Fm+;DK4}v)l$$nXLl|!>i#9qkti{jP(C%uXiJ8GXTZT{YXe{Lz2&=FP8Ph95t! ze)a0r%a<=-ym;~a`SZ7Lr#*iB5C|ST`1RnygFAQb+`fJL#*G`7E?v5C;ljCd=T4tK zeeBq=!-o&=-o1P0&Yj!0Z{NCg>*mdyH*MOqZr!?7t5z*rwruIrrAwA9S-5cF{Q2{z zPoF+*+O&xiCr+3!p}&7dPft&GcXxaH{Em*6j*iy0w)WQ6{+5=O#>QC<4Gnd5b=B3? z6%`fb<>jTNrNza?MMXu0g#~$edAYf{IXOAm+1XiHS(%xc85tSr>FKGdsVONbNl8hG ziHQjb32|{5F){HmF)`86(NR$;QBes|QBjeRkr5ye6BZT<1|cCK(IFv0U=ZN%@9*d5 z=j-e1=;p@xl=H}+?>}+FWV`*t-WhG&5Zf;>AZ)|LAXy|NUV4$z>sH>~1 zt!=KUX`-pAsiC2vs;a7@qN1p%AR{9qA|faxBqS&($j8UW!^6YP&CS8V!N$hMz`*eT z|9>Dk3g{dHia%LcMHreHbU^lk@&p6N4F+~jksS>Oo0_?$L?kRW9GR}>GtK1Zr=`4X zZIUNkJ_slsY3Gt$6p?TuiIqVuU{z0|fC|%L?hK9<4uy|e7`V#fawKLXwKS{vOc4=e zXgw!ypvm^|!{p@S-OKf>L>xaUd&?CmxU zGk$0Uv78Vy&s%olgfo*Hx19u&&kTi!2OF8Wc$VA@P8U$H%71iZ=Hg{Ol4eC8BqA>} v9FdjQ$+)nhP`QoU*1fGpU`6A}>3SRX7912h?!(^3ET!Obg5ltS1_o;Y&;c21 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/progress.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/progress.gif new file mode 100644 index 0000000000000000000000000000000000000000..b713e27dfba708a01c380e7c731a13b52a34edfc GIT binary patch literal 734 zcmZ?wbhEHb6krfw*v!jdZ*RYU|9&kkt+4ULFya6I z{|pQa5E95x{Lk&@8WQa67~pE8XTZz|68g!)$-uzNpaWzB4HaNuV6okB(sT7*i`QqX zc^L!>4t!=<(wVp51?zD`Kkg=-D~S>;skcR%7#$omMC>21xN*pcHs0c0tRNsF(;}SM ziPc1Fu!&|20tT$-nJa`fCQUjv@kC+C3!quI1U@ISvoqf2Xk|(i=IUl?N@{e_G3Yq3 z;U-H^uFrB+CTuRW+i+5nfx|fagWLs?!jQY{X6=arU0riqs^&x$2`7X};t z37RYmQ;O#*G6uOVn*=nAm7~Q)&(!ybaj}oz`WtJ?PQSHN#^y?3ICf5PGS1Ha8pE+k zgJmJh5y6y1=@^y-ft=a0ZG|ZdPArq?H(+2`(;|7`F{6Xpbl>GI8B?M_My|#ljzAN4 z3Pb@-+?qdUsm6)xA>j@^Y0K7lSt}-Mopvo#qQ-sCkLXFkyF zSLvgkf4d8-w;?feL$4)lp3HYoMI*E5@=0AueT*09aVgICcu;r3k!5-F!GZ%U3=K0F z9S$(a^)KPCsC4r`z65*B*uc`x?)kvPGDl;Yns{Fj0|R3#FisfHGY4!D^0$zED2R>s)qBO7<=E|DCFS zxzznhP=52{@9z0pLYbH6&gT5ka-LOh%d)1mMV1}vOV1TfydP?9*K$^9_SYS;We#3< h3YJ|z#=4t(zIw=6Lkq*ZVXLPoy7a`n`xF2FCIH?$X}JIZ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/quickhelp_dk.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/quickhelp_dk.gif new file mode 100644 index 0000000000000000000000000000000000000000..05fe83ec716bd4cd6d12daa0a640e8ef128589be GIT binary patch literal 155 zcmV;M0A&A1Nk%w1VGIBa0J9GO|NsBV*5os0nM8A;PI{+Yg{^6iv~7{La+SG~t;xI0 z-JrP7rM%Lu!q)Ni`2YX^A^8LW000jFEC2ui01N;O06+vt@JV*YI7~h!I!Q^_QKA?C zg>XEGPyjHn2*@*(fMbY*)Rr_2t79+_f}2iZVL&)g0>({LPyia8ODQlDt$qeTKvdIE JEEr7$06S0DKNJ7} literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/quickhelp_lt.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/quickhelp_lt.gif new file mode 100644 index 0000000000000000000000000000000000000000..b629545ef4006cf17bd56585a7f35924f2af787e GIT binary patch literal 897 zcmbu8zf0F~5XKKHYLJ8+BgoPvBZvd($E45?9a?OP79lT!2AhPoh%eb-k<@UTP$3CM zM55$ULXvQiLpVfIh)W4VEsfXfKL0}R?YMiMd!FY$p9_QMPn{lVmv;FplJz3fGc8jy zrK*Sw&#(;5kZO9Qd%C4-y40*inx|Qsrb$6HQa#mDHC13ri4;$<6iuOk8)~=!GcC2J zo<~@OMo6utau2s~4VO|u(>%<=G)zhqv+AK1s-c2LpdlV&AsWI~R6~YnR3eKWi{XYE zF2GWTs^*!yx=Z`=HC$53RhycpW>P`okF`{)rb4dRMFmY0H6cfmCIECXPSCg|O7cJ^XyQNq@SrBWY9<=Wi4n#~C-=H@Cj+XP*yH`x`miKC9t zI4q_{bls%UQN#^3p95DSJUp>#=g;5O^{w?E+x=tHL*vgc-JZGHnj4vTb>rciabIdZ zU7mcgGBvll6dTivpXZj>->rTB@MUvr`#0GCdB+P}|AOo@8GN+acj8dr&7Ui`Ixqe@ zct+&)=9OmMvSR5xm?zXRBrWnxjXLPG5e!YRd7v_Fea%eu{~S zaY2zx2?sei~VmW>0w6fk=7LgNI zu3o!-2!gGZr-L0r$mV`cM!6YMNS z0xcR7AGveLSX~NsXgG4V(wSq$4Tppidt_Ao#Z*^3W(^#$I*cQhF2PQhS=3duR_~Fpv z(95w+d5Xe^hpdf)#&J_-I5sgf-%?2^FBau#{yfLH<*U^}9!D+}mWTshjty=+%%=q; zCQP(tt7I~2nQ8IhRmj%DRgX?jKmW?1k>$td*Z0rw-w#YyY#s9%v~Q>%Y~)Z|@t}#v z?8Sp-0lAFBT-qWE2U;c4Ry=HzDSPp-T_H~65Q|*Eg#(=$%T_$<(%JUnQMbW7i$`1x XS27;=T0C3vxX3+28>1_o;Y=reXr literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/raptor.jpg b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/raptor.jpg new file mode 100644 index 0000000000000000000000000000000000000000..401efb4b10411116bb4ccff32271d6224f7d2ebb GIT binary patch literal 889 zcmex=i3*BJ!6k`h{6D}T z$ibk%puo&1$iO7X$SlbC{|JL510w?yGXoM}XJ%n#;{Zx&3otM-GJ^msBSfB&2`DGX zCZxz9?8vTUC?XoDZ0rRH}TDedy3V;oi^JSC=(D zio3Mv)V*u79A-~{-c(@Z{(Qy1VE=$X5%(wS=IvCvdi1N=wJc6q=kwfhZ#@1poP3mc z?!JYs$fr+i>zTG{=WB&tz1SAys<2w~hnD*Z<#jE>C)i(?-r7{_FH<;oWAp?qCXcWQ zZzoJV$M~JE@O;eb=c!ZOnxjsnbS>)JG^cI#!v2&XE1d;-aktYfnKkb$Kk>M4GXI@g zk9YQqw3%K>)$ZNZb9@3zDTCF5;KvWI{AZYJxRm9%rrch&Ydll4m#ivJ(~w$r>-{4W zg_9iTPe^}Pe~?n~s$b~Ni`cIZjK6v%7hWk(=-m+*k~>Y4q15oaRPpv-?J*_YTMh@6 zByO=ibu{;W?k;EVFOxifiEEu`bqOdhTkRfXUvj{VX-#`crJdESJ?5JW7Z)#{?-g`! z-pTSy`o7U7d71m}M{7i?cZp3^_Sq)A_jpF1bibvnZj$<@-!Be*_M932e51QhRr1mm z`X;y9+M;HybWvRUK2&ppo0{`<1{O)fll?#ceGLtD`cjlr=WZ3hZguHZaqm_pk1JDs zb}vpnERY;Jq44m#*mM<#1GUcHCRpfA`>H*}wyr?l(4j q#^f1CCQN(mFl|;_rrB+QCWZDLcU!D$7q&!~Gaj%F*x+;g|4jf}Ydt>z literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/raptor_logo.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/raptor_logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..5ea2629998beeaf9239ef57157ecfb266b6e61b3 GIT binary patch literal 3150 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

    a%pfTWH*+0=e|)E#?j7M~kfIGJ}e z_8BK+3AWbSMW%$AL}ttw=;@LC*x80t&CH#_5|&Yx+xXFq4uPl5yu+MD#`TlmQ=|st z+Ra6 zm9?kmH9KT;0=Bgi{PC{4u*nGXp}N>&Of#rR68s9CkGTR&lLiF#Dp!B;XL>D(*csZCw|XtKS4PR1b62fP$ZsRia>CAgaXgRn{K{E*D&0at6tGTKa7b^zq|q2&gu4Bxgnrs3 zv9x`~?WdG*+xb2cPoq!}0voV-Q^B}%$5}2!uP&?Y6jr?r(C;U+xA$X)f0MsOE@H$( z3~4H*L&%pQ?S|1giV@YAAYm%NdIGg5lD zhmF(6YJ~Cms6PjMQT}Du9Xif9zgjp$tREnzF(14=is7k6*DHn(S^C~ zr~D#!L37IN$CcKxDN0$YhBkr3Dzh|s4a?2KEX}G9^LDpzOSftsv^^}sGOU^w)1DS- znO4n`WiN}eEUPAs2v|cCUJ&6jr@#h`ZN};IfeQC@uU5!m-VvVR)q>$cJJK_~T0gXy zj`A$8wgb1Y2R|?X#YjXGB47s_c2-my zO)TVq@i>jOc!_zqg+2Iz0VqZyq``tUG~opiE&~lVU~Dr^pAS@ZW>|?r4)d;#ko*ap zgo%_435}G9g&Z&*r?D0+PY;|B(y7>SSu3)awt7eu%WG}wT#%{YBNQ2g%xr51ii zN2Cue53djZ6C2|Ly}Zus-JRT@jZZIL9DQDGUXLxV94|dTZe4xMAG|$%KfK?}4lXD6 QkG{5Vrw-5OW~Q|M2j<|RVE_OC literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/shareicon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/shareicon.gif new file mode 100644 index 0000000000000000000000000000000000000000..31153568cb0aa84eaceaa86b0e5728df823c8e11 GIT binary patch literal 542 zcmc&wyGz|*96i3Hy|wY#*!F63eMYSs?Zfo?xPDcyrVqWJli4I=+`jP^)c8>xB1LfM z;Mh=UDYyi?1e`Kv42Y1`r65kyDUFkVf(H(qbC%!loZ|B0q_&Yk1_ueYwvxZ!kR%C! z;go5bL7_5x_*IfGJ|FQ~Y+Ube{%p*h|LN_!`F?!*<;OaZHzjgtfGJ?AU}-Q^&7?4i zAB8eAbce%8t>O8;AIIGDpsIvB8h1cVPz$=LTHFgl=oVxRq#R#fg;D%FxP;0aH#AHJ z)zx$cnL+Ut5<_H=TtWj#0R$bQ4>5!o$w~;}$oGRVjDsL@-Sp&*X>v-Lu9pSD11!J= zQV{?Va0Mhp;|Arob?+PUzv_zHAMUoVD{sTLE6KZEyJeNYCSjdO=)3m%LbAf6_5gntN%_>npD&KMsxW;fXrX+Fnz;H(J-6?ae-F&i#7+ p;#sC6J3O|kN$7s_wo?!uyk7mVY!{rirs@8vwX-6nOJsKk`Tu7nfHeRB literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/sv.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/sv.png new file mode 100644 index 0000000000000000000000000000000000000000..f57fecb174d364e4e2db31466a76073243ad43fa GIT binary patch literal 11373 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

    sH%BDIs<8Lz2ZaFcUyR(2cPd*=HzMS$K?Ob%~ln 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tab_left_sel.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tab_left_sel.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a534806a3d2cdf1f561b23f3df5ea84a44064f0 GIT binary patch literal 106 zcmZ?wbhEHbCDMGlDm$-EFzMgk49fe>n?- FH2@0WB%J^N literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tab_right.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tab_right.gif new file mode 100644 index 0000000000000000000000000000000000000000..62f251623b5af71a642686a334e8fb861b7db683 GIT binary patch literal 138 zcmZ?wbhEHb6{|wPX#A``c2r$balzsFrjDf{7oyQBO4=BTa>EJq_-^7{d;T^Z*RqwV*7*n9x`eS4Aua= CaUzTW literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/test_run.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/test_run.gif new file mode 100644 index 0000000000000000000000000000000000000000..92c1c3dc27d319bf6abef7fbc7c1c3c002b708f9 GIT binary patch literal 330 zcmV-Q0k!@|Nk%w1VGsZi0M$MKX#W6b{{Z><`D_0GYX1QG|M$|;(qxQFWBCAUtU>4h z)@1ttY~3D~n3Z&XZT$ZGzWsYh1vu6GPZT|pi{{U$J1Z)2X`1ttaigX=Cp(*SI0y3U!itKrN zA4*M=JAS=^10fZgV9vF;T5*2%A0~{;|85SplJs|@O7%(0s0(E#Z cDGoOmBu5|{2`CLJl}IlWD+Z-htUf^iJI_;^x&QzG literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/text.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/text.gif new file mode 100644 index 0000000000000000000000000000000000000000..6db2fe1edfc7cf9a3e9607913310266f52cb9be4 GIT binary patch literal 141 zcmZ?wbhEHbg?oy^+88&+tVz;(vzb{gr5#(gle>w9!5RQ6uP{dd literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/context-menu-gradient.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/context-menu-gradient.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e289cecc51b59a01c1278ce95653badf4e643de GIT binary patch literal 807 xcmZ?wbhEHbWMp7u_|7m2Mnhmkhk)Ww7Dfh!{|q{yPypo#1`Za6|Ew$w)&O`M20Z`( literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_folder.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_folder.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd89accb5ff8fa9fcdb028e0e4e302524ace4c69 GIT binary patch literal 1120 zcmchW`!|~h06@R09@eQ77RRf#)F@LnI-|0!_3oHQ(@ooH8||o9RaM7odbVWoR$D}B zh*u=ih(}N)5pR`lf_a3NE=Ud$rt%?@IEnAu`cLeh`}_UrUI+?2>vanWAOST1ppXdL z_f4Ho9rv&^^>TCcb3tDC*fiJ`5$uW#b4P}qLk6JTBLXesF;*EjPDF>>rCf8(xP!*{ z`d~vt5+lRYV=w=djLnI${x!jxlzf7G*QWY=TWXp)E5nTb=mST%%ME zx&$>@ff7}o7FRjHq@EVhy|~f^87(=7}ysM_Fe*eFUxwO-w3ea z00tbq1P(=lBayo!*FZre_yP;QhysOJa5QRrENX8&N;(|B`8;WREOu|=_V#$f&P1Ye z^qy)uPC1pJo=H^A+*6D0E2lE|XH&EpX`E+RE2k7-fNc=OEl0&8B)lrBI z)nqo6%%+jq3^JQZX0s~zEF71a!*3$+TeA4|Tk z)clQy#W;8o4=)nnr7YFb6X`34Y=Hqwv*G1@SW*Z}ij>kac$o;T65*9%SVn?mCGZLv zUZp^56nL%XV51D$pg`+2Dk)XHMpvyd)$&HoMm@Ayd!V4{HlIRUPxm)i8U^cMt7%Ws zrjm2ja-Mdpbzjk`RdneT&mcvYM$Us2JT2G^fovG;SeO(3vo2BZ%J-BzI-ORh(;XZf zKoA7OFz~-{a$o-t0KkCr+uGYF07DqyzjOS{*4n{4Wrz>Ixq8gnlc4W;Ke#@4)*-YM z{jE^YM(et(cQT?b9`jzEe>uwd5j~G23?f;$pktVmD07#qhyuIGVu$!ivb}b-(A)__ zl{UFOIFfIOFRBZm$&AWfZ*)ekQfC;2X7-NGhDhb+d`I*^>d1Fb;*71_BFa`!7@wQ9 zvEy`;Vf#k226WO;65jTCj=@pALvGQr&SfrF>NmNT!?z1cP-i?s5SqC8_FJ5r<=wlo z$L3Dqd73<`&oAERM+)9lq-_{ix<|G9d+iVmjEvsZSFO($&N+RaD#A_K*8f4Y`2>3% zg(Cjdc!jn|9Gs5HH$k0E7JY$p8^Qzl%#ZL+B{8|iRt_O#V4He4*XWp@q3D@!Kmo$U g8w3s?wZj2=1{N0w0D!r&Oh5!WO0x8i=mVeq3*8(!MF0Q* literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_minus.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_minus.gif new file mode 100644 index 0000000000000000000000000000000000000000..45ff7280097b4f8f447a66bb619b846fdb8b3cbc GIT binary patch literal 197 zcmZ?wbhEHb6k_0IIKsg2|HuCcD-JB!aNzXC>mNS+-*Di;feRlFTzGKd#)k(FK79D` z|Gl+R{`0(TZfeQ}~T=?+e!~X*}K0J8w z;rZ+L7l4cpA09mTu;Ijm2@8OV{x4W@V8Mwf+E_2IZBL%z;F%$ z#h)yU3=IDnbU>a2egTwKuI+n{sPHtS_GlL^5ug0=yf!}-^d8VzBQx+YV@7}#g art7kX_tJpbdbM0vmt1WP+04emU=0AYMm#?N literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_sheet_crosstab.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_sheet_crosstab.gif new file mode 100644 index 0000000000000000000000000000000000000000..f8ccce34a2e9a64d1990956b7f632147f6957b30 GIT binary patch literal 1144 zcmdVZ*;5+@00!_4u?(e>1{?4gKxk>El@_q$Xev5Vdnni{6}d{#5Yk#1#^P|a16a9D zC=u-oB^r;rl4z0_Aiz z2_ONR0FZy;m%Yghd;R96Y02O&L3npaS4$^G|I!2(|19F@MhMmB0 z1Tb8LTzf#SCm_%J5)BTdS%b2nmvi92Yj)yQ=W7fkG#4cmdZP>U5qVZ}u7#Y3MCU^% ziyd({p}1S{`R~maZyP^gZj{z_e^y~gs?erX8!ob(Ni~*~T1y%WqBfec8j#FJEU5|l zf{SKy;4hmkR1TcQh0}TV489|S@4O;#ToE`kg|4rm>YqKvz)8?BatHe(^rLhIV5iMGpc->j)BZMaj(uCH!vsBL0bw=~ys zntl}W*&Ra8PaWJI5wEX@C+-#Y_X+yN!m-i8KmT}G-?dQPt*Pk+?>$nr4`S^@Ufz&L zIP4J*PT!ZzKNwy7`H5OI=6*Z{O2>z!km(t0RzhYKY*E7&4FaiQ2t*()0_&{svK3jjA!^L3Ly;BKx{6x$ zb`-Rs28RuF*t8C8m(GbTJFyj)W7X|6*ia*8GhsHf9kaNd#x>V2lgDNDxGf$x*37XRQ$ z__$y~9qYxjl&`6#{IuILr zM7$9CZjp}`$Cw$opDdP?WIgtO4m05#IRHGG${>N#J^k0BlA(xM9^k}u`sBSQX3f72s8lv>(lv# zdH{4dp=DKipyhzhK&<7I9H-K)K@3LR#I0ow79Ai;aLTD*+^pI~DLj-SsA4uU+I6Zt zH>vTe^8I?fjVp9<77tgj$*?wHG6z`)r7vSStI@KNF%)k$uCKNMl}&}&q1HF&34Dm64$N@U!oLr!;iYh8DfF;xG`uH9W79RqEh{cT;t?R)ok zw)b{+436%9)f1fx?3fC)Oh%fy{PceYW_^Az1?^E;YRS-LRai zIyCmqz2BBs9wr3&&qwLZN;;cPW*%o&QrUD`NUr2^E25O9mjBv(~FyNVp2k+V4=mlLxBpOv$`Ao8*x z@EMWk1zwVKvMgpKF)N8VQOc|?$TBaBg8UyPQIaHClEMFmEsG%l$iV%i>B%PmDT7aj zYPZjI0;+~~+8qN0!QOKpw9drthsO)|J(xcdnKPER{Y;`)_D)2PZ>Ucm%{vpCxfmbn zIZV}Jv9r&=blM&poc-luJOr*=mzE#=X!jXGY0nqa=bqhhw8nd&YqCiJGfk8~OeD_%}M~_J{*Jd#!igGcn_7 zz3g}MT~}U5kL6*nHC)ofZu&1P%4S=ZZq}XrjDF_fd?xz#&dYt%A1?R){lZ;-tjxKf z$Hu-i1^eH>bD+7U{kgZcl`f3B#{V)0dv4!4eFPd0E=`Pn+6qGO_vuMCc+W9%qvG4^ y!$;O|?iJd(Wo{1{{OQfwn}KVCU)?CbVD%}3jZsg?v8>5w%N9?)!B!&(*z^xu@scS3 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_sheet_graph.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dhtmlgoodies_sheet_graph.gif new file mode 100644 index 0000000000000000000000000000000000000000..c8efeed8fccb5904c35e1ff8afcfac35af181d7f GIT binary patch literal 983 zcmZ?wbhEHb6k!ly_|5dX?GuzPZUeHn!L79B0Xm z`3F1mPZpLREUZ7+SpP6G{b6MN%p~-YMfd@;@)i6%-y=7@jkCI29goFC+ee zyVGMYhc~X?kHbQr#6&);$a^xY{l%oV*VFo5&FFhSd(yKdGv6+o{&COdH^>h!SjV!~uq*5w?A7d9^Fm+|2cvs|$FiGzx| z(H#$^3ny8`t!2I`NVGDwOBhH9Ok{e}+RVV0%_Aw{(#pi6Wuo)Lu*r>KNeBbago2hX zAr|eBkO>5pwJ{JBkr)IqA`iBTP*Wx+*gM~EIk6OOadDi71!Tet)!zO fkZ@ze;XS-k=5;zdH$^ebFwVZ$W0`!Yfx#L8E+w|N literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dragDrop_ind1.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dragDrop_ind1.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f9bf5a658dd413e71394bd7a7e7a5ee7484dfec GIT binary patch literal 53 zcmZ?wbhEHb0r5dH3`{&d{VTH{@GqXzce9#{!5RQO C!3{0| literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dragDrop_ind2.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/dragDrop_ind2.gif new file mode 100644 index 0000000000000000000000000000000000000000..a1da63108a5b87bc573b98c16193624f66ab62e1 GIT binary patch literal 56 zcmZ?wbhEHbjEB<5wG8q|kKzxu40~3EwKif(6-;3sKIW|r1+%g6R FYXE2^4z&OP literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_close.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..bba11d3901104873a4afec51a7ecee851dd8f244 GIT binary patch literal 283 zcmZ?wbhEHb6krfxxXQrL)YR12*vP=Z@c;jRAUWiK;!hSv1_l-e9gxdGeqvy=aA+#< z(2?ptv7|^c!)osF0|{QTEQ>;4UDY@nwQ+yJ5ATL)d!Hnk@786yko%~3-!S=8s#5af{2qyg(Jo`C4r_bSm=iY3&czuDALGq_W z&@xPgYed*Q1dff!NQ!8%YdmUI6Hy+tRsd8AZX{?WeJb<{poy^=y9DB5gqDBV{&=we z{p;uVN`TW5W3f#@CrYjeYzrZ{Rn*pKs=+Eiryg%nuhXdfl{4FqYv4Tlbskiu7Qhxvps~A$oSF0Q4=KGB9$f1sUHo6m2J?X~9?XR35Kmt9cX zkAs&tE>RM}vj-#B9_^%0DsrPID1QorUvZF|Ucc}PWVH@-zTC$%wi@KmG;N(t~0C3f3B~@R#=VwN4rbtr-^YzWG)#U~2jN^GoZ_ NzyJNefyI%*8UO@ZCwTw> literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_sub.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/folder_sub.gif new file mode 100644 index 0000000000000000000000000000000000000000..e3c8e44ec174a7cb896d542b72d4ce3372cb407a GIT binary patch literal 265 zcmZ?wbhEHb6krfxxXQ@T*x1N0l!4+;7DfgJMg|>_CqRB;U{gELP{1J})qg@|(~2Cc h&hslKX|Cm38J1Zn{UB}neJ!&)GLt8#6$vm{0|4(R7U}>1 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/grnarrowleft.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/tree/grnarrowleft.gif new file mode 100644 index 0000000000000000000000000000000000000000..22b9bdbef94f5236b6c45f1b0ee244adeb1b697d GIT binary patch literal 854 zcmZ?wbhEHbo401@aEo&W#< literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/txt_icon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/txt_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a73eb528f5bc9d19fdc9d832a276e5f5e45bfd2 GIT binary patch literal 154 zcmZ?wbhEHbo_6!xF4BNL?B?KS2u#MsW|L>pg{l9(T z|Nndc|G)qL|G(l-7DfgJeg++oPLLT6EbbppvagbzY&31x;{F9aDUA&eE7o*1GB8Fe z$r~`9-DK#UPa$=z|ml z=ckpFCl;kLWag#i>!oGpq^9K;V@WICg-Q52IQp&rxumvq?Tkb)*Aq| zI)Svhq!uR^WfqiV=I1eFl#~=$>Fbx5mm`}2GE*N+ltK*BPXoFSD3X#|p_fsTd$;3Z z4A3-dkZI2O1(ija=@}(3vyzKa6H7A7Qj_y@bMy0x_413-^>Z?lQ}c>bi}jN#b@P&S zixc&Y^bGWKIwpbqv(eMVF{I+w+ZzXY85B4e48N6C$R762aDO1jk_MD!Xqew8xFsnj zIpe5+ikS0+2p-2ILzYhRI4%N#EE})53LZ)9xPEey#*sw=-A+1O8}TtfPCy20zA?z~ V@Y(b3UVa-S?CI*~vd$@?2>>8&q+kF5 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/uF034.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/uF034.png new file mode 100644 index 0000000000000000000000000000000000000000..4f6073452948d052d09b1781c631c4ace4c96f1a GIT binary patch literal 536 zcmeAS@N?(olHy`uVBq!ia0vp^DImTV;?(En=FLC_`XB|t z`DrEPiAAXlnR#jXdTE(CscHE|xrrruDTyVCdZBrl$@wX%0eR`csYPWusU;bV^#(w# zP9Uu=sl~}fnFS@8`FRW(B_#z``ugSN<;Z4$%+v=Hr4WPk(}3;+iln4g=w+1Te%bux zKF~C4kZI2O1(ija=@}(3vyzKa6H7A7Qj_y@bMy0x_413-^>Z?lQ}c>bi}jN#b@P&S zixc&Y^bGWKIwpbqbI{YpF{I+w+v^8885DR}4t~k~7}fkBdE!i=P5sKoKm`m3yiapR zZPVDRu!yC(Lx@Mo%b-K!AbA`Pr49+VSOG(uwvLaH0)|eGM>tpol|@{70*K=X7=j#x b40e<-JX^qLpCCOG6v7Oiu6{1-oD!M?Q;W)SQcE%z>kWWf zoj_V$Qj3#|G7CyF^Ya)oN=gc>^!3Zj%aP3hnW+yZN+Aa6rvcpu6iG>~(90;vHMP~2 z2byLLGR--^pt2}4J);C>R&r5lVo7FMYI1&VZhl^|UVc%!eokg`YF=?_v3^peZeFr( zaiYGFo`HT&$0U${CV09yhE&{odvzo40RsVM!}oI^PCn)kX7St8K{#gNR-g(9c<}v= zVCTnookCrTUIuL%2PGDl6|I3PO_+inT$-o`^H%N VmCwG{({B$**wfX|Wt~$(696vGo2UQ) literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/uF036.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/images/uF036.png new file mode 100644 index 0000000000000000000000000000000000000000..da9db296078ebb137b0f390319ee36d04306dd3c GIT binary patch literal 482 zcmeAS@N?(olHy`uVBq!ia0vp^DIm?Q;W)SQcE%z>kWWf zoj_V$Qj3#|G7CyF^Ya)oN=gc>^!3Zj%aP3hnW+yZN+Aa6rvcpu6iG>~(90;vU31@8 z4rrP+$Ta8tg36-I^o$aiS;ez#rjE=x_QaE z#fkbxdItJA9g{%*>GpJS45_&F_97#1gMq+-13%|gv~j)oRPHHSq6?IUfx6B2=bgT_ zY)0a#Cz9qqlIDwTQs4AEn)1=uEBFkDuc5NZ(Vhz;#!f_YVCEv|hJKk$Lq7Yf46EG%?U-IXlbLZy#%lDoCToEAz z-QC?pBobk4Yz)k=npiCU-@o(o^TELaT)1$7ya|54pLBI~k+!xr=K1Ukn zu^0k@0A7do_I4B&7UJN+gSdP5E?Qe#as2pkybdarihJqWhw<=uJm~N5$Kc=~%w{t> zJ3En_oD7S_g5u(0R8>_WB_##xAU?pQOP837<6wS%9(IQl3n39?DLIho3y__Y0GGoG zS(*$T*Kgs+n>Vp3I~xTB1&~UmFF9C+7%xy#Qo@ZP7z|=|b{5mm1!QgBjLSn@z38Au$YYSxgAhQV$doTP)b49PNX=WBcc5}B+_7I zB?ZVWDu;3E85|DB`T_3WzmLVR1l2osU`_~Q^vN(K)Q$tSJ5ZYY4$?NL!H_N!VfSD! zWcB;8Y%oBnkRmlX31wxaAQA=c-MhC&MH~|o6Hp{-A(zQ8Gd+bwl@gxi1x$=j;=M8^ z0BV;nqw>K6taNn1R8s@V*7uR5QG-APy)G50>3WQgj;>#U-EK#cHWdqA4?HdbHme2V zSeUhrb7Z@93t%IFN^?-7f#T>s=cl6beB`TN4Qd z5L^jhW@Zj1N|;gtDCJ^Aqft~;RPZGHd-vkh$&+~e_%W@FKrE3!u23Kv1A>7i_AaYB zE&v}1Nl8g?xSjkYX6ST$W1q_juVBOZ^XK{Vrluxl{M4qWr^Dy-Ax)>_fgFMxPAUo= zT}L93cn%~qi_+3kEc=}BxZOO9a3~DHZpG=-r?8D?-_mjpM~)o9$jAuqv%z5C?Fp^~ z5spN7))un~TefUr`^5#|*;Q9pBkXr$YRZVEr6mLc%lPZzpE&zX3+;bBD7IiI?7 zb8{FN7~oX|LqRP0{V+a#3V~Lzi}FPGiwnRni;Rp6=+e?KGd_f=>1i&#y3f8uenAm( za&w_nsTo%+JN7OQ=J9wD4o5I!GGTC_A4NrlOi66NxBzULaw{({M{v=NzTdj=)c6dc zNEA}J0x<$wfgDz=6*B4x;bl`|V|*~)xqTZxD(}k5%GJH%NM4=kytJJ=ccQnq7r*>; z9nS65Fwj|}OVvUwA`mD)fCw%s3NJMyZD(I^ALT2EhK7b!F4xF(&FysT*fD;K-MH}s z9_llZlb46A%uHw!6A)NlrX*Woo;7j*>45{BdIinsOI b!j0iS`~}CFLktAO00000NkvXXu0mjf++1`$ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/Calendar-16x16.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/Calendar-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..ac970bda5aef01cd511c0e7057a2908c35684fb2 GIT binary patch literal 552 zcmV+@0@wYCP)(aA0vjm$GKT!NKV0=%S*cl$4Z&goLZB zt9p8RZf3oV`F2-$H!JyRzN^NI5;@= z_V$N|hu7EFeSLlX{rxH`DlacDfq{YL<>iKkhEPyYb#--KUS8DH)X>n-@9*#R_4WGt z`dC<4K0ZF(-QB#qyUWYV(a_MVs;bu3*4WqA>+9>EpP!SHlW1sY=jZ3@>gwlM!Rn-&G^DQzX&f*6E1TOv(fEX!Mq{&gE`z~ZIh?xL?lP&AiXnaEPS-cLclYeW;}ZhoIq~xP qmP{%ieEJgs&wlAN?EB}J`2+vOKN)2h$QSPb0000&DPQaDX_8vaoya2(=drgx5|^ z{{sX6cz8VT?7R>Xazt48yqMSp4UK0fPCR?|?D_NO4}sv~#hYPaZ@j&~1O~p#&;Om3 zwM9(qq=3M~efyp~dGhe&$y?FUuV24@eD>^NLBWq7KfX9~=IQR;_xJCA@ZiDybLVcj zxxMuA+AAkFfsgNopC8cg(?vz^sjA-c^Sifu_e~$4x3RG|A|meX*>k(0;Z01;W;eHg zRaKi98TV*wzqGJ;U}^awJp6xA(Z{^JM`>xVva^pzMowj8dlL|FF*deaK;XKk=huXU zfBE@ei;J&kWefP4lt>3dz6Bt`+B|(0` z2z;_y*QWZ{Pv*&NlWmqRee(0?lP61;+RU8E*7E013!A~}=g(IgEZSMM0jT4Yr;B4q zMcmx;m&;fJMOZG}dACtCI{Egt+#}m^U(cRw{Fi;@@~Gb{S3Qq+UEa|zF;xX`RAZ!z2169QfXuD??0b@ef#(E>)*{DY!6N>-Bjg#XH7^pcMOBi z!jP4wQJwb^Og=LF2%CNPVTtD*x%K`G3OsFxCT8f&^H_FCso`GCz5t!6(QnV)36f{1 zOfAi=O)k!^PA^|C&%i4qCp&-6yt(l)d_srY+T7p0lb4(CcKjHpLq<~3tKzCOv3-A- Yq#ZRBZhPE*3iK6&r>mdKI;Vst048HtuK)l5 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/addbtn.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/addbtn.png new file mode 100644 index 0000000000000000000000000000000000000000..8f746db6344f2d90f7f3b00b4fdb2bbaa6db7b95 GIT binary patch literal 662 zcmV;H0%`q;P)1CwVuy+|2CE&iCvZ zwrxYN*Rxlv6`W2dK>U9!!!RHi3_?Diheo4e80~i3-tYHNuh$`)&4Ou~f>AaA1(Ak- zS}G&ueZrs5Cu}ww=yto1OeVohBoaT(W)pI`oWm@Cuh&Zn`~70E7^Kr_7!HSE9gj!I zWHQ1comWKX9uiH3lRU=>MqQ}WI-k#iK%Thei0_w5C5JwpPL&FE@|Vj6to!{AkH^Dz zu|y&f2gYc5F_zZtb^{BAexsN#zw#Je3x&9#F2`;u@T>TGy@G|>G2E&)krm2DP$*@2 zF9ur}Z?u>fhAdF4)joPT91c5hwOaky9}EV{GZ7X!<~h@w~fvEfiy@ zRH4=NqSu0xJ>}tu;j_(CB$+; z&1N&ta~fA55ctd2Pl=SIMktT4RFlVy&#g0>rr%?JcP4Y{ z)33R|bLV@`J@=mb^GtOc3B$d8zz)op z1kx#Eam0IghIEAeunc38v6-n2_XH0RRoOxrG)XC1-3qIvR7*8t@jeD8um`8`EI}B_ z8k4cw(20zNnV=$FgJBDocbJ5I5i>nz$>Zm<5$fPE3vUpH85_|Hn1^He9fD1}M4U42 zg$5BVxA3`wQMgPQTa*pBq0>MD(kPTwf!D<62nN$cl{LeXZpOuOB&;kdrMNM9r-H24 zZJB-%w`-e?4rg6U*y}L426mx6*O!D#a}JN&o-=07*qoM6N<$f^*mIf&c&j literal 0 HcmV?d00001 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/copyicon-highlighted.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/copyicon-highlighted.png similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/copyicon-highlighted.png rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/copyicon-highlighted.png diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/copyicon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/copyicon.png new file mode 100644 index 0000000000000000000000000000000000000000..6c1c3c155f6d2dbaf649a4f5094ff679b95960c9 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~q!3HGX7W?Z1DaPU;cPEB*=VV?2Ic!PZ?k)`C z3>^$7)npGG1d4DLctjR6FmMZlFeAgPITAoY_7YEDSN1!MTw=l^GqS((0)?_YT^vI+ z&flH1oA-bLhf9A)V!q0;B$;wQVb_0}$I8UDRQM|9Oqe3%=fv2M(q}efW(o7WLtAD( zneo8;f}Td^S)US>S#tt(Z!1<5mmfDf*vWo%g1kV?>h-sSvRLY0IsUw_Qv77fLiW`r b3gO^r07ZZb9?HtTFf{z&?foM;`Cmziw@m*Bpy6UAL4F{Y zFfbS!djLUUVRiKx2x!nuJq#3g^K@|xk+__k;KOP> z$SlZU&rqycaA6@!r;0!BN1YS34fTpD^R%o27eCqCZ?c?MVg3J` E0D=f~PXGV_ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/csv_icon.jpg b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/csv_icon.jpg similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/csv_icon.jpg rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/csv_icon.jpg diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/csv_icon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/csv_icon.png similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/csv_icon.png rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/csv_icon.png diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/deleteicon-highlighted.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/deleteicon-highlighted.gif similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/deleteicon-highlighted.gif rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/deleteicon-highlighted.gif diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/deleteicon-highlighted.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/deleteicon-highlighted.png similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/deleteicon-highlighted.png rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/deleteicon-highlighted.png diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/deleteicon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/deleteicon.gif new file mode 100644 index 0000000000000000000000000000000000000000..4b07af82662b62f35cec00a27928410b3a500703 GIT binary patch literal 579 zcmZ?wbhEHb6krfwcoxG@Sk?Of|NnJ64o{l5^5f?(vzBZ)a{9`(JCAl8x%lMu$DK#c z>zF%z`1D?`s3%jufI0#KBi$}ACsD|ZRYsk#YasOhpTs=O`N;x z;Mtoyj-20r>Pkdn_PnKQb{x5|>*$4vbC=Irw6d_et$pI`MXR@InL5;WOuts z!{ReH9XR*l^OrfxHWk*i$ED>L)phmETzdTC&4XvIH}*`w^W=3_aZP4XT~1k3YF>q! zk==&f$751*tJ@~Nc>neI`Rjet=g(NQZpwnyvsY~S@%R7YRH%<=E7`yz-`< zM=rSeMLd4>Au+4i(L40~m0LRwpSy7D$@%LKrp{TqVehH3#_rw6uUx(T=;r-rx)#nU zc@@9_VW1aK{K>+|z!1Zr1F{elCk*Th8e*E78Cn^dJ31J6czJo+J7d}=PibMCK4T_h zzyt<9Gs$3MSuPt*7b&B;hFWg&${~)brW$H?6Jqok9R%(5BEy}9xxzXu8QEAkS=l+5 znF3WhEKZy{bB;;It0VgA>9gm#%scq+U4LlRA^PkAleb@o+?yNj1|8ar9=g6x5eiC7 mPG1~Y9tH_=iZ97Y2yAtmDOAtqh!89ZDp4AuZRknPU^ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/downloadicon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/downloadicon.gif new file mode 100644 index 0000000000000000000000000000000000000000..1dddfb68b9dde6b2132ca794d6cc3ef3ebd0f596 GIT binary patch literal 74 zcmZ?wbhEHb>h; dQ<$_`$xvhKx5|`)?rR-$zPn^(YOyj{0{|cG7Z3md literal 0 HcmV?d00001 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/editicon.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/editicon.gif similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/editicon.gif rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/editicon.gif diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/excel2007.jpg b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/excel2007.jpg new file mode 100644 index 0000000000000000000000000000000000000000..77d7cc208b428f3deb5a834f8234a167bda328f7 GIT binary patch literal 761 zcmex=~;k+`^QRlZ%U&n^%&LPtsIH zPQ?@_&_t6lF*VUKG0`;re}F-dgF%5oftgW>fk}{&S&;Gn5e5mMGl75s0a#es*qMPc zx&jQ0%uKAz%uMW1Nk%4S7FIz9HX%hrVG&2Az(V#$BPZ912QOX%Di>#DU`93usE3&a zWP_9-NCw#oMxgaVip>9SG4KGjFbOgXGT1Y`V7>CJUAivXtIB#-k4MzCX;*GUXqFzC zFni4luO^Q#HFu`2nsuw*rT1G`^PdFERL4`hPPddizI=o253jGne};;ap~WV9R?bi{ z<*QzIS+y!?yGZDz`=2HsUFZ6z_ak>zW483BTH|H8(`DQKGl)tye&)1)&b=rkbD~y| z=G-F|o1R!qk8BZZu~_mYz|*^CV!_%2A8I!!UAgfy_4>>;<;Jp?mtIyVxuC~8$#c70 zph|dQ^4cMbTID8n%}>k{f9kL>K}dJQ<2w&Sf819HJTqBn zma(L4hp*(sMM|DtTum{N3h~8TkFS27UD$awEu#C&YC|dS^XFss%}H6vBd}@dS`ALl zoqNCb83wNpshag*ZLQUm(>kxpT_i8wv&nM`+A^u^0aNV;_SaXgWo|hkm?^p{YT301 iFI}Cu*D@{mouwSfYQBl@`iFv3myWh71nTJgzXb|M%zL??1nP{{8vo|Ce8Xe*O6KgAi458gev`swPEmrtHPe|qcHt(&iJ-gtH6`pfILp5HqE>in&T zw=O@teD2A)^AFFTet3Gt(-ljeE?M?u*^);~=G>h#`}*uTr{-+iv2DY)4J$XTT)uI6 z`M&a5OJ^l-Po6$^de@w;&e@$YD`Vo9#+T15FPmAGv@oe?R#D;1!ng%-CDThvW|Sn( zPmGx#lQ=gqYJOC~l!BC*DN!?{!e)l~%<&1E5f(lzJak5A%A}N-DKWv*gERXw6DKBy zOb^22BQ*wU!3;23n0;`t|xAB_5iMnoea-rd6iSrOx`b`WBTI zCe`g+BB+Qr)HrRoL+2D*j1MtMexC5i@l20HmVdbxTE#R}4; z()zjjip7djB~l7S3UWnqibaZwg^Joa+B!Kpnz@?th4NCxQgVfIvPH78g|eDCnsNnl z+L_u6Ll7wbWML6u_|KpNayuwbFmU`~xG$5Gk{!G@h{O2rBazd7i=3*TsT@pta(bq5 za!bfZp%Z;eOvEiJ3>p=jSlHDKY))L_zA=HT&*b1OMur3Y@fA8gAD?KR;;`_Idbq36 zd4^nqYTK1nPgPj?rQC}mH(hx?ou4z&sxj!YLUW&_R|)5)Da;3&%oe$<3=B}!b)qDdy}i44Ywv_D6M8rIc5dnH-O$^$sjG2IWAB>Y_OzkX_H}$RVt6W>T zaNfe2RW$`G3Z_n-I%U$7$&)6hEJ;aToSe2WEo)v@;=;tl1&LiWA`P_yHI*zCs z$-*MS@Si~kWHu;IFmT*wIKAd!bNYEXo60{g77DX995#*hYI(r$n2noPcSerm1_p-( zJUm$sI0PCT_?g9*IQ(Q{INvUl%a$7WVA%x$j;ID1!!5^Kng!jy9I#AQcjVBv@6%vP zVRmTYb$W6oli>jC)Fqu?&PY5^J=da8e&WK037xpybXSP6iouujQF5(a^meB`M)(bbQmmjInd0Wenmrp!5RRJOg3-; literal 0 HcmV?d00001 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/executeicon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/executeicon.png similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/executeicon.png rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/executeicon.png diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/file_import.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/file_import.png similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/file_import.png rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/file_import.png diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/pdficon_small.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/pdficon_small.gif new file mode 100644 index 0000000000000000000000000000000000000000..bb5edcac38153b483a4acf5861baed1c0b37ff73 GIT binary patch literal 361 zcmZ?wbhEHb6l4%&xT?(Xq^9xig-Z|Ctbgg?_GrqC`#W}j3XQI=shQi{^5MgWdq<8v zEhyb6D*e#K`?j5nxw(0;n|mw2$ZHLKYj)1_67tU@;+FUJm+=WjaPbz|IpilLKkn#x zmXi6xCur%?WqEn|Z)H>t95`_2?!Ev2|1;14DE?$&WMEKc&;gkZ@)HAF+kuN3f?87j ziVKZOK3L2@=ggwW61hGi;P~MM3PLwOh!xLlIdrox<1eQq53hUry@@G6N zVqj{h_EfHGkZEqHX|J#9YU%Bmz%r?AiV|ZnW6zBKMiy3CuByrXjH0XzGRz9hGRtSl iG*xj)%Sz2>sc2a?L#%w?{#pS^`4cBk@hdtqSOWm%P;emt literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/pen_paper.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/pen_paper.gif new file mode 100644 index 0000000000000000000000000000000000000000..ba562347cf8784be0d8aec404700a2edacd6ad30 GIT binary patch literal 618 zcmV-w0+szoNk%w1VG#fi0OkMy|NsB~|NsC0{{R2_{{H{{|NsB}`1$|;{QUg?{QCd< z`u_ay{`>U%`}_X;^X&is`T6gwt0?CI&~=H}+(QPO;Nalf+uPaM+47M)jEnprD}cnE*k#weFYzo}QlVmjIoeo$-_a{Ez_JnGo!g1Dl(hz?NN_ znwspA0GOJYnVFgFj{xhC0GODV_lf}PjsmxmQ{#>S=!*d8hyaa^jf{+pi;IgBtEPp8 zg#e?lB%Xe%ct9eUb^w}>0Gg1TXCazU0E#Q~82}G3Tvtmq4yY|yBpNDBs4rewW;zCsAX-{SLUOh)Q&nX< z36BUA(5%H)TNjk7dQ-lqe0toxr(hx-ifE8=> z1{~11vt$(8Lw095Ws@Fo!AwloFUSRg8e)%)3Qj!sy(o(@h`% EJ7w!p(f|Me literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/pencil-small.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/pencil-small.png new file mode 100644 index 0000000000000000000000000000000000000000..e6f2ca02bb9aa67e8cc5c214fc3803667060e97d GIT binary patch literal 309 zcmV-50m}Y~P)`LMn_X3TABzVeq(i&C>DOwXzos3==K?{X0OC3xHvya*3DMS+Tx8;57q7BVHF^ zYG$zi_U)T)$Nv4z?#jyjk^leiAld-1=C2H8Yv<^DX=`iOefaTXV;BR&C87cmrrF)U z!fW1)j{VvS&yM{4`}Y!2v4F1m%a{Lc|Nb%TCn_5M{bx|aqInO|(fH~;V`N_04XO|Ay<2G}iD7Fia8CMAjO~q5&_xCz#6katuG}qEhBAGI9mwAl-SkJ_^u|{tf~y>ZC2R$Vxp1g zf`CmHDF*5X927MI_!^(DbkbGW!1p%uQ7?;xf5ysIk2%KEW@#+ldL(;>%@wB|r`>Dn Q>ZKZ+8!FqB0u&jn0dUY{fdBvi literal 0 HcmV?d00001 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/search.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/search.png similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/search.png rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/search.png diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/tick-small.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/img/tick-small.png new file mode 100644 index 0000000000000000000000000000000000000000..a110aef9330c6e9089dfb18544d1a46d65d9fa92 GIT binary patch literal 283 zcmV+$0p$LPP)r|rbf13~o0CF{;I zeE(Mibj=Rp4EXV{=Jdj2XJrEwj6pPr&+z~M4x(cLY}2dX43E2Sv@ozT)-Z^%?!Xtu hjH5}JasvPY3;^T3N38C(J0t)A002ovPDHLkV1ipCc|`yK literal 0 HcmV?d00001 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/CalendarPopup.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/CalendarPopup.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/CalendarPopup.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/CalendarPopup.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/ajax.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/ajax.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/ajax.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/ajax.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/ajax_dynamic_content.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/ajax_dynamic_content.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/ajax_dynamic_content.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/ajax_dynamic_content.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/cingular_button.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/cingular_button.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/cingular_button.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/cingular_button.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/drupal.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/drupal.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/drupal.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/drupal.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/editabledropdown.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/editabledropdown.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/editabledropdown.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/editabledropdown.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/form-field-tooltip.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/form-field-tooltip.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/form-field-tooltip.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/form-field-tooltip.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/gmap.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/gmap.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/gmap.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/gmap.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/jquery.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/jquery.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/jquery.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/jquery.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/jquery.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/jquery.min.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/jquery.min.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/jquery.min.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/label_quantum.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/label_quantum.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/label_quantum.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/label_quantum.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/nova_button.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/nova_button.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/nova_button.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/nova_button.js diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/other_scripts.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/other_scripts.js new file mode 100644 index 00000000..e45b97f9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/other_scripts.js @@ -0,0 +1,331 @@ +//Reusable Asset Library - CSS Positioning Version (v3.3) +//Release Date: 1/26/07 + + +//begin: quick help ======================================= +var uitmpl_qhId; +var uitmpl_cookieVal; +var qhRule; +var qhCookie; + +//sets cookie value and qhId +qhCookie=document.cookie; +var pos=qhCookie.indexOf("qhId="); + +if(pos==-1){ +document.cookie="qhId=0"; +uitmpl_qhId="0"; +qhCookie=document.cookie; +pos=qhCookie.indexOf("qhId="); +} +//reads cookie if value is present and sets qhId accordingly +var start=pos+5; +var end=qhCookie.indexOf(";", start); +if (end==-1) end=qhCookie.length; +uitmpl_cookieVal=qhCookie.substring(start,end); +if(uitmpl_cookieVal!=0){ + uitmpl_qhId=1; +}else{ +uitmpl_qhId=0; +} + + +//loops through all qh divs and toggles display based on qhId +function uitmpl_qhPageInit(){ +var getTag = document.getElementsByTagName("div"); + for (i=0;i5) { +strDay = strDate.substr(0, 2); +strMonth = strDate.substr(2, 2); +strYear = strDate.substr(4); + } +} +if (strYear.length == 2) { +strYear = '20' + strYear; +} +// US style +if (strDatestyle == "US") { +strTemp = strDay; +strDay = strMonth; +strMonth = strTemp; +} +intday = parseInt(strDay, 10); +if (isNaN(intday)) { +err = 2; +return false; +} +intMonth = parseInt(strMonth, 10); +if (isNaN(intMonth)) { +for (i = 0;i<12;i++) { +if (strMonth.toUpperCase() == strMonthArray[i].toUpperCase()) { +intMonth = i+1; +strMonth = strMonthArray[i]; +i = 12; + } +} +if (isNaN(intMonth)) { +err = 3; +return false; + } +} +intYear = parseInt(strYear, 10); +if (isNaN(intYear)) { +err = 4; +return false; +} +if (intMonth>12 || intMonth<1) { +err = 5; +return false; +} +if ((intMonth == 1 || intMonth == 3 || intMonth == 5 || intMonth == 7 || intMonth == 8 || intMonth == 10 || intMonth == 12) && (intday > 31 || intday < 1)) { +err = 6; +return false; +} +if ((intMonth == 4 || intMonth == 6 || intMonth == 9 || intMonth == 11) && (intday > 30 || intday < 1)) { +err = 7; +return false; +} +if (intMonth == 2) { +if (intday < 1) { +err = 8; +return false; +} +if (LeapYear(intYear) == true) { +if (intday > 29) { +err = 9; +return false; +} +} +else { +if (intday > 28) { +err = 10; +return false; +} +} +} +//if (strDatestyle == "US") { +//datefield.value = strMonthArray[intMonth-1] + " " + intday+" " + strYear; +//} +//else { +//datefield.value = intday + " " + strMonthArray[intMonth-1] + " " + strYear; +//} +return true; +} +function LeapYear(intYear) { +if (intYear % 100 == 0) { +if (intYear % 400 == 0) { return true; } +} +else { +if ((intYear % 4) == 0) { return true; } +} +return false; +} + +//range validation +function uitmpl_errRangeVal(obj, minNum, maxNum){ +if (obj.value>=minNum&&obj.value<=maxNum||obj.value==""){ +return true; +}else{ +alert("Please input a number within the range of "+minNum+" and "+maxNum+"!"); +obj.focus(); +obj.select(); +} +} + +//end: error validation ======================================= +//begin: popup windows ======================================= +function uitmpl_popUpReg(url) { + window.open(url); +} +function uitmpl_popUpConfig(url, name, w, h, sc, rsz) { + var features = "width="+w+",height="+h+",scrollbars="+sc+",resizable="+rsz+"menubar=0,status=1"; + var newWin = window.open(url, name, features); + newWin.focus(); +//popups from nav links: +} + + +function uitmpl_contact(){ + uitmpl_popUpReg(""); +} +function uitmpl_bizDirect(){ + uitmpl_popUpReg(""); +} + +//function uitmpl_closeApp(){ +//if(window.confirm("You did NOT save your data. Do you want to close 'application name' without saving your data?")) { +//window.close(); + +function uitmpl_closeApp(name){ +if (name != "") { +var cAppName=name; +} +else { +var cAppName="the current application"; +} +if(window.confirm("You did NOT save your data. Do you want to close\n" + cAppName + " without saving your data?")) { +window.close(); +} +} +//end: popup windows ======================================= + + + + + +//Select all checkboxes on a form===================================== +function uitmpl_chkBoxSelect(formName,btnOn,btnOff) { + + document.getElementById(btnOff).style.display = "block"; + document.getElementById(btnOn).style.display = "none"; + + var f = formName; + for (i=0; i < f.elements.length; i++) { + if (f.elements[i].type=="checkbox") { + var e = f.elements[i]; + e.checked = true; + } + } +} + + +//Clear all checkboxes on a form====================================== +function uitmpl_chkBoxClear(formName,btnOn, btnOff) { + + document.getElementById(btnOff).style.display = "none"; + document.getElementById(btnOn).style.display = "block"; + + var f = formName; + for (i=0; i < f.elements.length; i++) { + if (f.elements[i].type=="checkbox") { + var e = f.elements[i]; + e.checked = false; + } + } +} + diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/persist_table_header.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/persist_table_header.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/persist_table_header.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/persist_table_header.js diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/projected_overlay.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/projected_overlay.js new file mode 100644 index 00000000..00ce65a1 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/projected_overlay.js @@ -0,0 +1,129 @@ +// Create an overlay on the map from a projected image... +// Author. John D. Coryat 01/2008 +// USNaviguide LLC - http://www.usnaviguide.com +// Thanks go to Mile Williams EInsert: http://econym.googlepages.com/einsert.js, Google's GOverlay Example and Bratliff's suggestion... +// Opacity code from TPhoto: http://gmaps.tommangan.us/addtphoto.html +// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// Parameters: +// imageUrl: URL of the image +// bounds: Bounds object of image destination +// addZoom: Added Zoom factor as a parameter to the imageUrl (include complete parameter, including separater like '?zoom=' +// + +function ProjectedOverlay(imageUrl, bounds, addZoom) +{ + this.url_ = imageUrl ; + this.bounds_ = bounds ; + this.addZ_ = addZoom ; // Add the zoom to the image as a parameter + + // Is this IE, if so we need to use AlphaImageLoader + + this.ie = false ; + var agent = navigator.userAgent.toLowerCase(); + if ((agent.indexOf("msie") > -1) && (agent.indexOf("opera") < 1)) + { + this.ie = true ; + } +} + +ProjectedOverlay.prototype = new GOverlay(); + +ProjectedOverlay.prototype.initialize = function(map) +{ + var div = document.createElement("div") ; + div.style.position = "absolute" ; + div.setAttribute('id',this.id) ; + map.getPane(G_MAP_MAP_PANE).appendChild(div) ; + this.map_ = map ; + this.div_ = div ; + if( this.percentOpacity ) + { + this.setOpacity(this.percentOpacity) ; + } +} + +// Remove the main DIV from the map pane + +ProjectedOverlay.prototype.remove = function() +{ + this.div_.parentNode.removeChild(this.div_); + delete(this.map) ; + delete(this.div) ; +} + +// Copy our data to a new ProjectedOverlay... + +ProjectedOverlay.prototype.copy = function() +{ + return new ProjectedOverlay(this.url_, this.bounds_, this.addZ_); +} + +// Redraw based on the current projection and zoom level... + +ProjectedOverlay.prototype.redraw = function(force) +{ + // We only need to redraw if the coordinate system has changed + if (!force) + { + return ; + } + + var c1 = this.map_.fromLatLngToDivPixel(this.bounds_.getSouthWest()); + var c2 = this.map_.fromLatLngToDivPixel(this.bounds_.getNorthEast()); + + // Now position our DIV based on the DIV coordinates of our bounds + + this.div_.style.width = Math.abs(c2.x - c1.x) + "px"; + this.div_.style.height = Math.abs(c2.y - c1.y) + "px"; + this.div_.style.left = Math.min(c2.x, c1.x) + "px"; + this.div_.style.top = Math.min(c2.y, c1.y) + "px"; + + var url = this.url_ ; + var extn = url.substring(url.length - 4, 4) ; + + if ( this.addZ_ ) + { + url += this.addZ_ + this.map_.getZoom() ; + } + + if (this.ie && extn.toLowerCase() == '.png') + { + var loader = "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url + "', sizingMethod='scale');" ; + this.div_.innerHTML = '

    ' ; + } else + { + this.div_.innerHTML = '' ; + } +} + +ProjectedOverlay.prototype.setOpacity=function(opacity) +{ + if (opacity < 0) + { + opacity = 0 ; + } + if(opacity > 100) + { + opacity = 100 ; + } + var c = opacity/100 ; + var d = document.getElementById( this.id ) ; + + if (typeof(d.style.filter) =='string') + { + d.style.filter = 'alpha(opacity:' + opacity + ')' ; + } + if (typeof(d.style.KHTMLOpacity) == 'string' ) + { + d.style.KHTMLOpacity = c ; + } + if (typeof(d.style.MozOpacity) == 'string') + { + d.style.MozOpacity = c ; + } + if (typeof(d.style.opacity) == 'string') + { + d.style.opacity = c ; + } +} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/prototype-1.6.0.3.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/prototype-1.6.0.3.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/prototype-1.6.0.3.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/prototype-1.6.0.3.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/raptor.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/raptor.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/raptor.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/raptor.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/rounded-corners.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/rounded-corners.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/rounded-corners.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/rounded-corners.js diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/script.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/script.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/script.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/script.js diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/ajax.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/ajax.js new file mode 100644 index 00000000..a727447d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/ajax.js @@ -0,0 +1,194 @@ +/* Simple AJAX Code-Kit (SACK) v1.6.1 */ +/* ©2005 Gregory Wild-Smith */ +/* www.twilightuniverse.com */ +/* Software licenced under a modified X11 licence, + see documentation or authors website for more details */ + +function sack(file) { + this.xmlhttp = null; + this.resetData = function() { + this.method = "POST"; + this.queryStringSeparator = "?"; + this.argumentSeparator = "&"; + this.URLString = ""; + this.encodeURIString = true; + this.execute = false; + this.element = null; + this.elementObj = null; + this.requestFile = file; + this.vars = new Object(); + this.responseStatus = new Array(2); + }; + + this.resetFunctions = function() { + this.onLoading = function() { }; + this.onLoaded = function() { }; + this.onInteractive = function() { }; + this.onCompletion = function() { }; + this.onError = function() { }; + this.onFail = function() { }; + }; + + this.reset = function() { + this.resetFunctions(); + this.resetData(); + }; + + this.createAJAX = function() { + try { + this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e1) { + try { + this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (e2) { + this.xmlhttp = null; + } + } + + if (! this.xmlhttp) { + if (typeof XMLHttpRequest != "undefined") { + this.xmlhttp = new XMLHttpRequest(); + } else { + this.failed = true; + } + } + }; + + this.setVar = function(name, value){ + this.vars[name] = Array(value, false); + }; + + this.encVar = function(name, value, returnvars) { + if (true == returnvars) { + return Array(encodeURIComponent(name), encodeURIComponent(value)); + } else { + this.vars[encodeURIComponent(name)] = Array(encodeURIComponent(value), true); + } + } + + this.processURLString = function(string, encode) { + encoded = encodeURIComponent(this.argumentSeparator); + regexp = new RegExp(this.argumentSeparator + "|" + encoded); + varArray = string.split(regexp); + for (i = 0; i < varArray.length; i++){ + urlVars = varArray[i].split("="); + if (true == encode){ + this.encVar(urlVars[0], urlVars[1]); + } else { + this.setVar(urlVars[0], urlVars[1]); + } + } + } + + this.createURLString = function(urlstring) { + if (this.encodeURIString && this.URLString.length) { + this.processURLString(this.URLString, true); + } + if (urlstring) { + if (this.URLString.length) { + this.URLString += this.argumentSeparator + urlstring; + } else { + this.URLString = urlstring; + } + } + + // prevents caching of URLString + this.setVar("rndval", new Date().getTime()); + + urlstringtemp = new Array(); + for (key in this.vars) { + if (false == this.vars[key][1] && true == this.encodeURIString) { + encoded = this.encVar(key, this.vars[key][0], true); + delete this.vars[key]; + this.vars[encoded[0]] = Array(encoded[1], true); + key = encoded[0]; + } + + urlstringtemp[urlstringtemp.length] = key + "=" + this.vars[key][0]; + } + if (urlstring){ + this.URLString += this.argumentSeparator + urlstringtemp.join(this.argumentSeparator); + } else { + this.URLString += urlstringtemp.join(this.argumentSeparator); + } + } + + this.runResponse = function() { + eval(this.response); + } + + this.runAJAX = function(urlstring) { + if (this.failed) { + this.onFail(); + } else { + this.createURLString(urlstring); + + if (this.element) { + this.elementObj = document.getElementById(this.element); + } + + if (this.xmlhttp) { + var self = this; + if (this.method == "GET") { + totalurlstring = this.requestFile + this.queryStringSeparator + this.URLString; + this.xmlhttp.open(this.method, totalurlstring, true); + } else { + this.xmlhttp.open(this.method, this.requestFile, true); + try { + this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") + } catch (e) { } + } + //document.myForm.action=urlstring; + //document.myForm.submit(); + this.xmlhttp.onreadystatechange = function() { + switch (self.xmlhttp.readyState) { + case 1: + self.onLoading(); + break; + case 2: + self.onLoaded(); + break; + case 3: + self.onInteractive(); + break; + case 4: + self.response = self.xmlhttp.responseText; + self.responseXML = self.xmlhttp.responseXML; + self.responseStatus[0] = self.xmlhttp.status; + self.responseStatus[1] = self.xmlhttp.statusText; + + if (self.execute) { + self.runResponse(); + } + + if (self.elementObj) { + elemNodeName = self.elementObj.nodeName; + elemNodeName.toLowerCase(); + if (elemNodeName == "input" + || elemNodeName == "select" + || elemNodeName == "option" + || elemNodeName == "textarea") { + self.elementObj.value = self.response; + } else { + self.elementObj.innerHTML = self.response; + } + } + if (self.responseStatus[0] == "200") { + self.onCompletion(); + } else { + self.onError(); + } + + self.URLString = ""; + break; + } + }; + this.xmlhttp.send(this.URLString); + + } + } + }; + + this.reset() ; + this.createAJAX(); +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/context-menu.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/context-menu.js new file mode 100644 index 00000000..70fb7096 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/context-menu.js @@ -0,0 +1,444 @@ +/************************************************************************************************************ +Context menu +Copyright (C) 2006 DTHMLGoodies.com, Alf Magne Kalleland + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Dhtmlgoodies.com., hereby disclaims all copyright interest in this script +written by Alf Magne Kalleland. + +Alf Magne Kalleland, 2006 +Owner of DHTMLgoodies.com + + +************************************************************************************************************/ + +DHTMLGoodies_menuModel = function() +{ + var menuItems; + this.menuItems = new Array(); + + +} + +/************************************************************************************************************ +* DHTML menu model class +* +* Created: October, 30th, 2006 +* @class Purpose of class: Saves menu item data +* +* +* Demos of this class: demo-menu-strip.html +* +* Update log: +* +************************************************************************************************************/ + + +/** +* @constructor +* @class Purpose of class: Organize menu items for different menu widgets. demos of menus: (Demo) +* @version 1.0 +* @author Alf Magne Kalleland(www.dhtmlgoodies.com) +*/ + + +DHTMLGoodies_menuModel.prototype = { + // {{{ addItem() + /** + * Add separator (special type of menu item) + * + * @param int id of menu item + * @param string itemText = text of menu item + * @param string itemIcon = file name of menu icon(in front of menu text. Path will be imagePath for the DHTMLSuite + file name) + * @param string url = Url of menu item + * @param int parent id of menu item + * @param String jsFunction Name of javascript function to execute. It will replace the url param. The function with this name will be called and the element triggering the action will be + * sent as argument. Name of the element which triggered the menu action may also be sent as a second argument. That depends on the widget. The context menu is an example where + * the element triggering the context menu is sent as second argument to this function. + * + * @public + */ + addItem : function(id,itemText,itemIcon,url,parentId,jsFunction) + { + this.menuItems[id] = new Array(); + this.menuItems[id]['id'] = id; + this.menuItems[id]['itemText'] = itemText; + this.menuItems[id]['itemIcon'] = itemIcon; + this.menuItems[id]['url'] = url; + this.menuItems[id]['parentId'] = parentId; + this.menuItems[id]['separator'] = false; + this.menuItems[id]['jsFunction'] = jsFunction; + + } + , + // {{{ addSeparator() + /** + * Add separator (special type of menu item) + * + * @param int id of menu item + * @param int parent id of menu item + * @public + */ + addSeparator : function(id,parentId) + { + this.menuItems[id] = new Array(); + this.menuItems[id]['parentId'] = parentId; + this.menuItems[id]['separator'] = true; + } + , + // {{{ init() + /** + * Initilizes the menu model. This method should be called when all items has been added to the model. + * + * + * @public + */ + init : function() + { + this.__getDepths(); + + } + // }}} + , + // {{{ __getDepths() + /** + * Create variable for the depth of each menu item. + * + * + * @private + */ + getItems : function() + { + return this.menuItems; + } + + , + // {{{ __getDepths() + /** + * Create variable for the depth of each menu item. + * + * + * @private + */ + __getDepths : function() + { + for(var no in this.menuItems){ + this.menuItems[no]['depth'] = 1; + if(this.menuItems[no]['parentId']){ + this.menuItems[no]['depth'] = this.menuItems[this.menuItems[no]['parentId']]['depth']+1; + } + } + } + , + // {{{ __hasSubs() + /** + * Does a menu item have sub elements ? + * + * + * @private + */ + // }}} + __hasSubs : function(id) + { + for(var no in this.menuItems){ // Looping through menu items + if(this.menuItems[no]['parentId']==id)return true; + } + return false; + } + + +} + + + +var referenceToDHTMLSuiteContextMenu; + + +DHTMLGoodies_contextMenu = function() +{ + var menuModels; + var menuItems; + var menuObject; // Reference to context menu div + var layoutCSS; + var menuUls; // Array of
      elements + var width; // Width of context menu + var srcElement; // Reference to the element which triggered the context menu, i.e. the element which caused the context menu to be displayed. + var indexCurrentlyDisplayedMenuModel; // Index of currently displayed menu model. + var imagePath; + + this.menuModels = new Array(); + this.menuObject = false; + this.menuUls = new Array(); + this.width = 100; + this.srcElement = false; + this.indexCurrentlyDisplayedMenuModel = false; + this.imagePath = imgFolder+'tree/'; + +} + +DHTMLGoodies_contextMenu.prototype = +{ + + setWidth : function(newWidth) + { + this.width = newWidth; + } + // }}} + , + // {{{ setLayoutCss() + /** + * Add menu items + * + * @param String cssFileName Name of css file + * + * @public + */ + setLayoutCss : function(cssFileName) + { + this.layoutCSS = cssFileName; + } + // }}} + , + // {{{ attachToElement() + /** + * Add menu items + * + * @param Object HTML Element = Reference to html element + * @param String elementId = String id of element(optional). An alternative to HTML Element + * + * @public + */ + attachToElement : function(element,elementId,menuModel) + { + window.refToThisContextMenu = this; + if(!element && elementId)element = document.getElementById(elementId); + if(!element.id){ + element.id = 'context_menu' + Math.random(); + element.id = element.id.replace('.',''); + } + this.menuModels[element.id] = menuModel; + element.oncontextmenu = this.__displayContextMenu; + //element.onmousedown = function() { window.refToThisContextMenu.__setReference(window.refToThisContextMenu); }; + document.documentElement.onclick = this.__hideContextMenu; + + } + // }}} + , + // {{{ __setReference() + /** + * Creates a reference to current context menu object. (Note: This method should be deprecated as only one context menu object is needed) + * + * @param Object context menu object = Reference to context menu object + * + * @private + */ + __setReference : function(obj) + { + referenceToDHTMLSuiteContextMenu = obj; + } + , + // {{{ __displayContextMenu() + /** + * Displays the context menu + * + * @param Event e + * + * @private + */ + __displayContextMenu : function(e) + { + if(document.all)e = event; + var ref = referenceToDHTMLSuiteContextMenu; + ref.srcElement = ref.getSrcElement(e); + + if(!ref.indexCurrentlyDisplayedMenuModel || ref.indexCurrentlyDisplayedMenuModel!=this.id){ + if(ref.indexCurrentlyDisplayedMenuModel){ + ref.menuObject.innerHTML = ''; + }else{ + ref.__createDivs(); + } + ref.menuItems = ref.menuModels[this.id].getItems(); + ref.__createMenuItems(); + } + ref.indexCurrentlyDisplayedMenuModel=this.id; + + ref.menuObject.style.left = (e.clientX + Math.max(document.body.scrollLeft,document.documentElement.scrollLeft)) + 'px'; + ref.menuObject.style.top = (e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop)) + 'px'; + ref.menuObject.style.display='block'; + return false; + + } + // }}} + , + // {{{ __displayContextMenu() + /** + * Add menu items + * + * @param Event e + * + * @private + */ + __hideContextMenu : function() + { + var ref = referenceToDHTMLSuiteContextMenu; + if(ref.menuObject)ref.menuObject.style.display = 'none'; + + + } + // }}} + , + // {{{ __createDivs() + /** + * Creates general divs for the menu + * + * + * @private + */ + __createDivs : function() + { + this.menuObject = document.createElement('DIV'); + this.menuObject.className = 'DHTMLSuite_contextMenu'; + this.menuObject.style.backgroundImage = 'url(\'' + this.imagePath + 'context-menu-gradient.gif' + '\')'; + this.menuObject.style.backgroundRepeat = 'repeat-y'; + if(this.width)this.menuObject.style.width = this.width + 'px'; + document.body.appendChild(this.menuObject); + } + // }}} + , + + // {{{ __mouseOver() + /** + * Display mouse over effect when moving the mouse over a menu item + * + * + * @private + */ + __mouseOver : function() + { + this.className = 'DHTMLSuite_item_mouseover'; + if(!document.all){ + this.style.backgroundPosition = 'left center'; + } + + } + // }}} + , + // {{{ __mouseOut() + /** + * Remove mouse over effect when moving the mouse away from a menu item + * + * + * @private + */ + __mouseOut : function() + { + this.className = ''; + if(!document.all){ + this.style.backgroundPosition = '1px center'; + } + } + // }}} + , + // {{{ __createMenuItems() + /** + * Create menu items + * + * + * @private + */ + __evalUrl : function() + { + var js = this.getAttribute('jsFunction'); + if(!js)js = this.jsFunction; + if(js)eval(js); + + } + // }}} + , + // {{{ __createMenuItems() + /** + * Create menu items + * + * + * @private + */ + __createMenuItems : function() + { + window.refToContextMenu = this; // Reference to menu strip object + this.menuUls = new Array(); + for(var no in this.menuItems){ // Looping through menu items + if(!this.menuUls[0]){ // Create main ul element + this.menuUls[0] = document.createElement('UL'); + this.menuObject.appendChild(this.menuUls[0]); + } + + if(this.menuItems[no]['depth']==1){ + + if(this.menuItems[no]['separator']){ + var li = document.createElement('DIV'); + li.className = 'DHTMLSuite_contextMenu_separator'; + }else{ + var li = document.createElement('LI'); + if(this.menuItems[no]['jsFunction']){ + this.menuItems[no]['url'] = this.menuItems[no]['jsFunction'] + '(this,referenceToDHTMLSuiteContextMenu.srcElement)'; + } + if(this.menuItems[no]['itemIcon']){ + li.style.backgroundImage = 'url(\'' + this.menuItems[no]['itemIcon'] + '\')'; + if(!document.all)li.style.backgroundPosition = '1px center'; + + } + + if(this.menuItems[no]['url']){ + var url = this.menuItems[no]['url'] + ''; + var tmpUrl = url + ''; + li.setAttribute('jsFunction',url); + li.jsFunction = url; + li.onclick = this.__evalUrl; + + } + + li.innerHTML = '' + this.menuItems[no]['itemText'] + ''; + li.onmouseover = this.__mouseOver; + li.onmouseout = this.__mouseOut; + } + this.menuUls[0].appendChild(li); + } + } + } + + , + + // {{{ getSrcElement() + /** + * + * Returns a reference to the element which triggered an event. + * @param Event e = Event object + * + * + * @private + */ + getSrcElement : function(e) + { + var el; + // Dropped on which element + if (e.target) el = e.target; + else if (e.srcElement) el = e.srcElement; + if (el.nodeType == 3) // defeat Safari bug + el = el.parentNode; + return el; + } + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/drag-drop-folder-tree.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/drag-drop-folder-tree.js new file mode 100644 index 00000000..165306f2 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/js/tree/drag-drop-folder-tree.js @@ -0,0 +1,1059 @@ + /************************************************************************************************************ +Drag and drop folder tree +Copyright (C) 2006 DTHMLGoodies.com, Alf Magne Kalleland + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Dhtmlgoodies.com., hereby disclaims all copyright interest in this script +written by Alf Magne Kalleland. + +Alf Magne Kalleland, 2006 +Owner of DHTMLgoodies.com + + +************************************************************************************************************/ + + var JSTreeObj; + var treeUlCounter = 0; + var nodeId = 1; + + /* Constructor */ + function JSDragDropTree() + { + var idOfTree; + var imageFolder; + var folderImage; + var plusImage; + var minusImage; + var maximumDepth; + var dragNode_source; + var dragNode_parent; + var dragNode_sourceNextSib; + var dragNode_noSiblings; + var ajaxObjects; + + var dragNode_destination; + var floatingContainer; + var dragDropTimer; + var dropTargetIndicator; + var insertAsSub; + var indicator_offsetX; + var indicator_offsetX_sub; + var indicator_offsetY; + + this.imageFolder = imgFolder+'tree/'; + this.folderImage = 'dhtmlgoodies_folder.gif'; + this.plusImage = 'dhtmlgoodies_plus.gif'; + this.minusImage = 'dhtmlgoodies_minus.gif'; + this.maximumDepth = 6; + var messageMaximumDepthReached; + var messageNoRightsOnFolder; + var filePathRenameItem; + var filePathDeleteItem; + var additionalRenameRequestParameters = {}; + var additionalDeleteRequestParameters = {}; + + var renameAllowed; + var deleteAllowed; + var addAllowed; + var currentlyActiveItem; + var contextMenu; + var currentItemToEdit; // Reference to item currently being edited(example: renamed) + var selectedItem; // ADDED BY FARHAN + var helpObj; + + this.contextMenu = false; + this.floatingContainer = document.createElement('UL'); + this.floatingContainer.style.position = 'absolute'; + this.floatingContainer.style.display='none'; + this.floatingContainer.id = 'floatingContainer'; + this.insertAsSub = false; + document.body.appendChild(this.floatingContainer); + this.dragDropTimer = -1; + this.dragNode_noSiblings = false; + this.currentItemToEdit = false; + + if(document.all){ + this.indicator_offsetX = 2; // Offset position of small black lines indicating where nodes would be dropped. + this.indicator_offsetX_sub = 4; + this.indicator_offsetY = 2; + }else{ + this.indicator_offsetX = 1; // Offset position of small black lines indicating where nodes would be dropped. + this.indicator_offsetX_sub = 3; + this.indicator_offsetY = 2; + } + if(navigator.userAgent.indexOf('Opera')>=0){ + this.indicator_offsetX = 2; // Offset position of small black lines indicating where nodes would be dropped. + this.indicator_offsetX_sub = 3; + this.indicator_offsetY = -7; + } + + this.messageMaximumDepthReached = ''; // Use '' if you don't want to display a message + this.messageNoRightsOnFolder = 'You do not have access to this folder'; + + this.renameAllowed = true; + this.deleteAllowed = true; + this.addAllowed = true; + this.currentlyActiveItem = false; + this.filePathRenameItem = 'folderTree_updateItem.php'; + this.filePathDeleteItem = 'tree'; + this.ajaxObjects = new Array(); + this.helpObj = false; + + this.RENAME_STATE_BEGIN = 1; + this.RENAME_STATE_CANCELED = 2; + this.RENAME_STATE_REQUEST_SENDED = 3; + this.renameState = null; + } + + + /* JSDragDropTree class */ + JSDragDropTree.prototype = { + // {{{ addEvent() + /** + * + * This function adds an event listener to an element on the page. + * + * @param Object whichObject = Reference to HTML element(Which object to assigne the event) + * @param String eventType = Which type of event, example "mousemove" or "mouseup" + * @param functionName = Name of function to execute. + * + * @public + */ + addEvent : function(whichObject,eventType,functionName) + { + if(whichObject.attachEvent){ + whichObject['e'+eventType+functionName] = functionName; + whichObject[eventType+functionName] = function(){whichObject['e'+eventType+functionName]( window.event );} + whichObject.attachEvent( 'on'+eventType, whichObject[eventType+functionName] ); + } else + whichObject.addEventListener(eventType,functionName,false); + } + // }}} + , + // {{{ removeEvent() + /** + * + * This function removes an event listener from an element on the page. + * + * @param Object whichObject = Reference to HTML element(Which object to assigne the event) + * @param String eventType = Which type of event, example "mousemove" or "mouseup" + * @param functionName = Name of function to execute. + * + * @public + */ + removeEvent : function(whichObject,eventType,functionName) + { + if(whichObject.detachEvent){ + whichObject.detachEvent('on'+eventType, whichObject[eventType+functionName]); + whichObject[eventType+functionName] = null; + } else + whichObject.removeEventListener(eventType,functionName,false); + } + , + Get_Cookie : function(name) { + var start = document.cookie.indexOf(name+"="); + var len = start+name.length+1; + if ((!start) && (name != document.cookie.substring(0,name.length))) return null; + if (start == -1) return null; + var end = document.cookie.indexOf(";",len); + if (end == -1) end = document.cookie.length; + return unescape(document.cookie.substring(len,end)); + } + , + // This function has been slightly modified + Set_Cookie : function(name,value,expires,path,domain,secure) { + expires = expires * 60*60*24*1000; + var today = new Date(); + var expires_date = new Date( today.getTime() + (expires) ); + var cookieString = name + "=" +escape(value) + + ( (expires) ? ";expires=" + expires_date.toGMTString() : "") + + ( (path) ? ";path=" + path : "") + + ( (domain) ? ";domain=" + domain : "") + + ( (secure) ? ";secure" : ""); + document.cookie = cookieString; + } + , + setFileNameRename : function(newFileName) + { + this.filePathRenameItem = newFileName; + } + , + setFileNameDelete : function(newFileName) + { + this.filePathDeleteItem = newFileName; + } + , + setAdditionalRenameRequestParameters : function(requestParameters) + { + this.additionalRenameRequestParameters = requestParameters; + } + , + setAdditionalDeleteRequestParameters : function(requestParameters) + { + this.additionalDeleteRequestParameters = requestParameters; + } + ,setRenameAllowed : function(renameAllowed) + { + this.renameAllowed = renameAllowed; + } + , + setDeleteAllowed : function(deleteAllowed) + { + this.deleteAllowed = deleteAllowed; + } + , + setAddAllowed : function(addAllowed) + { + this.addAllowed = addAllowed; + } + ,setMaximumDepth : function(maxDepth) + { + this.maximumDepth = maxDepth; + } + ,setMessageMaximumDepthReached : function(newMessage) + { + this.messageMaximumDepthReached = newMessage; + } + , + setImageFolder : function(path) + { + this.imageFolder = path; + } + , + setFolderImage : function(imagePath) + { + this.folderImage = imagePath; + } + , + setPlusImage : function(imagePath) + { + this.plusImage = imagePath; + } + , + setMinusImage : function(imagePath) + { + this.minusImage = imagePath; + } + , + setTreeId : function(idOfTree) + { + this.idOfTree = idOfTree; + } + , + expandAll : function() + { + var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI'); + for(var no=0;no0 && subItems[0].style.display!='block'){ + JSTreeObj.showHideNode(false,menuItems[no].id); + } + } + } + , + collapseAll : function() + { + var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI'); + for(var no=0;no0 && subItems[0].style.display=='block'){ + JSTreeObj.showHideNode(false,menuItems[no].id); + } + } + JSTreeObj.showHideNode(false,menuItems[0].id); + } + , + /* + Find top pos of a tree node + */ + getTopPos : function(obj){ + var top = obj.offsetTop/1; + while((obj = obj.offsetParent) != null){ + if(obj.tagName!='HTML')top += obj.offsetTop; + } + if(document.all)top = top/1 + 13; else top = top/1 + 4; + return top; + } + , + /* + Find left pos of a tree node + */ + getLeftPos : function(obj){ + var left = obj.offsetLeft/1 + 1; + while((obj = obj.offsetParent) != null){ + if(obj.tagName!='HTML')left += obj.offsetLeft; + } + + if(document.all)left = left/1 - 2; + return left; + } + + , + showHideNode : function(e,inputId) + { + if(inputId){ + if(!document.getElementById(inputId))return; + thisNode = document.getElementById(inputId).getElementsByTagName('IMG')[0]; + }else { + thisNode = this; + if(this.tagName=='A')thisNode = this.parentNode.getElementsByTagName('IMG')[0]; + + } + if(thisNode.style.visibility=='hidden')return; + var parentNode = thisNode.parentNode; + inputId = parentNode.id.replace(/[^0-9]/g,''); + if(thisNode.src.indexOf(JSTreeObj.plusImage)>=0){ + thisNode.src = thisNode.src.replace(JSTreeObj.plusImage,JSTreeObj.minusImage); + var ul = parentNode.getElementsByTagName('UL')[0]; + ul.style.display='block'; + if(!initExpandedNodes)initExpandedNodes = ','; + if(initExpandedNodes.indexOf(',' + inputId + ',')<0) initExpandedNodes = initExpandedNodes + inputId + ','; + }else{ + thisNode.src = thisNode.src.replace(JSTreeObj.minusImage,JSTreeObj.plusImage); + parentNode.getElementsByTagName('UL')[0].style.display='none'; + initExpandedNodes = initExpandedNodes.replace(',' + inputId,''); + } + JSTreeObj.Set_Cookie('dhtmlgoodies_expandedNodes',initExpandedNodes,500); + return false; + } + , + /*expand only the selected node*/ + showSelectedNode : function(selectedItemId) + { + var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI'); // Get an array of all menu items + + var selectedNode ; + for(var no=0;no0 && subItems[0].style.display!='block'){ + JSTreeObj.showHideNode(false,selectedNode.id); + } + selectedNode = selectedNode.parentNode; + } + }while (selectedNode && selectedNode.id.replace(/[^0-9]/gi,'') != '0'); + return false; + } + , + isDeleteAllowed : function(selectedItemId) + { + var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI'); // Get an array of all menu items + + var selectedNode ; + for(var no=0;no0){ + if(JSTreeObj.dragNode_sourceNextSib){ + JSTreeObj.dragNode_parent.insertBefore(JSTreeObj.dragNode_source,JSTreeObj.dragNode_sourceNextSib); + }else{ + JSTreeObj.dragNode_parent.appendChild(JSTreeObj.dragNode_source); + } + } + + JSTreeObj.dragNode_source = this.parentNode; + JSTreeObj.dragNode_parent = this.parentNode.parentNode; + JSTreeObj.dragNode_sourceNextSib = false; + + + if(JSTreeObj.dragNode_source.nextSibling)JSTreeObj.dragNode_sourceNextSib = JSTreeObj.dragNode_source.nextSibling; + JSTreeObj.dragNode_destination = false; + JSTreeObj.dragDropTimer = 0; + JSTreeObj.timerDrag(); + return false; + } + , + timerDrag : function() + { + if(this.dragDropTimer>=0 && this.dragDropTimer<10){ + this.dragDropTimer = this.dragDropTimer + 1; + setTimeout('JSTreeObj.timerDrag()',20); + return; + } + if(this.dragDropTimer==10) + { + JSTreeObj.floatingContainer.style.display='block'; + JSTreeObj.floatingContainer.appendChild(JSTreeObj.dragNode_source); + } + } + , + moveDragableNodes : function(e) + { + if(JSTreeObj.dragDropTimer<10)return; + if(document.all)e = event; + dragDrop_x = e.clientX/1 + 5 + document.body.scrollLeft; + dragDrop_y = e.clientY/1 + 5 + document.documentElement.scrollTop; + + JSTreeObj.floatingContainer.style.left = dragDrop_x + 'px'; + JSTreeObj.floatingContainer.style.top = dragDrop_y + 'px'; + + var thisObj = this; + if(thisObj.tagName=='A' || thisObj.tagName=='IMG')thisObj = thisObj.parentNode; + + JSTreeObj.dragNode_noSiblings = false; + var tmpVar = thisObj.getAttribute('noSiblings'); + if(!tmpVar)tmpVar = thisObj.noSiblings; + if(tmpVar=='true')JSTreeObj.dragNode_noSiblings=true; + + if(thisObj && thisObj.id) + { + JSTreeObj.dragNode_destination = thisObj; + var img = thisObj.getElementsByTagName('IMG')[1]; + var tmpObj= JSTreeObj.dropTargetIndicator; + tmpObj.style.display='block'; + + var eventSourceObj = this; + if(JSTreeObj.dragNode_noSiblings && eventSourceObj.tagName=='IMG')eventSourceObj = eventSourceObj.nextSibling; + + var tmpImg = tmpObj.getElementsByTagName('IMG')[0]; + if(this.tagName=='A' || JSTreeObj.dragNode_noSiblings){ + tmpImg.src = tmpImg.src.replace('ind1','ind2'); + JSTreeObj.insertAsSub = true; + tmpObj.style.left = (JSTreeObj.getLeftPos(eventSourceObj) + JSTreeObj.indicator_offsetX_sub) + 'px'; + }else{ + tmpImg.src = tmpImg.src.replace('ind2','ind1'); + JSTreeObj.insertAsSub = false; + tmpObj.style.left = (JSTreeObj.getLeftPos(eventSourceObj) + JSTreeObj.indicator_offsetX) + 'px'; + } + + tmpObj.style.top = (JSTreeObj.getTopPos(thisObj) + JSTreeObj.indicator_offsetY) - document.getElementById("scrollableTable").scrollTop + 'px' ; + + + } + var divHeight = document.getElementById("scrollableTable").style.height; + divHeight = divHeight.substring(0, divHeight.indexOf("px")); + if (dragDrop_y - JSTreeObj.getTopPos(document.getElementById("scrollableTable"))< 50) + document.getElementById("scrollableTable").scrollTop = document.getElementById("scrollableTable").scrollTop - 5; + else if (dragDrop_y - JSTreeObj.getTopPos(document.getElementById("scrollableTable")) > divHeight - 50) + document.getElementById("scrollableTable").scrollTop = document.getElementById("scrollableTable").scrollTop + 5; + + return false; + + } + , + dropDragableNodes:function() + { + if(JSTreeObj.dragDropTimer<10){ + JSTreeObj.dragDropTimer = -1; + return; + } + var showMessage = false; + var message = ''; + if(JSTreeObj.dragNode_destination){ // Check depth + var countUp = JSTreeObj.dragDropCountLevels(JSTreeObj.dragNode_destination,'up'); + var countDown = JSTreeObj.dragDropCountLevels(JSTreeObj.dragNode_source,'down'); + var countLevels = countUp/1 + countDown/1 + (JSTreeObj.insertAsSub?1:0); + + if(countLevels>JSTreeObj.maximumDepth){ + JSTreeObj.dragNode_destination = false; + showMessage = true; // Used later down in this function + message = JSTreeObj.messageMaximumDepthReachedl + } + } + if (JSTreeObj.dragNode_destination && JSTreeObj.dragNode_destination.getAttribute('noDrop') == 'true'){ + JSTreeObj.dragNode_destination = false; + showMessage = true; // Used later down in this function + message = JSTreeObj.messageNoRightsOnFolder; + } + + + if(JSTreeObj.dragNode_destination){ + + if(JSTreeObj.insertAsSub){ + var uls = JSTreeObj.dragNode_destination.getElementsByTagName('UL'); + if(uls.length>0){ + ul = uls[0]; + ul.style.display='block'; + + var lis = ul.getElementsByTagName('LI'); + + if(lis.length>0){ // Sub elements exists - drop dragable node before the first one + ul.insertBefore(JSTreeObj.dragNode_source,lis[0]); + }else { // No sub exists - use the appendChild method - This line should not be executed unless there's something wrong in the HTML, i.e empty
        + ul.appendChild(JSTreeObj.dragNode_source); + } + }else{ + var ul = document.createElement('UL'); + ul.style.display='block'; + JSTreeObj.dragNode_destination.appendChild(ul); + ul.appendChild(JSTreeObj.dragNode_source); + } + var img = JSTreeObj.dragNode_destination.getElementsByTagName('IMG')[0]; + img.style.visibility='visible'; + img.src = img.src.replace(JSTreeObj.plusImage,JSTreeObj.minusImage); + + + }else{ + if(JSTreeObj.dragNode_destination.nextSibling){ + var nextSib = JSTreeObj.dragNode_destination.nextSibling; + nextSib.parentNode.insertBefore(JSTreeObj.dragNode_source,nextSib); + }else{ + JSTreeObj.dragNode_destination.parentNode.appendChild(JSTreeObj.dragNode_source); + } + } + /* Clear parent object */ + var tmpObj = JSTreeObj.dragNode_parent; + var lis = tmpObj.getElementsByTagName('LI'); + if(lis.length==0){ + var img = tmpObj.parentNode.getElementsByTagName('IMG')[0]; + img.style.visibility='hidden'; // Hide [+],[-] icon + tmpObj.parentNode.removeChild(tmpObj); + } + + }else{ + // Putting the item back to it's original location + + if(JSTreeObj.dragNode_sourceNextSib){ + JSTreeObj.dragNode_parent.insertBefore(JSTreeObj.dragNode_source,JSTreeObj.dragNode_sourceNextSib); + }else{ + JSTreeObj.dragNode_parent.appendChild(JSTreeObj.dragNode_source); + } + + } + JSTreeObj.dropTargetIndicator.style.display='none'; + JSTreeObj.dragDropTimer = -1; + if(showMessage && message){ alert(message); return;} + //save tree structure + saveMyTree_byForm(); + } + , + createDropIndicator : function() + { + this.dropTargetIndicator = document.createElement('DIV'); + this.dropTargetIndicator.style.position = 'absolute'; + this.dropTargetIndicator.style.display='none'; + var img = document.createElement('IMG'); + img.src = this.imageFolder + 'dragDrop_ind1.gif'; + img.id = 'dragDropIndicatorImage'; + this.dropTargetIndicator.appendChild(img); + document.body.appendChild(this.dropTargetIndicator); + + } + , + dragDropCountLevels : function(obj,direction,stopAtObject){ + var countLevels = 0; + if(direction=='up'){ + while(obj.parentNode && obj.parentNode!=stopAtObject){ + obj = obj.parentNode; + if(obj.tagName=='UL')countLevels = countLevels/1 +1; + } + return countLevels; + } + + if(direction=='down'){ + var subObjects = obj.getElementsByTagName('LI'); + for(var no=0;no0){ + var li = lis[0]; + while(li){ + if(li.id){ + if(saveString.length>0)saveString = saveString + ','; + var numericID = li.id.replace(/[^0-9]/gi,''); + if(numericID.length==0)numericID='A'; + var numericParentID = li.parentNode.parentNode.id.replace(/[^0-9]/gi,''); + if(numericID!='0'){ + saveString = saveString + numericID; + saveString = saveString + '-'; + + + if(li.parentNode.id!=this.idOfTree)saveString = saveString + numericParentID; else saveString = saveString + '0'; + } + var ul = li.getElementsByTagName('UL'); + if(ul.length>0){ + saveString = this.getNodeOrders(ul[0],saveString); + } + } + li = li.nextSibling; + } + } + + if(initObj.id == this.idOfTree){ + return saveString; + + } + return saveString; + } + ,highlightItem : function(inputObj,e) + { + if(JSTreeObj.currentlyActiveItem)JSTreeObj.currentlyActiveItem.className = ''; + this.className = 'highlightedNodeItem'; + JSTreeObj.currentlyActiveItem = this; + } + ,clickItem : function(inputObj,e) + { + if(JSTreeObj.currentlyActiveItem) JSTreeObj.currentlyActiveItem.className = ''; + this.className = 'highlightedNodeItem'; + JSTreeObj.currentlyActiveItem = this; + JSTreeObj.selectedItem = this; + }, + removeHighlight : function() + { + //if(JSTreeObj.currentlyActiveItem)JSTreeObj.currentlyActiveItem.className = ''; + //JSTreeObj.currentlyActiveItem = false; + } + , + hasSubNodes : function(obj) + { + var subs = obj.getElementsByTagName('LI'); + if(subs.length>0)return true; + return false; + } + , + deleteItem : function(obj1,obj2) + { + var message = 'Click OK to delete item ' + obj2.innerHTML; + if(this.hasSubNodes(obj2.parentNode)) message = message + ' and it\'s sub nodes'; + if(confirm(message)){ + this.__deleteItem_step2(obj2.parentNode); // Sending
      • tag to the __deleteItem_step2 method + //deleteItem(); + }else{ + return false; + } + + + } + , + addItem : function(obj1,obj2) + { + var message = 'Click OK to Add item ' + obj2.innerHTML; + return this.__addItem_step2(obj2.parentNode); // Sending
      • tag to the __addItem_step2 method + } + , + createMenuReport : function(obj1,obj2) + { + JSTreeObj.selectedItem = obj2; + createReport(); + } + , + runMenuReport : function(obj1,obj2) + { + JSTreeObj.selectedItem = obj2; + runReport(); + + } + , + editMenuReport : function(obj1,obj2) + { + JSTreeObj.selectedItem = obj2; + editReport(); + } + , + deleteMenuReport : function(obj1,obj2) + { + JSTreeObj.selectedItem = obj2; + if (confirm("Do you want to delete this report?")){ + deleteReport(); + } + + } + , + __refreshDisplay : function(obj) + { + if(this.hasSubNodes(obj))return; + + var img = obj.getElementsByTagName('IMG')[0]; + img.style.visibility = 'hidden'; + } + , + __deleteItem_step2 : function(obj) + { + + var saveString = obj.id.replace(/[^0-9]/gi,''); + + var lis = obj.getElementsByTagName('LI'); + for(var no=0;no0){ + inputObj.nextSibling.innerHTML = inputObj.value; + // Send changes to the server. + if (JSTreeObj.renameState != JSTreeObj.RENAME_STATE_BEGIN) { + return; + } + JSTreeObj.renameState = JSTreeObj.RENAME_STATE_REQUEST_SENDED; + var ajaxIndex = JSTreeObj.ajaxObjects.length; + JSTreeObj.ajaxObjects[ajaxIndex] = new sack(); + JSTreeObj.ajaxObjects[ajaxIndex].method = "GET"; + JSTreeObj.ajaxObjects[ajaxIndex].setVar("renameId", inputObj.parentNode.id.replace(/[^0-9]/gi,'')); + JSTreeObj.ajaxObjects[ajaxIndex].setVar("newName", inputObj.value); + JSTreeObj.__addAdditionalRequestParameters(JSTreeObj.ajaxObjects[ajaxIndex], JSTreeObj.additionalRenameRequestParameters); + JSTreeObj.ajaxObjects[ajaxIndex].requestFile = JSTreeObj.filePathRenameItem; // Specifying which file to get + JSTreeObj.ajaxObjects[ajaxIndex].onCompletion = function() { JSTreeObj.__renameComplete(ajaxIndex); } ; // Specify function that will be executed after file has been found + JSTreeObj.ajaxObjects[ajaxIndex].runAJAX(); // Execute AJAX function + + document.all.renameId.value=inputObj.parentNode.id.replace(/[^0-9]/gi,''); + document.all.newName.value= inputObj.value; + renameMyTree_byForm(); + + } + } + , + __cancelRename : function(e,inputObj) + { + JSTreeObj.renameState = JSTreeObj.RENAME_STATE_CANCELD; + if(!inputObj && this)inputObj = this; + inputObj.value = JSTreeObj.helpObj.innerHTML; + inputObj.nextSibling.innerHTML = JSTreeObj.helpObj.innerHTML; + inputObj.style.display = 'none'; + inputObj.nextSibling.style.visibility = 'visible'; + } + , + __renameCheckKeyCode : function(e) + { + if(document.all)e = event; + if(e.keyCode==13){ // Enter pressed + JSTreeObj.__saveTextBoxChanges(false,this); + } + if(e.keyCode==27){ // ESC pressed + JSTreeObj.__cancelRename(false,this); + } + } + , + __createTextBox : function(obj) + { + var textBox = document.createElement('INPUT'); + textBox.className = 'folderTreeTextBox'; + textBox.value = obj.innerHTML; + obj.parentNode.insertBefore(textBox,obj); + textBox.id = 'textBox' + obj.parentNode.id.replace(/[^0-9]/gi,''); + textBox.onblur = this.__saveTextBoxChanges; + textBox.onkeydown = this.__renameCheckKeyCode; + textBox.style.height="16px"; + this.__renameEnableTextBox(obj); + } + , + __renameEnableTextBox : function(obj) + { + JSTreeObj.renameState = JSTreeObj.RENAME_STATE_BEGIN; + obj.style.visibility = 'hidden'; + obj.previousSibling.value = obj.innerHTML; + obj.previousSibling.style.display = 'inline'; + obj.previousSibling.select(); + } + , + renameItem : function(obj1,obj2) + { + currentItemToEdit = obj2.parentNode; // Reference to the
      • tag. + if(!obj2.previousSibling || obj2.previousSibling.tagName.toLowerCase()!='input'){ + this.__createTextBox(obj2); + }else{ + this.__renameEnableTextBox(obj2); + } + this.helpObj.innerHTML = obj2.innerHTML; + + } + , + initTree : function(selectedItemId) + { + JSTreeObj = this; + JSTreeObj.createDropIndicator(); + document.documentElement.onselectstart = JSTreeObj.cancelSelectionEvent; + document.documentElement.ondragstart = JSTreeObj.cancelEvent; + document.documentElement.onmousedown = JSTreeObj.removeHighlight; + + /* Creating help object for storage of values */ + this.helpObj = document.createElement('DIV'); + this.helpObj.style.display = 'none'; + document.body.appendChild(this.helpObj); + /* Create context menu */ + if(this.deleteAllowed || this.renameAllowed || this.addAllowed){ + try{ + /* Creating menu model for the context menu, i.e. the datasource */ + var menuModel = new DHTMLGoodies_menuModel(); + if(this.deleteAllowed)menuModel.addItem(1,'Delete Folder','','',false,'JSTreeObj.deleteItem'); + if(this.deleteAllowed)menuModel.addItem(2,'Rename Folder','','',false,'JSTreeObj.renameItem'); + if(this.addAllowed)menuModel.addItem(3,'New Folder','','',false,'JSTreeObj.addItem'); + menuModel.addItem(4,'Create Report','','',false,'JSTreeObj.createMenuReport'); + menuModel.init(); + + /*For Reports*/ + var menuReportNoRights = new DHTMLGoodies_menuModel(); + menuReportNoRights.addItem(3,'Run','','',false,'JSTreeObj.runItem'); + menuReportNoRights.init(); + + var menuReportWithRights = new DHTMLGoodies_menuModel(); + menuReportWithRights.addItem(1,'Run','','',false,'JSTreeObj.runMenuReport'); + menuReportWithRights.addItem(2,'Edit','','',false,'JSTreeObj.editMenuReport'); + menuReportWithRights.addItem(3,'Delete','','',false,'JSTreeObj.deleteMenuReport'); + menuReportWithRights.init(); + + + var menuModelRenameOnly = new DHTMLGoodies_menuModel(); + if(this.renameAllowed)menuModelRenameOnly.addItem(3,'Rename Folder','','',false,'JSTreeObj.renameItem'); + menuModelRenameOnly.init(); + + var menuModelDeleteOnly = new DHTMLGoodies_menuModel(); + if(this.deleteAllowed)menuModelDeleteOnly.addItem(4,'Delete Folder','','',false,'JSTreeObj.deleteItem'); + menuModelDeleteOnly.init(); + + var menuModelAddOnly = new DHTMLGoodies_menuModel(); + menuModelAddOnly.addItem(1,'New Folder','','',false,'JSTreeObj.addItem'); + menuModelAddOnly.init(); + + window.refToDragDropTree = this; + + this.contextMenu = new DHTMLGoodies_contextMenu(); + this.contextMenu.setWidth(120); + referenceToDHTMLSuiteContextMenu = this.contextMenu; + }catch(e){ + + } + } + + + var nodeId = 0; + var dhtmlgoodies_tree = document.getElementById(this.idOfTree); + var menuItems = dhtmlgoodies_tree.getElementsByTagName('LI'); // Get an array of all menu items + for(var no=0;no/, + FUNC_REGEXP: /(\([^)]*\))?$/, + DOT_REGEXP: /\./g, + APOS_REGEXP: /'/g, + BRACKET_REGEXP: /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/, + COL_CLASS_PREFIX: 'ui-grid-col', + events: { + GRID_SCROLL: 'uiGridScroll', + COLUMN_MENU_SHOWN: 'uiGridColMenuShown', + ITEM_DRAGGING: 'uiGridItemDragStart', // For any item being dragged + COLUMN_HEADER_CLICK: 'uiGridColumnHeaderClick' + }, + // copied from http://www.lsauer.com/2011/08/javascript-keymap-keycodes-in-json.html + keymap: { + TAB: 9, + STRG: 17, + CAPSLOCK: 20, + CTRL: 17, + CTRLRIGHT: 18, + CTRLR: 18, + SHIFT: 16, + RETURN: 13, + ENTER: 13, + BACKSPACE: 8, + BCKSP: 8, + ALT: 18, + ALTR: 17, + ALTRIGHT: 17, + SPACE: 32, + WIN: 91, + MAC: 91, + FN: null, + PG_UP: 33, + PG_DOWN: 34, + UP: 38, + DOWN: 40, + LEFT: 37, + RIGHT: 39, + ESC: 27, + DEL: 46, + F1: 112, + F2: 113, + F3: 114, + F4: 115, + F5: 116, + F6: 117, + F7: 118, + F8: 119, + F9: 120, + F10: 121, + F11: 122, + F12: 123 + }, + ASC: 'asc', + DESC: 'desc', + filter: { + STARTS_WITH: 2, + ENDS_WITH: 4, + EXACT: 8, + CONTAINS: 16, + GREATER_THAN: 32, + GREATER_THAN_OR_EQUAL: 64, + LESS_THAN: 128, + LESS_THAN_OR_EQUAL: 256, + NOT_EQUAL: 512, + SELECT: 'select', + INPUT: 'input' + }, + + aggregationTypes: { + sum: 2, + count: 4, + avg: 8, + min: 16, + max: 32 + }, + + // TODO(c0bra): Create full list of these somehow. NOTE: do any allow a space before or after them? + CURRENCY_SYMBOLS: ['ƒ', '$', '£', '$', '¤', 'Â¥', '៛', '₩', '₱', '฿', '₫'], + + scrollDirection: { + UP: 'up', + DOWN: 'down', + LEFT: 'left', + RIGHT: 'right', + NONE: 'none' + + }, + + dataChange: { + ALL: 'all', + EDIT: 'edit', + ROW: 'row', + COLUMN: 'column', + OPTIONS: 'options' + }, + scrollbars: { + NEVER: 0, + ALWAYS: 1 + //WHEN_NEEDED: 2 + } + }); + +})(); +angular.module('ui.grid').directive('uiGridCell', ['$compile', '$parse', 'gridUtil', 'uiGridConstants', function ($compile, $parse, gridUtil, uiGridConstants) { + var uiGridCell = { + priority: 0, + scope: false, + require: '?^uiGrid', + compile: function() { + return { + pre: function($scope, $elm, $attrs, uiGridCtrl) { + function compileTemplate() { + var compiledElementFn = $scope.col.compiledElementFn; + + compiledElementFn($scope, function(clonedElement, scope) { + $elm.append(clonedElement); + }); + } + + // If the grid controller is present, use it to get the compiled cell template function + if (uiGridCtrl && $scope.col.compiledElementFn) { + compileTemplate(); + } + // No controller, compile the element manually (for unit tests) + else { + if ( uiGridCtrl && !$scope.col.compiledElementFn ){ + // gridUtil.logError('Render has been called before precompile. Please log a ui-grid issue'); + + $scope.col.getCompiledElementFn() + .then(function (compiledElementFn) { + compiledElementFn($scope, function(clonedElement, scope) { + $elm.append(clonedElement); + }); + }); + } + else { + var html = $scope.col.cellTemplate + .replace(uiGridConstants.MODEL_COL_FIELD, 'row.entity.' + gridUtil.preEval($scope.col.field)) + .replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)'); + + var cellElement = $compile(html)($scope); + $elm.append(cellElement); + } + } + }, + post: function($scope, $elm, $attrs, uiGridCtrl) { + var initColClass = $scope.col.getColClass(false); + $elm.addClass(initColClass); + + var classAdded; + var updateClass = function( grid ){ + var contents = $elm; + if ( classAdded ){ + contents.removeClass( classAdded ); + classAdded = null; + } + + if (angular.isFunction($scope.col.cellClass)) { + classAdded = $scope.col.cellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex); + } + else { + classAdded = $scope.col.cellClass; + } + contents.addClass(classAdded); + }; + + if ($scope.col.cellClass) { + updateClass(); + } + + // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs + var dataChangeDereg = $scope.grid.registerDataChangeCallback( updateClass, [uiGridConstants.dataChange.COLUMN, uiGridConstants.dataChange.EDIT]); + + // watch the col and row to see if they change - which would indicate that we've scrolled or sorted or otherwise + // changed the row/col that this cell relates to, and we need to re-evaluate cell classes and maybe other things + var cellChangeFunction = function( n, o ){ + if ( n !== o ) { + if ( classAdded || $scope.col.cellClass ){ + updateClass(); + } + + // See if the column's internal class has changed + var newColClass = $scope.col.getColClass(false); + if (newColClass !== initColClass) { + $elm.removeClass(initColClass); + $elm.addClass(newColClass); + initColClass = newColClass; + } + } + }; + + // TODO(c0bra): Turn this into a deep array watch +/* shouldn't be needed any more given track by col.name + var colWatchDereg = $scope.$watch( 'col', cellChangeFunction ); +*/ + var rowWatchDereg = $scope.$watch( 'row', cellChangeFunction ); + + + var deregisterFunction = function() { + dataChangeDereg(); +// colWatchDereg(); + rowWatchDereg(); + }; + + $scope.$on( '$destroy', deregisterFunction ); + $elm.on( '$destroy', deregisterFunction ); + } + }; + } + }; + + return uiGridCell; +}]); + + +(function(){ + +angular.module('ui.grid') +.service('uiGridColumnMenuService', [ 'i18nService', 'uiGridConstants', 'gridUtil', +function ( i18nService, uiGridConstants, gridUtil ) { +/** + * @ngdoc service + * @name ui.grid.service:uiGridColumnMenuService + * + * @description Services for working with column menus, factored out + * to make the code easier to understand + */ + + var service = { + /** + * @ngdoc method + * @methodOf ui.grid.service:uiGridColumnMenuService + * @name initialize + * @description Sets defaults, puts a reference to the $scope on + * the uiGridController + * @param {$scope} $scope the $scope from the uiGridColumnMenu + * @param {controller} uiGridCtrl the uiGridController for the grid + * we're on + * + */ + initialize: function( $scope, uiGridCtrl ){ + $scope.grid = uiGridCtrl.grid; + + // Store a reference to this link/controller in the main uiGrid controller + // to allow showMenu later + uiGridCtrl.columnMenuScope = $scope; + + // Save whether we're shown or not so the columns can check + $scope.menuShown = false; + }, + + + /** + * @ngdoc method + * @methodOf ui.grid.service:uiGridColumnMenuService + * @name setColMenuItemWatch + * @description Setup a watch on $scope.col.menuItems, and update + * menuItems based on this. $scope.col needs to be set by the column + * before calling the menu. + * @param {$scope} $scope the $scope from the uiGridColumnMenu + * @param {controller} uiGridCtrl the uiGridController for the grid + * we're on + * + */ + setColMenuItemWatch: function ( $scope ){ + var deregFunction = $scope.$watch('col.menuItems', function (n, o) { + if (typeof(n) !== 'undefined' && n && angular.isArray(n)) { + n.forEach(function (item) { + if (typeof(item.context) === 'undefined' || !item.context) { + item.context = {}; + } + item.context.col = $scope.col; + }); + + $scope.menuItems = $scope.defaultMenuItems.concat(n); + } + else { + $scope.menuItems = $scope.defaultMenuItems; + } + }); + + $scope.$on( '$destroy', deregFunction ); + }, + + + /** + * @ngdoc boolean + * @name enableSorting + * @propertyOf ui.grid.class:GridOptions.columnDef + * @description (optional) True by default. When enabled, this setting adds sort + * widgets to the column header, allowing sorting of the data in the individual column. + */ + /** + * @ngdoc method + * @methodOf ui.grid.service:uiGridColumnMenuService + * @name sortable + * @description determines whether this column is sortable + * @param {$scope} $scope the $scope from the uiGridColumnMenu + * + */ + sortable: function( $scope ) { + if ( $scope.grid.options.enableSorting && typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.enableSorting) { + return true; + } + else { + return false; + } + }, + + /** + * @ngdoc method + * @methodOf ui.grid.service:uiGridColumnMenuService + * @name isActiveSort + * @description determines whether the requested sort direction is current active, to + * allow highlighting in the menu + * @param {$scope} $scope the $scope from the uiGridColumnMenu + * @param {string} direction the direction that we'd have selected for us to be active + * + */ + isActiveSort: function( $scope, direction ){ + return (typeof($scope.col) !== 'undefined' && typeof($scope.col.sort) !== 'undefined' && + typeof($scope.col.sort.direction) !== 'undefined' && $scope.col.sort.direction === direction); + + }, + + /** + * @ngdoc method + * @methodOf ui.grid.service:uiGridColumnMenuService + * @name suppressRemoveSort + * @description determines whether we should suppress the removeSort option + * @param {$scope} $scope the $scope from the uiGridColumnMenu + * + */ + suppressRemoveSort: function( $scope ) { + if ($scope.col && $scope.col.suppressRemoveSort) { + return true; + } + else { + return false; + } + }, + + + /** + * @ngdoc boolean + * @name enableHiding + * @propertyOf ui.grid.class:GridOptions.columnDef + * @description (optional) True by default. When set to false, this setting prevents a user from hiding the column + * using the column menu or the grid menu. + */ + /** + * @ngdoc method + * @methodOf ui.grid.service:uiGridColumnMenuService + * @name hideable + * @description determines whether a column can be hidden, by checking the enableHiding columnDef option + * @param {$scope} $scope the $scope from the uiGridColumnMenu + * + */ + hideable: function( $scope ) { + if (typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.colDef && $scope.col.colDef.enableHiding === false ) { + return false; + } + else { + return true; + } + }, + + + /** + * @ngdoc method + * @methodOf ui.grid.service:uiGridColumnMenuService + * @name getDefaultMenuItems + * @description returns the default menu items for a column menu + * @param {$scope} $scope the $scope from the uiGridColumnMenu + * + */ + getDefaultMenuItems: function( $scope ){ + return [ + { + title: i18nService.getSafeText('sort.ascending'), + icon: 'ui-grid-icon-sort-alt-up', + action: function($event) { + $event.stopPropagation(); + $scope.sortColumn($event, uiGridConstants.ASC); + }, + shown: function () { + return service.sortable( $scope ); + }, + active: function() { + return service.isActiveSort( $scope, uiGridConstants.ASC); + } + }, + { + title: i18nService.getSafeText('sort.descending'), + icon: 'ui-grid-icon-sort-alt-down', + action: function($event) { + $event.stopPropagation(); + $scope.sortColumn($event, uiGridConstants.DESC); + }, + shown: function() { + return service.sortable( $scope ); + }, + active: function() { + return service.isActiveSort( $scope, uiGridConstants.DESC); + } + }, + { + title: i18nService.getSafeText('sort.remove'), + icon: 'ui-grid-icon-cancel', + action: function ($event) { + $event.stopPropagation(); + $scope.unsortColumn(); + }, + shown: function() { + return service.sortable( $scope ) && + typeof($scope.col) !== 'undefined' && (typeof($scope.col.sort) !== 'undefined' && + typeof($scope.col.sort.direction) !== 'undefined') && $scope.col.sort.direction !== null && + !service.suppressRemoveSort( $scope ); + } + }, + { + title: i18nService.getSafeText('column.hide'), + icon: 'ui-grid-icon-cancel', + shown: function() { + return service.hideable( $scope ); + }, + action: function ($event) { + $event.stopPropagation(); + $scope.hideColumn(); + } + }, + { + title: i18nService.getSafeText('columnMenu.close'), + screenReaderOnly: true, + shown: function(){ + return true; + }, + action: function($event){ + $event.stopPropagation(); + } + } + ]; + }, + + + /** + * @ngdoc method + * @methodOf ui.grid.service:uiGridColumnMenuService + * @name getColumnElementPosition + * @description gets the position information needed to place the column + * menu below the column header + * @param {$scope} $scope the $scope from the uiGridColumnMenu + * @param {GridCol} column the column we want to position below + * @param {element} $columnElement the column element we want to position below + * @returns {hash} containing left, top, offset, height, width + * + */ + getColumnElementPosition: function( $scope, column, $columnElement ){ + var positionData = {}; + positionData.left = $columnElement[0].offsetLeft; + positionData.top = $columnElement[0].offsetTop; + positionData.parentLeft = $columnElement[0].offsetParent.offsetLeft; + + // Get the grid scrollLeft + positionData.offset = 0; + if (column.grid.options.offsetLeft) { + positionData.offset = column.grid.options.offsetLeft; + } + + positionData.height = gridUtil.elementHeight($columnElement, true); + positionData.width = gridUtil.elementWidth($columnElement, true); + + return positionData; + }, + + + /** + * @ngdoc method + * @methodOf ui.grid.service:uiGridColumnMenuService + * @name repositionMenu + * @description Reposition the menu below the new column. If the menu has no child nodes + * (i.e. it's not currently visible) then we guess it's width at 100, we'll be called again + * later to fix it + * @param {$scope} $scope the $scope from the uiGridColumnMenu + * @param {GridCol} column the column we want to position below + * @param {hash} positionData a hash containing left, top, offset, height, width + * @param {element} $elm the column menu element that we want to reposition + * @param {element} $columnElement the column element that we want to reposition underneath + * + */ + repositionMenu: function( $scope, column, positionData, $elm, $columnElement ) { + var menu = $elm[0].querySelectorAll('.ui-grid-menu'); + var containerId = column.renderContainer ? column.renderContainer : 'body'; + var renderContainer = column.grid.renderContainers[containerId]; + + // It's possible that the render container of the column we're attaching to is + // offset from the grid (i.e. pinned containers), we need to get the difference in the offsetLeft + // between the render container and the grid + var renderContainerElm = gridUtil.closestElm($columnElement, '.ui-grid-render-container'); + var renderContainerOffset = renderContainerElm.getBoundingClientRect().left - $scope.grid.element[0].getBoundingClientRect().left; + + var containerScrollLeft = renderContainerElm.querySelectorAll('.ui-grid-viewport')[0].scrollLeft; + + // default value the last width for _this_ column, otherwise last width for _any_ column, otherwise default to 170 + var myWidth = column.lastMenuWidth ? column.lastMenuWidth : ( $scope.lastMenuWidth ? $scope.lastMenuWidth : 170); + var paddingRight = column.lastMenuPaddingRight ? column.lastMenuPaddingRight : ( $scope.lastMenuPaddingRight ? $scope.lastMenuPaddingRight : 10); + + if ( menu.length !== 0 ){ + var mid = menu[0].querySelectorAll('.ui-grid-menu-mid'); + if ( mid.length !== 0 && !angular.element(mid).hasClass('ng-hide') ) { + myWidth = gridUtil.elementWidth(menu, true); + $scope.lastMenuWidth = myWidth; + column.lastMenuWidth = myWidth; + + // TODO(c0bra): use padding-left/padding-right based on document direction (ltr/rtl), place menu on proper side + // Get the column menu right padding + paddingRight = parseInt(gridUtil.getStyles(angular.element(menu)[0])['paddingRight'], 10); + $scope.lastMenuPaddingRight = paddingRight; + column.lastMenuPaddingRight = paddingRight; + } + } + + var left = positionData.left + renderContainerOffset - containerScrollLeft + positionData.parentLeft + positionData.width - myWidth + paddingRight; + if (left < positionData.offset){ + left = positionData.offset; + } + + $elm.css('left', left + 'px'); + $elm.css('top', (positionData.top + positionData.height) + 'px'); + } + + }; + + return service; +}]) + + +.directive('uiGridColumnMenu', ['$timeout', 'gridUtil', 'uiGridConstants', 'uiGridColumnMenuService', '$document', +function ($timeout, gridUtil, uiGridConstants, uiGridColumnMenuService, $document) { +/** + * @ngdoc directive + * @name ui.grid.directive:uiGridColumnMenu + * @description Provides the column menu framework, leverages uiGridMenu underneath + * + */ + + var uiGridColumnMenu = { + priority: 0, + scope: true, + require: '^uiGrid', + templateUrl: 'ui-grid/uiGridColumnMenu', + replace: true, + link: function ($scope, $elm, $attrs, uiGridCtrl) { + var self = this; + + uiGridColumnMenuService.initialize( $scope, uiGridCtrl ); + + $scope.defaultMenuItems = uiGridColumnMenuService.getDefaultMenuItems( $scope ); + + // Set the menu items for use with the column menu. The user can later add additional items via the watch + $scope.menuItems = $scope.defaultMenuItems; + uiGridColumnMenuService.setColMenuItemWatch( $scope ); + + + /** + * @ngdoc method + * @methodOf ui.grid.directive:uiGridColumnMenu + * @name showMenu + * @description Shows the column menu. If the menu is already displayed it + * calls the menu to ask it to hide (it will animate), then it repositions the menu + * to the right place whilst hidden (it will make an assumption on menu width), + * then it asks the menu to show (it will animate), then it repositions the menu again + * once we can calculate it's size. + * @param {GridCol} column the column we want to position below + * @param {element} $columnElement the column element we want to position below + */ + $scope.showMenu = function(column, $columnElement, event) { + // Swap to this column + $scope.col = column; + + // Get the position information for the column element + var colElementPosition = uiGridColumnMenuService.getColumnElementPosition( $scope, column, $columnElement ); + + if ($scope.menuShown) { + // we want to hide, then reposition, then show, but we want to wait for animations + // we set a variable, and then rely on the menu-hidden event to call the reposition and show + $scope.colElement = $columnElement; + $scope.colElementPosition = colElementPosition; + $scope.hideThenShow = true; + + $scope.$broadcast('hide-menu', { originalEvent: event }); + } else { + self.shown = $scope.menuShown = true; + uiGridColumnMenuService.repositionMenu( $scope, column, colElementPosition, $elm, $columnElement ); + + $scope.colElement = $columnElement; + $scope.colElementPosition = colElementPosition; + $scope.$broadcast('show-menu', { originalEvent: event }); + } + }; + + + /** + * @ngdoc method + * @methodOf ui.grid.directive:uiGridColumnMenu + * @name hideMenu + * @description Hides the column menu. + * @param {boolean} broadcastTrigger true if we were triggered by a broadcast + * from the menu itself - in which case don't broadcast again as we'll get + * an infinite loop + */ + $scope.hideMenu = function( broadcastTrigger ) { + $scope.menuShown = false; + if ( !broadcastTrigger ){ + $scope.$broadcast('hide-menu'); + } + }; + + + $scope.$on('menu-hidden', function() { + if ( $scope.hideThenShow ){ + delete $scope.hideThenShow; + + uiGridColumnMenuService.repositionMenu( $scope, $scope.col, $scope.colElementPosition, $elm, $scope.colElement ); + $scope.$broadcast('show-menu'); + + $scope.menuShown = true; + } else { + $scope.hideMenu( true ); + + if ($scope.col) { + //Focus on the menu button + gridUtil.focus.bySelector($document, '.ui-grid-header-cell.' + $scope.col.getColClass()+ ' .ui-grid-column-menu-button', $scope.col.grid, false); + } + } + }); + + $scope.$on('menu-shown', function() { + $timeout( function() { + uiGridColumnMenuService.repositionMenu( $scope, $scope.col, $scope.colElementPosition, $elm, $scope.colElement ); + delete $scope.colElementPosition; + delete $scope.columnElement; + }, 200); + }); + + + /* Column methods */ + $scope.sortColumn = function (event, dir) { + event.stopPropagation(); + + $scope.grid.sortColumn($scope.col, dir, true) + .then(function () { + $scope.grid.refresh(); + $scope.hideMenu(); + }); + }; + + $scope.unsortColumn = function () { + $scope.col.unsort(); + + $scope.grid.refresh(); + $scope.hideMenu(); + }; + + //Since we are hiding this column the default hide action will fail so we need to focus somewhere else. + var setFocusOnHideColumn = function(){ + $timeout(function(){ + // Get the UID of the first + var focusToGridMenu = function(){ + return gridUtil.focus.byId('grid-menu', $scope.grid); + }; + + var thisIndex; + $scope.grid.columns.some(function(element, index){ + if (angular.equals(element, $scope.col)) { + thisIndex = index; + return true; + } + }); + + var previousVisibleCol; + // Try and find the next lower or nearest column to focus on + $scope.grid.columns.some(function(element, index){ + if (!element.visible){ + return false; + } // This columns index is below the current column index + else if ( index < thisIndex){ + previousVisibleCol = element; + } // This elements index is above this column index and we haven't found one that is lower + else if ( index > thisIndex && !previousVisibleCol) { + // This is the next best thing + previousVisibleCol = element; + // We've found one so use it. + return true; + } // We've reached an element with an index above this column and the previousVisibleCol variable has been set + else if (index > thisIndex && previousVisibleCol) { + // We are done. + return true; + } + }); + // If found then focus on it + if (previousVisibleCol){ + var colClass = previousVisibleCol.getColClass(); + gridUtil.focus.bySelector($document, '.ui-grid-header-cell.' + colClass+ ' .ui-grid-header-cell-primary-focus', true).then(angular.noop, function(reason){ + if (reason !== 'canceled'){ // If this is canceled then don't perform the action + //The fallback action is to focus on the grid menu + return focusToGridMenu(); + } + }); + } else { + // Fallback action to focus on the grid menu + focusToGridMenu(); + } + }); + }; + + $scope.hideColumn = function () { + $scope.col.colDef.visible = false; + $scope.col.visible = false; + + $scope.grid.queueGridRefresh(); + $scope.hideMenu(); + $scope.grid.api.core.notifyDataChange( uiGridConstants.dataChange.COLUMN ); + $scope.grid.api.core.raise.columnVisibilityChanged( $scope.col ); + + // We are hiding so the default action of focusing on the button that opened this menu will fail. + setFocusOnHideColumn(); + }; + }, + + + + controller: ['$scope', function ($scope) { + var self = this; + + $scope.$watch('menuItems', function (n, o) { + self.menuItems = n; + }); + }] + }; + + return uiGridColumnMenu; + +}]); + +})(); + +(function(){ + 'use strict'; + + angular.module('ui.grid').directive('uiGridFilter', ['$compile', '$templateCache', 'i18nService', 'gridUtil', function ($compile, $templateCache, i18nService, gridUtil) { + + return { + compile: function() { + return { + pre: function ($scope, $elm, $attrs, controllers) { + $scope.col.updateFilters = function( filterable ){ + $elm.children().remove(); + if ( filterable ){ + var template = $scope.col.filterHeaderTemplate; + + $elm.append($compile(template)($scope)); + } + }; + + $scope.$on( '$destroy', function() { + delete $scope.col.updateFilters; + }); + }, + post: function ($scope, $elm, $attrs, controllers){ + $scope.aria = i18nService.getSafeText('headerCell.aria'); + $scope.removeFilter = function(colFilter, index){ + colFilter.term = null; + //Set the focus to the filter input after the action disables the button + gridUtil.focus.bySelector($elm, '.ui-grid-filter-input-' + index); + }; + } + }; + } + }; + }]); +})(); + +(function () { + 'use strict'; + + angular.module('ui.grid').directive('uiGridFooterCell', ['$timeout', 'gridUtil', 'uiGridConstants', '$compile', + function ($timeout, gridUtil, uiGridConstants, $compile) { + var uiGridFooterCell = { + priority: 0, + scope: { + col: '=', + row: '=', + renderIndex: '=' + }, + replace: true, + require: '^uiGrid', + compile: function compile(tElement, tAttrs, transclude) { + return { + pre: function ($scope, $elm, $attrs, uiGridCtrl) { + var cellFooter = $compile($scope.col.footerCellTemplate)($scope); + $elm.append(cellFooter); + }, + post: function ($scope, $elm, $attrs, uiGridCtrl) { + //$elm.addClass($scope.col.getColClass(false)); + $scope.grid = uiGridCtrl.grid; + + var initColClass = $scope.col.getColClass(false); + $elm.addClass(initColClass); + + // apply any footerCellClass + var classAdded; + var updateClass = function( grid ){ + var contents = $elm; + if ( classAdded ){ + contents.removeClass( classAdded ); + classAdded = null; + } + + if (angular.isFunction($scope.col.footerCellClass)) { + classAdded = $scope.col.footerCellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex); + } + else { + classAdded = $scope.col.footerCellClass; + } + contents.addClass(classAdded); + }; + + if ($scope.col.footerCellClass) { + updateClass(); + } + + $scope.col.updateAggregationValue(); + + // Watch for column changes so we can alter the col cell class properly +/* shouldn't be needed any more, given track by col.name + $scope.$watch('col', function (n, o) { + if (n !== o) { + // See if the column's internal class has changed + var newColClass = $scope.col.getColClass(false); + if (newColClass !== initColClass) { + $elm.removeClass(initColClass); + $elm.addClass(newColClass); + initColClass = newColClass; + } + } + }); +*/ + + + // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs + var dataChangeDereg = $scope.grid.registerDataChangeCallback( updateClass, [uiGridConstants.dataChange.COLUMN]); + // listen for visible rows change and update aggregation values + $scope.grid.api.core.on.rowsRendered( $scope, $scope.col.updateAggregationValue ); + $scope.grid.api.core.on.rowsRendered( $scope, updateClass ); + $scope.$on( '$destroy', dataChangeDereg ); + } + }; + } + }; + + return uiGridFooterCell; + }]); + +})(); + +(function () { + 'use strict'; + + angular.module('ui.grid').directive('uiGridFooter', ['$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', function ($templateCache, $compile, uiGridConstants, gridUtil, $timeout) { + + return { + restrict: 'EA', + replace: true, + // priority: 1000, + require: ['^uiGrid', '^uiGridRenderContainer'], + scope: true, + compile: function ($elm, $attrs) { + return { + pre: function ($scope, $elm, $attrs, controllers) { + var uiGridCtrl = controllers[0]; + var containerCtrl = controllers[1]; + + $scope.grid = uiGridCtrl.grid; + $scope.colContainer = containerCtrl.colContainer; + + containerCtrl.footer = $elm; + + var footerTemplate = $scope.grid.options.footerTemplate; + gridUtil.getTemplate(footerTemplate) + .then(function (contents) { + var template = angular.element(contents); + + var newElm = $compile(template)($scope); + $elm.append(newElm); + + if (containerCtrl) { + // Inject a reference to the footer viewport (if it exists) into the grid controller for use in the horizontal scroll handler below + var footerViewport = $elm[0].getElementsByClassName('ui-grid-footer-viewport')[0]; + + if (footerViewport) { + containerCtrl.footerViewport = footerViewport; + } + } + }); + }, + + post: function ($scope, $elm, $attrs, controllers) { + var uiGridCtrl = controllers[0]; + var containerCtrl = controllers[1]; + + // gridUtil.logDebug('ui-grid-footer link'); + + var grid = uiGridCtrl.grid; + + // Don't animate footer cells + gridUtil.disableAnimations($elm); + + containerCtrl.footer = $elm; + + var footerViewport = $elm[0].getElementsByClassName('ui-grid-footer-viewport')[0]; + if (footerViewport) { + containerCtrl.footerViewport = footerViewport; + } + } + }; + } + }; + }]); + +})(); +(function () { + 'use strict'; + + angular.module('ui.grid').directive('uiGridGridFooter', ['$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', function ($templateCache, $compile, uiGridConstants, gridUtil, $timeout) { + + return { + restrict: 'EA', + replace: true, + // priority: 1000, + require: '^uiGrid', + scope: true, + compile: function ($elm, $attrs) { + return { + pre: function ($scope, $elm, $attrs, uiGridCtrl) { + + $scope.grid = uiGridCtrl.grid; + + + + var footerTemplate = $scope.grid.options.gridFooterTemplate; + gridUtil.getTemplate(footerTemplate) + .then(function (contents) { + var template = angular.element(contents); + + var newElm = $compile(template)($scope); + $elm.append(newElm); + }); + }, + + post: function ($scope, $elm, $attrs, controllers) { + + } + }; + } + }; + }]); + +})(); +(function(){ + 'use strict'; + + angular.module('ui.grid').directive('uiGridGroupPanel', ["$compile", "uiGridConstants", "gridUtil", function($compile, uiGridConstants, gridUtil) { + var defaultTemplate = 'ui-grid/ui-grid-group-panel'; + + return { + restrict: 'EA', + replace: true, + require: '?^uiGrid', + scope: false, + compile: function($elm, $attrs) { + return { + pre: function ($scope, $elm, $attrs, uiGridCtrl) { + var groupPanelTemplate = $scope.grid.options.groupPanelTemplate || defaultTemplate; + + gridUtil.getTemplate(groupPanelTemplate) + .then(function (contents) { + var template = angular.element(contents); + + var newElm = $compile(template)($scope); + $elm.append(newElm); + }); + }, + + post: function ($scope, $elm, $attrs, uiGridCtrl) { + $elm.bind('$destroy', function() { + // scrollUnbinder(); + }); + } + }; + } + }; + }]); + +})(); +(function(){ + 'use strict'; + + angular.module('ui.grid').directive('uiGridHeaderCell', ['$compile', '$timeout', '$window', '$document', 'gridUtil', 'uiGridConstants', 'ScrollEvent', 'i18nService', + function ($compile, $timeout, $window, $document, gridUtil, uiGridConstants, ScrollEvent, i18nService) { + // Do stuff after mouse has been down this many ms on the header cell + var mousedownTimeout = 500; + var changeModeTimeout = 500; // length of time between a touch event and a mouse event being recognised again, and vice versa + + var uiGridHeaderCell = { + priority: 0, + scope: { + col: '=', + row: '=', + renderIndex: '=' + }, + require: ['^uiGrid', '^uiGridRenderContainer'], + replace: true, + compile: function() { + return { + pre: function ($scope, $elm, $attrs) { + var cellHeader = $compile($scope.col.headerCellTemplate)($scope); + $elm.append(cellHeader); + }, + + post: function ($scope, $elm, $attrs, controllers) { + var uiGridCtrl = controllers[0]; + var renderContainerCtrl = controllers[1]; + + $scope.i18n = { + headerCell: i18nService.getSafeText('headerCell'), + sort: i18nService.getSafeText('sort') + }; + $scope.getSortDirectionAriaLabel = function(){ + var col = $scope.col; + //Trying to recreate this sort of thing but it was getting messy having it in the template. + //Sort direction {{col.sort.direction == asc ? 'ascending' : ( col.sort.direction == desc ? 'descending':'none')}}. {{col.sort.priority ? {{columnPriorityText}} {{col.sort.priority}} : ''} + var sortDirectionText = col.sort.direction === uiGridConstants.ASC ? $scope.i18n.sort.ascending : ( col.sort.direction === uiGridConstants.DESC ? $scope.i18n.sort.descending : $scope.i18n.sort.none); + var label = sortDirectionText; + //Append the priority if it exists + if (col.sort.priority) { + label = label + '. ' + $scope.i18n.headerCell.priority + ' ' + col.sort.priority; + } + return label; + }; + + $scope.grid = uiGridCtrl.grid; + + $scope.renderContainer = uiGridCtrl.grid.renderContainers[renderContainerCtrl.containerId]; + + var initColClass = $scope.col.getColClass(false); + $elm.addClass(initColClass); + + // Hide the menu by default + $scope.menuShown = false; + + // Put asc and desc sort directions in scope + $scope.asc = uiGridConstants.ASC; + $scope.desc = uiGridConstants.DESC; + + // Store a reference to menu element + var $colMenu = angular.element( $elm[0].querySelectorAll('.ui-grid-header-cell-menu') ); + + var $contentsElm = angular.element( $elm[0].querySelectorAll('.ui-grid-cell-contents') ); + + + // apply any headerCellClass + var classAdded; + var previousMouseX; + + // filter watchers + var filterDeregisters = []; + + + /* + * Our basic approach here for event handlers is that we listen for a down event (mousedown or touchstart). + * Once we have a down event, we need to work out whether we have a click, a drag, or a + * hold. A click would sort the grid (if sortable). A drag would be used by moveable, so + * we ignore it. A hold would open the menu. + * + * So, on down event, we put in place handlers for move and up events, and a timer. If the + * timer expires before we see a move or up, then we have a long press and hence a column menu open. + * If the up happens before the timer, then we have a click, and we sort if the column is sortable. + * If a move happens before the timer, then we are doing column move, so we do nothing, the moveable feature + * will handle it. + * + * To deal with touch enabled devices that also have mice, we only create our handlers when + * we get the down event, and we create the corresponding handlers - if we're touchstart then + * we get touchmove and touchend, if we're mousedown then we get mousemove and mouseup. + * + * We also suppress the click action whilst this is happening - otherwise after the mouseup there + * will be a click event and that can cause the column menu to close + * + */ + + $scope.downFn = function( event ){ + event.stopPropagation(); + + if (typeof(event.originalEvent) !== 'undefined' && event.originalEvent !== undefined) { + event = event.originalEvent; + } + + // Don't show the menu if it's not the left button + if (event.button && event.button !== 0) { + return; + } + previousMouseX = event.pageX; + + $scope.mousedownStartTime = (new Date()).getTime(); + $scope.mousedownTimeout = $timeout(function() { }, mousedownTimeout); + + $scope.mousedownTimeout.then(function () { + if ( $scope.colMenu ) { + uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm, event); + } + }); + + uiGridCtrl.fireEvent(uiGridConstants.events.COLUMN_HEADER_CLICK, {event: event, columnName: $scope.col.colDef.name}); + + $scope.offAllEvents(); + if ( event.type === 'touchstart'){ + $document.on('touchend', $scope.upFn); + $document.on('touchmove', $scope.moveFn); + } else if ( event.type === 'mousedown' ){ + $document.on('mouseup', $scope.upFn); + $document.on('mousemove', $scope.moveFn); + } + }; + + $scope.upFn = function( event ){ + event.stopPropagation(); + $timeout.cancel($scope.mousedownTimeout); + $scope.offAllEvents(); + $scope.onDownEvents(event.type); + + var mousedownEndTime = (new Date()).getTime(); + var mousedownTime = mousedownEndTime - $scope.mousedownStartTime; + + if (mousedownTime > mousedownTimeout) { + // long click, handled above with mousedown + } + else { + // short click + if ( $scope.sortable ){ + $scope.handleClick(event); + } + } + }; + + $scope.moveFn = function( event ){ + // Chrome is known to fire some bogus move events. + var changeValue = event.pageX - previousMouseX; + if ( changeValue === 0 ){ return; } + + // we're a move, so do nothing and leave for column move (if enabled) to take over + $timeout.cancel($scope.mousedownTimeout); + $scope.offAllEvents(); + $scope.onDownEvents(event.type); + }; + + $scope.clickFn = function ( event ){ + event.stopPropagation(); + $contentsElm.off('click', $scope.clickFn); + }; + + + $scope.offAllEvents = function(){ + $contentsElm.off('touchstart', $scope.downFn); + $contentsElm.off('mousedown', $scope.downFn); + + $document.off('touchend', $scope.upFn); + $document.off('mouseup', $scope.upFn); + + $document.off('touchmove', $scope.moveFn); + $document.off('mousemove', $scope.moveFn); + + $contentsElm.off('click', $scope.clickFn); + }; + + $scope.onDownEvents = function( type ){ + // If there is a previous event, then wait a while before + // activating the other mode - i.e. if the last event was a touch event then + // don't enable mouse events for a wee while (500ms or so) + // Avoids problems with devices that emulate mouse events when you have touch events + + switch (type){ + case 'touchmove': + case 'touchend': + $contentsElm.on('click', $scope.clickFn); + $contentsElm.on('touchstart', $scope.downFn); + $timeout(function(){ + $contentsElm.on('mousedown', $scope.downFn); + }, changeModeTimeout); + break; + case 'mousemove': + case 'mouseup': + $contentsElm.on('click', $scope.clickFn); + $contentsElm.on('mousedown', $scope.downFn); + $timeout(function(){ + $contentsElm.on('touchstart', $scope.downFn); + }, changeModeTimeout); + break; + default: + $contentsElm.on('click', $scope.clickFn); + $contentsElm.on('touchstart', $scope.downFn); + $contentsElm.on('mousedown', $scope.downFn); + } + }; + + + var updateHeaderOptions = function( grid ){ + var contents = $elm; + if ( classAdded ){ + contents.removeClass( classAdded ); + classAdded = null; + } + + if (angular.isFunction($scope.col.headerCellClass)) { + classAdded = $scope.col.headerCellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex); + } + else { + classAdded = $scope.col.headerCellClass; + } + contents.addClass(classAdded); + + var rightMostContainer = $scope.grid.renderContainers['right'] ? $scope.grid.renderContainers['right'] : $scope.grid.renderContainers['body']; + $scope.isLastCol = ( $scope.col === rightMostContainer.visibleColumnCache[ rightMostContainer.visibleColumnCache.length - 1 ] ); + + // Figure out whether this column is sortable or not + if (uiGridCtrl.grid.options.enableSorting && $scope.col.enableSorting) { + $scope.sortable = true; + } + else { + $scope.sortable = false; + } + + // Figure out whether this column is filterable or not + var oldFilterable = $scope.filterable; + if (uiGridCtrl.grid.options.enableFiltering && $scope.col.enableFiltering) { + $scope.filterable = true; + } + else { + $scope.filterable = false; + } + + if ( oldFilterable !== $scope.filterable){ + if ( typeof($scope.col.updateFilters) !== 'undefined' ){ + $scope.col.updateFilters($scope.filterable); + } + + // if column is filterable add a filter watcher + if ($scope.filterable) { + $scope.col.filters.forEach( function(filter, i) { + filterDeregisters.push($scope.$watch('col.filters[' + i + '].term', function(n, o) { + if (n !== o) { + uiGridCtrl.grid.api.core.raise.filterChanged(); + uiGridCtrl.grid.api.core.notifyDataChange( uiGridConstants.dataChange.COLUMN ); + uiGridCtrl.grid.queueGridRefresh(); + } + })); + }); + $scope.$on('$destroy', function() { + filterDeregisters.forEach( function(filterDeregister) { + filterDeregister(); + }); + }); + } else { + filterDeregisters.forEach( function(filterDeregister) { + filterDeregister(); + }); + } + + } + + // figure out whether we support column menus + if ($scope.col.grid.options && $scope.col.grid.options.enableColumnMenus !== false && + $scope.col.colDef && $scope.col.colDef.enableColumnMenu !== false){ + $scope.colMenu = true; + } else { + $scope.colMenu = false; + } + + /** + * @ngdoc property + * @name enableColumnMenu + * @propertyOf ui.grid.class:GridOptions.columnDef + * @description if column menus are enabled, controls the column menus for this specific + * column (i.e. if gridOptions.enableColumnMenus, then you can control column menus + * using this option. If gridOptions.enableColumnMenus === false then you get no column + * menus irrespective of the value of this option ). Defaults to true. + * + */ + /** + * @ngdoc property + * @name enableColumnMenus + * @propertyOf ui.grid.class:GridOptions.columnDef + * @description Override for column menus everywhere - if set to false then you get no + * column menus. Defaults to true. + * + */ + + $scope.offAllEvents(); + + if ($scope.sortable || $scope.colMenu) { + $scope.onDownEvents(); + + $scope.$on('$destroy', function () { + $scope.offAllEvents(); + }); + } + }; + +/* + $scope.$watch('col', function (n, o) { + if (n !== o) { + // See if the column's internal class has changed + var newColClass = $scope.col.getColClass(false); + if (newColClass !== initColClass) { + $elm.removeClass(initColClass); + $elm.addClass(newColClass); + initColClass = newColClass; + } + } + }); +*/ + updateHeaderOptions(); + + // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs + var dataChangeDereg = $scope.grid.registerDataChangeCallback( updateHeaderOptions, [uiGridConstants.dataChange.COLUMN]); + + $scope.$on( '$destroy', dataChangeDereg ); + + $scope.handleClick = function(event) { + // If the shift key is being held down, add this column to the sort + var add = false; + if (event.shiftKey) { + add = true; + } + + // Sort this column then rebuild the grid's rows + uiGridCtrl.grid.sortColumn($scope.col, add) + .then(function () { + if (uiGridCtrl.columnMenuScope) { uiGridCtrl.columnMenuScope.hideMenu(); } + uiGridCtrl.grid.refresh(); + }); + }; + + + $scope.toggleMenu = function(event) { + event.stopPropagation(); + + // If the menu is already showing... + if (uiGridCtrl.columnMenuScope.menuShown) { + // ... and we're the column the menu is on... + if (uiGridCtrl.columnMenuScope.col === $scope.col) { + // ... hide it + uiGridCtrl.columnMenuScope.hideMenu(); + } + // ... and we're NOT the column the menu is on + else { + // ... move the menu to our column + uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm); + } + } + // If the menu is NOT showing + else { + // ... show it on our column + uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm); + } + }; + } + }; + } + }; + + return uiGridHeaderCell; + }]); + +})(); + +(function(){ + 'use strict'; + + angular.module('ui.grid').directive('uiGridHeader', ['$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', 'ScrollEvent', + function($templateCache, $compile, uiGridConstants, gridUtil, $timeout, ScrollEvent) { + var defaultTemplate = 'ui-grid/ui-grid-header'; + var emptyTemplate = 'ui-grid/ui-grid-no-header'; + + return { + restrict: 'EA', + // templateUrl: 'ui-grid/ui-grid-header', + replace: true, + // priority: 1000, + require: ['^uiGrid', '^uiGridRenderContainer'], + scope: true, + compile: function($elm, $attrs) { + return { + pre: function ($scope, $elm, $attrs, controllers) { + var uiGridCtrl = controllers[0]; + var containerCtrl = controllers[1]; + + $scope.grid = uiGridCtrl.grid; + $scope.colContainer = containerCtrl.colContainer; + + updateHeaderReferences(); + + var headerTemplate; + if (!$scope.grid.options.showHeader) { + headerTemplate = emptyTemplate; + } + else { + headerTemplate = ($scope.grid.options.headerTemplate) ? $scope.grid.options.headerTemplate : defaultTemplate; + } + + gridUtil.getTemplate(headerTemplate) + .then(function (contents) { + var template = angular.element(contents); + + var newElm = $compile(template)($scope); + $elm.replaceWith(newElm); + + // And update $elm to be the new element + $elm = newElm; + + updateHeaderReferences(); + + if (containerCtrl) { + // Inject a reference to the header viewport (if it exists) into the grid controller for use in the horizontal scroll handler below + var headerViewport = $elm[0].getElementsByClassName('ui-grid-header-viewport')[0]; + + + if (headerViewport) { + containerCtrl.headerViewport = headerViewport; + angular.element(headerViewport).on('scroll', scrollHandler); + $scope.$on('$destroy', function () { + angular.element(headerViewport).off('scroll', scrollHandler); + }); + } + } + + $scope.grid.queueRefresh(); + }); + + function updateHeaderReferences() { + containerCtrl.header = containerCtrl.colContainer.header = $elm; + + var headerCanvases = $elm[0].getElementsByClassName('ui-grid-header-canvas'); + + if (headerCanvases.length > 0) { + containerCtrl.headerCanvas = containerCtrl.colContainer.headerCanvas = headerCanvases[0]; + } + else { + containerCtrl.headerCanvas = null; + } + } + + function scrollHandler(evt) { + if (uiGridCtrl.grid.isScrollingHorizontally) { + return; + } + var newScrollLeft = gridUtil.normalizeScrollLeft(containerCtrl.headerViewport, uiGridCtrl.grid); + var horizScrollPercentage = containerCtrl.colContainer.scrollHorizontal(newScrollLeft); + + var scrollEvent = new ScrollEvent(uiGridCtrl.grid, null, containerCtrl.colContainer, ScrollEvent.Sources.ViewPortScroll); + scrollEvent.newScrollLeft = newScrollLeft; + if ( horizScrollPercentage > -1 ){ + scrollEvent.x = { percentage: horizScrollPercentage }; + } + + uiGridCtrl.grid.scrollContainers(null, scrollEvent); + } + }, + + post: function ($scope, $elm, $attrs, controllers) { + var uiGridCtrl = controllers[0]; + var containerCtrl = controllers[1]; + + // gridUtil.logDebug('ui-grid-header link'); + + var grid = uiGridCtrl.grid; + + // Don't animate header cells + gridUtil.disableAnimations($elm); + + function updateColumnWidths() { + // this styleBuilder always runs after the renderContainer, so we can rely on the column widths + // already being populated correctly + + var columnCache = containerCtrl.colContainer.visibleColumnCache; + + // Build the CSS + // uiGridCtrl.grid.columns.forEach(function (column) { + var ret = ''; + var canvasWidth = 0; + columnCache.forEach(function (column) { + ret = ret + column.getColClassDefinition(); + canvasWidth += column.drawnWidth; + }); + + containerCtrl.colContainer.canvasWidth = canvasWidth; + + // Return the styles back to buildStyles which pops them into the `customStyles` scope variable + return ret; + } + + containerCtrl.header = $elm; + + var headerViewport = $elm[0].getElementsByClassName('ui-grid-header-viewport')[0]; + if (headerViewport) { + containerCtrl.headerViewport = headerViewport; + } + + //todo: remove this if by injecting gridCtrl into unit tests + if (uiGridCtrl) { + uiGridCtrl.grid.registerStyleComputation({ + priority: 15, + func: updateColumnWidths + }); + } + } + }; + } + }; + }]); + +})(); + +(function(){ + +angular.module('ui.grid') +.service('uiGridGridMenuService', [ 'gridUtil', 'i18nService', 'uiGridConstants', function( gridUtil, i18nService, uiGridConstants ) { + /** + * @ngdoc service + * @name ui.grid.gridMenuService + * + * @description Methods for working with the grid menu + */ + + var service = { + /** + * @ngdoc method + * @methodOf ui.grid.gridMenuService + * @name initialize + * @description Sets up the gridMenu. Most importantly, sets our + * scope onto the grid object as grid.gridMenuScope, allowing us + * to operate when passed only the grid. Second most importantly, + * we register the 'addToGridMenu' and 'removeFromGridMenu' methods + * on the core api. + * @param {$scope} $scope the scope of this gridMenu + * @param {Grid} grid the grid to which this gridMenu is associated + */ + initialize: function( $scope, grid ){ + grid.gridMenuScope = $scope; + $scope.grid = grid; + $scope.registeredMenuItems = []; + + // not certain this is needed, but would be bad to create a memory leak + $scope.$on('$destroy', function() { + if ( $scope.grid && $scope.grid.gridMenuScope ){ + $scope.grid.gridMenuScope = null; + } + if ( $scope.grid ){ + $scope.grid = null; + } + if ( $scope.registeredMenuItems ){ + $scope.registeredMenuItems = null; + } + }); + + $scope.registeredMenuItems = []; + + /** + * @ngdoc function + * @name addToGridMenu + * @methodOf ui.grid.core.api:PublicApi + * @description add items to the grid menu. Used by features + * to add their menu items if they are enabled, can also be used by + * end users to add menu items. This method has the advantage of allowing + * remove again, which can simplify management of which items are included + * in the menu when. (Noting that in most cases the shown and active functions + * provide a better way to handle visibility of menu items) + * @param {Grid} grid the grid on which we are acting + * @param {array} items menu items in the format as described in the tutorial, with + * the added note that if you want to use remove you must also specify an `id` field, + * which is provided when you want to remove an item. The id should be unique. + * + */ + grid.api.registerMethod( 'core', 'addToGridMenu', service.addToGridMenu ); + + /** + * @ngdoc function + * @name removeFromGridMenu + * @methodOf ui.grid.core.api:PublicApi + * @description Remove an item from the grid menu based on a provided id. Assumes + * that the id is unique, removes only the last instance of that id. Does nothing if + * the specified id is not found + * @param {Grid} grid the grid on which we are acting + * @param {string} id the id we'd like to remove from the menu + * + */ + grid.api.registerMethod( 'core', 'removeFromGridMenu', service.removeFromGridMenu ); + }, + + + /** + * @ngdoc function + * @name addToGridMenu + * @propertyOf ui.grid.gridMenuService + * @description add items to the grid menu. Used by features + * to add their menu items if they are enabled, can also be used by + * end users to add menu items. This method has the advantage of allowing + * remove again, which can simplify management of which items are included + * in the menu when. (Noting that in most cases the shown and active functions + * provide a better way to handle visibility of menu items) + * @param {Grid} grid the grid on which we are acting + * @param {array} items menu items in the format as described in the tutorial, with + * the added note that if you want to use remove you must also specify an `id` field, + * which is provided when you want to remove an item. The id should be unique. + * + */ + addToGridMenu: function( grid, menuItems ) { + if ( !angular.isArray( menuItems ) ) { + gridUtil.logError( 'addToGridMenu: menuItems must be an array, and is not, not adding any items'); + } else { + if ( grid.gridMenuScope ){ + grid.gridMenuScope.registeredMenuItems = grid.gridMenuScope.registeredMenuItems ? grid.gridMenuScope.registeredMenuItems : []; + grid.gridMenuScope.registeredMenuItems = grid.gridMenuScope.registeredMenuItems.concat( menuItems ); + } else { + gridUtil.logError( 'Asked to addToGridMenu, but gridMenuScope not present. Timing issue? Please log issue with ui-grid'); + } + } + }, + + + /** + * @ngdoc function + * @name removeFromGridMenu + * @methodOf ui.grid.gridMenuService + * @description Remove an item from the grid menu based on a provided id. Assumes + * that the id is unique, removes only the last instance of that id. Does nothing if + * the specified id is not found. If there is no gridMenuScope or registeredMenuItems + * then do nothing silently - the desired result is those menu items not be present and they + * aren't. + * @param {Grid} grid the grid on which we are acting + * @param {string} id the id we'd like to remove from the menu + * + */ + removeFromGridMenu: function( grid, id ){ + var foundIndex = -1; + + if ( grid && grid.gridMenuScope ){ + grid.gridMenuScope.registeredMenuItems.forEach( function( value, index ) { + if ( value.id === id ){ + if (foundIndex > -1) { + gridUtil.logError( 'removeFromGridMenu: found multiple items with the same id, removing only the last' ); + } else { + + foundIndex = index; + } + } + }); + } + + if ( foundIndex > -1 ){ + grid.gridMenuScope.registeredMenuItems.splice( foundIndex, 1 ); + } + }, + + + /** + * @ngdoc array + * @name gridMenuCustomItems + * @propertyOf ui.grid.class:GridOptions + * @description (optional) An array of menu items that should be added to + * the gridMenu. Follow the format documented in the tutorial for column + * menu customisation. The context provided to the action function will + * include context.grid. An alternative if working with dynamic menus is to use the + * provided api - core.addToGridMenu and core.removeFromGridMenu, which handles + * some of the management of items for you. + * + */ + /** + * @ngdoc boolean + * @name gridMenuShowHideColumns + * @propertyOf ui.grid.class:GridOptions + * @description true by default, whether the grid menu should allow hide/show + * of columns + * + */ + /** + * @ngdoc method + * @methodOf ui.grid.gridMenuService + * @name getMenuItems + * @description Decides the menu items to show in the menu. This is a + * combination of: + * + * - the default menu items that are always included, + * - any menu items that have been provided through the addMenuItem api. These + * are typically added by features within the grid + * - any menu items included in grid.options.gridMenuCustomItems. These can be + * changed dynamically, as they're always recalculated whenever we show the + * menu + * @param {$scope} $scope the scope of this gridMenu, from which we can find all + * the information that we need + * @returns {array} an array of menu items that can be shown + */ + getMenuItems: function( $scope ) { + var menuItems = [ + // this is where we add any menu items we want to always include + ]; + + if ( $scope.grid.options.gridMenuCustomItems ){ + if ( !angular.isArray( $scope.grid.options.gridMenuCustomItems ) ){ + gridUtil.logError( 'gridOptions.gridMenuCustomItems must be an array, and is not'); + } else { + menuItems = menuItems.concat( $scope.grid.options.gridMenuCustomItems ); + } + } + + var clearFilters = [{ + title: i18nService.getSafeText('gridMenu.clearAllFilters'), + action: function ($event) { + $scope.grid.clearAllFilters(undefined, true, undefined); + }, + shown: function() { + return $scope.grid.options.enableFiltering; + }, + order: 100 + }]; + menuItems = menuItems.concat( clearFilters ); + + menuItems = menuItems.concat( $scope.registeredMenuItems ); + + if ( $scope.grid.options.gridMenuShowHideColumns !== false ){ + menuItems = menuItems.concat( service.showHideColumns( $scope ) ); + } + + menuItems.sort(function(a, b){ + return a.order - b.order; + }); + + return menuItems; + }, + + + /** + * @ngdoc array + * @name gridMenuTitleFilter + * @propertyOf ui.grid.class:GridOptions + * @description (optional) A function that takes a title string + * (usually the col.displayName), and converts it into a display value. The function + * must return either a string or a promise. + * + * Used for internationalization of the grid menu column names - for angular-translate + * you can pass $translate as the function, for i18nService you can pass getSafeText as the + * function + * @example + *
        +     *   gridOptions = {
        +     *     gridMenuTitleFilter: $translate
        +     *   }
        +     * 
        + */ + /** + * @ngdoc method + * @methodOf ui.grid.gridMenuService + * @name showHideColumns + * @description Adds two menu items for each of the columns in columnDefs. One + * menu item for hide, one menu item for show. Each is visible when appropriate + * (show when column is not visible, hide when column is visible). Each toggles + * the visible property on the columnDef using toggleColumnVisibility + * @param {$scope} $scope of a gridMenu, which contains a reference to the grid + */ + showHideColumns: function( $scope ){ + var showHideColumns = []; + if ( !$scope.grid.options.columnDefs || $scope.grid.options.columnDefs.length === 0 || $scope.grid.columns.length === 0 ) { + return showHideColumns; + } + + // add header for columns + showHideColumns.push({ + title: i18nService.getSafeText('gridMenu.columns'), + order: 300 + }); + + $scope.grid.options.gridMenuTitleFilter = $scope.grid.options.gridMenuTitleFilter ? $scope.grid.options.gridMenuTitleFilter : function( title ) { return title; }; + + $scope.grid.options.columnDefs.forEach( function( colDef, index ){ + if ( colDef.enableHiding !== false ){ + // add hide menu item - shows an OK icon as we only show when column is already visible + var menuItem = { + icon: 'ui-grid-icon-ok', + action: function($event) { + $event.stopPropagation(); + service.toggleColumnVisibility( this.context.gridCol ); + }, + shown: function() { + return this.context.gridCol.colDef.visible === true || this.context.gridCol.colDef.visible === undefined; + }, + context: { gridCol: $scope.grid.getColumn(colDef.name || colDef.field) }, + leaveOpen: true, + order: 301 + index * 2 + }; + service.setMenuItemTitle( menuItem, colDef, $scope.grid ); + showHideColumns.push( menuItem ); + + // add show menu item - shows no icon as we only show when column is invisible + menuItem = { + icon: 'ui-grid-icon-cancel', + action: function($event) { + $event.stopPropagation(); + service.toggleColumnVisibility( this.context.gridCol ); + }, + shown: function() { + return !(this.context.gridCol.colDef.visible === true || this.context.gridCol.colDef.visible === undefined); + }, + context: { gridCol: $scope.grid.getColumn(colDef.name || colDef.field) }, + leaveOpen: true, + order: 301 + index * 2 + 1 + }; + service.setMenuItemTitle( menuItem, colDef, $scope.grid ); + showHideColumns.push( menuItem ); + } + }); + return showHideColumns; + }, + + + /** + * @ngdoc method + * @methodOf ui.grid.gridMenuService + * @name setMenuItemTitle + * @description Handles the response from gridMenuTitleFilter, adding it directly to the menu + * item if it returns a string, otherwise waiting for the promise to resolve or reject then + * putting the result into the title + * @param {object} menuItem the menuItem we want to put the title on + * @param {object} colDef the colDef from which we can get displayName, name or field + * @param {Grid} grid the grid, from which we can get the options.gridMenuTitleFilter + * + */ + setMenuItemTitle: function( menuItem, colDef, grid ){ + var title = grid.options.gridMenuTitleFilter( colDef.displayName || gridUtil.readableColumnName(colDef.name) || colDef.field ); + + if ( typeof(title) === 'string' ){ + menuItem.title = title; + } else if ( title.then ){ + // must be a promise + menuItem.title = ""; + title.then( function( successValue ) { + menuItem.title = successValue; + }, function( errorValue ) { + menuItem.title = errorValue; + }); + } else { + gridUtil.logError('Expected gridMenuTitleFilter to return a string or a promise, it has returned neither, bad config'); + menuItem.title = 'badconfig'; + } + }, + + /** + * @ngdoc method + * @methodOf ui.grid.gridMenuService + * @name toggleColumnVisibility + * @description Toggles the visibility of an individual column. Expects to be + * provided a context that has on it a gridColumn, which is the column that + * we'll operate upon. We change the visibility, and refresh the grid as appropriate + * @param {GridCol} gridCol the column that we want to toggle + * + */ + toggleColumnVisibility: function( gridCol ) { + gridCol.colDef.visible = !( gridCol.colDef.visible === true || gridCol.colDef.visible === undefined ); + + gridCol.grid.refresh(); + gridCol.grid.api.core.notifyDataChange( uiGridConstants.dataChange.COLUMN ); + gridCol.grid.api.core.raise.columnVisibilityChanged( gridCol ); + } + }; + + return service; +}]) + + + +.directive('uiGridMenuButton', ['gridUtil', 'uiGridConstants', 'uiGridGridMenuService', 'i18nService', +function (gridUtil, uiGridConstants, uiGridGridMenuService, i18nService) { + + return { + priority: 0, + scope: true, + require: ['^uiGrid'], + templateUrl: 'ui-grid/ui-grid-menu-button', + replace: true, + + link: function ($scope, $elm, $attrs, controllers) { + var uiGridCtrl = controllers[0]; + + // For the aria label + $scope.i18n = { + aria: i18nService.getSafeText('gridMenu.aria') + }; + + uiGridGridMenuService.initialize($scope, uiGridCtrl.grid); + + $scope.shown = false; + + $scope.toggleMenu = function () { + if ( $scope.shown ){ + $scope.$broadcast('hide-menu'); + $scope.shown = false; + } else { + $scope.menuItems = uiGridGridMenuService.getMenuItems( $scope ); + $scope.$broadcast('show-menu'); + $scope.shown = true; + } + }; + + $scope.$on('menu-hidden', function() { + $scope.shown = false; + gridUtil.focus.bySelector($elm, '.ui-grid-icon-container'); + }); + } + }; + +}]); + +})(); + +(function(){ + +/** + * @ngdoc directive + * @name ui.grid.directive:uiGridMenu + * @element style + * @restrict A + * + * @description + * Allows us to interpolate expressions in ` + I am in a box. +
    + + + it('should apply the right class to the element', function () { + element(by.css('.blah')).getCssValue('border-top-width') + .then(function(c) { + expect(c).toContain('1px'); + }); + }); + + + */ + + + angular.module('ui.grid').directive('uiGridStyle', ['gridUtil', '$interpolate', function(gridUtil, $interpolate) { + return { + // restrict: 'A', + // priority: 1000, + // require: '?^uiGrid', + link: function($scope, $elm, $attrs, uiGridCtrl) { + // gridUtil.logDebug('ui-grid-style link'); + // if (uiGridCtrl === undefined) { + // gridUtil.logWarn('[ui-grid-style link] uiGridCtrl is undefined!'); + // } + + var interpolateFn = $interpolate($elm.text(), true); + + if (interpolateFn) { + $scope.$watch(interpolateFn, function(value) { + $elm.text(value); + }); + } + + // uiGridCtrl.recalcRowStyles = function() { + // var offset = (scope.options.offsetTop || 0) - (scope.options.excessRows * scope.options.rowHeight); + // var rowHeight = scope.options.rowHeight; + + // var ret = ''; + // var rowStyleCount = uiGridCtrl.minRowsToRender() + (scope.options.excessRows * 2); + // for (var i = 1; i <= rowStyleCount; i++) { + // ret = ret + ' .grid' + scope.gridId + ' .ui-grid-row:nth-child(' + i + ') { top: ' + offset + 'px; }'; + // offset = offset + rowHeight; + // } + + // scope.rowStyles = ret; + // }; + + // uiGridCtrl.styleComputions.push(uiGridCtrl.recalcRowStyles); + + } + }; + }]); + +})(); + +(function(){ + 'use strict'; + + angular.module('ui.grid').directive('uiGridViewport', ['gridUtil','ScrollEvent','uiGridConstants', '$log', + function(gridUtil, ScrollEvent, uiGridConstants, $log) { + return { + replace: true, + scope: {}, + controllerAs: 'Viewport', + templateUrl: 'ui-grid/uiGridViewport', + require: ['^uiGrid', '^uiGridRenderContainer'], + link: function($scope, $elm, $attrs, controllers) { + // gridUtil.logDebug('viewport post-link'); + + var uiGridCtrl = controllers[0]; + var containerCtrl = controllers[1]; + + $scope.containerCtrl = containerCtrl; + + var rowContainer = containerCtrl.rowContainer; + var colContainer = containerCtrl.colContainer; + + var grid = uiGridCtrl.grid; + + $scope.grid = uiGridCtrl.grid; + + // Put the containers in scope so we can get rows and columns from them + $scope.rowContainer = containerCtrl.rowContainer; + $scope.colContainer = containerCtrl.colContainer; + + // Register this viewport with its container + containerCtrl.viewport = $elm; + + + $elm.on('scroll', scrollHandler); + + var ignoreScroll = false; + + function scrollHandler(evt) { + //Leaving in this commented code in case it can someday be used + //It does improve performance, but because the horizontal scroll is normalized, + // using this code will lead to the column header getting slightly out of line with columns + // + //if (ignoreScroll && (grid.isScrollingHorizontally || grid.isScrollingHorizontally)) { + // //don't ask for scrollTop if we just set it + // ignoreScroll = false; + // return; + //} + //ignoreScroll = true; + + var newScrollTop = $elm[0].scrollTop; + var newScrollLeft = gridUtil.normalizeScrollLeft($elm, grid); + + var vertScrollPercentage = rowContainer.scrollVertical(newScrollTop); + var horizScrollPercentage = colContainer.scrollHorizontal(newScrollLeft); + + var scrollEvent = new ScrollEvent(grid, rowContainer, colContainer, ScrollEvent.Sources.ViewPortScroll); + scrollEvent.newScrollLeft = newScrollLeft; + scrollEvent.newScrollTop = newScrollTop; + if ( horizScrollPercentage > -1 ){ + scrollEvent.x = { percentage: horizScrollPercentage }; + } + + if ( vertScrollPercentage > -1 ){ + scrollEvent.y = { percentage: vertScrollPercentage }; + } + + grid.scrollContainers($scope.$parent.containerId, scrollEvent); + } + + if ($scope.$parent.bindScrollVertical) { + grid.addVerticalScrollSync($scope.$parent.containerId, syncVerticalScroll); + } + + if ($scope.$parent.bindScrollHorizontal) { + grid.addHorizontalScrollSync($scope.$parent.containerId, syncHorizontalScroll); + grid.addHorizontalScrollSync($scope.$parent.containerId + 'header', syncHorizontalHeader); + grid.addHorizontalScrollSync($scope.$parent.containerId + 'footer', syncHorizontalFooter); + } + + function syncVerticalScroll(scrollEvent){ + containerCtrl.prevScrollArgs = scrollEvent; + var newScrollTop = scrollEvent.getNewScrollTop(rowContainer,containerCtrl.viewport); + $elm[0].scrollTop = newScrollTop; + + } + + function syncHorizontalScroll(scrollEvent){ + containerCtrl.prevScrollArgs = scrollEvent; + var newScrollLeft = scrollEvent.getNewScrollLeft(colContainer, containerCtrl.viewport); + $elm[0].scrollLeft = gridUtil.denormalizeScrollLeft(containerCtrl.viewport,newScrollLeft, grid); + } + + function syncHorizontalHeader(scrollEvent){ + var newScrollLeft = scrollEvent.getNewScrollLeft(colContainer, containerCtrl.viewport); + if (containerCtrl.headerViewport) { + containerCtrl.headerViewport.scrollLeft = gridUtil.denormalizeScrollLeft(containerCtrl.viewport,newScrollLeft, grid); + } + } + + function syncHorizontalFooter(scrollEvent){ + var newScrollLeft = scrollEvent.getNewScrollLeft(colContainer, containerCtrl.viewport); + if (containerCtrl.footerViewport) { + containerCtrl.footerViewport.scrollLeft = gridUtil.denormalizeScrollLeft(containerCtrl.viewport,newScrollLeft, grid); + } + } + + + }, + controller: ['$scope', function ($scope) { + this.rowStyle = function (index) { + var rowContainer = $scope.rowContainer; + var colContainer = $scope.colContainer; + + var styles = {}; + + if (index === 0 && rowContainer.currentTopRow !== 0) { + // The row offset-top is just the height of the rows above the current top-most row, which are no longer rendered + var hiddenRowWidth = (rowContainer.currentTopRow) * rowContainer.grid.options.rowHeight; + + // return { 'margin-top': hiddenRowWidth + 'px' }; + styles['margin-top'] = hiddenRowWidth + 'px'; + } + + if (colContainer.currentFirstColumn !== 0) { + if (colContainer.grid.isRTL()) { + styles['margin-right'] = colContainer.columnOffset + 'px'; + } + else { + styles['margin-left'] = colContainer.columnOffset + 'px'; + } + } + + return styles; + }; + }] + }; + } + ]); + +})(); + +(function() { + +angular.module('ui.grid') +.directive('uiGridVisible', function uiGridVisibleAction() { + return function ($scope, $elm, $attr) { + $scope.$watch($attr.uiGridVisible, function (visible) { + // $elm.css('visibility', visible ? 'visible' : 'hidden'); + $elm[visible ? 'removeClass' : 'addClass']('ui-grid-invisible'); + }); + }; +}); + +})(); +(function () { + 'use strict'; + + angular.module('ui.grid').controller('uiGridController', ['$scope', '$element', '$attrs', 'gridUtil', '$q', 'uiGridConstants', + '$templateCache', 'gridClassFactory', '$timeout', '$parse', '$compile', + function ($scope, $elm, $attrs, gridUtil, $q, uiGridConstants, + $templateCache, gridClassFactory, $timeout, $parse, $compile) { + // gridUtil.logDebug('ui-grid controller'); + + var self = this; + + self.grid = gridClassFactory.createGrid($scope.uiGrid); + + //assign $scope.$parent if appScope not already assigned + self.grid.appScope = self.grid.appScope || $scope.$parent; + + $elm.addClass('grid' + self.grid.id); + self.grid.rtl = gridUtil.getStyles($elm[0])['direction'] === 'rtl'; + + + // angular.extend(self.grid.options, ); + + //all properties of grid are available on scope + $scope.grid = self.grid; + + if ($attrs.uiGridColumns) { + $attrs.$observe('uiGridColumns', function(value) { + self.grid.options.columnDefs = value; + self.grid.buildColumns() + .then(function(){ + self.grid.preCompileCellTemplates(); + + self.grid.refreshCanvas(true); + }); + }); + } + + + // if fastWatch is set we watch only the length and the reference, not every individual object + var deregFunctions = []; + if (self.grid.options.fastWatch) { + self.uiGrid = $scope.uiGrid; + if (angular.isString($scope.uiGrid.data)) { + deregFunctions.push( $scope.$parent.$watch($scope.uiGrid.data, dataWatchFunction) ); + deregFunctions.push( $scope.$parent.$watch(function() { + if ( self.grid.appScope[$scope.uiGrid.data] ){ + return self.grid.appScope[$scope.uiGrid.data].length; + } else { + return undefined; + } + }, dataWatchFunction) ); + } else { + deregFunctions.push( $scope.$parent.$watch(function() { return $scope.uiGrid.data; }, dataWatchFunction) ); + deregFunctions.push( $scope.$parent.$watch(function() { return $scope.uiGrid.data.length; }, dataWatchFunction) ); + } + deregFunctions.push( $scope.$parent.$watch(function() { return $scope.uiGrid.columnDefs; }, columnDefsWatchFunction) ); + deregFunctions.push( $scope.$parent.$watch(function() { return $scope.uiGrid.columnDefs.length; }, columnDefsWatchFunction) ); + } else { + if (angular.isString($scope.uiGrid.data)) { + deregFunctions.push( $scope.$parent.$watchCollection($scope.uiGrid.data, dataWatchFunction) ); + } else { + deregFunctions.push( $scope.$parent.$watchCollection(function() { return $scope.uiGrid.data; }, dataWatchFunction) ); + } + deregFunctions.push( $scope.$parent.$watchCollection(function() { return $scope.uiGrid.columnDefs; }, columnDefsWatchFunction) ); + } + + + function columnDefsWatchFunction(n, o) { + if (n && n !== o) { + self.grid.options.columnDefs = n; + self.grid.buildColumns({ orderByColumnDefs: true }) + .then(function(){ + + self.grid.preCompileCellTemplates(); + + self.grid.callDataChangeCallbacks(uiGridConstants.dataChange.COLUMN); + }); + } + } + + function dataWatchFunction(newData) { + // gridUtil.logDebug('dataWatch fired'); + var promises = []; + + if ( self.grid.options.fastWatch ){ + if (angular.isString($scope.uiGrid.data)) { + newData = self.grid.appScope[$scope.uiGrid.data]; + } else { + newData = $scope.uiGrid.data; + } + } + + if (newData) { + // columns length is greater than the number of row header columns, which don't count because they're created automatically + var hasColumns = self.grid.columns.length > (self.grid.rowHeaderColumns ? self.grid.rowHeaderColumns.length : 0); + + if ( + // If we have no columns + !hasColumns && + // ... and we don't have a ui-grid-columns attribute, which would define columns for us + !$attrs.uiGridColumns && + // ... and we have no pre-defined columns + self.grid.options.columnDefs.length === 0 && + // ... but we DO have data + newData.length > 0 + ) { + // ... then build the column definitions from the data that we have + self.grid.buildColumnDefsFromData(newData); + } + + // If we haven't built columns before and either have some columns defined or some data defined + if (!hasColumns && (self.grid.options.columnDefs.length > 0 || newData.length > 0)) { + // Build the column set, then pre-compile the column cell templates + promises.push(self.grid.buildColumns() + .then(function() { + self.grid.preCompileCellTemplates(); + })); + } + + $q.all(promises).then(function() { + self.grid.modifyRows(newData) + .then(function () { + // if (self.viewport) { + self.grid.redrawInPlace(true); + // } + + $scope.$evalAsync(function() { + self.grid.refreshCanvas(true); + self.grid.callDataChangeCallbacks(uiGridConstants.dataChange.ROW); + }); + }); + }); + } + } + + var styleWatchDereg = $scope.$watch(function () { return self.grid.styleComputations; }, function() { + self.grid.refreshCanvas(true); + }); + + $scope.$on('$destroy', function() { + deregFunctions.forEach( function( deregFn ){ deregFn(); }); + styleWatchDereg(); + }); + + self.fireEvent = function(eventName, args) { + // Add the grid to the event arguments if it's not there + if (typeof(args) === 'undefined' || args === undefined) { + args = {}; + } + + if (typeof(args.grid) === 'undefined' || args.grid === undefined) { + args.grid = self.grid; + } + + $scope.$broadcast(eventName, args); + }; + + self.innerCompile = function innerCompile(elm) { + $compile(elm)($scope); + }; + + }]); + +/** + * @ngdoc directive + * @name ui.grid.directive:uiGrid + * @element div + * @restrict EA + * @param {Object} uiGrid Options for the grid to use + * + * @description Create a very basic grid. + * + * @example + + + var app = angular.module('app', ['ui.grid']); + + app.controller('MainCtrl', ['$scope', function ($scope) { + $scope.data = [ + { name: 'Bob', title: 'CEO' }, + { name: 'Frank', title: 'Lowly Developer' } + ]; + }]); + + +
    +
    +
    +
    +
    + */ +angular.module('ui.grid').directive('uiGrid', uiGridDirective); + +uiGridDirective.$inject = ['$compile', '$templateCache', '$timeout', '$window', 'gridUtil', 'uiGridConstants']; +function uiGridDirective($compile, $templateCache, $timeout, $window, gridUtil, uiGridConstants) { + return { + templateUrl: 'ui-grid/ui-grid', + scope: { + uiGrid: '=' + }, + replace: true, + transclude: true, + controller: 'uiGridController', + compile: function () { + return { + post: function ($scope, $elm, $attrs, uiGridCtrl) { + var grid = uiGridCtrl.grid; + // Initialize scrollbars (TODO: move to controller??) + uiGridCtrl.scrollbars = []; + grid.element = $elm; + + + // See if the grid has a rendered width, if not, wait a bit and try again + var sizeCheckInterval = 100; // ms + var maxSizeChecks = 20; // 2 seconds total + var sizeChecks = 0; + + // Setup (event listeners) the grid + setup(); + + // And initialize it + init(); + + // Mark rendering complete so API events can happen + grid.renderingComplete(); + + // If the grid doesn't have size currently, wait for a bit to see if it gets size + checkSize(); + + /*-- Methods --*/ + + function checkSize() { + // If the grid has no width and we haven't checked more than times, check again in milliseconds + if ($elm[0].offsetWidth <= 0 && sizeChecks < maxSizeChecks) { + setTimeout(checkSize, sizeCheckInterval); + sizeChecks++; + } + else { + $timeout(init); + } + } + + // Setup event listeners and watchers + function setup() { + // Bind to window resize events + angular.element($window).on('resize', gridResize); + + // Unbind from window resize events when the grid is destroyed + $elm.on('$destroy', function () { + angular.element($window).off('resize', gridResize); + }); + + // If we add a left container after render, we need to watch and react + $scope.$watch(function () { return grid.hasLeftContainer();}, function (newValue, oldValue) { + if (newValue === oldValue) { + return; + } + grid.refreshCanvas(true); + }); + + // If we add a right container after render, we need to watch and react + $scope.$watch(function () { return grid.hasRightContainer();}, function (newValue, oldValue) { + if (newValue === oldValue) { + return; + } + grid.refreshCanvas(true); + }); + } + + // Initialize the directive + function init() { + grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm); + + // Default canvasWidth to the grid width, in case we don't get any column definitions to calculate it from + grid.canvasWidth = uiGridCtrl.grid.gridWidth; + + grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm); + + // If the grid isn't tall enough to fit a single row, it's kind of useless. Resize it to fit a minimum number of rows + if (grid.gridHeight < grid.options.rowHeight && grid.options.enableMinHeightCheck) { + autoAdjustHeight(); + } + + // Run initial canvas refresh + grid.refreshCanvas(true); + } + + // Set the grid's height ourselves in the case that its height would be unusably small + function autoAdjustHeight() { + // Figure out the new height + var contentHeight = grid.options.minRowsToShow * grid.options.rowHeight; + var headerHeight = grid.options.showHeader ? grid.options.headerRowHeight : 0; + var footerHeight = grid.calcFooterHeight(); + + var scrollbarHeight = 0; + if (grid.options.enableHorizontalScrollbar === uiGridConstants.scrollbars.ALWAYS) { + scrollbarHeight = gridUtil.getScrollbarWidth(); + } + + var maxNumberOfFilters = 0; + // Calculates the maximum number of filters in the columns + angular.forEach(grid.options.columnDefs, function(col) { + if (col.hasOwnProperty('filter')) { + if (maxNumberOfFilters < 1) { + maxNumberOfFilters = 1; + } + } + else if (col.hasOwnProperty('filters')) { + if (maxNumberOfFilters < col.filters.length) { + maxNumberOfFilters = col.filters.length; + } + } + }); + + if (grid.options.enableFiltering) { + var allColumnsHaveFilteringTurnedOff = grid.options.columnDefs.every(function(col) { + return col.enableFiltering === false; + }); + + if (!allColumnsHaveFilteringTurnedOff) { + maxNumberOfFilters++; + } + } + + var filterHeight = maxNumberOfFilters * headerHeight; + + var newHeight = headerHeight + contentHeight + footerHeight + scrollbarHeight + filterHeight; + + $elm.css('height', newHeight + 'px'); + + grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm); + } + + // Resize the grid on window resize events + function gridResize($event) { + grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm); + grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm); + + grid.refreshCanvas(true); + } + } + }; + } + }; +} + +})(); + +(function(){ + 'use strict'; + + // TODO: rename this file to ui-grid-pinned-container.js + + angular.module('ui.grid').directive('uiGridPinnedContainer', ['gridUtil', function (gridUtil) { + return { + restrict: 'EA', + replace: true, + template: '
    ', + scope: { + side: '=uiGridPinnedContainer' + }, + require: '^uiGrid', + compile: function compile() { + return { + post: function ($scope, $elm, $attrs, uiGridCtrl) { + // gridUtil.logDebug('ui-grid-pinned-container ' + $scope.side + ' link'); + + var grid = uiGridCtrl.grid; + + var myWidth = 0; + + $elm.addClass('ui-grid-pinned-container-' + $scope.side); + + // Monkey-patch the viewport width function + if ($scope.side === 'left' || $scope.side === 'right') { + grid.renderContainers[$scope.side].getViewportWidth = monkeyPatchedGetViewportWidth; + } + + function monkeyPatchedGetViewportWidth() { + /*jshint validthis: true */ + var self = this; + + var viewportWidth = 0; + self.visibleColumnCache.forEach(function (column) { + viewportWidth += column.drawnWidth; + }); + + var adjustment = self.getViewportAdjustment(); + + viewportWidth = viewportWidth + adjustment.width; + + return viewportWidth; + } + + function updateContainerWidth() { + if ($scope.side === 'left' || $scope.side === 'right') { + var cols = grid.renderContainers[$scope.side].visibleColumnCache; + var width = 0; + for (var i = 0; i < cols.length; i++) { + var col = cols[i]; + width += col.drawnWidth || col.width || 0; + } + + return width; + } + } + + function updateContainerDimensions() { + var ret = ''; + + // Column containers + if ($scope.side === 'left' || $scope.side === 'right') { + myWidth = updateContainerWidth(); + + // gridUtil.logDebug('myWidth', myWidth); + + // TODO(c0bra): Subtract sum of col widths from grid viewport width and update it + $elm.attr('style', null); + + // var myHeight = grid.renderContainers.body.getViewportHeight(); // + grid.horizontalScrollbarHeight; + + ret += '.grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ', .grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ' .ui-grid-render-container-' + $scope.side + ' .ui-grid-viewport { width: ' + myWidth + 'px; } '; + } + + return ret; + } + + grid.renderContainers.body.registerViewportAdjuster(function (adjustment) { + myWidth = updateContainerWidth(); + + // Subtract our own width + adjustment.width -= myWidth; + adjustment.side = $scope.side; + + return adjustment; + }); + + // Register style computation to adjust for columns in `side`'s render container + grid.registerStyleComputation({ + priority: 15, + func: updateContainerDimensions + }); + } + }; + } + }; + }]); +})(); + +(function(){ + +angular.module('ui.grid') +.factory('Grid', ['$q', '$compile', '$parse', 'gridUtil', 'uiGridConstants', 'GridOptions', 'GridColumn', 'GridRow', 'GridApi', 'rowSorter', 'rowSearcher', 'GridRenderContainer', '$timeout','ScrollEvent', + function($q, $compile, $parse, gridUtil, uiGridConstants, GridOptions, GridColumn, GridRow, GridApi, rowSorter, rowSearcher, GridRenderContainer, $timeout, ScrollEvent) { + + /** + * @ngdoc object + * @name ui.grid.core.api:PublicApi + * @description Public Api for the core grid features + * + */ + + /** + * @ngdoc function + * @name ui.grid.class:Grid + * @description Grid is the main viewModel. Any properties or methods needed to maintain state are defined in + * this prototype. One instance of Grid is created per Grid directive instance. + * @param {object} options Object map of options to pass into the grid. An 'id' property is expected. + */ + var Grid = function Grid(options) { + var self = this; + // Get the id out of the options, then remove it + if (options !== undefined && typeof(options.id) !== 'undefined' && options.id) { + if (!/^[_a-zA-Z0-9-]+$/.test(options.id)) { + throw new Error("Grid id '" + options.id + '" is invalid. It must follow CSS selector syntax rules.'); + } + } + else { + throw new Error('No ID provided. An ID must be given when creating a grid.'); + } + + self.id = options.id; + delete options.id; + + // Get default options + self.options = GridOptions.initialize( options ); + + /** + * @ngdoc object + * @name appScope + * @propertyOf ui.grid.class:Grid + * @description reference to the application scope (the parent scope of the ui-grid element). Assigned in ui-grid controller + *
    + * use gridOptions.appScopeProvider to override the default assignment of $scope.$parent with any reference + */ + self.appScope = self.options.appScopeProvider; + + self.headerHeight = self.options.headerRowHeight; + + + /** + * @ngdoc object + * @name footerHeight + * @propertyOf ui.grid.class:Grid + * @description returns the total footer height gridFooter + columnFooter + */ + self.footerHeight = self.calcFooterHeight(); + + + /** + * @ngdoc object + * @name columnFooterHeight + * @propertyOf ui.grid.class:Grid + * @description returns the total column footer height + */ + self.columnFooterHeight = self.calcColumnFooterHeight(); + + self.rtl = false; + self.gridHeight = 0; + self.gridWidth = 0; + self.columnBuilders = []; + self.rowBuilders = []; + self.rowsProcessors = []; + self.columnsProcessors = []; + self.styleComputations = []; + self.viewportAdjusters = []; + self.rowHeaderColumns = []; + self.dataChangeCallbacks = {}; + self.verticalScrollSyncCallBackFns = {}; + self.horizontalScrollSyncCallBackFns = {}; + + // self.visibleRowCache = []; + + // Set of 'render' containers for self grid, which can render sets of rows + self.renderContainers = {}; + + // Create a + self.renderContainers.body = new GridRenderContainer('body', self); + + self.cellValueGetterCache = {}; + + // Cached function to use with custom row templates + self.getRowTemplateFn = null; + + + //representation of the rows on the grid. + //these are wrapped references to the actual data rows (options.data) + self.rows = []; + + //represents the columns on the grid + self.columns = []; + + /** + * @ngdoc boolean + * @name isScrollingVertically + * @propertyOf ui.grid.class:Grid + * @description set to true when Grid is scrolling vertically. Set to false via debounced method + */ + self.isScrollingVertically = false; + + /** + * @ngdoc boolean + * @name isScrollingHorizontally + * @propertyOf ui.grid.class:Grid + * @description set to true when Grid is scrolling horizontally. Set to false via debounced method + */ + self.isScrollingHorizontally = false; + + /** + * @ngdoc property + * @name scrollDirection + * @propertyOf ui.grid.class:Grid + * @description set one of the uiGridConstants.scrollDirection values (UP, DOWN, LEFT, RIGHT, NONE), which tells + * us which direction we are scrolling. Set to NONE via debounced method + */ + self.scrollDirection = uiGridConstants.scrollDirection.NONE; + + //if true, grid will not respond to any scroll events + self.disableScrolling = false; + + + function vertical (scrollEvent) { + self.isScrollingVertically = false; + self.api.core.raise.scrollEnd(scrollEvent); + self.scrollDirection = uiGridConstants.scrollDirection.NONE; + } + + var debouncedVertical = gridUtil.debounce(vertical, self.options.scrollDebounce); + var debouncedVerticalMinDelay = gridUtil.debounce(vertical, 0); + + function horizontal (scrollEvent) { + self.isScrollingHorizontally = false; + self.api.core.raise.scrollEnd(scrollEvent); + self.scrollDirection = uiGridConstants.scrollDirection.NONE; + } + + var debouncedHorizontal = gridUtil.debounce(horizontal, self.options.scrollDebounce); + var debouncedHorizontalMinDelay = gridUtil.debounce(horizontal, 0); + + + /** + * @ngdoc function + * @name flagScrollingVertically + * @methodOf ui.grid.class:Grid + * @description sets isScrollingVertically to true and sets it to false in a debounced function + */ + self.flagScrollingVertically = function(scrollEvent) { + if (!self.isScrollingVertically && !self.isScrollingHorizontally) { + self.api.core.raise.scrollBegin(scrollEvent); + } + self.isScrollingVertically = true; + if (self.options.scrollDebounce === 0 || !scrollEvent.withDelay) { + debouncedVerticalMinDelay(scrollEvent); + } + else { + debouncedVertical(scrollEvent); + } + }; + + /** + * @ngdoc function + * @name flagScrollingHorizontally + * @methodOf ui.grid.class:Grid + * @description sets isScrollingHorizontally to true and sets it to false in a debounced function + */ + self.flagScrollingHorizontally = function(scrollEvent) { + if (!self.isScrollingVertically && !self.isScrollingHorizontally) { + self.api.core.raise.scrollBegin(scrollEvent); + } + self.isScrollingHorizontally = true; + if (self.options.scrollDebounce === 0 || !scrollEvent.withDelay) { + debouncedHorizontalMinDelay(scrollEvent); + } + else { + debouncedHorizontal(scrollEvent); + } + }; + + self.scrollbarHeight = 0; + self.scrollbarWidth = 0; + if (self.options.enableHorizontalScrollbar === uiGridConstants.scrollbars.ALWAYS) { + self.scrollbarHeight = gridUtil.getScrollbarWidth(); + } + + if (self.options.enableVerticalScrollbar === uiGridConstants.scrollbars.ALWAYS) { + self.scrollbarWidth = gridUtil.getScrollbarWidth(); + } + + + + self.api = new GridApi(self); + + /** + * @ngdoc function + * @name refresh + * @methodOf ui.grid.core.api:PublicApi + * @description Refresh the rendered grid on screen. + * The refresh method re-runs both the columnProcessors and the + * rowProcessors, as well as calling refreshCanvas to update all + * the grid sizing. In general you should prefer to use queueGridRefresh + * instead, which is basically a debounced version of refresh. + * + * If you only want to resize the grid, not regenerate all the rows + * and columns, you should consider directly calling refreshCanvas instead. + * + */ + self.api.registerMethod( 'core', 'refresh', this.refresh ); + + /** + * @ngdoc function + * @name queueGridRefresh + * @methodOf ui.grid.core.api:PublicApi + * @description Request a refresh of the rendered grid on screen, if multiple + * calls to queueGridRefresh are made within a digest cycle only one will execute. + * The refresh method re-runs both the columnProcessors and the + * rowProcessors, as well as calling refreshCanvas to update all + * the grid sizing. In general you should prefer to use queueGridRefresh + * instead, which is basically a debounced version of refresh. + * + */ + self.api.registerMethod( 'core', 'queueGridRefresh', this.queueGridRefresh ); + + /** + * @ngdoc function + * @name refreshRows + * @methodOf ui.grid.core.api:PublicApi + * @description Runs only the rowProcessors, columns remain as they were. + * It then calls redrawInPlace and refreshCanvas, which adjust the grid sizing. + * @returns {promise} promise that is resolved when render completes? + * + */ + self.api.registerMethod( 'core', 'refreshRows', this.refreshRows ); + + /** + * @ngdoc function + * @name queueRefresh + * @methodOf ui.grid.core.api:PublicApi + * @description Requests execution of refreshCanvas, if multiple requests are made + * during a digest cycle only one will run. RefreshCanvas updates the grid sizing. + * @returns {promise} promise that is resolved when render completes? + * + */ + self.api.registerMethod( 'core', 'queueRefresh', this.queueRefresh ); + + /** + * @ngdoc function + * @name handleWindowResize + * @methodOf ui.grid.core.api:PublicApi + * @description Trigger a grid resize, normally this would be picked + * up by a watch on window size, but in some circumstances it is necessary + * to call this manually + * @returns {promise} promise that is resolved when render completes? + * + */ + self.api.registerMethod( 'core', 'handleWindowResize', this.handleWindowResize ); + + + /** + * @ngdoc function + * @name addRowHeaderColumn + * @methodOf ui.grid.core.api:PublicApi + * @description adds a row header column to the grid + * @param {object} column def + * + */ + self.api.registerMethod( 'core', 'addRowHeaderColumn', this.addRowHeaderColumn ); + + /** + * @ngdoc function + * @name scrollToIfNecessary + * @methodOf ui.grid.core.api:PublicApi + * @description Scrolls the grid to make a certain row and column combo visible, + * in the case that it is not completely visible on the screen already. + * @param {GridRow} gridRow row to make visible + * @param {GridCol} gridCol column to make visible + * @returns {promise} a promise that is resolved when scrolling is complete + * + */ + self.api.registerMethod( 'core', 'scrollToIfNecessary', function(gridRow, gridCol) { return self.scrollToIfNecessary(gridRow, gridCol);} ); + + /** + * @ngdoc function + * @name scrollTo + * @methodOf ui.grid.core.api:PublicApi + * @description Scroll the grid such that the specified + * row and column is in view + * @param {object} rowEntity gridOptions.data[] array instance to make visible + * @param {object} colDef to make visible + * @returns {promise} a promise that is resolved after any scrolling is finished + */ + self.api.registerMethod( 'core', 'scrollTo', function (rowEntity, colDef) { return self.scrollTo(rowEntity, colDef);} ); + + /** + * @ngdoc function + * @name registerRowsProcessor + * @methodOf ui.grid.core.api:PublicApi + * @description + * Register a "rows processor" function. When the rows are updated, + * the grid calls each registered "rows processor", which has a chance + * to alter the set of rows (sorting, etc) as long as the count is not + * modified. + * + * @param {function(renderedRowsToProcess, columns )} processorFunction rows processor function, which + * is run in the context of the grid (i.e. this for the function will be the grid), and must + * return the updated rows list, which is passed to the next processor in the chain + * @param {number} priority the priority of this processor. In general we try to do them in 100s to leave room + * for other people to inject rows processors at intermediate priorities. Lower priority rowsProcessors run earlier. + * + * At present allRowsVisible is running at 50, sort manipulations running at 60-65, filter is running at 100, + * sort is at 200, grouping and treeview at 400-410, selectable rows at 500, pagination at 900 (pagination will generally want to be last) + */ + self.api.registerMethod( 'core', 'registerRowsProcessor', this.registerRowsProcessor ); + + /** + * @ngdoc function + * @name registerColumnsProcessor + * @methodOf ui.grid.core.api:PublicApi + * @description + * Register a "columns processor" function. When the columns are updated, + * the grid calls each registered "columns processor", which has a chance + * to alter the set of columns as long as the count is not + * modified. + * + * @param {function(renderedColumnsToProcess, rows )} processorFunction columns processor function, which + * is run in the context of the grid (i.e. this for the function will be the grid), and must + * return the updated columns list, which is passed to the next processor in the chain + * @param {number} priority the priority of this processor. In general we try to do them in 100s to leave room + * for other people to inject columns processors at intermediate priorities. Lower priority columnsProcessors run earlier. + * + * At present allRowsVisible is running at 50, filter is running at 100, sort is at 200, grouping at 400, selectable rows at 500, pagination at 900 (pagination will generally want to be last) + */ + self.api.registerMethod( 'core', 'registerColumnsProcessor', this.registerColumnsProcessor ); + + + + /** + * @ngdoc function + * @name sortHandleNulls + * @methodOf ui.grid.core.api:PublicApi + * @description A null handling method that can be used when building custom sort + * functions + * @example + *
    +     *   mySortFn = function(a, b) {
    +     *   var nulls = $scope.gridApi.core.sortHandleNulls(a, b);
    +     *   if ( nulls !== null ){
    +     *     return nulls;
    +     *   } else {
    +     *     // your code for sorting here
    +     *   };
    +     * 
    + * @param {object} a sort value a + * @param {object} b sort value b + * @returns {number} null if there were no nulls/undefineds, otherwise returns + * a sort value that should be passed back from the sort function + * + */ + self.api.registerMethod( 'core', 'sortHandleNulls', rowSorter.handleNulls ); + + + /** + * @ngdoc function + * @name sortChanged + * @methodOf ui.grid.core.api:PublicApi + * @description The sort criteria on one or more columns has + * changed. Provides as parameters the grid and the output of + * getColumnSorting, which is an array of gridColumns + * that have sorting on them, sorted in priority order. + * + * @param {$scope} scope The scope of the controller. This is used to deregister this event when the scope is destroyed. + * @param {Function} callBack Will be called when the event is emited. The function passes back an array of columns with + * sorts on them, in priority order. + * + * @example + *
    +     *      gridApi.core.on.sortChanged( $scope, function(sortColumns){
    +     *        // do something
    +     *      });
    +     * 
    + */ + self.api.registerEvent( 'core', 'sortChanged' ); + + /** + * @ngdoc function + * @name columnVisibilityChanged + * @methodOf ui.grid.core.api:PublicApi + * @description The visibility of a column has changed, + * the column itself is passed out as a parameter of the event. + * + * @param {$scope} scope The scope of the controller. This is used to deregister this event when the scope is destroyed. + * @param {Function} callBack Will be called when the event is emited. The function passes back the GridCol that has changed. + * + * @example + *
    +     *      gridApi.core.on.columnVisibilityChanged( $scope, function (column) {
    +     *        // do something
    +     *      } );
    +     * 
    + */ + self.api.registerEvent( 'core', 'columnVisibilityChanged' ); + + /** + * @ngdoc method + * @name notifyDataChange + * @methodOf ui.grid.core.api:PublicApi + * @description Notify the grid that a data or config change has occurred, + * where that change isn't something the grid was otherwise noticing. This + * might be particularly relevant where you've changed values within the data + * and you'd like cell classes to be re-evaluated, or changed config within + * the columnDef and you'd like headerCellClasses to be re-evaluated. + * @param {string} type one of the + * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN), which tells + * us which refreshes to fire. + * + */ + self.api.registerMethod( 'core', 'notifyDataChange', this.notifyDataChange ); + + /** + * @ngdoc method + * @name clearAllFilters + * @methodOf ui.grid.core.api:PublicApi + * @description Clears all filters and optionally refreshes the visible rows. + * @param {object} refreshRows Defaults to true. + * @param {object} clearConditions Defaults to false. + * @param {object} clearFlags Defaults to false. + * @returns {promise} If `refreshRows` is true, returns a promise of the rows refreshing. + */ + self.api.registerMethod('core', 'clearAllFilters', this.clearAllFilters); + + self.registerDataChangeCallback( self.columnRefreshCallback, [uiGridConstants.dataChange.COLUMN]); + self.registerDataChangeCallback( self.processRowsCallback, [uiGridConstants.dataChange.EDIT]); + self.registerDataChangeCallback( self.updateFooterHeightCallback, [uiGridConstants.dataChange.OPTIONS]); + + self.registerStyleComputation({ + priority: 10, + func: self.getFooterStyles + }); + }; + + Grid.prototype.calcFooterHeight = function () { + if (!this.hasFooter()) { + return 0; + } + + var height = 0; + if (this.options.showGridFooter) { + height += this.options.gridFooterHeight; + } + + height += this.calcColumnFooterHeight(); + + return height; + }; + + Grid.prototype.calcColumnFooterHeight = function () { + var height = 0; + + if (this.options.showColumnFooter) { + height += this.options.columnFooterHeight; + } + + return height; + }; + + Grid.prototype.getFooterStyles = function () { + var style = '.grid' + this.id + ' .ui-grid-footer-aggregates-row { height: ' + this.options.columnFooterHeight + 'px; }'; + style += ' .grid' + this.id + ' .ui-grid-footer-info { height: ' + this.options.gridFooterHeight + 'px; }'; + return style; + }; + + Grid.prototype.hasFooter = function () { + return this.options.showGridFooter || this.options.showColumnFooter; + }; + + /** + * @ngdoc function + * @name isRTL + * @methodOf ui.grid.class:Grid + * @description Returns true if grid is RightToLeft + */ + Grid.prototype.isRTL = function () { + return this.rtl; + }; + + + /** + * @ngdoc function + * @name registerColumnBuilder + * @methodOf ui.grid.class:Grid + * @description When the build creates columns from column definitions, the columnbuilders will be called to add + * additional properties to the column. + * @param {function(colDef, col, gridOptions)} columnBuilder function to be called + */ + Grid.prototype.registerColumnBuilder = function registerColumnBuilder(columnBuilder) { + this.columnBuilders.push(columnBuilder); + }; + + /** + * @ngdoc function + * @name buildColumnDefsFromData + * @methodOf ui.grid.class:Grid + * @description Populates columnDefs from the provided data + * @param {function(colDef, col, gridOptions)} rowBuilder function to be called + */ + Grid.prototype.buildColumnDefsFromData = function (dataRows){ + this.options.columnDefs = gridUtil.getColumnsFromData(dataRows, this.options.excludeProperties); + }; + + /** + * @ngdoc function + * @name registerRowBuilder + * @methodOf ui.grid.class:Grid + * @description When the build creates rows from gridOptions.data, the rowBuilders will be called to add + * additional properties to the row. + * @param {function(row, gridOptions)} rowBuilder function to be called + */ + Grid.prototype.registerRowBuilder = function registerRowBuilder(rowBuilder) { + this.rowBuilders.push(rowBuilder); + }; + + + /** + * @ngdoc function + * @name registerDataChangeCallback + * @methodOf ui.grid.class:Grid + * @description When a data change occurs, the data change callbacks of the specified type + * will be called. The rules are: + * + * - when the data watch fires, that is considered a ROW change (the data watch only notices + * added or removed rows) + * - when the api is called to inform us of a change, the declared type of that change is used + * - when a cell edit completes, the EDIT callbacks are triggered + * - when the columnDef watch fires, the COLUMN callbacks are triggered + * - when the options watch fires, the OPTIONS callbacks are triggered + * + * For a given event: + * - ALL calls ROW, EDIT, COLUMN, OPTIONS and ALL callbacks + * - ROW calls ROW and ALL callbacks + * - EDIT calls EDIT and ALL callbacks + * - COLUMN calls COLUMN and ALL callbacks + * - OPTIONS calls OPTIONS and ALL callbacks + * + * @param {function(grid)} callback function to be called + * @param {array} types the types of data change you want to be informed of. Values from + * the uiGridConstants.dataChange values ( ALL, EDIT, ROW, COLUMN, OPTIONS ). Optional and defaults to + * ALL + * @returns {function} deregister function - a function that can be called to deregister this callback + */ + Grid.prototype.registerDataChangeCallback = function registerDataChangeCallback(callback, types, _this) { + var uid = gridUtil.nextUid(); + if ( !types ){ + types = [uiGridConstants.dataChange.ALL]; + } + if ( !Array.isArray(types)){ + gridUtil.logError("Expected types to be an array or null in registerDataChangeCallback, value passed was: " + types ); + } + this.dataChangeCallbacks[uid] = { callback: callback, types: types, _this:_this }; + + var self = this; + var deregisterFunction = function() { + delete self.dataChangeCallbacks[uid]; + }; + return deregisterFunction; + }; + + /** + * @ngdoc function + * @name callDataChangeCallbacks + * @methodOf ui.grid.class:Grid + * @description Calls the callbacks based on the type of data change that + * has occurred. Always calls the ALL callbacks, calls the ROW, EDIT, COLUMN and OPTIONS callbacks if the + * event type is matching, or if the type is ALL. + * @param {number} type the type of event that occurred - one of the + * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN, OPTIONS) + */ + Grid.prototype.callDataChangeCallbacks = function callDataChangeCallbacks(type, options) { + angular.forEach( this.dataChangeCallbacks, function( callback, uid ){ + if ( callback.types.indexOf( uiGridConstants.dataChange.ALL ) !== -1 || + callback.types.indexOf( type ) !== -1 || + type === uiGridConstants.dataChange.ALL ) { + if (callback._this) { + callback.callback.apply(callback._this,this); + } + else { + callback.callback( this ); + } + } + }, this); + }; + + /** + * @ngdoc function + * @name notifyDataChange + * @methodOf ui.grid.class:Grid + * @description Notifies us that a data change has occurred, used in the public + * api for users to tell us when they've changed data or some other event that + * our watches cannot pick up + * @param {string} type the type of event that occurred - one of the + * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN) + */ + Grid.prototype.notifyDataChange = function notifyDataChange(type) { + var constants = uiGridConstants.dataChange; + if ( type === constants.ALL || + type === constants.COLUMN || + type === constants.EDIT || + type === constants.ROW || + type === constants.OPTIONS ){ + this.callDataChangeCallbacks( type ); + } else { + gridUtil.logError("Notified of a data change, but the type was not recognised, so no action taken, type was: " + type); + } + }; + + + /** + * @ngdoc function + * @name columnRefreshCallback + * @methodOf ui.grid.class:Grid + * @description refreshes the grid when a column refresh + * is notified, which triggers handling of the visible flag. + * This is called on uiGridConstants.dataChange.COLUMN, and is + * registered as a dataChangeCallback in grid.js + * @param {string} name column name + */ + Grid.prototype.columnRefreshCallback = function columnRefreshCallback( grid ){ + grid.buildColumns(); + grid.queueGridRefresh(); + }; + + + /** + * @ngdoc function + * @name processRowsCallback + * @methodOf ui.grid.class:Grid + * @description calls the row processors, specifically + * intended to reset the sorting when an edit is called, + * registered as a dataChangeCallback on uiGridConstants.dataChange.EDIT + * @param {string} name column name + */ + Grid.prototype.processRowsCallback = function processRowsCallback( grid ){ + grid.queueGridRefresh(); + }; + + + /** + * @ngdoc function + * @name updateFooterHeightCallback + * @methodOf ui.grid.class:Grid + * @description recalculates the footer height, + * registered as a dataChangeCallback on uiGridConstants.dataChange.OPTIONS + * @param {string} name column name + */ + Grid.prototype.updateFooterHeightCallback = function updateFooterHeightCallback( grid ){ + grid.footerHeight = grid.calcFooterHeight(); + grid.columnFooterHeight = grid.calcColumnFooterHeight(); + }; + + + /** + * @ngdoc function + * @name getColumn + * @methodOf ui.grid.class:Grid + * @description returns a grid column for the column name + * @param {string} name column name + */ + Grid.prototype.getColumn = function getColumn(name) { + var columns = this.columns.filter(function (column) { + return column.colDef.name === name; + }); + return columns.length > 0 ? columns[0] : null; + }; + + /** + * @ngdoc function + * @name getColDef + * @methodOf ui.grid.class:Grid + * @description returns a grid colDef for the column name + * @param {string} name column.field + */ + Grid.prototype.getColDef = function getColDef(name) { + var colDefs = this.options.columnDefs.filter(function (colDef) { + return colDef.name === name; + }); + return colDefs.length > 0 ? colDefs[0] : null; + }; + + /** + * @ngdoc function + * @name assignTypes + * @methodOf ui.grid.class:Grid + * @description uses the first row of data to assign colDef.type for any types not defined. + */ + /** + * @ngdoc property + * @name type + * @propertyOf ui.grid.class:GridOptions.columnDef + * @description the type of the column, used in sorting. If not provided then the + * grid will guess the type. Add this only if the grid guessing is not to your + * satisfaction. One of: + * - 'string' + * - 'boolean' + * - 'number' + * - 'date' + * - 'object' + * - 'numberStr' + * Note that if you choose date, your dates should be in a javascript date type + * + */ + Grid.prototype.assignTypes = function(){ + var self = this; + self.options.columnDefs.forEach(function (colDef, index) { + + //Assign colDef type if not specified + if (!colDef.type) { + var col = new GridColumn(colDef, index, self); + var firstRow = self.rows.length > 0 ? self.rows[0] : null; + if (firstRow) { + colDef.type = gridUtil.guessType(self.getCellValue(firstRow, col)); + } + else { + colDef.type = 'string'; + } + } + }); + }; + + + /** + * @ngdoc function + * @name isRowHeaderColumn + * @methodOf ui.grid.class:Grid + * @description returns true if the column is a row Header + * @param {object} column column + */ + Grid.prototype.isRowHeaderColumn = function isRowHeaderColumn(column) { + return this.rowHeaderColumns.indexOf(column) !== -1; + }; + + /** + * @ngdoc function + * @name addRowHeaderColumn + * @methodOf ui.grid.class:Grid + * @description adds a row header column to the grid + * @param {object} column def + */ + Grid.prototype.addRowHeaderColumn = function addRowHeaderColumn(colDef) { + var self = this; + var rowHeaderCol = new GridColumn(colDef, gridUtil.nextUid(), self); + rowHeaderCol.isRowHeader = true; + if (self.isRTL()) { + self.createRightContainer(); + rowHeaderCol.renderContainer = 'right'; + } + else { + self.createLeftContainer(); + rowHeaderCol.renderContainer = 'left'; + } + + // relies on the default column builder being first in array, as it is instantiated + // as part of grid creation + self.columnBuilders[0](colDef,rowHeaderCol,self.options) + .then(function(){ + rowHeaderCol.enableFiltering = false; + rowHeaderCol.enableSorting = false; + rowHeaderCol.enableHiding = false; + self.rowHeaderColumns.push(rowHeaderCol); + self.buildColumns() + .then( function() { + self.preCompileCellTemplates(); + self.queueGridRefresh(); + }); + }); + }; + + /** + * @ngdoc function + * @name getOnlyDataColumns + * @methodOf ui.grid.class:Grid + * @description returns all columns except for rowHeader columns + */ + Grid.prototype.getOnlyDataColumns = function getOnlyDataColumns() { + var self = this; + var cols = []; + self.columns.forEach(function (col) { + if (self.rowHeaderColumns.indexOf(col) === -1) { + cols.push(col); + } + }); + return cols; + }; + + /** + * @ngdoc function + * @name buildColumns + * @methodOf ui.grid.class:Grid + * @description creates GridColumn objects from the columnDefinition. Calls each registered + * columnBuilder to further process the column + * @param {object} options An object contains options to use when building columns + * + * * **orderByColumnDefs**: defaults to **false**. When true, `buildColumns` will reorder existing columns according to the order within the column definitions. + * + * @returns {Promise} a promise to load any needed column resources + */ + Grid.prototype.buildColumns = function buildColumns(opts) { + var options = { + orderByColumnDefs: false + }; + + angular.extend(options, opts); + + // gridUtil.logDebug('buildColumns'); + var self = this; + var builderPromises = []; + var headerOffset = self.rowHeaderColumns.length; + var i; + + // Remove any columns for which a columnDef cannot be found + // Deliberately don't use forEach, as it doesn't like splice being called in the middle + // Also don't cache columns.length, as it will change during this operation + for (i = 0; i < self.columns.length; i++){ + if (!self.getColDef(self.columns[i].name)) { + self.columns.splice(i, 1); + i--; + } + } + + //add row header columns to the grid columns array _after_ columns without columnDefs have been removed + self.rowHeaderColumns.forEach(function (rowHeaderColumn) { + self.columns.unshift(rowHeaderColumn); + }); + + + // look at each column def, and update column properties to match. If the column def + // doesn't have a column, then splice in a new gridCol + self.options.columnDefs.forEach(function (colDef, index) { + self.preprocessColDef(colDef); + var col = self.getColumn(colDef.name); + + if (!col) { + col = new GridColumn(colDef, gridUtil.nextUid(), self); + self.columns.splice(index + headerOffset, 0, col); + } + else { + // tell updateColumnDef that the column was pre-existing + col.updateColumnDef(colDef, false); + } + + self.columnBuilders.forEach(function (builder) { + builderPromises.push(builder.call(self, colDef, col, self.options)); + }); + }); + + /*** Reorder columns if necessary ***/ + if (!!options.orderByColumnDefs) { + // Create a shallow copy of the columns as a cache + var columnCache = self.columns.slice(0); + + // We need to allow for the "row headers" when mapping from the column defs array to the columns array + // If we have a row header in columns[0] and don't account for it we'll overwrite it with the column in columnDefs[0] + + // Go through all the column defs, use the shorter of columns length and colDefs.length because if a user has given two columns the same name then + // columns will be shorter than columnDefs. In this situation we'll avoid an error, but the user will still get an unexpected result + var len = Math.min(self.options.columnDefs.length, self.columns.length); + for (i = 0; i < len; i++) { + // If the column at this index has a different name than the column at the same index in the column defs... + if (self.columns[i + headerOffset].name !== self.options.columnDefs[i].name) { + // Replace the one in the cache with the appropriate column + columnCache[i + headerOffset] = self.getColumn(self.options.columnDefs[i].name); + } + else { + // Otherwise just copy over the one from the initial columns + columnCache[i + headerOffset] = self.columns[i + headerOffset]; + } + } + + // Empty out the columns array, non-destructively + self.columns.length = 0; + + // And splice in the updated, ordered columns from the cache + Array.prototype.splice.apply(self.columns, [0, 0].concat(columnCache)); + } + + return $q.all(builderPromises).then(function(){ + if (self.rows.length > 0){ + self.assignTypes(); + } + }); + }; + +/** + * @ngdoc function + * @name preCompileCellTemplates + * @methodOf ui.grid.class:Grid + * @description precompiles all cell templates + */ + Grid.prototype.preCompileCellTemplates = function() { + var self = this; + + var preCompileTemplate = function( col ) { + var html = col.cellTemplate.replace(uiGridConstants.MODEL_COL_FIELD, self.getQualifiedColField(col)); + html = html.replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)'); + + var compiledElementFn = $compile(html); + col.compiledElementFn = compiledElementFn; + + if (col.compiledElementFnDefer) { + col.compiledElementFnDefer.resolve(col.compiledElementFn); + } + }; + + this.columns.forEach(function (col) { + if ( col.cellTemplate ){ + preCompileTemplate( col ); + } else if ( col.cellTemplatePromise ){ + col.cellTemplatePromise.then( function() { + preCompileTemplate( col ); + }); + } + }); + }; + + /** + * @ngdoc function + * @name getGridQualifiedColField + * @methodOf ui.grid.class:Grid + * @description Returns the $parse-able accessor for a column within its $scope + * @param {GridColumn} col col object + */ + Grid.prototype.getQualifiedColField = function (col) { + return 'row.entity.' + gridUtil.preEval(col.field); + }; + + /** + * @ngdoc function + * @name createLeftContainer + * @methodOf ui.grid.class:Grid + * @description creates the left render container if it doesn't already exist + */ + Grid.prototype.createLeftContainer = function() { + if (!this.hasLeftContainer()) { + this.renderContainers.left = new GridRenderContainer('left', this, { disableColumnOffset: true }); + } + }; + + /** + * @ngdoc function + * @name createRightContainer + * @methodOf ui.grid.class:Grid + * @description creates the right render container if it doesn't already exist + */ + Grid.prototype.createRightContainer = function() { + if (!this.hasRightContainer()) { + this.renderContainers.right = new GridRenderContainer('right', this, { disableColumnOffset: true }); + } + }; + + /** + * @ngdoc function + * @name hasLeftContainer + * @methodOf ui.grid.class:Grid + * @description returns true if leftContainer exists + */ + Grid.prototype.hasLeftContainer = function() { + return this.renderContainers.left !== undefined; + }; + + /** + * @ngdoc function + * @name hasRightContainer + * @methodOf ui.grid.class:Grid + * @description returns true if rightContainer exists + */ + Grid.prototype.hasRightContainer = function() { + return this.renderContainers.right !== undefined; + }; + + + /** + * undocumented function + * @name preprocessColDef + * @methodOf ui.grid.class:Grid + * @description defaults the name property from field to maintain backwards compatibility with 2.x + * validates that name or field is present + */ + Grid.prototype.preprocessColDef = function preprocessColDef(colDef) { + var self = this; + + if (!colDef.field && !colDef.name) { + throw new Error('colDef.name or colDef.field property is required'); + } + + //maintain backwards compatibility with 2.x + //field was required in 2.x. now name is required + if (colDef.name === undefined && colDef.field !== undefined) { + // See if the column name already exists: + var newName = colDef.field, + counter = 2; + while (self.getColumn(newName)) { + newName = colDef.field + counter.toString(); + counter++; + } + colDef.name = newName; + } + }; + + // Return a list of items that exist in the `n` array but not the `o` array. Uses optional property accessors passed as third & fourth parameters + Grid.prototype.newInN = function newInN(o, n, oAccessor, nAccessor) { + var self = this; + + var t = []; + for (var i = 0; i < n.length; i++) { + var nV = nAccessor ? n[i][nAccessor] : n[i]; + + var found = false; + for (var j = 0; j < o.length; j++) { + var oV = oAccessor ? o[j][oAccessor] : o[j]; + if (self.options.rowEquality(nV, oV)) { + found = true; + break; + } + } + if (!found) { + t.push(nV); + } + } + + return t; + }; + + /** + * @ngdoc function + * @name getRow + * @methodOf ui.grid.class:Grid + * @description returns the GridRow that contains the rowEntity + * @param {object} rowEntity the gridOptions.data array element instance + * @param {array} rows [optional] the rows to look in - if not provided then + * looks in grid.rows + */ + Grid.prototype.getRow = function getRow(rowEntity, lookInRows) { + var self = this; + + lookInRows = typeof(lookInRows) === 'undefined' ? self.rows : lookInRows; + + var rows = lookInRows.filter(function (row) { + return self.options.rowEquality(row.entity, rowEntity); + }); + return rows.length > 0 ? rows[0] : null; + }; + + + /** + * @ngdoc function + * @name modifyRows + * @methodOf ui.grid.class:Grid + * @description creates or removes GridRow objects from the newRawData array. Calls each registered + * rowBuilder to further process the row + * @param {array} newRawData Modified set of data + * + * This method aims to achieve three things: + * 1. the resulting rows array is in the same order as the newRawData, we'll call + * rowsProcessors immediately after to sort the data anyway + * 2. if we have row hashing available, we try to use the rowHash to find the row + * 3. no memory leaks - rows that are no longer in newRawData need to be garbage collected + * + * The basic logic flow makes use of the newRawData, oldRows and oldHash, and creates + * the newRows and newHash + * + * ``` + * newRawData.forEach newEntity + * if (hashing enabled) + * check oldHash for newEntity + * else + * look for old row directly in oldRows + * if !oldRowFound // must be a new row + * create newRow + * append to the newRows and add to newHash + * run the processors + * ``` + * + * Rows are identified using the hashKey if configured. If not configured, then rows + * are identified using the gridOptions.rowEquality function + * + * This method is useful when trying to select rows immediately after loading data without + * using a $timeout/$interval, e.g.: + * + * $scope.gridOptions.data = someData; + * $scope.gridApi.grid.modifyRows($scope.gridOptions.data); + * $scope.gridApi.selection.selectRow($scope.gridOptions.data[0]); + * + * OR to persist row selection after data update (e.g. rows selected, new data loaded, want + * originally selected rows to be re-selected)) + */ + Grid.prototype.modifyRows = function modifyRows(newRawData) { + var self = this; + var oldRows = self.rows.slice(0); + var oldRowHash = self.rowHashMap || self.createRowHashMap(); + self.rowHashMap = self.createRowHashMap(); + self.rows.length = 0; + + newRawData.forEach( function( newEntity, i ) { + var newRow; + if ( self.options.enableRowHashing ){ + // if hashing is enabled, then this row will be in the hash if we already know about it + newRow = oldRowHash.get( newEntity ); + } else { + // otherwise, manually search the oldRows to see if we can find this row + newRow = self.getRow(newEntity, oldRows); + } + + // if we didn't find the row, it must be new, so create it + if ( !newRow ){ + newRow = self.processRowBuilders(new GridRow(newEntity, i, self)); + } + + self.rows.push( newRow ); + self.rowHashMap.put( newEntity, newRow ); + }); + + self.assignTypes(); + + var p1 = $q.when(self.processRowsProcessors(self.rows)) + .then(function (renderableRows) { + return self.setVisibleRows(renderableRows); + }); + + var p2 = $q.when(self.processColumnsProcessors(self.columns)) + .then(function (renderableColumns) { + return self.setVisibleColumns(renderableColumns); + }); + + return $q.all([p1, p2]); + }; + + + /** + * Private Undocumented Method + * @name addRows + * @methodOf ui.grid.class:Grid + * @description adds the newRawData array of rows to the grid and calls all registered + * rowBuilders. this keyword will reference the grid + */ + Grid.prototype.addRows = function addRows(newRawData) { + var self = this; + + var existingRowCount = self.rows.length; + for (var i = 0; i < newRawData.length; i++) { + var newRow = self.processRowBuilders(new GridRow(newRawData[i], i + existingRowCount, self)); + + if (self.options.enableRowHashing) { + var found = self.rowHashMap.get(newRow.entity); + if (found) { + found.row = newRow; + } + } + + self.rows.push(newRow); + } + }; + + /** + * @ngdoc function + * @name processRowBuilders + * @methodOf ui.grid.class:Grid + * @description processes all RowBuilders for the gridRow + * @param {GridRow} gridRow reference to gridRow + * @returns {GridRow} the gridRow with all additional behavior added + */ + Grid.prototype.processRowBuilders = function processRowBuilders(gridRow) { + var self = this; + + self.rowBuilders.forEach(function (builder) { + builder.call(self, gridRow, self.options); + }); + + return gridRow; + }; + + /** + * @ngdoc function + * @name registerStyleComputation + * @methodOf ui.grid.class:Grid + * @description registered a styleComputation function + * + * If the function returns a value it will be appended into the grid's `
    " + ); + + + $templateCache.put('ui-grid/uiGridCell', + "
    {{COL_FIELD CUSTOM_FILTERS}}
    " + ); + + + $templateCache.put('ui-grid/uiGridColumnMenu', + "
    " + ); + + + $templateCache.put('ui-grid/uiGridFooterCell', + "
    {{ col.getAggregationText() + ( col.getAggregationValue() CUSTOM_FILTERS ) }}
    " + ); + + + $templateCache.put('ui-grid/uiGridHeaderCell', + "
    {{ col.displayName CUSTOM_FILTERS }} {{col.sort.priority}}
     
    " + ); + + + $templateCache.put('ui-grid/uiGridMenu', + "
    " + ); + + + $templateCache.put('ui-grid/uiGridMenuItem', + "" + ); + + + $templateCache.put('ui-grid/uiGridRenderContainer', + "
    " + ); + + + $templateCache.put('ui-grid/uiGridViewport', + "
    " + ); + + + $templateCache.put('ui-grid/cellEditor', + "
    " + ); + + + $templateCache.put('ui-grid/dropdownEditor', + "
    " + ); + + + $templateCache.put('ui-grid/fileChooserEditor', + "
    " + ); + + + $templateCache.put('ui-grid/expandableRow', + "
    " + ); + + + $templateCache.put('ui-grid/expandableRowHeader', + "
    " + ); + + + $templateCache.put('ui-grid/expandableScrollFiller', + "
    " + ); + + + $templateCache.put('ui-grid/expandableTopRowHeader', + "
    " + ); + + + $templateCache.put('ui-grid/csvLink', + "LINK_LABEL" + ); + + + $templateCache.put('ui-grid/importerMenuItem', + "
  • " + ); + + + $templateCache.put('ui-grid/importerMenuItemContainer', + "
    " + ); + + + $templateCache.put('ui-grid/pagination', + "
    0\">/ {{ paginationApi.getTotalPages() }}
    1\"> {{sizesLabel}}
    {{grid.options.paginationPageSize}} {{sizesLabel}}
    0\">{{showingLow}} - {{showingHigh}} {{paginationOf}} {{grid.options.totalItems}} {{totalItemsLabel}}
    " + ); + + + $templateCache.put('ui-grid/columnResizer', + "
    " + ); + + + $templateCache.put('ui-grid/gridFooterSelectedItems', + "({{\"search.selectedItems\" | t}} {{grid.selection.selectedCount}})" + ); + + + $templateCache.put('ui-grid/selectionHeaderCell', + "
    " + ); + + + $templateCache.put('ui-grid/selectionRowHeader', + "
    " + ); + + + $templateCache.put('ui-grid/selectionRowHeaderButtons', + "
     
    " + ); + + + $templateCache.put('ui-grid/selectionSelectAllButtons', + "
    " + ); + + + $templateCache.put('ui-grid/treeBaseExpandAllButtons', + "
    0 && grid.treeBase.expandAll, 'ui-grid-icon-plus-squared': grid.treeBase.numberLevels > 0 && !grid.treeBase.expandAll}\" ng-click=\"headerButtonClick($event)\">
    " + ); + + + $templateCache.put('ui-grid/treeBaseHeaderCell', + "
    " + ); + + + $templateCache.put('ui-grid/treeBaseRowHeader', + "
    " + ); + + + $templateCache.put('ui-grid/treeBaseRowHeaderButtons', + "
    -1 }\" ng-click=\"treeButtonClick(row, $event)\"> -1 ) || ( row.treeNode.children && row.treeNode.children.length > 0 ) ) && row.treeNode.state === 'expanded', 'ui-grid-icon-plus-squared': ( ( grid.options.showTreeExpandNoChildren && row.treeLevel > -1 ) || ( row.treeNode.children && row.treeNode.children.length > 0 ) ) && row.treeNode.state === 'collapsed'}\" ng-style=\"{'padding-left': grid.options.treeIndent * row.treeLevel + 'px'}\">  
    " + ); + +}]); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.svg b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.svg similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.svg rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.svg diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.ttf b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.ttf similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.ttf rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.ttf diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.woff b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.woff similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.woff rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.woff diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/vfs_fonts.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/uigrid/vfs_fonts.js similarity index 100% rename from ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/vfs_fonts.js rename to ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/raptor/uigrid/vfs_fonts.js diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/flexslider.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/flexslider.css new file mode 100644 index 00000000..c459ef44 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/flexslider.css @@ -0,0 +1,275 @@ +/* + * jQuery FlexSlider v2.6.0 + * http://www.woothemes.com/flexslider/ + * + * Copyright 2012 WooThemes + * Free to use under the GPLv2 and later license. + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Contributing author: Tyler Smith (@mbmufffin) + * + */ +/* ==================================================================================================================== + * FONT-FACE + * ====================================================================================================================*/ +@font-face { + font-family: 'flexslider-icon'; + src: url('fonts/flexslider-icon.eot'); + src: url('fonts/flexslider-icon.eot?#iefix') format('embedded-opentype'), url('fonts/flexslider-icon.woff') format('woff'), url('fonts/flexslider-icon.ttf') format('truetype'), url('fonts/flexslider-icon.svg#flexslider-icon') format('svg'); + font-weight: normal; + font-style: normal; +} +/* ==================================================================================================================== + * RESETS + * ====================================================================================================================*/ +.flex-container a:hover, +.flex-slider a:hover { + outline: none; +} +.slides, +.slides > li, +.flex-control-nav, +.flex-direction-nav { + margin: 0; + padding: 0; + list-style: none; +} +.flex-pauseplay span { + text-transform: capitalize; +} +/* ==================================================================================================================== + * BASE STYLES + * ====================================================================================================================*/ +.flexslider { + margin: 0; + padding: 0; +} +.flexslider .slides > li { + display: none; + -webkit-backface-visibility: hidden; +} +.flexslider .slides img { + width: 100%; + display: block; +} +.flexslider .slides:after { + content: "\0020"; + display: block; + clear: both; + visibility: hidden; + line-height: 0; + height: 0; +} +html[xmlns] .flexslider .slides { + display: block; +} +* html .flexslider .slides { + height: 1%; +} +.no-js .flexslider .slides > li:first-child { + display: block; +} +/* ==================================================================================================================== + * DEFAULT THEME + * ====================================================================================================================*/ +.flexslider { + margin: 0 0 60px; + background: #ffffff; + border: 4px solid #ffffff; + position: relative; + zoom: 1; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2); + -moz-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2); + -o-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2); + box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2); +} +.flexslider .slides { + zoom: 1; +} +.flexslider .slides img { + height: auto; + -moz-user-select: none; +} +.flex-viewport { + max-height: 2000px; + -webkit-transition: all 1s ease; + -moz-transition: all 1s ease; + -ms-transition: all 1s ease; + -o-transition: all 1s ease; + transition: all 1s ease; +} +.loading .flex-viewport { + max-height: 300px; +} +.carousel li { + margin-right: 5px; +} +.flex-direction-nav { + *height: 0; +} +.flex-direction-nav a { + text-decoration: none; + display: block; + width: 40px; + height: 40px; + margin: -20px 0 0; + position: absolute; + top: 50%; + z-index: 10; + overflow: hidden; + opacity: 0; + cursor: pointer; + color: rgba(0, 0, 0, 0.8); + text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3); + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; +} +.flex-direction-nav a:before { + font-family: "flexslider-icon"; + font-size: 40px; + display: inline-block; + content: '\f001'; + color: rgba(0, 0, 0, 0.8); + text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3); +} +.flex-direction-nav a.flex-next:before { + content: '\f002'; +} +.flex-direction-nav .flex-prev { + left: -50px; +} +.flex-direction-nav .flex-next { + right: -50px; + text-align: right; +} +.flexslider:hover .flex-direction-nav .flex-prev { + opacity: 0.7; + left: 10px; +} +.flexslider:hover .flex-direction-nav .flex-prev:hover { + opacity: 1; +} +.flexslider:hover .flex-direction-nav .flex-next { + opacity: 0.7; + right: 10px; +} +.flexslider:hover .flex-direction-nav .flex-next:hover { + opacity: 1; +} +.flex-direction-nav .flex-disabled { + opacity: 0!important; + filter: alpha(opacity=0); + cursor: default; + z-index: -1; +} +.flex-pauseplay a { + display: block; + width: 20px; + height: 20px; + position: absolute; + bottom: 5px; + left: 10px; + opacity: 0.8; + z-index: 10; + overflow: hidden; + cursor: pointer; + color: #000; +} +.flex-pauseplay a:before { + font-family: "flexslider-icon"; + font-size: 20px; + display: inline-block; + content: '\f004'; +} +.flex-pauseplay a:hover { + opacity: 1; +} +.flex-pauseplay a.flex-play:before { + content: '\f003'; +} +.flex-control-nav { + width: 100%; + position: absolute; + bottom: -40px; + text-align: center; +} +.flex-control-nav li { + margin: 0 6px; + display: inline-block; + zoom: 1; + *display: inline; +} +.flex-control-paging li a { + width: 11px; + height: 11px; + display: block; + background: #666; + background: rgba(0, 0, 0, 0.5); + cursor: pointer; + text-indent: -9999px; + -webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3); + -moz-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3); + -o-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3); + box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3); + -webkit-border-radius: 20px; + -moz-border-radius: 20px; + border-radius: 20px; +} +.flex-control-paging li a:hover { + background: #333; + background: rgba(0, 0, 0, 0.7); +} +.flex-control-paging li a.flex-active { + background: #000; + background: rgba(0, 0, 0, 0.9); + cursor: default; +} +.flex-control-thumbs { + margin: 5px 0 0; + position: static; + overflow: hidden; +} +.flex-control-thumbs li { + width: 25%; + float: left; + margin: 0; +} +.flex-control-thumbs img { + width: 100%; + height: auto; + display: block; + opacity: .7; + cursor: pointer; + -moz-user-select: none; + -webkit-transition: all 1s ease; + -moz-transition: all 1s ease; + -ms-transition: all 1s ease; + -o-transition: all 1s ease; + transition: all 1s ease; +} +.flex-control-thumbs img:hover { + opacity: 1; +} +.flex-control-thumbs .flex-active { + opacity: 1; + cursor: default; +} +/* ==================================================================================================================== + * RESPONSIVE + * ====================================================================================================================*/ +@media screen and (max-width: 860px) { + .flex-direction-nav .flex-prev { + opacity: 1; + left: 10px; + } + .flex-direction-nav .flex-next { + opacity: 1; + right: 10px; + } +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.eot b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.eot new file mode 100644 index 0000000000000000000000000000000000000000..97c4196f5565e56a244609b8120505488331b152 GIT binary patch literal 2082 zcmds2&2Jk;6o1dVUhi($gw)1{HcgkLq?OvF_Qr8SfyRf{MJN@PKo)QzR%|Cmj&0dN zN^|m`P^p4);1F;QNL+eA&{iBQajVM5p;B7}YE;fhmJkO(iuuj#By}TD#Fdq2-tT?P z^P72Z-i(<C1{G`usYZej6{SEqR}Xu$-H@~bmz}QM4?w99l3b^ zLWWXgfIkV|ef^Cy-nmCVeuhPFfzK_i=Ih(1wMXFZV&s((JaJh$3NF=&9%FK-1?Hp_!|0x+#B|{d9(ZA-JzF%rvZj7 z(YF^r|Ku_4b-2SV@TN*2T;bR1b?Bt9-$`SJEL;Dy{68-{vb6B$LPa zMaa%6dXJ(=YhRTJ`@O;d&Xz6|DBY!QP{q)qbW6r0Ed3n-d;si{gK?A>fm;}x$fW;? z3KU~RMV2q4N5G=Y#pwTbmHo2+ zFFsBSxS}6YhrYwHIK5w4<0heoV<#q(^PKXIaWpc-F))2dJ6{;4Y4C#a(GA@&xNaEw4IN!fWVN@=E!5Kx z9Ye;4BgQEnlPh0hFB;m%bIUebhApS<$B?r-n?lNqV(!D@tWdF6S)=FF9>>SjCR5Wm zv{^Yv`Kr~nok6p0+lS<~HY~@n!`2TD@tkEgDrmzm1Ulb0aTMQ^{&=Ajx8>EYK9ffNj2XIT`3TtS?^9t** z`9|R&?)z^F8#KzXgPMD(Qe1CV%7tQMvbY?qPmVa=i)o@vt-6+}HI|F6Hx+l!y8FU_Br!MXO?vSJj1PF9_N~QJ@y{<* zuGnanYgIQfh3D$O`t + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.ttf b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.ttf new file mode 100644 index 0000000000000000000000000000000000000000..05432986a52b0f912ca393ebe5ef90b6d152e9bb GIT binary patch literal 1892 zcmds2&2Jk;6#qSYz24p6gw)1{Hf@)rq?OvFw&OUVK;uK}BGigVAPcwe5H=->3bqbfrz+LO@A5xJTOkE>0=? zgB(}oX?WP4#D=T)sGZ`;a@tJfRe1{`STZF~Q+8g{?+`}|+!o?F4aTDbK)PJMxQ1L0 zy^xNfja=J{Ng4SW5WG$7BEor8R*2i2yR4)?ly5aBbmYtAR1Om`kRdfmMaA9=v0@xO z_|&s9D6qK0VEiV+^voU@9D%4@)f^rJ<*@Aki%;M(%6JD|e9dEt^naD0w7?!toSe=q zNj804;;}JFsKuPTwP)LV_7OX3+dDfp$q~EbO%Lu|bq*8I&r$k`(oX_-%G-EWrswJI zq_=ubB}z|+?U?T=W=&Xo_Kk?sp;spovFVFz)S*C?tAAHkq=*sv3z^gN)I=on&^7hqmCYak*x9oXDuvahyY5T03?m;zaFl zBa}NGYg94*Svp>x{tagIRFJxUR85n_n~z z@wFJy*un2Ji#ASO=~)*X-3m|O&J%2FJr*# fgi&&jd*4!gkkuD<(%>}|rMdmw2j3_<{Ezt?pE?K; literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.woff b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/fonts/flexslider-icon.woff new file mode 100644 index 0000000000000000000000000000000000000000..10c4eeb8355ffd7a51fe733cd15a0bd3cd5f9ee7 GIT binary patch literal 1268 zcmY+D3rtg27{|}$@~UZBL1>E#R_GW?CzPim!irc7&nd_{-MZTcrEI;>0h886rSg)L zM~l3~5~q#7Q2*p4hZko+O#!HzmB2LhXq&ro&WMA^nJ^$Z#&iQh_drp2b zj|UI{!}b}VSicUEH{Lq_fADyzi2xu0kgkK;ART?_5*xFd2U!C28=;sW6xb)H_y__IE(a=fC96J41|ejS15YRx`nl!049`>M!!QXr9&|}# zD*Wr>LOb0c0|_@AA^@=FBp5b@ib(cUOa#Z$DNxPEJW*iV2X?;6mrL{nah(`w9hHp` z1m@7(6?B5*8Wa$~=?)Ac)Zq9CReP_|F!e+|jrxhNT2S)3athgrLME3pw*$O%jUMhZ zSw27^m}Jx+FK`;?Fp5@NF!aF(Q5^;EKAbZ;DK5Se6*X3mJxb+hhU|7$I2W5{wb2a`|v|_CE0!fo(q9}w^8ap)m})l;ZjTH>HPfLY}@QyI(OHg(v{}p z$mbhTKL6nK`Ubx0RzF(NJhBLAw800S>M$++iJMafy<$jYSihA#RY_YlblOno&SrRUC%wy^IY$J_lG9qHbX%kFYftSm^ z(#g8HXJ-XZ+Cx0kJC@kv#yz`~J!XRZyyv~XlDOf=bH_dH( z`9o)!ELM8k$T?42I`Q+N2jtZNRk5&drHhx9+L@qT>biz6&AcxaSd_nyRA1W=68^%Z ze7ZI#XOnqr;ZQ@aP@X~`dQ{4HKlp{0;N$zJqr;9|=x-)%kFPPVF5?@{cYJ4TZyPk* z>}`sMx9jac1~Ya$q9)4cFPpCuV@lv_P~1MU6m7d|0kg=EJ+r=0O=7J9rHzz>u)%NF z$X^^Q;1(_d^lFp?ljO=p^q|PYF8Fmmf&fU0JA>iIP^$TL9K@IfE0Ft`n?ZCXngaLu zFIe#XNI@MSfa%}+CixJ(}7<5qNLjiO^J2=i@Vsn~Uv%H3KT=sNU!%w|?Iea^!q-Wn1>(A0I6UZ*24xB=3EF zMlmKL-r1&Z(5cIGWx7+kVqLASLf6zE?ElLcK~Uq?b2G)hxJ`57*&YNWdQd{ZKg#6U Ao&W#< literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/images/blank.gif b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/images/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..75b945d2553848b8b6f41fe5e24599c0687b8472 GIT binary patch literal 49 zcmZ?wbhEHbWMp7unE0RJ|Ns9C3=9Vj8~~DvKUo+V7?>DzfNY>Fh|Ltj$Y2csQN9XW literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/scribble.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/scribble.css new file mode 100644 index 00000000..9986f2ac --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/scribble.css @@ -0,0 +1,40 @@ +#scribble-pad { +/* margin-left:auto; + margin-right:auto; + height: 475px; + width: 475px;*/ + background:url(https://www.ibm.com/developerworks/mydeveloperworks/blogs/bobleah/resource/stickynote.jpg) no-repeat center center; + background-size: 110% 110%; +} + + + +#scribble { + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ + max-width: 300px; + padding: 120px 100px 100px 75px; + color: #486891; + border-color: #ff0000 #0000ff; + border-color: transparent; + background-color:rgba(0, 0, 0, 0); + font-family: Arial,sans-serif; + font-size: 120%; + font-style: italic; + font-weight:bold; + line-height: 1.5em; +} + +#scribble:focus { +outline-width: 0; +} +.c-link { + color: #486891; + font-family: Arial,sans-serif; + font-size: 95%; + font-weight:bold; + text-decoration: none; +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/slider.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/slider.css new file mode 100644 index 00000000..f609403c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/slider.css @@ -0,0 +1,142 @@ +div,span,p { margin:0; padding:0; border:0; outline:0; font-weight:inherit; font-style:inherit; font-size:100%; font-family:inherit; vertical-align:baseline; } + + +#container { + width:580px; + padding:10px; + margin:0 auto; + position:relative; + z-index:0; +} + +#example { + width:600px; + height:350px; + position:relative; +} + +#ribbon { + position:absolute; + top:-3px; + left:-15px; + z-index:500; +} + +#frame { + position:absolute; + z-index:0; + width:739px; + height:341px; + top:-3px; + left:-80px; +} + +/* + Slideshow +*/ + +#slides { + position:absolute; + top:15px; + left:4px; + z-index:100; +} + +/* + Slides container + Important: + Set the width of your slides container + Set to display none, prevents content flash +*/ + +.slides_container { + width:570px; + overflow:hidden; + position:relative; + display:none; +} + +/* + Each slide + Important: + Set the width of your slides + If height not specified height will be set by the slide content + Set to display block +*/ + +.slides_container div.slide { + width:570px; + height:270px; + display:block; +} + + +/* + Next/prev buttons +*/ + +#slides .next,#slides .prev { + position:absolute; + top:107px; + left:-39px; + width:24px; + height:43px; + display:block; + z-index:101; +} + +#slides .next { + left:585px; +} + +/* + Pagination +*/ + +.pagination { + margin:26px auto 0; + width:100px; +} + +.pagination li { + float:left; + margin:0 1px; + list-style:none; +} + +.pagination li a { + display:block; + width:12px; + height:0; + padding-top:12px; + background-image:url(../images/pagination.png); + background-position:0 0; + float:left; + overflow:hidden; +} + +.pagination li.current a { + background-position:0 -12px; +} + +/* + Caption +*/ + +.caption { + z-index:500; + position:absolute; + bottom:-35px; + left:0; + height:30px; + padding:5px 20px 0 20px; + background:#000; + background:rgba(0,0,0,.5); + width:540px; + font-size:1.3em; + line-height:1.33; + color:#fff; + border-top:1px solid #000; + text-shadow:none; +} + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/spacegallery.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/spacegallery.css new file mode 100644 index 00000000..ce4fd57c --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/spacegallery.css @@ -0,0 +1,18 @@ +.spacegallery { + position: relative; + overflow: hidden; +} +.spacegallery img { + position: absolute; + left: 50%; +} +.spacegallery a { + position: absolute; + z-index: 1000; + display: block; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: url(images/blank.gif); +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/welcome.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/welcome.css new file mode 100644 index 00000000..4e52d662 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/css/welcome.css @@ -0,0 +1,173 @@ +/* Area Chart */ + +#areaChart { + overflow: hidden;} + +#lineChart { + overflow: hidden; +} + +#areaChart svg { + height: 200px; + width: 380px; + min-width: 100px; + min-height: 100px; +} + +#lineChart svg { + height: 200px; + width: 380px; + min-width: 100px; + min-height: 100px; +} + +#areaChart tr.z-row-over>td.z-row-inner, tr.z-row-over>.z-cell { + background-color: rgb(255, 255, 255); +} + +#lineChart tr.z-row-over>td.z-row-inner, tr.z-row-over>.z-cell { + background-color: rgb(255, 255, 255); +} + +#areaChart .nodatadiv { + display: table-cell; + width: 700px; + height: 370px; + text-align: center; + vertical-align: middle; +} + +#lineChart .nodatadiv { + display: table-cell; + width: 700px; + height: 370px; + text-align: center; + vertical-align: middle; +} + +#areaChart .nodatainner { + padding: 10px; +} + +#lineChart .nodatainner { + padding: 10px; +} + +/* Area Chart END */ + +.button--small, [class*=bg-] .button--small { + font-size: 14px; + }; + +/* Gridster (EBIZ) */ + +.gridster-item-container .gridster-item-body{ +bottom:0px; +} +.gridster-item-container{ +min-height:50px; +} +.att-accordion { + border-width: 0px; +} + +/* End Gridster */ + +#myGallery { + width: 100%; + height: 400px; +} + +#myGallery img { + border: 2px solid #52697E; +} + +a.loading { + background: #fff url(../images/ajax_small.gif) no-repeat center; +} + +.center { + margin-left: auto; + margin-right: auto; +} + + +#selectedTrafficDay ul { + list-style: none; + padding: 0; + margin: 0; +} + +#selectedTrafficDay li { + float: left; + border: 1px solid #000; + border-bottom-width: 0; + margin: 3px 3px 3px 3px; + padding: 5px 5px 5px 5px; + background-color: #F2F2F2; + color: #696969; +} + +#SelectedTrafficeDayView { + padding: 0 1em; +} + +#selectedTrafficDay .active1 { + background-color: #FFF; + color: #000; +} + +#BusyHourTraffic ul { + list-style: none; + padding: 0; + margin: 0; +} + +#BusyHourTraffic li { + float: left; + border: 1px solid #000; + border-bottom-width: 0; + margin: 3px 3px 3px 3px; + padding: 5px 5px 5px 5px; + background-color: #F2F2F2; + color: #696969; +} + +#BusyHourTrafficView { + padding: 0 1em; +} + +#BusyHourTraffic .active2 { + background-color: #FFF; + color: #000; +} + +#slider { + width: 600px; + margin: 0 auto; + clear: left; +} + +@media only screen and (device-width: 768px) { + #slider { + width: 400px; + } +} + +#container { + +} + +#title { + float:left; + width:100%; + height:30px; + margin:; + color:#222222; + text-shadow: 1px 1px 2px #A0A0A0; +} +.content{ + margin-right:-230px; + top:50px; + +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/area_chart.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/area_chart.html new file mode 100644 index 00000000..30ef2011 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/area_chart.html @@ -0,0 +1,49 @@ + + + + + + + +

    + + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/bar_chart.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/bar_chart.html new file mode 100644 index 00000000..0be16ec1 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/bar_chart.html @@ -0,0 +1,95 @@ + + + + + + + +

    + + + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/d3_gauges_demo.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/d3_gauges_demo.html new file mode 100644 index 00000000..94596e73 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/d3_gauges_demo.html @@ -0,0 +1,39 @@ + + + + + d3.js gauges + + + + + + + + + + + + + + +
    + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/speedometer2.csv b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/speedometer2.csv new file mode 100644 index 00000000..406143ea --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/speedometer2.csv @@ -0,0 +1,16 @@ +"YEARMONTH","Bedminster","Piscataway","Middletown","Paramus" +"201401",8.27,4.89,2.36,2.17 +"201402",10.02,4.57,3.15,3.01 +"201403",11.16,5.00,4.27,4.06 +"201404",13.31,5.00,5.35,5.11 +"201405",12.82,5.00,5.01,4.74 +"201406",14.01,6.09,9.17,8.98 +"201407",14.66,7.00,8.84,8.41 +"201408",16.95,7.02,12.22,11.84 +"201409",21.56,8.12,16.09,15.50 +"201410",25.35,9.00,19.04,18.37 +"201411",21.93,9.00,17.61,17.13 +"201412",24.00,9.00,19.00,18.00 +"201501",25.14,2.01,15.19,12.13 +"201502",26.30,2.67,16.95,13.47 +"201503",26.5833333333333,45.63333333333333,16.1166666666667,12.40 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/speedometer3.csv b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/speedometer3.csv new file mode 100644 index 00000000..046383e4 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/speedometer3.csv @@ -0,0 +1,2 @@ +"YEARMONTH","Bedminster","Piscataway","Middletown","Paramus" +"201401",8.27,4.89,2.36,2.17 \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/worddata.csv b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/worddata.csv new file mode 100644 index 00000000..762cb423 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/data/worddata.csv @@ -0,0 +1 @@ +text,frequency service,98 portal,70 management,70 virtual,56 design,56 VNF,56 studio,42 operations,42 inventory,42 POLO,42 D2.0,42 ASDC,42 router,28 restart,28 process,28 platform,28 manage,28 loop,28 licensing,28 license,28 integrated,28 flow-through,28 enable,28 data,28 controller,28 control,28 configure,28 component,28 common,28 asset,28 application,28 ECOMP,28 workflow,14 waterfall,14 visual,14 view,14 vCTS,14 utilization,14 user,14 usage,14 troubleshoot,14 transformation,14 track,14 topolgies,14 topics,14 time,14 tickets,14 thresholds,14 templates,14 structures,14 standards-based,14 software,14 reuse,14 repository,14 reports,14 release,14 recipes,14 real-time,14 provisioning,14 properties,14 project-based,14 processes,14 physical,14 oversight,14 openl-loop,14 network,14 monitor,14 modeling,14 model-driven,14 model,14 message,14 maximize,14 manually,14 machine,14 layer,14 interact,14 instances,14 initiate,14 increase,14 imported,14 impacts,14 host,14 function,14 feeds,14 features,14 faults,14 extended,14 engines,14 engine,14 dynamic,14 document-driven,14 determine,14 dashboard,14 current,14 creation,14 created,14 create,14 configuration,14 composer,14 components,14 collective,14 certification,14 bus,14 basis,14 available,14 automation,14 automated,14 associated,14 assignment,14 appropriate,14 against,14 aervice,14 adminstrators,14 activation,14 action,14 VMs,14 VM,14 VLAN,14 SDN,14 SDK,14 SBG,14 SAM,14 RUBY,14 Policy,14 PODS,14 Ops,14 GFP,14 F5FW,14 DMaaP,14 DCAE,14 DBC,14 CPADS,14 AT&T,14 APP-C,14 AOTS-TM,14 ALTS,14 A&AI,14 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/donut_d3.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/donut_d3.html new file mode 100644 index 00000000..afcac359 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/donut_d3.html @@ -0,0 +1,43 @@ + + + + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/area_chart.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/area_chart.min.js new file mode 100644 index 00000000..9b3decb9 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/area_chart.min.js @@ -0,0 +1 @@ +function redrawAreaChart(){d3.select("#areaChart svg").datum(historicalBarChart).call(area_chart)}var area_chart;nv.addGraph(function(){return area_chart=nv.models.stackedAreaChart().showControls(!1).margin({top:30,right:60,bottom:50,left:100}).showLegend(!1).yAxisTooltipFormat(d3.format(",.1f")).x(function(a){return a.x}).y(function(a){return a.y}).color(d3.scale.category10().range()),area_chart.xAxis.axisLabel("").staggerLabels(!1).showMaxMin(!1).rotateLabels(90).tickFormat(function(a){return d3.time.format("%b %y")(new Date(a))}),area_chart.yAxis.axisLabel("").tickFormat(d3.format(",.1f")),d3.select("#areaChart svg").datum(historicalBarChart).call(area_chart),nv.utils.windowResize(area_chart.update),area_chart}),redrawAreaChart(),historicalBarChart.length<=0&&(document.getElementById("areaChart").innerHTML="
    No Data Available
    ",document.getElementById("areaChart").className="nodatadiv",document.getElementById("nodata").className="nodatainner"); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/donut.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/donut.min.js new file mode 100644 index 00000000..60c4fd4b --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/donut.min.js @@ -0,0 +1 @@ +function angle(t){var e=90*(t.startAngle+t.endAngle)/Math.PI-90;return e>90?e-180:e}function arcTween(t,e){return function(){d3.select(this).transition().delay(e).attrTween("d",function(e){var r=d3.interpolate(e.outerRadius,t);return function(t){return e.outerRadius=r(t),arc(e)}})}}var arc=d3.svg.arc().padRadius(outerRadius).innerRadius(innerRadius),pie=d3.layout.pie().sort(null).padAngle(.02).value(function(t){return t.performance});d3.csv(dataURL,function(t,e){color.domain(d3.keys(e[0]).filter(function(t){return"YEARMONTH"!==t})),e.forEach(function(t){t.performance=color.domain().map(function(e){return{name:e,performance:+t[e]}})});var r=d3.select("body").append("svg").attr("class","legend").attr("width",radius).attr("height",2*radius).selectAll("g").data(color.domain().slice().reverse()).enter().append("g").attr("transform",function(t,e){return"translate(0,"+20*e+")"});r.append("rect").attr("width",18).attr("height",18).style("fill",color),r.append("text").attr("x",24).attr("y",9).attr("dy",".35em").text(function(t){return t});var a=d3.select("body").append("svg").attr("width",width).attr("height",height).data(e).append("g").attr("transform","translate("+radius+","+height/2+")"),n=a.selectAll("g.slice").data(function(t){return pie(t.performance)}).enter().append("g").attr("class","slice");n.append("path").each(function(t){t.outerRadius=outerRadius-10}).attr("class","arc").attr("d",arc).style("fill",function(t){return color(t.data.name)}).on("mouseover",arcTween(outerRadius,0)).on("mouseout",arcTween(outerRadius-10,150)),n.append("text").attr("dy",".35em").attr("transform",function(t){return t.outerRadius=outerRadius,t.innerRadius=outerRadius/2,"translate("+arc.centroid(t)+")rotate("+angle(t)+")"}).attr("text-anchor","middle").style("fill","white").style("font","bold 12px Arial").text(function(t){return t.value}),a.append("text").attr("dy",".35em").style("text-anchor","middle").text(function(t){return t.YEARMONTH})}); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/gauges.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/gauges.min.js new file mode 100644 index 00000000..c0fd7484 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/gauges.min.js @@ -0,0 +1 @@ +function Gauge(t,i){this.placeholderName=t;var n=this;this.configure=function(t){this.config=t,this.config.size=.9*this.config.size,this.config.raduis=.97*this.config.size/2,this.config.cx=this.config.size/2,this.config.cy=this.config.size/2,this.config.min=void 0!=t.min?t.min:0,this.config.max=void 0!=t.max?t.max:100,this.config.range=this.config.max-this.config.min,this.config.majorTicks=t.majorTicks||5,this.config.minorTicks=t.minorTicks||2,this.config.greenColor=t.greenColor||"#109618",this.config.yellowColor=t.yellowColor||"#FF9900",this.config.redColor=t.redColor||"#DC3912",this.config.transitionDuration=t.transitionDuration||500},this.render=function(){this.body=d3.select("#"+this.placeholderName).append("svg:svg").attr("class","gauge").attr("width",this.config.size).attr("height",this.config.size),this.body.append("svg:circle").attr("cx",this.config.cx).attr("cy",this.config.cy).attr("r",this.config.raduis).style("fill","#ccc").style("stroke","#000").style("stroke-width","0.5px"),this.body.append("svg:circle").attr("cx",this.config.cx).attr("cy",this.config.cy).attr("r",.9*this.config.raduis).style("fill","#fff").style("stroke","#e0e0e0").style("stroke-width","2px");for(var t in this.config.greenZones)this.drawBand(this.config.greenZones[t].from,this.config.greenZones[t].to,n.config.greenColor);for(var t in this.config.yellowZones)this.drawBand(this.config.yellowZones[t].from,this.config.yellowZones[t].to,n.config.yellowColor);for(var t in this.config.redZones)this.drawBand(this.config.redZones[t].from,this.config.redZones[t].to,n.config.redColor);if(void 0!=this.config.label){var i=Math.round(this.config.size/12);this.body.append("svg:text").attr("x",this.config.cx).attr("y",this.config.cy/2+i/2).attr("dy",i/2).attr("text-anchor","middle").text(this.config.label).style("font-size",i+"px").style("fill","#333").style("stroke-width","0px")}for(var i=Math.round(this.config.size/16),e=this.config.range/(this.config.majorTicks-1),o=this.config.min;o<=this.config.max;o+=e){for(var a=e/this.config.minorTicks,r=o+a;r=i-t||this.body.append("svg:path").style("fill",e).attr("d",d3.svg.arc().startAngle(this.valueToRadians(t)).endAngle(this.valueToRadians(i)).innerRadius(.65*this.config.raduis).outerRadius(.85*this.config.raduis)).attr("transform",function(){return"translate("+n.config.cx+", "+n.config.cy+") rotate(270)"})},this.redraw=function(t,i,e){var o=this.body.select(".pointerContainer"),a=o.selectAll("text");y=a.attr("y"),dy=parseFloat(a.attr("dy")),a.selectAll("tspan").remove(),a.append("tspan").attr("x",45).attr("dy",0).text(Math.round(t)),a.append("tspan").attr("x",45).attr("dy",10).text(i),o.selectAll("text").style("fill",function(){var i=n.config.max-n.config.min;return Math.round(t)>.9*i?"#DC3912":Math.round(t)>.5*i&&Math.round(t)<.9*i?"#FF9900":"#000000"});var r=o.selectAll("path");r.transition().duration(void 0!=e?e:this.config.transitionDuration).attrTween("transform",function(){var i=t;t>n.config.max?i=n.config.max+.02*n.config.range:tNo Data Available",document.getElementById("lineChart").className="nodatadiv",document.getElementById("nodata2").className="nodatainner"); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/pie_chart.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/pie_chart.min.js new file mode 100644 index 00000000..f78eec70 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/pie_chart.min.js @@ -0,0 +1 @@ +function redraw(){d3.select("#chart423 svg").datum(historicalBarChart).transition().duration(500).call(chart)}var chart;nv.addGraph(function(){return chart=nv.models.pieChart().margin({top:30,right:60,bottom:50,left:100}).x(function(t){return t.key}).y(function(t){return t.y}),chart.showLegend(!1),d3.select("#chart423 svg").datum(historicalBarChart).transition().duration(1200).call(chart),nv.utils.windowResize(chart.update),chart}),setInterval(function(){redraw()},1500),historicalBarChart.length<=0&&(document.getElementById("chart423").innerHTML="
    No Data Available
    ",document.getElementById("chart423").className="nodatadiv",document.getElementById("nodata").className="nodatainner"); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/worddata.min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/worddata.min.js new file mode 100644 index 00000000..6b827460 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/js/worddata.min.js @@ -0,0 +1 @@ +function dataViz(t){function e(t){var e=d3.select("svg").append("g").attr("id","wordCloudG").attr("transform","translate(210,175)");e.selectAll("text").data(t).enter().append("text").style("font-size",function(t){return 1*t.size+"px"}).style("fill",function(t){return keywords.indexOf(t.text)>-1?"red":"black"}).style("opacity",.75).attr("text-anchor","middle").attr("transform",function(t){return"translate("+[t.x,t.y]+")rotate("+t.rotate+")"}).text(function(t){return t.text})}d3.layout.cloud().size([420,350]).words(t).rotate(function(t){return t.text.length>5?0:90}).fontSize(function(t){return wordScale(t.frequency)}).on("end",e).start()}d3.csv(dataURL,function(t){dataViz(t)}),wordScale=d3.scale.linear().domain([0,100]).range([0,70]).clamp(!0); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/line_chart.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/line_chart.html new file mode 100644 index 00000000..d4ba57a4 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/line_chart.html @@ -0,0 +1,49 @@ + + + + + + + +

    + + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/pie_chart.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/pie_chart.html new file mode 100644 index 00000000..ebbdd9c0 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/pie_chart.html @@ -0,0 +1,38 @@ + + + + + + + +
    + + + + + + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/wordcloud.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/wordcloud.html new file mode 100644 index 00000000..6cf00079 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/html/wordcloud.html @@ -0,0 +1,36 @@ + + + Word Cloud Example + + + + + + + + + +
    + + +
    +
    + +
    + + + +
    + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/Calendar-16x16.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/Calendar-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..ac970bda5aef01cd511c0e7057a2908c35684fb2 GIT binary patch literal 552 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 Hu0mjfDDUGo literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_drive_test_map.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_drive_test_map.png new file mode 100644 index 0000000000000000000000000000000000000000..78a8873bbfa7e99dbcd07844e2739beb35736238 GIT binary patch literal 202465 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⁡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 AegFUf literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_eppt_county.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_eppt_county.png new file mode 100644 index 0000000000000000000000000000000000000000..df471d7d8591af0fbedb1db3405d5d8e94443f7a GIT binary patch literal 21222 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_eppt_regression.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_eppt_regression.png new file mode 100644 index 0000000000000000000000000000000000000000..e59fc189c0ea74340c764c2d356da7bb9487d33c GIT binary patch literal 11536 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 GnEwMu?xSD; literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_lata_map.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_lata_map.png new file mode 100644 index 0000000000000000000000000000000000000000..174ef9b8e8b47a2d09b02962270cf1d233acbb97 GIT binary patch literal 192031 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_lata_map_legend.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_lata_map_legend.png new file mode 100644 index 0000000000000000000000000000000000000000..f7f2719ae94b0d6440803f985ffd14ef441863b8 GIT binary patch literal 3021 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_nova_sdn_map.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/carousel/slide_b_nova_sdn_map.png new file mode 100644 index 0000000000000000000000000000000000000000..ee0ddef913d9203fb1dcd752a9748c25566bf0a6 GIT binary patch literal 179361 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

    &`J;XCF}C}D@|&>9^xqb8BVpoGA;^#WWD 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 V3~|ceSquOG002ovPDHLkV1mEs$szy% literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/copyicon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/copyicon.png new file mode 100644 index 0000000000000000000000000000000000000000..6c1c3c155f6d2dbaf649a4f5094ff679b95960c9 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~q!3HGX7W?Z1DaPU;cPEB*=VV?2Ic!PZ?k)`C z3>^$7)npGG1d4DLctjR6FmMZlFeAgPITAoY_7YEDSN1!MTw=l^GqS((0)?_YT^vI+ z&flH1oA-bLhf9A)V!q0;B$;wQVb_0}$I8UDRQM|9Oqe3%=fv2M(q}efW(o7WLtAD( zneo8;f}Td^S)US>S#tt(Z!1<5mmfDf*vWo%g1kV?>h-sSvRLY0IsUw_Qv77fLiW`r b3zF%z`1D?`s3%jufI0#KBi$}ACsD|ZRYsk#YasOhpTs=O`N;x z;Mtoyj-20r>Pkdn_PnKQb{x5|>*$4vbC=Irw6d_et$pI`MXR@InL5;WOuts z!{ReH9XR*l^OrfxHWk*i$ED>L)phmETzdTC&4XvIH}*`w^W=3_aZP4XT~1k3YF>q! zk==&f$751*tJ@~Nc>neI`Rjet=g(NQZpwnyvsY~S@%R7YRH%<=E7`yz-`< zM=rSeMLd4>Au+4i(L40~m0LRwpSy7D$@%LKrp{TqVehH3#_rw6uUx(T=;r-rx)#nU zc@@9_VW1aK{K>+|z!1Zr1F{elCk*Th8e*E78Cn^dJ31J6czJo+J7d}=PibMCK4T_h zzyt<9Gs$3MSuPt*7b&B;hFWg&${~)brW$H?6Jqok9R%(5BEy}9xxzXu8QEAkS=l+5 znF3WhEKZy{bB;;It0VgA>9gm#%scq+U4LlRA^PkAleb@o+?yNj1|8ar9=g6x5eiC7 mPG1~Y9tH_=iZ97Y2yAtmDOAtqh!89ZDp4AuZRknPU^ literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/example-frame.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/example-frame.png new file mode 100644 index 0000000000000000000000000000000000000000..31f2fe1cc66141a21c93cc3b9fdc53e09fd4a742 GIT binary patch literal 33699 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 z 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 Li@*OP`t$q`mG8q8 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/1_mon.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/1_mon.png new file mode 100644 index 0000000000000000000000000000000000000000..d46eee50533e46db5ed6c7579f887da1b552f996 GIT binary patch literal 22762 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 IH-CHdZ?zgZz5oCK literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/7_sun.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/7_sun.png new file mode 100644 index 0000000000000000000000000000000000000000..9d579d680b5f1d25f0b6bc6de121e6be6c990fc7 GIT binary patch literal 22845 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 N{HfC6JE={)lc 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 Z@V+X@{$L&s*p0}hf64e_iT3ro{{iM&5-$J% literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat_Def.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat_Def.png new file mode 100644 index 0000000000000000000000000000000000000000..a8b516d9f5ad2034541797b8a165825acded69b4 GIT binary patch literal 8941 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat_Priority.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/BH_Nat_Priority.png new file mode 100644 index 0000000000000000000000000000000000000000..2cf814113ff2e323a0989e5c990eab340a53962c GIT binary patch literal 10590 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 a_WPBf5I#}E3*4Ke(^dyvFT8dq=sy4^qgY`8 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/FusionCharts.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/FusionCharts.js new file mode 100644 index 00000000..4c174dfa --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/FusionCharts.js @@ -0,0 +1,361 @@ +/** + * FusionCharts: Flash Player detection and Chart embedding. + * Version 1.2.3F ( 22 November 2008) - Specialized for FusionChartsFREE + * Checking Flash Version >=6 and added updateChartXML() for FREE Charts. + * Version: 1.2.3 (1st September, 2008) - Added Fix for % and & characters, scaled dimensions, fixes in to properly handling of double quotes and single quotes in setDataXML() function. + * Version: 1.2.2 (10th July, 2008) - Added Fix for % scaled dimensions, fixes in setDataXML() and setDataURL() functions + * Version: 1.2.1 (21st December, 2007) - Added setting up Transparent/opaque mode: setTransparent() function + * Version: 1.2 (1st November, 2007) - Added FORM fixes for IE + * Version: 1.1 (29th June, 2007) - Added Player detection, New conditional fixes for IE + * + * Morphed from SWFObject (http://blog.deconcept.com/swfobject/) under MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ +if(typeof infosoftglobal == "undefined") var infosoftglobal = new Object(); +if(typeof infosoftglobal.FusionChartsUtil == "undefined") infosoftglobal.FusionChartsUtil = new Object(); +infosoftglobal.FusionCharts = function(swf, id, w, h, debugMode, registerWithJS, c, scaleMode, lang, detectFlashVersion, autoInstallRedirect){ + if (!document.getElementById) { return; } + + //Flag to see whether data has been set initially + this.initialDataSet = false; + + //Create container objects + this.params = new Object(); + this.variables = new Object(); + this.attributes = new Array(); + + //Set attributes for the SWF + if(swf) { this.setAttribute('swf', swf); } + if(id) { this.setAttribute('id', id); } + + w=w.toString().replace(/\%$/,"%25"); + if(w) { this.setAttribute('width', w); } + h=h.toString().replace(/\%$/,"%25"); + if(h) { this.setAttribute('height', h); } + + + //Set background color + if(c) { this.addParam('bgcolor', c); } + + //Set Quality + this.addParam('quality', 'high'); + + //Add scripting access parameter + this.addParam('allowScriptAccess', 'always'); + + //Pass width and height to be appended as chartWidth and chartHeight + this.addVariable('chartWidth', w); + this.addVariable('chartHeight', h); + + //Whether in debug mode + debugMode = debugMode ? debugMode : 0; + this.addVariable('debugMode', debugMode); + //Pass DOM ID to Chart + this.addVariable('DOMId', id); + //Whether to registed with JavaScript + registerWithJS = registerWithJS ? registerWithJS : 0; + this.addVariable('registerWithJS', registerWithJS); + + //Scale Mode of chart + scaleMode = scaleMode ? scaleMode : 'noScale'; + this.addVariable('scaleMode', scaleMode); + + //Application Message Language + lang = lang ? lang : 'EN'; + this.addVariable('lang', lang); + + //Whether to auto detect and re-direct to Flash Player installation + this.detectFlashVersion = detectFlashVersion?detectFlashVersion:1; + this.autoInstallRedirect = autoInstallRedirect?autoInstallRedirect:1; + + //Ger Flash Player version + this.installedVer = infosoftglobal.FusionChartsUtil.getPlayerVersion(); + + if (!window.opera && document.all && this.installedVer.major > 7) { + // Only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE + infosoftglobal.FusionCharts.doPrepUnload = true; + } +} + +infosoftglobal.FusionCharts.prototype = { + setAttribute: function(name, value){ + this.attributes[name] = value; + }, + getAttribute: function(name){ + return this.attributes[name]; + }, + addParam: function(name, value){ + this.params[name] = value; + }, + getParams: function(){ + return this.params; + }, + addVariable: function(name, value){ + this.variables[name] = value; + }, + getVariable: function(name){ + return this.variables[name]; + }, + getVariables: function(){ + return this.variables; + }, + getVariablePairs: function(){ + var variablePairs = new Array(); + var key; + var variables = this.getVariables(); + for(key in variables){ + variablePairs.push(key +"="+ variables[key]); + } + return variablePairs; + }, + getSWFHTML: function() { + var swfNode = ""; + if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { + // netscape plugin architecture + swfNode = ' 0){ swfNode += 'flashvars="'+ pairs +'"'; } + swfNode += '/>'; + } else { // PC IE + swfNode = ''; + swfNode += ''; + var params = this.getParams(); + for(var key in params) { + swfNode += ''; + } + var pairs = this.getVariablePairs().join("&"); + if(pairs.length > 0) {swfNode += '';} + swfNode += ""; + } + return swfNode; + }, + setDataURL: function(strDataURL){ + //This method sets the data URL for the chart. + //If being set initially + if (this.initialDataSet==false){ + this.addVariable('dataURL',strDataURL); + //Update flag + this.initialDataSet = true; + }else{ + //Else, we update the chart data using External Interface + //Get reference to chart object + var chartObj = infosoftglobal.FusionChartsUtil.getChartObject(this.getAttribute('id')); + + if (!chartObj.setDataURL) + { + __flash__addCallback(chartObj, "setDataURL"); + } + + chartObj.setDataURL(strDataURL); + } + }, + //This function : + //fixes the double quoted attributes to single quotes + //Encodes all quotes inside attribute values + //Encodes % to %25 and & to %26; + encodeDataXML: function(strDataXML){ + + var regExpReservedCharacters=["\\$","\\+"]; + var arrDQAtt=strDataXML.match(/=\s*\".*?\"/g); + if (arrDQAtt){ + for(var i=0;i compatibility + //Check if it's added in Mozilla embed array or if already exits + if(!document.embeds[this.getAttribute('id')] && !window[this.getAttribute('id')]) + window[this.getAttribute('id')]=document.getElementById(this.getAttribute('id')); + //or else document.forms[formName/formIndex][chartId] + return true; + } + } +} + +/* ---- detection functions ---- */ +infosoftglobal.FusionChartsUtil.getPlayerVersion = function(){ + var PlayerVersion = new infosoftglobal.PlayerVersion([0,0,0]); + if(navigator.plugins && navigator.mimeTypes.length){ + var x = navigator.plugins["Shockwave Flash"]; + if(x && x.description) { + PlayerVersion = new infosoftglobal.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split(".")); + } + }else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ + //If Windows CE + var axo = 1; + var counter = 3; + while(axo) { + try { + counter++; + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter); + PlayerVersion = new infosoftglobal.PlayerVersion([counter,0,0]); + } catch (e) { + axo = null; + } + } + } else { + // Win IE (non mobile) + // Do minor version lookup in IE, but avoid Flash Player 6 crashing issues + try{ + var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + }catch(e){ + try { + var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + PlayerVersion = new infosoftglobal.PlayerVersion([6,0,21]); + axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code) + } catch(e) { + if (PlayerVersion.major == 6) { + return PlayerVersion; + } + } + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + } catch(e) {} + } + if (axo != null) { + PlayerVersion = new infosoftglobal.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(",")); + } + } + return PlayerVersion; +} +infosoftglobal.PlayerVersion = function(arrVersion){ + this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0; + this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0; + this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0; +} +// ------------ Fix for Out of Memory Bug in IE in FP9 ---------------// +/* Fix for video streaming bug */ +infosoftglobal.FusionChartsUtil.cleanupSWFs = function() { + var objects = document.getElementsByTagName("OBJECT"); + for (var i = objects.length - 1; i >= 0; i--) { + objects[i].style.display = 'none'; + for (var x in objects[i]) { + if (typeof objects[i][x] == 'function') { + objects[i][x] = function(){}; + } + } + } +} +// Fixes bug in fp9 +if (infosoftglobal.FusionCharts.doPrepUnload) { + if (!infosoftglobal.unloadSet) { + infosoftglobal.FusionChartsUtil.prepUnload = function() { + __flash_unloadHandler = function(){}; + __flash_savedUnloadHandler = function(){}; + window.attachEvent("onunload", infosoftglobal.FusionChartsUtil.cleanupSWFs); + } + window.attachEvent("onbeforeunload", infosoftglobal.FusionChartsUtil.prepUnload); + infosoftglobal.unloadSet = true; + } +} +/* Add document.getElementById if needed (mobile IE < 5) */ +if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }} +/* Add Array.push if needed (ie5) */ +if (Array.prototype.push == null) { Array.prototype.push = function(item) { this[this.length] = item; return this.length; }} + +/* Function to return Flash Object from ID */ +infosoftglobal.FusionChartsUtil.getChartObject = function(id) +{ + var chartRef=null; + if (navigator.appName.indexOf("Microsoft Internet")==-1) { + if (document.embeds && document.embeds[id]) + chartRef = document.embeds[id]; + else + chartRef = window.document[id]; + } + else { + chartRef = window[id]; + } + if (!chartRef) + chartRef = document.getElementById(id); + + return chartRef; +} +/* + Function to update chart's data at client side (FOR FusionCharts vFREE and 2.x +*/ +infosoftglobal.FusionChartsUtil.updateChartXML = function(chartId, strXML){ + //Get reference to chart object + var chartObj = infosoftglobal.FusionChartsUtil.getChartObject(chartId); + //Set dataURL to null + chartObj.SetVariable("_root.dataURL",""); + //Set the flag + chartObj.SetVariable("_root.isNewData","1"); + //Set the actual data + chartObj.SetVariable("_root.newData",strXML); + //Go to the required frame + chartObj.TGotoLabel("/", "JavaScriptHandler"); +} + + +/* Aliases for easy usage */ +var getChartFromId = infosoftglobal.FusionChartsUtil.getChartObject; +var updateChartXML = infosoftglobal.FusionChartsUtil.updateChartXML; +var FusionCharts = infosoftglobal.FusionCharts; \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/charts.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/charts.js new file mode 100644 index 00000000..4bebbd36 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/charts.js @@ -0,0 +1,132 @@ + +function drawSingleSeriesChart(tabId, chartId, chartWidth, chartHeight, chartType, chartData,mme,yyyyMo) { + // define, set the data for each chart, and render them (if indicated) + var myChart = new FusionCharts("static/fusion/inc/fusionchart/" + chartType, "myChartId" + chartId, chartWidth, chartHeight); + + var mmeLabel = "";//mme + ""; + + var chartCaptionId = tabId + "-chartdiv" + chartId + "-label"; + + document.getElementById(chartCaptionId).innerHTML = "Hosted Voice Usage in "+ yyyyMo; + + myChart.setDataXML("" + chartData + ""); + myChart.setTransparent(true); + myChart.render(tabId + "-"+ "chartdiv" + chartId); + + + } + + + // gauge charts + function drawGaugeChart(chartId, gaugeIndex, value) { + var myChart = new FusionCharts("static/fusion/inc/fusionchart/AngularGauge.swf", "myChartId" + chartId, "300", "300", "0", "0"); + //CPU for NYCMNYBWLT1 on 201301 : 12.63// + var chartData = + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""; + + myChart.setDataXML(chartData); + myChart.render("chartdiv" + chartId); + } + + + function updateGaugeChart(chartId, gaugeIndex, refreshCount) { + var myChart = getChartFromId("myChartId" + chartId); + var val = 0; + if (gaugeIndex == "10") val = 12; + else if (gaugeIndex == "20") val = 15; + else if (gaugeIndex == "30") val = 52; + else if (gaugeIndex == "40") val = 42; + myChart.setData(1, val); + myChart.setData(2, val+20); + } + + function updateGaugeChartWithMMEData(chartId, value) { + var myChart = getChartFromId("myChartId" + chartId); + myChart.setData(1, value); + } + + + function updateGaugeChartWithMMEData(chartId, value, yyyyMo, mme) { + var myChart = getChartFromId("myChartId" + chartId); + myChart.setData(1, value); + document.getElementById("cpuYyyyMm").innerHTML = "Hosted Voice Utilization in "+ yyyyMo; + + } + + function drawMultiSeriesChart(tabId,chartId, chartWidth, chartHeight, chartType) { + var myChart = new FusionCharts("static/fusion/inc/fusionchart/" + chartType, "myChartId" + chartId, chartWidth, chartHeight, "0", "0"); + + myChart.setTransparent(true); + + var chartData = + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""; + + myChart.setDataXML(chartData); + myChart.render(tabId + "-" + "chartdiv" + chartId); + } + diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/eye.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/eye.js new file mode 100644 index 00000000..8a281dc3 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/eye.js @@ -0,0 +1,34 @@ +/** + * + * Zoomimage + * Author: Stefan Petre www.eyecon.ro + * + */ +(function($){ + var EYE = window.EYE = function() { + var _registered = { + init: [] + }; + return { + init: function() { + $.each(_registered.init, function(nr, fn){ + fn.call(); + }); + }, + extend: function(prop) { + for (var i in prop) { + if (prop[i] != undefined) { + this[i] = prop[i]; + } + } + }, + register: function(fn, type) { + if (!_registered[type]) { + _registered[type] = []; + } + _registered[type].push(fn); + } + }; + }(); + $(EYE.init); +})(jQuery); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/jquery.flexslider-min.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/jquery.flexslider-min.js new file mode 100644 index 00000000..5ad6c377 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/jquery.flexslider-min.js @@ -0,0 +1,5 @@ +/* + * jQuery FlexSlider v2.6.0 + * Copyright 2012 WooThemes + * Contributing Author: Tyler Smith + */!function($){var e=!0;$.flexslider=function(t,a){var n=$(t);n.vars=$.extend({},$.flexslider.defaults,a);var i=n.vars.namespace,s=window.navigator&&window.navigator.msPointerEnabled&&window.MSGesture,r=("ontouchstart"in window||s||window.DocumentTouch&&document instanceof DocumentTouch)&&n.vars.touch,o="click touchend MSPointerUp keyup",l="",c,d="vertical"===n.vars.direction,u=n.vars.reverse,v=n.vars.itemWidth>0,p="fade"===n.vars.animation,m=""!==n.vars.asNavFor,f={};$.data(t,"flexslider",n),f={init:function(){n.animating=!1,n.currentSlide=parseInt(n.vars.startAt?n.vars.startAt:0,10),isNaN(n.currentSlide)&&(n.currentSlide=0),n.animatingTo=n.currentSlide,n.atEnd=0===n.currentSlide||n.currentSlide===n.last,n.containerSelector=n.vars.selector.substr(0,n.vars.selector.search(" ")),n.slides=$(n.vars.selector,n),n.container=$(n.containerSelector,n),n.count=n.slides.length,n.syncExists=$(n.vars.sync).length>0,"slide"===n.vars.animation&&(n.vars.animation="swing"),n.prop=d?"top":"marginLeft",n.args={},n.manualPause=!1,n.stopped=!1,n.started=!1,n.startTimeout=null,n.transitions=!n.vars.video&&!p&&n.vars.useCSS&&function(){var e=document.createElement("div"),t=["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"];for(var a in t)if(void 0!==e.style[t[a]])return n.pfx=t[a].replace("Perspective","").toLowerCase(),n.prop="-"+n.pfx+"-transform",!0;return!1}(),n.ensureAnimationEnd="",""!==n.vars.controlsContainer&&(n.controlsContainer=$(n.vars.controlsContainer).length>0&&$(n.vars.controlsContainer)),""!==n.vars.manualControls&&(n.manualControls=$(n.vars.manualControls).length>0&&$(n.vars.manualControls)),""!==n.vars.customDirectionNav&&(n.customDirectionNav=2===$(n.vars.customDirectionNav).length&&$(n.vars.customDirectionNav)),n.vars.randomize&&(n.slides.sort(function(){return Math.round(Math.random())-.5}),n.container.empty().append(n.slides)),n.doMath(),n.setup("init"),n.vars.controlNav&&f.controlNav.setup(),n.vars.directionNav&&f.directionNav.setup(),n.vars.keyboard&&(1===$(n.containerSelector).length||n.vars.multipleKeyboard)&&$(document).bind("keyup",function(e){var t=e.keyCode;if(!n.animating&&(39===t||37===t)){var a=39===t?n.getTarget("next"):37===t?n.getTarget("prev"):!1;n.flexAnimate(a,n.vars.pauseOnAction)}}),n.vars.mousewheel&&n.bind("mousewheel",function(e,t,a,i){e.preventDefault();var s=0>t?n.getTarget("next"):n.getTarget("prev");n.flexAnimate(s,n.vars.pauseOnAction)}),n.vars.pausePlay&&f.pausePlay.setup(),n.vars.slideshow&&n.vars.pauseInvisible&&f.pauseInvisible.init(),n.vars.slideshow&&(n.vars.pauseOnHover&&n.hover(function(){n.manualPlay||n.manualPause||n.pause()},function(){n.manualPause||n.manualPlay||n.stopped||n.play()}),n.vars.pauseInvisible&&f.pauseInvisible.isHidden()||(n.vars.initDelay>0?n.startTimeout=setTimeout(n.play,n.vars.initDelay):n.play())),m&&f.asNav.setup(),r&&n.vars.touch&&f.touch(),(!p||p&&n.vars.smoothHeight)&&$(window).bind("resize orientationchange focus",f.resize),n.find("img").attr("draggable","false"),setTimeout(function(){n.vars.start(n)},200)},asNav:{setup:function(){n.asNav=!0,n.animatingTo=Math.floor(n.currentSlide/n.move),n.currentItem=n.currentSlide,n.slides.removeClass(i+"active-slide").eq(n.currentItem).addClass(i+"active-slide"),s?(t._slider=n,n.slides.each(function(){var e=this;e._gesture=new MSGesture,e._gesture.target=e,e.addEventListener("MSPointerDown",function(e){e.preventDefault(),e.currentTarget._gesture&&e.currentTarget._gesture.addPointer(e.pointerId)},!1),e.addEventListener("MSGestureTap",function(e){e.preventDefault();var t=$(this),a=t.index();$(n.vars.asNavFor).data("flexslider").animating||t.hasClass("active")||(n.direction=n.currentItem=s&&t.hasClass(i+"active-slide")?n.flexAnimate(n.getTarget("prev"),!0):$(n.vars.asNavFor).data("flexslider").animating||t.hasClass(i+"active-slide")||(n.direction=n.currentItem'),n.pagingCount>1)for(var r=0;r":''+t+"","thumbnails"===n.vars.controlNav&&!0===n.vars.thumbCaptions){var c=s.attr("data-thumbcaption");""!==c&&void 0!==c&&(a+=''+c+"")}n.controlNavScaffold.append("
  • "+a+"
  • "),t++}n.controlsContainer?$(n.controlsContainer).append(n.controlNavScaffold):n.append(n.controlNavScaffold),f.controlNav.set(),f.controlNav.active(),n.controlNavScaffold.delegate("a, img",o,function(e){if(e.preventDefault(),""===l||l===e.type){var t=$(this),a=n.controlNav.index(t);t.hasClass(i+"active")||(n.direction=a>n.currentSlide?"next":"prev",n.flexAnimate(a,n.vars.pauseOnAction))}""===l&&(l=e.type),f.setToClearWatchedEvent()})},setupManual:function(){n.controlNav=n.manualControls,f.controlNav.active(),n.controlNav.bind(o,function(e){if(e.preventDefault(),""===l||l===e.type){var t=$(this),a=n.controlNav.index(t);t.hasClass(i+"active")||(a>n.currentSlide?n.direction="next":n.direction="prev",n.flexAnimate(a,n.vars.pauseOnAction))}""===l&&(l=e.type),f.setToClearWatchedEvent()})},set:function(){var e="thumbnails"===n.vars.controlNav?"img":"a";n.controlNav=$("."+i+"control-nav li "+e,n.controlsContainer?n.controlsContainer:n)},active:function(){n.controlNav.removeClass(i+"active").eq(n.animatingTo).addClass(i+"active")},update:function(e,t){n.pagingCount>1&&"add"===e?n.controlNavScaffold.append($('
  • '+n.count+"
  • ")):1===n.pagingCount?n.controlNavScaffold.find("li").remove():n.controlNav.eq(t).closest("li").remove(),f.controlNav.set(),n.pagingCount>1&&n.pagingCount!==n.controlNav.length?n.update(t,e):f.controlNav.active()}},directionNav:{setup:function(){var e=$('");n.customDirectionNav?n.directionNav=n.customDirectionNav:n.controlsContainer?($(n.controlsContainer).append(e),n.directionNav=$("."+i+"direction-nav li a",n.controlsContainer)):(n.append(e),n.directionNav=$("."+i+"direction-nav li a",n)),f.directionNav.update(),n.directionNav.bind(o,function(e){e.preventDefault();var t;(""===l||l===e.type)&&(t=$(this).hasClass(i+"next")?n.getTarget("next"):n.getTarget("prev"),n.flexAnimate(t,n.vars.pauseOnAction)),""===l&&(l=e.type),f.setToClearWatchedEvent()})},update:function(){var e=i+"disabled";1===n.pagingCount?n.directionNav.addClass(e).attr("tabindex","-1"):n.vars.animationLoop?n.directionNav.removeClass(e).removeAttr("tabindex"):0===n.animatingTo?n.directionNav.removeClass(e).filter("."+i+"prev").addClass(e).attr("tabindex","-1"):n.animatingTo===n.last?n.directionNav.removeClass(e).filter("."+i+"next").addClass(e).attr("tabindex","-1"):n.directionNav.removeClass(e).removeAttr("tabindex")}},pausePlay:{setup:function(){var e=$('
    ');n.controlsContainer?(n.controlsContainer.append(e),n.pausePlay=$("."+i+"pauseplay a",n.controlsContainer)):(n.append(e),n.pausePlay=$("."+i+"pauseplay a",n)),f.pausePlay.update(n.vars.slideshow?i+"pause":i+"play"),n.pausePlay.bind(o,function(e){e.preventDefault(),(""===l||l===e.type)&&($(this).hasClass(i+"pause")?(n.manualPause=!0,n.manualPlay=!1,n.pause()):(n.manualPause=!1,n.manualPlay=!0,n.play())),""===l&&(l=e.type),f.setToClearWatchedEvent()})},update:function(e){"play"===e?n.pausePlay.removeClass(i+"pause").addClass(i+"play").html(n.vars.playText):n.pausePlay.removeClass(i+"play").addClass(i+"pause").html(n.vars.pauseText)}},touch:function(){function e(e){e.stopPropagation(),n.animating?e.preventDefault():(n.pause(),t._gesture.addPointer(e.pointerId),T=0,c=d?n.h:n.w,f=Number(new Date),l=v&&u&&n.animatingTo===n.last?0:v&&u?n.limit-(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo:v&&n.currentSlide===n.last?n.limit:v?(n.itemW+n.vars.itemMargin)*n.move*n.currentSlide:u?(n.last-n.currentSlide+n.cloneOffset)*c:(n.currentSlide+n.cloneOffset)*c)}function a(e){e.stopPropagation();var a=e.target._slider;if(a){var n=-e.translationX,i=-e.translationY;return T+=d?i:n,m=T,x=d?Math.abs(T)500)&&(e.preventDefault(),!p&&a.transitions&&(a.vars.animationLoop||(m=T/(0===a.currentSlide&&0>T||a.currentSlide===a.last&&T>0?Math.abs(T)/c+2:1)),a.setProps(l+m,"setTouch"))))}}function i(e){e.stopPropagation();var t=e.target._slider;if(t){if(t.animatingTo===t.currentSlide&&!x&&null!==m){var a=u?-m:m,n=a>0?t.getTarget("next"):t.getTarget("prev");t.canAdvance(n)&&(Number(new Date)-f<550&&Math.abs(a)>50||Math.abs(a)>c/2)?t.flexAnimate(n,t.vars.pauseOnAction):p||t.flexAnimate(t.currentSlide,t.vars.pauseOnAction,!0)}r=null,o=null,m=null,l=null,T=0}}var r,o,l,c,m,f,g,h,S,x=!1,y=0,b=0,T=0;s?(t.style.msTouchAction="none",t._gesture=new MSGesture,t._gesture.target=t,t.addEventListener("MSPointerDown",e,!1),t._slider=n,t.addEventListener("MSGestureChange",a,!1),t.addEventListener("MSGestureEnd",i,!1)):(g=function(e){n.animating?e.preventDefault():(window.navigator.msPointerEnabled||1===e.touches.length)&&(n.pause(),c=d?n.h:n.w,f=Number(new Date),y=e.touches[0].pageX,b=e.touches[0].pageY,l=v&&u&&n.animatingTo===n.last?0:v&&u?n.limit-(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo:v&&n.currentSlide===n.last?n.limit:v?(n.itemW+n.vars.itemMargin)*n.move*n.currentSlide:u?(n.last-n.currentSlide+n.cloneOffset)*c:(n.currentSlide+n.cloneOffset)*c,r=d?b:y,o=d?y:b,t.addEventListener("touchmove",h,!1),t.addEventListener("touchend",S,!1))},h=function(e){y=e.touches[0].pageX,b=e.touches[0].pageY,m=d?r-b:r-y,x=d?Math.abs(m)t)&&(e.preventDefault(),!p&&n.transitions&&(n.vars.animationLoop||(m/=0===n.currentSlide&&0>m||n.currentSlide===n.last&&m>0?Math.abs(m)/c+2:1),n.setProps(l+m,"setTouch")))},S=function(e){if(t.removeEventListener("touchmove",h,!1),n.animatingTo===n.currentSlide&&!x&&null!==m){var a=u?-m:m,i=a>0?n.getTarget("next"):n.getTarget("prev");n.canAdvance(i)&&(Number(new Date)-f<550&&Math.abs(a)>50||Math.abs(a)>c/2)?n.flexAnimate(i,n.vars.pauseOnAction):p||n.flexAnimate(n.currentSlide,n.vars.pauseOnAction,!0)}t.removeEventListener("touchend",S,!1),r=null,o=null,m=null,l=null},t.addEventListener("touchstart",g,!1))},resize:function(){!n.animating&&n.is(":visible")&&(v||n.doMath(),p?f.smoothHeight():v?(n.slides.width(n.computedW),n.update(n.pagingCount),n.setProps()):d?(n.viewport.height(n.h),n.setProps(n.h,"setTotal")):(n.vars.smoothHeight&&f.smoothHeight(),n.newSlides.width(n.computedW),n.setProps(n.computedW,"setTotal")))},smoothHeight:function(e){if(!d||p){var t=p?n:n.viewport;e?t.animate({height:n.slides.eq(n.animatingTo).height()},e):t.height(n.slides.eq(n.animatingTo).height())}},sync:function(e){var t=$(n.vars.sync).data("flexslider"),a=n.animatingTo;switch(e){case"animate":t.flexAnimate(a,n.vars.pauseOnAction,!1,!0);break;case"play":t.playing||t.asNav||t.play();break;case"pause":t.pause()}},uniqueID:function(e){return e.filter("[id]").add(e.find("[id]")).each(function(){var e=$(this);e.attr("id",e.attr("id")+"_clone")}),e},pauseInvisible:{visProp:null,init:function(){var e=f.pauseInvisible.getHiddenProp();if(e){var t=e.replace(/[H|h]idden/,"")+"visibilitychange";document.addEventListener(t,function(){f.pauseInvisible.isHidden()?n.startTimeout?clearTimeout(n.startTimeout):n.pause():n.started?n.play():n.vars.initDelay>0?setTimeout(n.play,n.vars.initDelay):n.play()})}},isHidden:function(){var e=f.pauseInvisible.getHiddenProp();return e?document[e]:!1},getHiddenProp:function(){var e=["webkit","moz","ms","o"];if("hidden"in document)return"hidden";for(var t=0;tn.currentSlide?"next":"prev"),m&&1===n.pagingCount&&(n.direction=n.currentItemn.limit&&1!==n.visible?n.limit:S):h=0===n.currentSlide&&e===n.count-1&&n.vars.animationLoop&&"next"!==n.direction?u?(n.count+n.cloneOffset)*c:0:n.currentSlide===n.last&&0===e&&n.vars.animationLoop&&"prev"!==n.direction?u?0:(n.count+1)*c:u?(n.count-1-e+n.cloneOffset)*c:(e+n.cloneOffset)*c,n.setProps(h,"",n.vars.animationSpeed),n.transitions?(n.vars.animationLoop&&n.atEnd||(n.animating=!1,n.currentSlide=n.animatingTo),n.container.unbind("webkitTransitionEnd transitionend"),n.container.bind("webkitTransitionEnd transitionend",function(){clearTimeout(n.ensureAnimationEnd),n.wrapup(c)}),clearTimeout(n.ensureAnimationEnd),n.ensureAnimationEnd=setTimeout(function(){n.wrapup(c)},n.vars.animationSpeed+100)):n.container.animate(n.args,n.vars.animationSpeed,n.vars.easing,function(){n.wrapup(c)})}n.vars.smoothHeight&&f.smoothHeight(n.vars.animationSpeed)}},n.wrapup=function(e){p||v||(0===n.currentSlide&&n.animatingTo===n.last&&n.vars.animationLoop?n.setProps(e,"jumpEnd"):n.currentSlide===n.last&&0===n.animatingTo&&n.vars.animationLoop&&n.setProps(e,"jumpStart")),n.animating=!1,n.currentSlide=n.animatingTo,n.vars.after(n)},n.animateSlides=function(){!n.animating&&e&&n.flexAnimate(n.getTarget("next"))},n.pause=function(){clearInterval(n.animatedSlides),n.animatedSlides=null,n.playing=!1,n.vars.pausePlay&&f.pausePlay.update("play"),n.syncExists&&f.sync("pause")},n.play=function(){n.playing&&clearInterval(n.animatedSlides),n.animatedSlides=n.animatedSlides||setInterval(n.animateSlides,n.vars.slideshowSpeed),n.started=n.playing=!0,n.vars.pausePlay&&f.pausePlay.update("pause"),n.syncExists&&f.sync("play")},n.stop=function(){n.pause(),n.stopped=!0},n.canAdvance=function(e,t){var a=m?n.pagingCount-1:n.last;return t?!0:m&&n.currentItem===n.count-1&&0===e&&"prev"===n.direction?!0:m&&0===n.currentItem&&e===n.pagingCount-1&&"next"!==n.direction?!1:e!==n.currentSlide||m?n.vars.animationLoop?!0:n.atEnd&&0===n.currentSlide&&e===a&&"next"!==n.direction?!1:n.atEnd&&n.currentSlide===a&&0===e&&"next"===n.direction?!1:!0:!1},n.getTarget=function(e){return n.direction=e,"next"===e?n.currentSlide===n.last?0:n.currentSlide+1:0===n.currentSlide?n.last:n.currentSlide-1},n.setProps=function(e,t,a){var i=function(){var a=e?e:(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo,i=function(){if(v)return"setTouch"===t?e:u&&n.animatingTo===n.last?0:u?n.limit-(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo:n.animatingTo===n.last?n.limit:a;switch(t){case"setTotal":return u?(n.count-1-n.currentSlide+n.cloneOffset)*e:(n.currentSlide+n.cloneOffset)*e;case"setTouch":return u?e:e;case"jumpEnd":return u?e:n.count*e;case"jumpStart":return u?n.count*e:e;default:return e}}();return-1*i+"px"}();n.transitions&&(i=d?"translate3d(0,"+i+",0)":"translate3d("+i+",0,0)",a=void 0!==a?a/1e3+"s":"0s",n.container.css("-"+n.pfx+"-transition-duration",a),n.container.css("transition-duration",a)),n.args[n.prop]=i,(n.transitions||void 0===a)&&n.container.css(n.args),n.container.css("transform",i)},n.setup=function(e){if(p)n.slides.css({width:"100%","float":"left",marginRight:"-100%",position:"relative"}),"init"===e&&(r?n.slides.css({opacity:0,display:"block",webkitTransition:"opacity "+n.vars.animationSpeed/1e3+"s ease",zIndex:1}).eq(n.currentSlide).css({opacity:1,zIndex:2}):0==n.vars.fadeFirstSlide?n.slides.css({opacity:0,display:"block",zIndex:1}).eq(n.currentSlide).css({zIndex:2}).css({opacity:1}):n.slides.css({opacity:0,display:"block",zIndex:1}).eq(n.currentSlide).css({zIndex:2}).animate({opacity:1},n.vars.animationSpeed,n.vars.easing)),n.vars.smoothHeight&&f.smoothHeight();else{var t,a;"init"===e&&(n.viewport=$('
    ').css({overflow:"hidden",position:"relative"}).appendTo(n).append(n.container),n.cloneCount=0,n.cloneOffset=0,u&&(a=$.makeArray(n.slides).reverse(),n.slides=$(a),n.container.empty().append(n.slides))),n.vars.animationLoop&&!v&&(n.cloneCount=2,n.cloneOffset=1,"init"!==e&&n.container.find(".clone").remove(),n.container.append(f.uniqueID(n.slides.first().clone().addClass("clone")).attr("aria-hidden","true")).prepend(f.uniqueID(n.slides.last().clone().addClass("clone")).attr("aria-hidden","true"))),n.newSlides=$(n.vars.selector,n),t=u?n.count-1-n.currentSlide+n.cloneOffset:n.currentSlide+n.cloneOffset,d&&!v?(n.container.height(200*(n.count+n.cloneCount)+"%").css("position","absolute").width("100%"),setTimeout(function(){n.newSlides.css({display:"block"}),n.doMath(),n.viewport.height(n.h),n.setProps(t*n.h,"init")},"init"===e?100:0)):(n.container.width(200*(n.count+n.cloneCount)+"%"),n.setProps(t*n.computedW,"init"),setTimeout(function(){n.doMath(),n.newSlides.css({width:n.computedW,marginRight:n.computedM,"float":"left",display:"block"}),n.vars.smoothHeight&&f.smoothHeight()},"init"===e?100:0))}v||n.slides.removeClass(i+"active-slide").eq(n.currentSlide).addClass(i+"active-slide"),n.vars.init(n)},n.doMath=function(){var e=n.slides.first(),t=n.vars.itemMargin,a=n.vars.minItems,i=n.vars.maxItems;n.w=void 0===n.viewport?n.width():n.viewport.width(),n.h=e.height(),n.boxPadding=e.outerWidth()-e.width(),v?(n.itemT=n.vars.itemWidth+t,n.itemM=t,n.minW=a?a*n.itemT:n.w,n.maxW=i?i*n.itemT-t:n.w,n.itemW=n.minW>n.w?(n.w-t*(a-1))/a:n.maxWn.w?n.w:n.vars.itemWidth,n.visible=Math.floor(n.w/n.itemW),n.move=n.vars.move>0&&n.vars.moven.w?n.itemW*(n.count-1)+t*(n.count-1):(n.itemW+t)*n.count-n.w-t):(n.itemW=n.w,n.itemM=t,n.pagingCount=n.count,n.last=n.count-1),n.computedW=n.itemW-n.boxPadding,n.computedM=n.itemM},n.update=function(e,t){n.doMath(),v||(en.controlNav.length?f.controlNav.update("add"):("remove"===t&&!v||n.pagingCountn.last&&(n.currentSlide-=1,n.animatingTo-=1),f.controlNav.update("remove",n.last))),n.vars.directionNav&&f.directionNav.update()},n.addSlide=function(e,t){var a=$(e);n.count+=1,n.last=n.count-1,d&&u?void 0!==t?n.slides.eq(n.count-t).after(a):n.container.prepend(a):void 0!==t?n.slides.eq(t).before(a):n.container.append(a),n.update(t,"add"),n.slides=$(n.vars.selector+":not(.clone)",n),n.setup(),n.vars.added(n)},n.removeSlide=function(e){var t=isNaN(e)?n.slides.index($(e)):e;n.count-=1,n.last=n.count-1,isNaN(e)?$(e,n.slides).remove():d&&u?n.slides.eq(n.last).remove():n.slides.eq(e).remove(),n.doMath(),n.update(t,"remove"),n.slides=$(n.vars.selector+":not(.clone)",n),n.setup(),n.vars.removed(n)},f.init()},$(window).blur(function(t){e=!1}).focus(function(t){e=!0}),$.flexslider.defaults={namespace:"flex-",selector:".slides > li",animation:"fade",easing:"swing",direction:"horizontal",reverse:!1,animationLoop:!0,smoothHeight:!1,startAt:0,slideshow:!0,slideshowSpeed:7e3,animationSpeed:600,initDelay:0,randomize:!1,fadeFirstSlide:!0,thumbCaptions:!1,pauseOnAction:!0,pauseOnHover:!1,pauseInvisible:!0,useCSS:!0,touch:!0,video:!1,controlNav:!0,directionNav:!0,prevText:"Previous",nextText:"Next",keyboard:!0,multipleKeyboard:!1,mousewheel:!1,pausePlay:!1,pauseText:"Pause",playText:"Play",controlsContainer:"",manualControls:"",customDirectionNav:"",sync:"",asNavFor:"",itemWidth:0,itemMargin:0,minItems:1,maxItems:0,move:0,allowOneSlide:!0,start:function(){},before:function(){},after:function(){},end:function(){},added:function(){},removed:function(){},init:function(){}},$.fn.flexslider=function(e){if(void 0===e&&(e={}),"object"==typeof e)return this.each(function(){var t=$(this),a=e.selector?e.selector:".slides > li",n=t.find(a);1===n.length&&e.allowOneSlide===!0||0===n.length?(n.fadeIn(400),e.start&&e.start(t)):void 0===t.data("flexslider")&&new $.flexslider(this,e)});var t=$(this).data("flexslider");switch(e){case"play":t.play();break;case"pause":t.pause();break;case"stop":t.stop();break;case"next":t.flexAnimate(t.getTarget("next"),!0);break;case"prev":case"previous":t.flexAnimate(t.getTarget("prev"),!0);break;default:"number"==typeof e&&t.flexAnimate(e,!0)}}}(jQuery); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/scribble.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/scribble.js new file mode 100644 index 00000000..5384b304 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/scribble.js @@ -0,0 +1,19 @@ + function storeUserScribble(id) { + var scribble = document.getElementById('scribble').innerHTML; + localStorage.setItem('userScribble',scribble); + } + + function getUserScribble() { + if ( localStorage.getItem('userScribble')) { + var scribble = localStorage.getItem('userScribble'); + } + else { + var scribble = 'You can scribble directly on this sticky... and I will also remember your message the next time you visit my blog!'; + } + document.getElementById('scribble').innerHTML = scribble; + } + + function clearLocal() { + clear: localStorage.clear(); + return false; + } diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/slides.min.jquery.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/slides.min.jquery.js new file mode 100644 index 00000000..1a1fcdd8 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/slides.min.jquery.js @@ -0,0 +1,20 @@ +/* +* Slides, A Slideshow Plugin for jQuery +* Intructions: http://slidesjs.com +* By: Nathan Searles, http://nathansearles.com +* Version: 1.1.9 +* Updated: September 5th, 2011 +* +* Licensed 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. +*/ +(function(a){a.fn.slides=function(b){return b=a.extend({},a.fn.slides.option,b),this.each(function(){function w(g,h,i){if(!p&&o){p=!0,b.animationStart(n+1);switch(g){case"next":l=n,k=n+1,k=e===k?0:k,r=f*2,g=-f*2,n=k;break;case"prev":l=n,k=n-1,k=k===-1?e-1:k,r=0,g=0,n=k;break;case"pagination":k=parseInt(i,10),l=a("."+b.paginationClass+" li."+b.currentClass+" a",c).attr("href").match("[^#/]+$"),k>l?(r=f*2,g=-f*2):(r=0,g=0),n=k}h==="fade"?b.crossfade?d.children(":eq("+k+")",c).css({zIndex:10}).fadeIn(b.fadeSpeed,b.fadeEasing,function(){b.autoHeight?d.animate({height:d.children(":eq("+k+")",c).outerHeight()},b.autoHeightSpeed,function(){d.children(":eq("+l+")",c).css({display:"none",zIndex:0}),d.children(":eq("+k+")",c).css({zIndex:0}),b.animationComplete(k+1),p=!1}):(d.children(":eq("+l+")",c).css({display:"none",zIndex:0}),d.children(":eq("+k+")",c).css({zIndex:0}),b.animationComplete(k+1),p=!1)}):d.children(":eq("+l+")",c).fadeOut(b.fadeSpeed,b.fadeEasing,function(){b.autoHeight?d.animate({height:d.children(":eq("+k+")",c).outerHeight()},b.autoHeightSpeed,function(){d.children(":eq("+k+")",c).fadeIn(b.fadeSpeed,b.fadeEasing)}):d.children(":eq("+k+")",c).fadeIn(b.fadeSpeed,b.fadeEasing,function(){a.browser.msie&&a(this).get(0).style.removeAttribute("filter")}),b.animationComplete(k+1),p=!1}):(d.children(":eq("+k+")").css({left:r,display:"block"}),b.autoHeight?d.animate({left:g,height:d.children(":eq("+k+")").outerHeight()},b.slideSpeed,b.slideEasing,function(){d.css({left:-f}),d.children(":eq("+k+")").css({left:f,zIndex:5}),d.children(":eq("+l+")").css({left:f,display:"none",zIndex:0}),b.animationComplete(k+1),p=!1}):d.animate({left:g},b.slideSpeed,b.slideEasing,function(){d.css({left:-f}),d.children(":eq("+k+")").css({left:f,zIndex:5}),d.children(":eq("+l+")").css({left:f,display:"none",zIndex:0}),b.animationComplete(k+1),p=!1})),b.pagination&&(a("."+b.paginationClass+" li."+b.currentClass,c).removeClass(b.currentClass),a("."+b.paginationClass+" li:eq("+k+")",c).addClass(b.currentClass))}}function x(){clearInterval(c.data("interval"))}function y(){b.pause?(clearTimeout(c.data("pause")),clearInterval(c.data("interval")),u=setTimeout(function(){clearTimeout(c.data("pause")),v=setInterval(function(){w("next",i)},b.play),c.data("interval",v)},b.pause),c.data("pause",u)):x()}a("."+b.container,a(this)).children().wrapAll('
    ');var c=a(this),d=a(".slides_control",c),e=d.children().size(),f=d.children().outerWidth(),g=d.children().outerHeight(),h=b.start-1,i=b.effect.indexOf(",")<0?b.effect:b.effect.replace(" ","").split(",")[0],j=b.effect.indexOf(",")<0?i:b.effect.replace(" ","").split(",")[1],k=0,l=0,m=0,n=0,o,p,q,r,s,t,u,v;if(e<2)return a("."+b.container,a(this)).fadeIn(b.fadeSpeed,b.fadeEasing,function(){o=!0,b.slidesLoaded()}),a("."+b.next+", ."+b.prev).fadeOut(0),!1;if(e<2)return;h<0&&(h=0),h>e&&(h=e-1),b.start&&(n=h),b.randomize&&d.randomize(),a("."+b.container,c).css({overflow:"hidden",position:"relative"}),d.children().css({position:"absolute",top:0,left:d.children().outerWidth(),zIndex:0,display:"none"}),d.css({position:"relative",width:f*3,height:g,left:-f}),a("."+b.container,c).css({display:"block"}),b.autoHeight&&(d.children().css({height:"auto"}),d.animate({height:d.children(":eq("+h+")").outerHeight()},b.autoHeightSpeed));if(b.preload&&d.find("img:eq("+h+")").length){a("."+b.container,c).css({background:"url("+b.preloadImage+") no-repeat 50% 50%"});var z=d.find("img:eq("+h+")").attr("src")+"?"+(new Date).getTime();a("img",c).parent().attr("class")!="slides_control"?t=d.children(":eq(0)")[0].tagName.toLowerCase():t=d.find("img:eq("+h+")"),d.find("img:eq("+h+")").attr("src",z).load(function(){d.find(t+":eq("+h+")").fadeIn(b.fadeSpeed,b.fadeEasing,function(){a(this).css({zIndex:5}),a("."+b.container,c).css({background:""}),o=!0,b.slidesLoaded()})})}else d.children(":eq("+h+")").fadeIn(b.fadeSpeed,b.fadeEasing,function(){o=!0,b.slidesLoaded()});b.bigTarget&&(d.children().css({cursor:"pointer"}),d.children().click(function(){return w("next",i),!1})),b.hoverPause&&b.play&&(d.bind("mouseover",function(){x()}),d.bind("mouseleave",function(){y()})),b.generateNextPrev&&(a("."+b.container,c).after('Prev'),a("."+b.prev,c).after('Next')),a("."+b.next,c).click(function(a){a.preventDefault(),b.play&&y(),w("next",i)}),a("."+b.prev,c).click(function(a){a.preventDefault(),b.play&&y(),w("prev",i)}),b.generatePagination?(b.prependPagination?c.prepend("
      "):c.append("
        "),d.children().each(function(){a("."+b.paginationClass,c).append('
      • '+(m+1)+"
      • "),m++})):a("."+b.paginationClass+" li a",c).each(function(){a(this).attr("href","#"+m),m++}),a("."+b.paginationClass+" li:eq("+h+")",c).addClass(b.currentClass),a("."+b.paginationClass+" li a",c).click(function(){return b.play&&y(),q=a(this).attr("href").match("[^#/]+$"),n!=q&&w("pagination",j,q),!1}),a("a.link",c).click(function(){return b.play&&y(),q=a(this).attr("href").match("[^#/]+$")-1,n!=q&&w("pagination",j,q),!1}),b.play&&(v=setInterval(function(){w("next",i)},b.play),c.data("interval",v))})},a.fn.slides.option={preload:!1,preloadImage:"/img/loading.gif",container:"slides_container",generateNextPrev:!1,next:"next",prev:"prev",pagination:!0,generatePagination:!0,prependPagination:!1,paginationClass:"pagination",currentClass:"current",fadeSpeed:350,fadeEasing:"",slideSpeed:350,slideEasing:"",start:1,effect:"slide",crossfade:!1,randomize:!1,play:0,pause:0,hoverPause:!1,autoHeight:!1,autoHeightSpeed:350,bigTarget:!1,animationStart:function(){},animationComplete:function(){},slidesLoaded:function(){}},a.fn.randomize=function(b){function c(){return Math.round(Math.random())-.5}return a(this).each(function(){var d=a(this),e=d.children(),f=e.length;if(f>1){e.hide();var g=[];for(i=0;i') + .appendTo(this) + .addClass(opt.loadingClass) + .bind('click', EYE.spacegallery.next); + el.spacegalleryCfg = opt; + el.spacegalleryCfg.images = el.getElementsByTagName('img').length; + el.spacegalleryCfg.loaded = 0; + el.spacegalleryCfg.asin = Math.asin(1); + el.spacegalleryCfg.asins = {}; + el.spacegalleryCfg.tops = {}; + el.spacegalleryCfg.increment = parseInt(el.spacegalleryCfg.perspective/el.spacegalleryCfg.images, 10); + var top = 0; + $('img', el) + .each(function(nr){ + var imgEl = new Image(); + var elImg = this; + el.spacegalleryCfg.asins[nr] = 1 - Math.asin((nr+1)/el.spacegalleryCfg.images)/el.spacegalleryCfg.asin; + top += el.spacegalleryCfg.increment - el.spacegalleryCfg.increment * el.spacegalleryCfg.asins[nr]; + el.spacegalleryCfg.tops[nr] = top; + elImg.spacegallery = {}; + imgEl.src = this.src; + if (imgEl.complete) { + el.spacegalleryCfg.loaded ++; + elImg.spacegallery.origWidth = imgEl.width; + elImg.spacegallery.origHeight = imgEl.height + } else { + imgEl.onload = function() { + el.spacegalleryCfg.loaded ++; + elImg.spacegallery.origWidth = imgEl.width; + elImg.spacegallery.origHeight = imgEl.height + if (el.spacegalleryCfg.loaded == el.spacegalleryCfg.images) { + + EYE.spacegallery.positionImages(el); + } + }; + } + }); + el.spacegalleryCfg.asins[el.spacegalleryCfg.images] = el.spacegalleryCfg.asins[el.spacegalleryCfg.images - 1] * 1.3; + el.spacegalleryCfg.tops[el.spacegalleryCfg.images] = el.spacegalleryCfg.tops[el.spacegalleryCfg.images - 1] * 1.3; + if (el.spacegalleryCfg.loaded == el.spacegalleryCfg.images) { + EYE.spacegallery.positionImages(el); + setInterval(function() { EYE.spacegallery.autoNext(el); }, 4000); + } + } + }); + } + } + }); + + $.fn.extend({ + + /** + * Create a space gallery + * @name spacegallery + * @description create a space gallery + * @option int border Images' border. Default: 6 + * @option int perspective Perpective height. Default: 140 + * @option float minScale Minimum scale for the image in the back. Default: 0.2 + * @option int duration Animation duration. Default: 800 + * @option string loadingClass CSS class applied to the element while looading images. Default: null + * @option function before Callback function triggered before going to the next image + * @option function after Callback function triggered after going to the next image + */ + spacegallery: EYE.spacegallery.init + }); + $.extend($.easing,{ + easeOut:function (x, t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + } + }); +})(jQuery); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/utils.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/utils.js new file mode 100644 index 00000000..d9be8532 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/js/utils.js @@ -0,0 +1,252 @@ +/** + * + * Utilities + * Author: Stefan Petre www.eyecon.ro + * + */ +(function($) { +EYE.extend({ + getPosition : function(e, forceIt) + { + var x = 0; + var y = 0; + var es = e.style; + var restoreStyles = false; + if (forceIt && jQuery.curCSS(e,'display') == 'none') { + var oldVisibility = es.visibility; + var oldPosition = es.position; + restoreStyles = true; + es.visibility = 'hidden'; + es.display = 'block'; + es.position = 'absolute'; + } + var el = e; + if (el.getBoundingClientRect) { // IE + var box = el.getBoundingClientRect(); + x = box.left + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft) - 2; + y = box.top + Math.max(document.documentElement.scrollTop, document.body.scrollTop) - 2; + } else { + x = el.offsetLeft; + y = el.offsetTop; + el = el.offsetParent; + if (e != el) { + while (el) { + x += el.offsetLeft; + y += el.offsetTop; + el = el.offsetParent; + } + } + if (jQuery.browser.safari && jQuery.curCSS(e, 'position') == 'absolute' ) { + x -= document.body.offsetLeft; + y -= document.body.offsetTop; + } + el = e.parentNode; + while (el && el.tagName.toUpperCase() != 'BODY' && el.tagName.toUpperCase() != 'HTML') + { + if (jQuery.curCSS(el, 'display') != 'inline') { + x -= el.scrollLeft; + y -= el.scrollTop; + } + el = el.parentNode; + } + } + if (restoreStyles == true) { + es.display = 'none'; + es.position = oldPosition; + es.visibility = oldVisibility; + } + return {x:x, y:y}; + }, + getSize : function(e) + { + var w = parseInt(jQuery.curCSS(e,'width'), 10); + var h = parseInt(jQuery.curCSS(e,'height'), 10); + var wb = 0; + var hb = 0; + if (jQuery.curCSS(e, 'display') != 'none') { + wb = e.offsetWidth; + hb = e.offsetHeight; + } else { + var es = e.style; + var oldVisibility = es.visibility; + var oldPosition = es.position; + es.visibility = 'hidden'; + es.display = 'block'; + es.position = 'absolute'; + wb = e.offsetWidth; + hb = e.offsetHeight; + es.display = 'none'; + es.position = oldPosition; + es.visibility = oldVisibility; + } + return {w:w, h:h, wb:wb, hb:hb}; + }, + getClient : function(e) + { + var h, w; + if (e) { + w = e.clientWidth; + h = e.clientHeight; + } else { + var de = document.documentElement; + w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth; + h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight; + } + return {w:w,h:h}; + }, + getScroll : function (e) + { + var t=0, l=0, w=0, h=0, iw=0, ih=0; + if (e && e.nodeName.toLowerCase() != 'body') { + t = e.scrollTop; + l = e.scrollLeft; + w = e.scrollWidth; + h = e.scrollHeight; + } else { + if (document.documentElement) { + t = document.documentElement.scrollTop; + l = document.documentElement.scrollLeft; + w = document.documentElement.scrollWidth; + h = document.documentElement.scrollHeight; + } else if (document.body) { + t = document.body.scrollTop; + l = document.body.scrollLeft; + w = document.body.scrollWidth; + h = document.body.scrollHeight; + } + if (typeof pageYOffset != 'undefined') { + t = pageYOffset; + l = pageXOffset; + } + iw = self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0; + ih = self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0; + } + return { t: t, l: l, w: w, h: h, iw: iw, ih: ih }; + }, + getMargins : function(e, toInteger) + { + var t = jQuery.curCSS(e,'marginTop') || ''; + var r = jQuery.curCSS(e,'marginRight') || ''; + var b = jQuery.curCSS(e,'marginBottom') || ''; + var l = jQuery.curCSS(e,'marginLeft') || ''; + if (toInteger) + return { + t: parseInt(t, 10)||0, + r: parseInt(r, 10)||0, + b: parseInt(b, 10)||0, + l: parseInt(l, 10) + }; + else + return {t: t, r: r, b: b, l: l}; + }, + getPadding : function(e, toInteger) + { + var t = jQuery.curCSS(e,'paddingTop') || ''; + var r = jQuery.curCSS(e,'paddingRight') || ''; + var b = jQuery.curCSS(e,'paddingBottom') || ''; + var l = jQuery.curCSS(e,'paddingLeft') || ''; + if (toInteger) + return { + t: parseInt(t, 10)||0, + r: parseInt(r, 10)||0, + b: parseInt(b, 10)||0, + l: parseInt(l, 10) + }; + else + return {t: t, r: r, b: b, l: l}; + }, + getBorder : function(e, toInteger) + { + var t = jQuery.curCSS(e,'borderTopWidth') || ''; + var r = jQuery.curCSS(e,'borderRightWidth') || ''; + var b = jQuery.curCSS(e,'borderBottomWidth') || ''; + var l = jQuery.curCSS(e,'borderLeftWidth') || ''; + if (toInteger) + return { + t: parseInt(t, 10)||0, + r: parseInt(r, 10)||0, + b: parseInt(b, 10)||0, + l: parseInt(l, 10)||0 + }; + else + return {t: t, r: r, b: b, l: l}; + }, + traverseDOM : function(nodeEl, func) + { + func(nodeEl); + nodeEl = nodeEl.firstChild; + while(nodeEl){ + EYE.traverseDOM(nodeEl, func); + nodeEl = nodeEl.nextSibling; + } + }, + getInnerWidth : function(el, scroll) { + var offsetW = el.offsetWidth; + return scroll ? Math.max(el.scrollWidth,offsetW) - offsetW + el.clientWidth:el.clientWidth; + }, + getInnerHeight : function(el, scroll) { + var offsetH = el.offsetHeight; + return scroll ? Math.max(el.scrollHeight,offsetH) - offsetH + el.clientHeight:el.clientHeight; + }, + getExtraWidth : function(el) { + if($.boxModel) + return (parseInt($.curCSS(el, 'paddingLeft'))||0) + + (parseInt($.curCSS(el, 'paddingRight'))||0) + + (parseInt($.curCSS(el, 'borderLeftWidth'))||0) + + (parseInt($.curCSS(el, 'borderRightWidth'))||0); + return 0; + }, + getExtraHeight : function(el) { + if($.boxModel) + return (parseInt($.curCSS(el, 'paddingTop'))||0) + + (parseInt($.curCSS(el, 'paddingBottom'))||0) + + (parseInt($.curCSS(el, 'borderTopWidth'))||0) + + (parseInt($.curCSS(el, 'borderBottomWidth'))||0); + return 0; + }, + isChildOf: function(parentEl, el, container) { + if (parentEl == el) { + return true; + } + if (!el || !el.nodeType || el.nodeType != 1) { + return false; + } + if (parentEl.contains && !$.browser.safari) { + return parentEl.contains(el); + } + if ( parentEl.compareDocumentPosition ) { + return !!(parentEl.compareDocumentPosition(el) & 16); + } + var prEl = el.parentNode; + while(prEl && prEl != container) { + if (prEl == parentEl) + return true; + prEl = prEl.parentNode; + } + return false; + }, + centerEl : function(el, axis) + { + var clientScroll = EYE.getScroll(); + var size = EYE.getSize(el); + if (!axis || axis == 'vertically') + $(el).css( + { + top: clientScroll.t + ((Math.min(clientScroll.h,clientScroll.ih) - size.hb)/2) + 'px' + } + ); + if (!axis || axis == 'horizontally') + $(el).css( + { + left: clientScroll.l + ((Math.min(clientScroll.w,clientScroll.iw) - size.wb)/2) + 'px' + } + ); + } +}); +if (!$.easing.easeout) { + $.easing.easeout = function(p, n, firstNum, delta, duration) { + return -delta * ((n=n/duration-1)*n*n*n - 1) + firstNum; + }; +} + +})(jQuery); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/bootstrap.min.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/bootstrap.min.css new file mode 100644 index 00000000..3424a5f1 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/bootstrap.min.css @@ -0,0 +1,351 @@ +html,body{margin:0;padding:0;} +h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,cite,code,del,dfn,em,img,q,s,samp,small,strike,strong,sub,sup,tt,var,dd,dl,dt,li,ol,ul,fieldset,form,label,legend,button,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;font-weight:normal;font-style:normal;font-size:100%;line-height:1;font-family:inherit;} +ol,ul{list-style:none;} +q:before,q:after,blockquote:before,blockquote:after{content:"";} +html{overflow-y:scroll;font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;} +a:focus{outline:thin dotted;} +a:hover,a:active{outline:0;} +article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;} +audio,canvas,video{display:inline-block;*display:inline;*zoom:1;} +audio:not([controls]){display:none;} +sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;} +sup{top:-0.5em;} +sub{bottom:-0.25em;} +img{border:0;-ms-interpolation-mode:bicubic;} +button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;} +button,input{line-height:normal;*overflow:visible;} +button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;} +button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;} +input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;} +input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;} +textarea{overflow:auto;vertical-align:top;} +body{background-color:#ffffff;margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:18px;color:#404040;} +.container{width:940px;margin-left:auto;margin-right:auto;zoom:1;}.container:before,.container:after{display:table;content:"";zoom:1;} +.container:after{clear:both;} +.container-fluid{position:relative;min-width:940px;padding-left:20px;padding-right:20px;zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";zoom:1;} +.container-fluid:after{clear:both;} +.container-fluid>.sidebar{position:absolute;top:0;left:20px;width:220px;} +.container-fluid>.content{margin-left:240px;} +a{color:#0069d6;text-decoration:none;line-height:inherit;font-weight:inherit;}a:hover{color:#00438a;text-decoration:underline;} +.pull-right{float:right;} +.pull-left{float:left;} +.hide{display:none;} +.show{display:block;} +.row{zoom:1;margin-left:-20px;}.row:before,.row:after{display:table;content:"";zoom:1;} +.row:after{clear:both;} +.row>[class*="span"]{display:inline;float:left;margin-left:20px;} +.span1{width:40px;} +.span2{width:100px;} +.span3{width:160px;} +.span4{width:220px;} +.span5{width:280px;} +.span6{width:340px;} +.span7{width:400px;} +.span8{width:460px;} +.span9{width:520px;} +.span10{width:580px;} +.span11{width:640px;} +.span12{width:700px;} +.span13{width:760px;} +.span14{width:820px;} +.span15{width:880px;} +.span16{width:940px;} +.span17{width:1000px;} +.span18{width:1060px;} +.span19{width:1120px;} +.span20{width:1180px;} +.span21{width:1240px;} +.span22{width:1300px;} +.span23{width:1360px;} +.span24{width:1420px;} +.row>.offset1{margin-left:80px;} +.row>.offset2{margin-left:140px;} +.row>.offset3{margin-left:200px;} +.row>.offset4{margin-left:260px;} +.row>.offset5{margin-left:320px;} +.row>.offset6{margin-left:380px;} +.row>.offset7{margin-left:440px;} +.row>.offset8{margin-left:500px;} +.row>.offset9{margin-left:560px;} +.row>.offset10{margin-left:620px;} +.row>.offset11{margin-left:680px;} +.row>.offset12{margin-left:740px;} +.span-one-third{width:300px;} +.span-two-thirds{width:620px;} +.offset-one-third{margin-left:340px;} +.offset-two-thirds{margin-left:660px;} +p{font-size:13px;font-weight:normal;line-height:18px;margin-bottom:9px;}p small{font-size:11px;color:#bfbfbf;} +h1,h2,h3,h4,h5,h6{font-weight:bold;color:#404040;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#bfbfbf;} +h1{margin-bottom:18px;font-size:30px;line-height:36px;}h1 small{font-size:18px;} +h2{font-size:24px;line-height:36px;}h2 small{font-size:14px;} +h3,h4,h5,h6{line-height:36px;} +h3{font-size:18px;}h3 small{font-size:14px;} +h4{font-size:16px;}h4 small{font-size:12px;} +h5{font-size:14px;} +h6{font-size:13px;color:#bfbfbf;text-transform:uppercase;} +ul,ol{margin:0 0 18px 25px;} +ul ul,ul ol,ol ol,ol ul{margin-bottom:0;} +ul{list-style:disc;} +ol{list-style:decimal;} +li{line-height:18px;color:#808080;} +ul.unstyled{list-style:none;margin-left:0;} +dl{margin-bottom:18px;}dl dt,dl dd{line-height:18px;} +dl dt{font-weight:bold;} +dl dd{margin-left:9px;} +hr{margin:20px 0 19px;border:0;border-bottom:1px solid #eee;} +strong{font-style:inherit;font-weight:bold;} +em{font-style:italic;font-weight:inherit;line-height:inherit;} +.muted{color:#bfbfbf;} +blockquote{margin-bottom:18px;border-left:5px solid #eee;padding-left:15px;}blockquote p{font-size:14px;font-weight:300;line-height:18px;margin-bottom:0;} +blockquote small{display:block;font-size:12px;font-weight:300;line-height:18px;color:#bfbfbf;}blockquote small:before{content:'\2014 \00A0';} +address{display:block;line-height:18px;margin-bottom:18px;} +code,pre{padding:0 3px 2px;font-family:Monaco, Andale Mono, Courier New, monospace;font-size:12px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +code{background-color:#fee9cc;color:rgba(0, 0, 0, 0.75);padding:1px 3px;} +pre{background-color:#f5f5f5;display:block;padding:8.5px;margin:0 0 18px;line-height:18px;font-size:12px;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;white-space:pre;white-space:pre-wrap;word-wrap:break-word;} +form{margin-bottom:18px;} +fieldset{margin-bottom:18px;padding-top:18px;}fieldset legend{display:block;padding-left:150px;font-size:19.5px;line-height:1;color:#404040;*padding:0 0 5px 145px;*line-height:1.5;} +form .clearfix{margin-bottom:18px;zoom:1;}form .clearfix:before,form .clearfix:after{display:table;content:"";zoom:1;} +form .clearfix:after{clear:both;} +label,input,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:normal;} +label{padding-top:6px;font-size:13px;line-height:18px;float:left;width:130px;text-align:right;color:#404040;} +form .input{margin-left:150px;} +input[type=checkbox],input[type=radio]{cursor:pointer;} +input,textarea,select,.uneditable-input{display:inline-block;width:210px;height:18px;padding:4px;font-size:13px;line-height:18px;color:#808080;border:1px solid #ccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +select{padding:initial;} +input[type=checkbox],input[type=radio]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;border:none;} +input[type=file]{background-color:#ffffff;padding:initial;border:initial;line-height:initial;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +input[type=button],input[type=reset],input[type=submit]{width:auto;height:auto;} +select,input[type=file]{height:27px;*height:auto;line-height:27px;*margin-top:4px;} +select[multiple]{height:inherit;background-color:#ffffff;} +textarea{height:auto;} +.uneditable-input{background-color:#ffffff;display:block;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;} +:-moz-placeholder{color:#bfbfbf;} +::-webkit-input-placeholder{color:#bfbfbf;} +input,textarea{-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-ms-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s;-webkit-box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1);} +input:focus,textarea:focus{outline:0;border-color:rgba(82, 168, 236, 0.8);-webkit-box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1),0 0 8px rgba(82, 168, 236, 0.6);-moz-box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1),0 0 8px rgba(82, 168, 236, 0.6);box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1),0 0 8px rgba(82, 168, 236, 0.6);} +input[type=file]:focus,input[type=checkbox]:focus,select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;outline:1px dotted #666;} +form .clearfix.error>label,form .clearfix.error .help-block,form .clearfix.error .help-inline{color:#b94a48;} +form .clearfix.error input,form .clearfix.error textarea{color:#b94a48;border-color:#ee5f5b;}form .clearfix.error input:focus,form .clearfix.error textarea:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;} +form .clearfix.error .input-prepend .add-on,form .clearfix.error .input-append .add-on{color:#b94a48;background-color:#fce6e6;border-color:#b94a48;} +form .clearfix.warning>label,form .clearfix.warning .help-block,form .clearfix.warning .help-inline{color:#c09853;} +form .clearfix.warning input,form .clearfix.warning textarea{color:#c09853;border-color:#ccae64;}form .clearfix.warning input:focus,form .clearfix.warning textarea:focus{border-color:#be9a3f;-webkit-box-shadow:0 0 6px #e5d6b1;-moz-box-shadow:0 0 6px #e5d6b1;box-shadow:0 0 6px #e5d6b1;} +form .clearfix.warning .input-prepend .add-on,form .clearfix.warning .input-append .add-on{color:#c09853;background-color:#d2b877;border-color:#c09853;} +form .clearfix.success>label,form .clearfix.success .help-block,form .clearfix.success .help-inline{color:#468847;} +form .clearfix.success input,form .clearfix.success textarea{color:#468847;border-color:#57a957;}form .clearfix.success input:focus,form .clearfix.success textarea:focus{border-color:#458845;-webkit-box-shadow:0 0 6px #9acc9a;-moz-box-shadow:0 0 6px #9acc9a;box-shadow:0 0 6px #9acc9a;} +form .clearfix.success .input-prepend .add-on,form .clearfix.success .input-append .add-on{color:#468847;background-color:#bcddbc;border-color:#468847;} +.input-mini,input.mini,textarea.mini,select.mini{width:60px;} +.input-small,input.small,textarea.small,select.small{width:90px;} +.input-medium,input.medium,textarea.medium,select.medium{width:150px;} +.input-large,input.large,textarea.large,select.large{width:210px;} +.input-xlarge,input.xlarge,textarea.xlarge,select.xlarge{width:270px;} +.input-xxlarge,input.xxlarge,textarea.xxlarge,select.xxlarge{width:530px;} +textarea.xxlarge{overflow-y:auto;} +input.span1,textarea.span1{display:inline-block;float:none;width:30px;margin-left:0;} +input.span2,textarea.span2{display:inline-block;float:none;width:90px;margin-left:0;} +input.span3,textarea.span3{display:inline-block;float:none;width:150px;margin-left:0;} +input.span4,textarea.span4{display:inline-block;float:none;width:210px;margin-left:0;} +input.span5,textarea.span5{display:inline-block;float:none;width:270px;margin-left:0;} +input.span6,textarea.span6{display:inline-block;float:none;width:330px;margin-left:0;} +input.span7,textarea.span7{display:inline-block;float:none;width:390px;margin-left:0;} +input.span8,textarea.span8{display:inline-block;float:none;width:450px;margin-left:0;} +input.span9,textarea.span9{display:inline-block;float:none;width:510px;margin-left:0;} +input.span10,textarea.span10{display:inline-block;float:none;width:570px;margin-left:0;} +input.span11,textarea.span11{display:inline-block;float:none;width:630px;margin-left:0;} +input.span12,textarea.span12{display:inline-block;float:none;width:690px;margin-left:0;} +input.span13,textarea.span13{display:inline-block;float:none;width:750px;margin-left:0;} +input.span14,textarea.span14{display:inline-block;float:none;width:810px;margin-left:0;} +input.span15,textarea.span15{display:inline-block;float:none;width:870px;margin-left:0;} +input.span16,textarea.span16{display:inline-block;float:none;width:930px;margin-left:0;} +input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{background-color:#f5f5f5;border-color:#ddd;cursor:not-allowed;} +.actions{background:#f5f5f5;margin-top:18px;margin-bottom:18px;padding:17px 20px 18px 150px;border-top:1px solid #ddd;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;}.actions .secondary-action{float:right;}.actions .secondary-action a{line-height:30px;}.actions .secondary-action a:hover{text-decoration:underline;} +.help-inline,.help-block{font-size:13px;line-height:18px;color:#bfbfbf;} +.help-inline{padding-left:5px;*position:relative;*top:-5px;} +.help-block{display:block;max-width:600px;} +.inline-inputs{color:#808080;}.inline-inputs span{padding:0 2px 0 1px;} +.input-prepend input,.input-append input{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.input-prepend .add-on,.input-append .add-on{position:relative;background:#f5f5f5;border:1px solid #ccc;z-index:2;float:left;display:block;width:auto;min-width:16px;height:18px;padding:4px 4px 4px 5px;margin-right:-1px;font-weight:normal;line-height:18px;color:#bfbfbf;text-align:center;text-shadow:0 1px 0 #ffffff;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-prepend .active,.input-append .active{background:#a9dba9;border-color:#46a546;} +.input-prepend .add-on{*margin-top:1px;} +.input-append input{float:left;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-append .add-on{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;margin-right:0;margin-left:-1px;} +.inputs-list{margin:0 0 5px;width:100%;}.inputs-list li{display:block;padding:0;width:100%;} +.inputs-list label{display:block;float:none;width:auto;padding:0;margin-left:20px;line-height:18px;text-align:left;white-space:normal;}.inputs-list label strong{color:#808080;} +.inputs-list label small{font-size:11px;font-weight:normal;} +.inputs-list .inputs-list{margin-left:25px;margin-bottom:10px;padding-top:0;} +.inputs-list:first-child{padding-top:6px;} +.inputs-list li+li{padding-top:2px;} +.inputs-list input[type=radio],.inputs-list input[type=checkbox]{margin-bottom:0;margin-left:-20px;float:left;} +.form-stacked{padding-left:20px;}.form-stacked fieldset{padding-top:9px;} +.form-stacked legend{padding-left:0;} +.form-stacked label{display:block;float:none;width:auto;font-weight:bold;text-align:left;line-height:20px;padding-top:0;} +.form-stacked .clearfix{margin-bottom:9px;}.form-stacked .clearfix div.input{margin-left:0;} +.form-stacked .inputs-list{margin-bottom:0;}.form-stacked .inputs-list li{padding-top:0;}.form-stacked .inputs-list li label{font-weight:normal;padding-top:0;} +.form-stacked div.clearfix.error{padding-top:10px;padding-bottom:10px;padding-left:10px;margin-top:0;margin-left:-10px;} +.form-stacked .actions{margin-left:-20px;padding-left:20px;} +.condensed-table th,.condensed-table td{padding:5px 5px 4px;} +.bordered-table{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.bordered-table th+th,.bordered-table td+td,.bordered-table th+td{border-left:1px solid #ddd;} +.bordered-table thead tr:first-child th:first-child,.bordered-table tbody tr:first-child td:first-child{-webkit-border-radius:4px 0 0 0;-moz-border-radius:4px 0 0 0;border-radius:4px 0 0 0;} +.bordered-table thead tr:first-child th:last-child,.bordered-table tbody tr:first-child td:last-child{-webkit-border-radius:0 4px 0 0;-moz-border-radius:0 4px 0 0;border-radius:0 4px 0 0;} +.bordered-table tbody tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;} +.bordered-table tbody tr:last-child td:last-child{-webkit-border-radius:0 0 4px 0;-moz-border-radius:0 0 4px 0;border-radius:0 0 4px 0;} +table .span1{width:20px;} +table .span2{width:60px;} +table .span3{width:100px;} +table .span4{width:140px;} +table .span5{width:180px;} +table .span6{width:220px;} +table .span7{width:260px;} +table .span8{width:300px;} +table .span9{width:340px;} +table .span10{width:380px;} +table .span11{width:420px;} +table .span12{width:460px;} +table .span13{width:500px;} +table .span14{width:540px;} +table .span15{width:580px;} +table .span16{width:620px;} +.zebra-striped tbody tr:nth-child(odd) td,.zebra-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;} +.zebra-striped tbody tr:hover td,.zebra-striped tbody tr:hover th{background-color:#f5f5f5;} +table .header{cursor:pointer;}table .header:after{content:"";float:right;margin-top:7px;border-width:0 4px 4px;border-style:solid;border-color:#000 transparent;visibility:hidden;} +table .headerSortUp,table .headerSortDown{background-color:rgba(141, 192, 219, 0.25);text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);} +table .header:hover:after{visibility:visible;} +table .headerSortDown:after,table .headerSortDown:hover:after{visibility:visible;filter:alpha(opacity=60);-khtml-opacity:0.6;-moz-opacity:0.6;opacity:0.6;} +table .headerSortUp:after{border-bottom:none;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000;visibility:visible;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:alpha(opacity=60);-khtml-opacity:0.6;-moz-opacity:0.6;opacity:0.6;} +table .blue{color:#049cdb;border-bottom-color:#049cdb;} +table .headerSortUp.blue,table .headerSortDown.blue{background-color:#ade6fe;} +table .green{color:#46a546;border-bottom-color:#46a546;} +table .headerSortUp.green,table .headerSortDown.green{background-color:#cdeacd;} +table .red{color:#9d261d;border-bottom-color:#9d261d;} +table .headerSortUp.red,table .headerSortDown.red{background-color:#f4c8c5;} +table .yellow{color:#ffc40d;border-bottom-color:#ffc40d;} +table .headerSortUp.yellow,table .headerSortDown.yellow{background-color:#fff6d9;} +table .orange{color:#f89406;border-bottom-color:#f89406;} +table .headerSortUp.orange,table .headerSortDown.orange{background-color:#fee9cc;} +table .purple{color:#7a43b6;border-bottom-color:#7a43b6;} +table .headerSortUp.purple,table .headerSortDown.purple{background-color:#e2d5f0;} +.topbar{height:40px;position:fixed;top:0;left:0;right:0;z-index:10000;overflow:visible;}.topbar a{color:#bfbfbf;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);} +.topbar h3 a:hover,.topbar .brand:hover,.topbar ul .active>a{background-color:#333;background-color:rgba(255, 255, 255, 0.05);color:#ffffff;text-decoration:none;} +.topbar h3{position:relative;} +.topbar h3 a,.topbar .brand{float:left;display:block;padding:8px 20px 12px;margin-left:-20px;color:#ffffff;font-size:20px;font-weight:200;line-height:1;} +.topbar p{margin:0;line-height:40px;}.topbar p a:hover{background-color:transparent;color:#ffffff;} +.topbar form{float:left;margin:5px 0 0 0;position:relative;filter:alpha(opacity=100);-khtml-opacity:1;-moz-opacity:1;opacity:1;} +.topbar form.pull-right{float:right;} +.topbar input{background-color:#444;background-color:rgba(255, 255, 255, 0.3);font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:normal;font-weight:13px;line-height:1;padding:4px 9px;color:#ffffff;color:rgba(255, 255, 255, 0.75);border:1px solid #111;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.25);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.25);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.25);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none;}.topbar input:-moz-placeholder{color:#e6e6e6;} +.topbar input::-webkit-input-placeholder{color:#e6e6e6;} +.topbar input:hover{background-color:#bfbfbf;background-color:rgba(255, 255, 255, 0.5);color:#ffffff;} +.topbar input:focus,.topbar input.focused{outline:0;background-color:#ffffff;color:#404040;text-shadow:0 1px 0 #ffffff;border:0;padding:5px 10px;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);} +.topbar-inner,.topbar .fill{background-color:#222;background-color:#222222;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);} +.topbar div>ul,.nav{display:block;float:left;margin:0 10px 0 0;position:relative;left:0;}.topbar div>ul>li,.nav>li{display:block;float:left;} +.topbar div>ul a,.nav a{display:block;float:none;padding:10px 10px 11px;line-height:19px;text-decoration:none;}.topbar div>ul a:hover,.nav a:hover{color:#ffffff;text-decoration:none;} +.topbar div>ul .active>a,.nav .active>a{background-color:#222;background-color:rgba(0, 0, 0, 0.5);} +.topbar div>ul.secondary-nav,.nav.secondary-nav{float:right;margin-left:10px;margin-right:0;}.topbar div>ul.secondary-nav .menu-dropdown,.nav.secondary-nav .menu-dropdown,.topbar div>ul.secondary-nav .dropdown-menu,.nav.secondary-nav .dropdown-menu{right:0;border:0;} +.topbar div>ul a.menu:hover,.nav a.menu:hover,.topbar div>ul li.open .menu,.nav li.open .menu,.topbar div>ul .dropdown-toggle:hover,.nav .dropdown-toggle:hover,.topbar div>ul .dropdown.open .dropdown-toggle,.nav .dropdown.open .dropdown-toggle{background:#444;background:rgba(255, 255, 255, 0.05);} +.topbar div>ul .menu-dropdown,.nav .menu-dropdown,.topbar div>ul .dropdown-menu,.nav .dropdown-menu{background-color:#333;}.topbar div>ul .menu-dropdown a.menu,.nav .menu-dropdown a.menu,.topbar div>ul .dropdown-menu a.menu,.nav .dropdown-menu a.menu,.topbar div>ul .menu-dropdown .dropdown-toggle,.nav .menu-dropdown .dropdown-toggle,.topbar div>ul .dropdown-menu .dropdown-toggle,.nav .dropdown-menu .dropdown-toggle{color:#ffffff;}.topbar div>ul .menu-dropdown a.menu.open,.nav .menu-dropdown a.menu.open,.topbar div>ul .dropdown-menu a.menu.open,.nav .dropdown-menu a.menu.open,.topbar div>ul .menu-dropdown .dropdown-toggle.open,.nav .menu-dropdown .dropdown-toggle.open,.topbar div>ul .dropdown-menu .dropdown-toggle.open,.nav .dropdown-menu .dropdown-toggle.open{background:#444;background:rgba(255, 255, 255, 0.05);} +.topbar div>ul .menu-dropdown li a,.nav .menu-dropdown li a,.topbar div>ul .dropdown-menu li a,.nav .dropdown-menu li a{color:#999;text-shadow:0 1px 0 rgba(0, 0, 0, 0.5);}.topbar div>ul .menu-dropdown li a:hover,.nav .menu-dropdown li a:hover,.topbar div>ul .dropdown-menu li a:hover,.nav .dropdown-menu li a:hover{background-color:#191919;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919));background-image:-moz-linear-gradient(top, #292929, #191919);background-image:-ms-linear-gradient(top, #292929, #191919);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919));background-image:-webkit-linear-gradient(top, #292929, #191919);background-image:-o-linear-gradient(top, #292929, #191919);background-image:linear-gradient(top, #292929, #191919);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0);color:#ffffff;} +.topbar div>ul .menu-dropdown .active a,.nav .menu-dropdown .active a,.topbar div>ul .dropdown-menu .active a,.nav .dropdown-menu .active a{color:#ffffff;} +.topbar div>ul .menu-dropdown .divider,.nav .menu-dropdown .divider,.topbar div>ul .dropdown-menu .divider,.nav .dropdown-menu .divider{background-color:#222;border-color:#444;} +.topbar ul .menu-dropdown li a,.topbar ul .dropdown-menu li a{padding:4px 15px;} +li.menu,.dropdown{position:relative;} +a.menu:after,.dropdown-toggle:after{width:0;height:0;display:inline-block;content:"↓";text-indent:-99999px;vertical-align:top;margin-top:8px;margin-left:4px;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #ffffff;filter:alpha(opacity=50);-khtml-opacity:0.5;-moz-opacity:0.5;opacity:0.5;} +.menu-dropdown,.dropdown-menu{background-color:#ffffff;float:left;display:none;position:absolute;top:40px;z-index:900;min-width:160px;max-width:220px;_width:160px;margin-left:0;margin-right:0;padding:6px 0;zoom:1;border-color:#999;border-color:rgba(0, 0, 0, 0.2);border-style:solid;border-width:0 1px 1px;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:0 2px 4px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 2px 4px rgba(0, 0, 0, 0.2);box-shadow:0 2px 4px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.menu-dropdown li,.dropdown-menu li{float:none;display:block;background-color:none;} +.menu-dropdown .divider,.dropdown-menu .divider{height:1px;margin:5px 0;overflow:hidden;background-color:#eee;border-bottom:1px solid #ffffff;} +.topbar .dropdown-menu a,.dropdown-menu a{display:block;padding:4px 15px;clear:both;font-weight:normal;line-height:18px;color:#808080;text-shadow:0 1px 0 #ffffff;}.topbar .dropdown-menu a:hover,.dropdown-menu a:hover,.topbar .dropdown-menu a.hover,.dropdown-menu a.hover{background-color:#dddddd;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#eeeeee), to(#dddddd));background-image:-moz-linear-gradient(top, #eeeeee, #dddddd);background-image:-ms-linear-gradient(top, #eeeeee, #dddddd);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #eeeeee), color-stop(100%, #dddddd));background-image:-webkit-linear-gradient(top, #eeeeee, #dddddd);background-image:-o-linear-gradient(top, #eeeeee, #dddddd);background-image:linear-gradient(top, #eeeeee, #dddddd);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#dddddd', GradientType=0);color:#404040;text-decoration:none;-webkit-box-shadow:inset 0 1px 0 rgba(0, 0, 0, 0.025),inset 0 -1px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 0 rgba(0, 0, 0, 0.025),inset 0 -1px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 0 rgba(0, 0, 0, 0.025),inset 0 -1px rgba(0, 0, 0, 0.025);} +.open .menu,.dropdown.open .menu,.open .dropdown-toggle,.dropdown.open .dropdown-toggle{color:#ffffff;background:#ccc;background:rgba(0, 0, 0, 0.3);} +.open .menu-dropdown,.dropdown.open .menu-dropdown,.open .dropdown-menu,.dropdown.open .dropdown-menu{display:block;} +.tabs,.pills{margin:0 0 18px;padding:0;list-style:none;zoom:1;}.tabs:before,.pills:before,.tabs:after,.pills:after{display:table;content:"";zoom:1;} +.tabs:after,.pills:after{clear:both;} +.tabs>li,.pills>li{float:left;}.tabs>li>a,.pills>li>a{display:block;} +.tabs{border-color:#ddd;border-style:solid;border-width:0 0 1px;}.tabs>li{position:relative;margin-bottom:-1px;}.tabs>li>a{padding:0 15px;margin-right:2px;line-height:34px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.tabs>li>a:hover{text-decoration:none;background-color:#eee;border-color:#eee #eee #ddd;} +.tabs .active>a,.tabs .active>a:hover{color:#808080;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} +.tabs .menu-dropdown,.tabs .dropdown-menu{top:35px;border-width:1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;} +.tabs a.menu:after,.tabs .dropdown-toggle:after{border-top-color:#999;margin-top:15px;margin-left:5px;} +.tabs li.open.menu .menu,.tabs .open.dropdown .dropdown-toggle{border-color:#999;} +.tabs li.open a.menu:after,.tabs .dropdown.open .dropdown-toggle:after{border-top-color:#555;} +.pills a{margin:5px 3px 5px 0;padding:0 15px;line-height:30px;text-shadow:0 1px 1px #ffffff;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}.pills a:hover{color:#ffffff;text-decoration:none;text-shadow:0 1px 1px rgba(0, 0, 0, 0.25);background-color:#00438a;} +.pills .active a{color:#ffffff;text-shadow:0 1px 1px rgba(0, 0, 0, 0.25);background-color:#0069d6;} +.pills-vertical>li{float:none;} +.tab-content>.tab-pane,.pill-content>.pill-pane,.tab-content>div,.pill-content>div{display:none;} +.tab-content>.active,.pill-content>.active{display:block;} +.breadcrumb{padding:7px 14px;margin:0 0 18px;background-color:#f5f5f5;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#ffffff), to(#f5f5f5));background-image:-moz-linear-gradient(top, #ffffff, #f5f5f5);background-image:-ms-linear-gradient(top, #ffffff, #f5f5f5);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #f5f5f5));background-image:-webkit-linear-gradient(top, #ffffff, #f5f5f5);background-image:-o-linear-gradient(top, #ffffff, #f5f5f5);background-image:linear-gradient(top, #ffffff, #f5f5f5);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;}.breadcrumb li{display:inline;text-shadow:0 1px 0 #ffffff;} +.breadcrumb .divider{padding:0 5px;color:#bfbfbf;} +.breadcrumb .active a{color:#404040;} +.hero-unit{background-color:#f5f5f5;margin-bottom:30px;padding:60px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;} +.hero-unit p{font-size:18px;font-weight:200;line-height:27px;} +footer{margin-top:17px;padding-top:17px;border-top:1px solid #eee;} +.page-header{margin-bottom:17px;border-bottom:1px solid #ddd;-webkit-box-shadow:0 1px 0 rgba(255, 255, 255, 0.5);-moz-box-shadow:0 1px 0 rgba(255, 255, 255, 0.5);box-shadow:0 1px 0 rgba(255, 255, 255, 0.5);}.page-header h1{margin-bottom:8px;} +.btn.danger,.alert-message.danger,.btn.danger:hover,.alert-message.danger:hover,.btn.error,.alert-message.error,.btn.error:hover,.alert-message.error:hover,.btn.success,.alert-message.success,.btn.success:hover,.alert-message.success:hover,.btn.info,.alert-message.info,.btn.info:hover,.alert-message.info:hover{color:#ffffff;} +.btn .close,.alert-message .close{font-family:Arial,sans-serif;line-height:18px;} +.btn.danger,.alert-message.danger,.btn.error,.alert-message.error{background-color:#c43c35;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(top, #ee5f5b, #c43c35);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#c43c35 #c43c35 #882a25;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);} +.btn.success,.alert-message.success{background-color:#57a957;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957));background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-ms-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(top, #62c462, #57a957);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#57a957 #57a957 #3d773d;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);} +.btn.info,.alert-message.info{background-color:#339bb9;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9));background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-ms-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(top, #5bc0de, #339bb9);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#339bb9 #339bb9 #22697d;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);} +.btn{cursor:pointer;display:inline-block;background-color:#e6e6e6;background-repeat:no-repeat;background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-image:-moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6);background-image:-ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-image:-o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-image:linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);padding:5px 14px 6px;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);color:#333;font-size:13px;line-height:normal;border:1px solid #ccc;border-bottom-color:#bbb;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-webkit-transition:0.1s linear all;-moz-transition:0.1s linear all;-ms-transition:0.1s linear all;-o-transition:0.1s linear all;transition:0.1s linear all;}.btn:hover{background-position:0 -15px;color:#333;text-decoration:none;} +.btn:focus{outline:1px dotted #666;} +.btn.primary{color:#ffffff;background-color:#0064cd;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd));background-image:-moz-linear-gradient(top, #049cdb, #0064cd);background-image:-ms-linear-gradient(top, #049cdb, #0064cd);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd));background-image:-webkit-linear-gradient(top, #049cdb, #0064cd);background-image:-o-linear-gradient(top, #049cdb, #0064cd);background-image:linear-gradient(top, #049cdb, #0064cd);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#049cdb', endColorstr='#0064cd', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#0064cd #0064cd #003f81;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);} +.btn.active,.btn :active{-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.25),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.25),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.25),0 1px 2px rgba(0, 0, 0, 0.05);} +.btn.disabled{cursor:default;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=65);-khtml-opacity:0.65;-moz-opacity:0.65;opacity:0.65;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn[disabled]{cursor:default;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=65);-khtml-opacity:0.65;-moz-opacity:0.65;opacity:0.65;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn.large{font-size:15px;line-height:normal;padding:9px 14px 9px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.btn.small{padding:7px 9px 7px;font-size:11px;} +:root .alert-message,:root .btn{border-radius:0 \0;} +button.btn::-moz-focus-inner,input[type=submit].btn::-moz-focus-inner{padding:0;border:0;} +.close{float:right;color:#000000;font-size:20px;font-weight:bold;line-height:13.5px;text-shadow:0 1px 0 #ffffff;filter:alpha(opacity=25);-khtml-opacity:0.25;-moz-opacity:0.25;opacity:0.25;}.close:hover{color:#000000;text-decoration:none;filter:alpha(opacity=40);-khtml-opacity:0.4;-moz-opacity:0.4;opacity:0.4;} +.alert-message{position:relative;padding:7px 15px;margin-bottom:18px;color:#404040;background-color:#eedc94;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94));background-image:-moz-linear-gradient(top, #fceec1, #eedc94);background-image:-ms-linear-gradient(top, #fceec1, #eedc94);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94));background-image:-webkit-linear-gradient(top, #fceec1, #eedc94);background-image:-o-linear-gradient(top, #fceec1, #eedc94);background-image:linear-gradient(top, #fceec1, #eedc94);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#eedc94 #eedc94 #e4c652;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);border-width:1px;border-style:solid;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);}.alert-message .close{margin-top:1px;*margin-top:0;} +.alert-message a{font-weight:bold;color:#404040;} +.alert-message.danger p a,.alert-message.error p a,.alert-message.success p a,.alert-message.info p a{color:#ffffff;} +.alert-message h5{line-height:18px;} +.alert-message p{margin-bottom:0;} +.alert-message div{margin-top:5px;margin-bottom:2px;line-height:28px;} +.alert-message .btn{-webkit-box-shadow:0 1px 0 rgba(255, 255, 255, 0.25);-moz-box-shadow:0 1px 0 rgba(255, 255, 255, 0.25);box-shadow:0 1px 0 rgba(255, 255, 255, 0.25);} +.alert-message.block-message{background-image:none;background-color:#fdf5d9;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);padding:14px;border-color:#fceec1;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}.alert-message.block-message ul,.alert-message.block-message p{margin-right:30px;} +.alert-message.block-message ul{margin-bottom:0;} +.alert-message.block-message li{color:#404040;} +.alert-message.block-message .alert-actions{margin-top:5px;} +.alert-message.block-message.error,.alert-message.block-message.success,.alert-message.block-message.info{color:#404040;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);} +.alert-message.block-message.error{background-color:#fddfde;border-color:#fbc7c6;} +.alert-message.block-message.success{background-color:#d1eed1;border-color:#bfe7bf;} +.alert-message.block-message.info{background-color:#ddf4fb;border-color:#c6edf9;} +.alert-message.block-message.danger p a,.alert-message.block-message.error p a,.alert-message.block-message.success p a,.alert-message.block-message.info p a{color:#404040;} +.pagination{height:36px;margin:18px 0;}.pagination ul{float:left;margin:0;border:1px solid #ddd;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} +.pagination li{display:inline;} +.pagination a{float:left;padding:0 14px;line-height:34px;border-right:1px solid;border-right-color:#ddd;border-right-color:rgba(0, 0, 0, 0.15);*border-right-color:#ddd;text-decoration:none;} +.pagination a:hover,.pagination .active a{background-color:#c7eefe;} +.pagination .disabled a,.pagination .disabled a:hover{background-color:transparent;color:#bfbfbf;} +.pagination .next a{border:0;} +.well{background-color:#f5f5f5;margin-bottom:20px;padding:19px;min-height:20px;border:1px solid #eee;border:1px solid rgba(0, 0, 0, 0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);} +.modal-backdrop{background-color:#000000;position:fixed;top:0;left:0;right:0;bottom:0;z-index:10000;}.modal-backdrop.fade{opacity:0;} +.modal-backdrop,.modal-backdrop.fade.in{filter:alpha(opacity=80);-khtml-opacity:0.8;-moz-opacity:0.8;opacity:0.8;} +.modal{position:fixed;top:50%;left:50%;z-index:11000;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.modal .close{margin-top:7px;} +.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-ms-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;} +.modal.fade.in{top:50%;} +.modal-header{border-bottom:1px solid #eee;padding:5px 15px;} +.modal-body{padding:15px;} +.modal-body form{margin-bottom:0;} +.modal-footer{background-color:#f5f5f5;padding:14px 15px 15px;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;zoom:1;margin-bottom:0;}.modal-footer:before,.modal-footer:after{display:table;content:"";zoom:1;} +.modal-footer:after{clear:both;} +.modal-footer .btn{float:right;margin-left:5px;} +.modal .popover,.modal .twipsy{z-index:12000;} +.twipsy{display:block;position:absolute;visibility:visible;padding:5px;font-size:11px;z-index:1000;filter:alpha(opacity=80);-khtml-opacity:0.8;-moz-opacity:0.8;opacity:0.8;}.twipsy.fade.in{filter:alpha(opacity=80);-khtml-opacity:0.8;-moz-opacity:0.8;opacity:0.8;} +.twipsy.above .twipsy-arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.twipsy.left .twipsy-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} +.twipsy.below .twipsy-arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} +.twipsy.right .twipsy-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} +.twipsy-inner{padding:3px 8px;background-color:#000000;color:white;text-align:center;max-width:200px;text-decoration:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.twipsy-arrow{position:absolute;width:0;height:0;} +.popover{position:absolute;top:0;left:0;z-index:1000;padding:5px;display:none;}.popover.above .arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} +.popover.below .arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} +.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} +.popover .arrow{position:absolute;width:0;height:0;} +.popover .inner{background:#000000;background:rgba(0, 0, 0, 0.8);padding:3px;overflow:hidden;width:280px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);} +.popover .title{background-color:#f5f5f5;padding:9px 15px;line-height:1;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;border-bottom:1px solid #eee;} +.popover .content{background-color:#ffffff;padding:14px;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.popover .content p,.popover .content ul,.popover .content ol{margin-bottom:0;} +.fade{-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-ms-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;opacity:0;}.fade.in{opacity:1;} +.label{padding:1px 3px 2px;font-size:9.75px;font-weight:bold;color:#ffffff;text-transform:uppercase;white-space:nowrap;background-color:#bfbfbf;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}.label.important{background-color:#c43c35;} +.label.warning{background-color:#f89406;} +.label.success{background-color:#46a546;} +.label.notice{background-color:#62cffc;} +.media-grid{margin-left:-20px;margin-bottom:0;zoom:1;}.media-grid:before,.media-grid:after{display:table;content:"";zoom:1;} +.media-grid:after{clear:both;} +.media-grid li{display:inline;} +.media-grid a{float:left;padding:4px;margin:0 0 18px 20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);}.media-grid a img{display:block;} +.media-grid a:hover{border-color:#0069d6;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/custom.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/custom.css new file mode 100644 index 00000000..b7df8c25 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/custom.css @@ -0,0 +1,97 @@ +body, html, div, p, span, a, h1, h2, h3, h4, h5{ + margin : 0; + padding : 0; +} + +body, html{ + width : 100%; +} + +body{ + color : white; + font-family : tahoma; + font-weight : lighter; + padding-top : 40px; +} + + body p{ + font-size : 14px; + } + + body p a{ + font-size : 16px; + } + +h1 { + color : #E05E00; + font-style : italic; +} + +a{ + color : #E05E00; + text-decoration : none; +} + +a:hover{ + text-decoration : underline; +} + +/* general */ +.clear { + clear: both; +} + +/* Header */ +.brand{ + color : #E05E00 !important; + font-family : georgia; + font-style : italic; +} + +/* list stuff */ +#org{ + background-color : white; + margin : 10px; + padding : 10px; +} + +#show-list{ + cursor : pointer; +} + +/* bootstrap overrides */ +.alert-message{ + margin: 2px 0; +} + +.topbar{ + position : absolute; +} + +/* Custom chart styling */ +.jOrgChart { + margin : 10px; + padding : 20px; +} + +/* Custom node styling */ +.jOrgChart .node { + font-weight : bold; + font-size : 14px; + background-color : #D5D6DB; + border-radius : 8px; + border : 5px solid gray; + color : #793a06; + -moz-border-radius : 8px; +} + .node p{ + font-family : tahoma; + font-size : 10px; + line-height : 11px; + padding : 2px; + } + +table { + margin-left: auto; + margin-right: auto; +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/jquery.jOrgChart.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/jquery.jOrgChart.css new file mode 100644 index 00000000..ffabe274 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/jquery.jOrgChart.css @@ -0,0 +1,51 @@ +/* Basic styling */ +/* Draw the lines */ +.jOrgChart .line { + height : 20px; + width : 4px; +} + +.jOrgChart .down { + background-color : black; + margin : 0px auto; +} + +.jOrgChart .top { + border-top : 3px solid black; +} + +.jOrgChart .left { + border-right : 2px solid black; +} + +.jOrgChart .right { + border-left : 2px solid black; +} + +/* node cell */ +.jOrgChart td { + text-align : center; + vertical-align : top; + padding : 0; +} + +/* The node */ +.jOrgChart .node { + background-color : #35363B; + display : inline-block; + width : 120px; + height : 60px; + z-index : 10; + margin : 0 2px; +} + +/* jQuery drag 'n drop */ + +.drag-active { + border-style : dashed !important; +} + +.drop-hover { + border-style : solid !important; + border-color : #E05E00 !important; +} diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/prettify.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/prettify.css new file mode 100644 index 00000000..d44b3a22 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/css/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/example.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/example.html new file mode 100644 index 00000000..543b0f92 --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/example.html @@ -0,0 +1,85 @@ + + + jOrgChart - A jQuery OrgChart Plugin + + + + + + + + + + + + + + + + + + + +
        + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/example_vsp.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/example_vsp.html new file mode 100644 index 00000000..a2e3703d --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/example_vsp.html @@ -0,0 +1,88 @@ + + + jOrgChart - A jQuery OrgChart Plugin + + + + + + + + + + + + + + + + + + + +
        + + + + \ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/images/bkgd.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/images/bkgd.png new file mode 100644 index 0000000000000000000000000000000000000000..3bbaf5eeea64914a5d5698b6c9fa0f03030bff7c GIT binary patch literal 133 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"); + if($this.is("ul")) { + buildNode($this.find("li:first"), $container, 0, opts); + } + else if($this.is("li")) { + buildNode($this, $container, 0, opts); + } + $appendTo.append($container); + + // add drag and drop if enabled + if(opts.dragAndDrop){ + $('div.node').draggable({ + cursor : 'move', + distance : 40, + helper : 'clone', + opacity : 0.8, + revert : true, + revertDuration : 100, + snap : 'div.node.expanded', + snapMode : 'inner', + stack : 'div.node' + }); + + $('div.node').droppable({ + accept : '.node', + activeClass : 'drag-active', + hoverClass : 'drop-hover' + }); + + // Drag start event handler for nodes + $('div.node').bind("dragstart", function handleDragStart( event, ui ){ + + var sourceNode = $(this); + sourceNode.parentsUntil('.node-container') + .find('*') + .filter('.node') + .droppable('disable'); + }); + + // Drag stop event handler for nodes + $('div.node').bind("dragstop", function handleDragStop( event, ui ){ + + /* reload the plugin */ + $(opts.chartElement).children().remove(); + $this.jOrgChart(opts); + }); + + // Drop event handler for nodes + $('div.node').bind("drop", function handleDropEvent( event, ui ) { + var sourceNode = ui.draggable; + var targetNode = $(this); + + // finding nodes based on plaintext and html + // content is hard! + var targetLi = $('li').filter(function(){ + + li = $(this).clone() + .children("ul,li") + .remove() + .end(); + var attr = li.attr('id'); + if (typeof attr !== 'undefined' && attr !== false) { + return li.attr("id") == targetNode.attr("id"); + } + else { + return li.html() == targetNode.html(); + } + + }); + + var sourceLi = $('li').filter(function(){ + + li = $(this).clone() + .children("ul,li") + .remove() + .end(); + var attr = li.attr('id'); + if (typeof attr !== 'undefined' && attr !== false) { + return li.attr("id") == sourceNode.attr("id"); + } + else { + return li.html() == sourceNode.html(); + } + + }); + + var sourceliClone = sourceLi.clone(); + var sourceUl = sourceLi.parent('ul'); + + if(sourceUl.children('li').size() > 1){ + sourceLi.remove(); + }else{ + sourceUl.remove(); + } + + var id = sourceLi.attr("id"); + + if(targetLi.children('ul').size() >0){ + if (typeof id !== 'undefined' && id !== false) { + targetLi.children('ul').append('
      • '+sourceliClone.html()+'
      • '); + }else{ + targetLi.children('ul').append('
      • '+sourceliClone.html()+'
      • '); + } + }else{ + if (typeof id !== 'undefined' && id !== false) { + targetLi.append('
        • '+sourceliClone.html()+'
        '); + }else{ + targetLi.append('
        • '+sourceliClone.html()+'
        '); + } + } + + }); // handleDropEvent + + } // Drag and drop + }; + + // Option defaults + $.fn.jOrgChart.defaults = { + chartElement : 'body', + depth : -1, + chartClass : "jOrgChart", + dragAndDrop: false + }; + + // Method that recursively builds the tree + function buildNode($node, $appendTo, level, opts) { + var $table = $(""); + var $tbody = $(""); + + // Construct the node container(s) + var $nodeRow = $("").addClass("node-cells"); + var $nodeCell = $(""); + var $downLineCell = $(""); + $childNodes.each(function() { + var $left = $("").addClass("line left top"); + var $right = $("").addClass("line right top"); + $linesRow.append($left).append($right); + }); + + // horizontal line shouldn't extend beyond the first and last child branches + $linesRow.find("td:first") + .removeClass("top") + .end() + .find("td:last") + .removeClass("top"); + + $tbody.append($linesRow); + var $childNodesRow = $(""); + $childNodes.each(function() { + var $td = $(" - } // if - } // for -*/ - - //cellNum = -1; - - -// Set mapSet = dataTypeMap.entrySet(); -// Map.Entry me; -// String element, value ; -// for (Iterator iter = mapSet.iterator(); iter.hasNext();) { -// me=(Map.Entry)iter.next(); -// element = (String) me.getKey(); -// value = (String) me.getValue(); -// System.out.println("DataTypeMap " + element + " " + value); -// } - - for (chr.resetNext(); chr.hasNext();) { - ColumnHeader ch = chr.getNext(); - if(ch.isVisible()) { - cellNum += 1; - - int colSpan = ch.getColSpan()-1; - title = ch.getColumnTitle(); - title = Utils.replaceInString(title,"_nl_", " \n"); - row.createCell((short) cellNum).setCellValue(title); - if(colSpan > 0) { - for ( int k = 1; k <= colSpan; k++ ) { - row.createCell((short) cellNum+k); - } - sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (cellNum+colSpan))); - } - - - -/* if (cellWidth.size() > cellNum) { - if (((Integer) cellWidth.get(cellNum)).intValue() < ch - .getColumnTitle().length()) - cellWidth - .set((cellNum), new Integer(ch.getColumnTitle().length())); - } else - cellWidth.add((cellNum), new Integer(ch.getColumnTitle().length())); -*/ row.getCell((short) (cellNum)).setCellStyle(styleDataHeader); - for ( int k = 1; k <= colSpan; k++ ) { - row.getCell((short) (cellNum+k)).setCellStyle(styleDataHeader); - } - - if(colSpan > 0) - cellNum += colSpan; - } - } // for - -/* int cw = 0; - for (int i = 0; i < cellWidth.size(); i++) { - cw = ((Integer) cellWidth.get(i)).intValue() + 6; - sheet.setColumnWidth((short) (i), (short) ((cw * 8) / ((double) 1 / 20))); - } -*/ - rowNum += 1; - } // for - - - // Data - // Create some cell styles. - //HSSFCellStyle styleDefault = wb.createCellStyle(); - HSSFCellStyle styleCell = null; - - HSSFCellStyle styleTotal = wb.createCellStyle(); - HSSFCellStyle styleCurrencyTotal = wb.createCellStyle(); - HSSFCellStyle styleDefaultTotal = wb.createCellStyle(); - HSSFCellStyle styleCurrencyDecimalNumberTotal = wb.createCellStyle(); - HSSFCellStyle styleDecimalNumberTotal = wb.createCellStyle(); - HSSFCellStyle styleCurrencyNumberTotal = wb.createCellStyle(); - - - // Create some fonts. - HSSFFont fontDefault = wb.createFont(); - HSSFFont fontBold = wb.createFont(); - // Initialize the styles & fonts. - // The default will be plain . - fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); - fontDefault.setFontHeight((short) (font_size / 0.05)); - fontDefault.setFontName("Tahoma"); - - // The default will be bold black tachoma 10pt text. - fontBold.setColor((short) HSSFFont.COLOR_NORMAL); - fontBold.setFontHeight((short) (font_size / 0.05)); - fontBold.setFontName("Tahoma"); - fontBold.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - // Style default will be normal with no background - styleDefault.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleDefault.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleDefault.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleDefault.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleDefault.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleDefault.setFillPattern(HSSFCellStyle.NO_FILL); - styleDefault.setFont(fontDefault); - styleDefault.setWrapText(true); - //Number - styleNumber.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleNumber.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleNumber.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleNumber.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleNumber.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleNumber.setFillPattern(HSSFCellStyle.NO_FILL); - styleNumber.setFont(fontDefault); - try { - styleNumber.setDataFormat((short)0x26);//HSSFDataFormat.getBuiltinFormat("(#,##0_);[Red](#,##0)")); - } catch (Exception e) { - - } - //Decimal Number - styleDecimalNumber.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleDecimalNumber.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleDecimalNumber.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleDecimalNumber.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleDecimalNumber.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleDecimalNumber.setFillPattern(HSSFCellStyle.NO_FILL); - styleDecimalNumber.setFont(fontDefault); - styleDecimalNumber.setDataFormat((short)0x27);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); - - //Decimal Number - styleDecimalNumberTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleDecimalNumberTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleDecimalNumberTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleDecimalNumberTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleDecimalNumberTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleDecimalNumberTotal.setFillPattern(HSSFCellStyle.NO_FILL); - styleDecimalNumberTotal.setFont(fontBold); - styleDecimalNumberTotal.setDataFormat((short)0x27);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); - - //CurrencyNumber - styleCurrencyDecimalNumber.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleCurrencyDecimalNumber.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleCurrencyDecimalNumber.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleCurrencyDecimalNumber.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleCurrencyDecimalNumber.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleCurrencyDecimalNumber.setFillPattern(HSSFCellStyle.NO_FILL); - styleCurrencyDecimalNumber.setFont(fontDefault); - styleCurrencyDecimalNumber.setDataFormat((short)8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); - - //currency number bold - styleCurrencyDecimalNumberTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleCurrencyDecimalNumberTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleCurrencyDecimalNumberTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleCurrencyDecimalNumberTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleCurrencyDecimalNumberTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleCurrencyDecimalNumberTotal.setFillPattern(HSSFCellStyle.NO_FILL); - styleCurrencyDecimalNumberTotal.setFont(fontBold); - styleCurrencyDecimalNumberTotal.setDataFormat((short)8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); - - - //CurrencyNumber - styleCurrencyNumber.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleCurrencyNumber.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleCurrencyNumber.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleCurrencyNumber.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleCurrencyNumber.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleCurrencyNumber.setFillPattern(HSSFCellStyle.NO_FILL); - styleCurrencyNumber.setFont(fontDefault); - styleCurrencyNumber.setDataFormat((short) 6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); - - - //CurrencyNumber - styleCurrencyNumberTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleCurrencyNumberTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleCurrencyNumberTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleCurrencyNumberTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleCurrencyNumberTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleCurrencyNumberTotal.setFillPattern(HSSFCellStyle.NO_FILL); - styleCurrencyNumberTotal.setFont(fontBold); - styleCurrencyNumberTotal.setDataFormat((short) 6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); - - //Date - styleDate.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleDate.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleDate.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleDate.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleDate.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleDate.setFillPattern(HSSFCellStyle.NO_FILL); - styleDate.setFont(fontDefault); - styleDate.setDataFormat((short)0xe);//HSSFDataFormat.getBuiltinFormat("m/d/yy")); - - // Style for Total will be Bold with normal font with no background - styleTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleTotal.setFillPattern(HSSFCellStyle.NO_FILL); - styleTotal.setDataFormat((short)0x28);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); - styleTotal.setFont(fontBold); - - styleCurrencyTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleCurrencyTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleCurrencyTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleCurrencyTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleCurrencyTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleCurrencyTotal.setFillPattern(HSSFCellStyle.NO_FILL); - styleCurrencyTotal.setDataFormat((short)8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); - styleCurrencyTotal.setFont(fontBold); - - styleDefaultTotal.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleDefaultTotal.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleDefaultTotal.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleDefaultTotal.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleDefaultTotal.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleDefaultTotal.setFillPattern(HSSFCellStyle.NO_FILL); - styleDefaultTotal.setDataFormat((short)0x28); - ////styleDefaultTotal.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); - styleDefaultTotal.setFont(fontBold); - - firstPass = true; - // Declare a row object reference. - HSSFRow row = null; - // Declare a cell object reference. - HSSFCell cell = null; - //HSSFCell cellNumber = null; - //HSSFCell cellCurrencyNumber = null; - //HSSFCell cellDate = null; - - //All the possible combinations of date format - SimpleDateFormat MMDDYYYYFormat = new SimpleDateFormat("MM/dd/yyyy"); - SimpleDateFormat YYYYMMDDFormat = new SimpleDateFormat("yyyy/MM/dd"); - SimpleDateFormat MONYYYYFormat = new SimpleDateFormat("MMM yyyy"); - SimpleDateFormat MMYYYYFormat = new SimpleDateFormat("MM/yyyy"); - SimpleDateFormat MMMMMDDYYYYFormat = new SimpleDateFormat("MMMMM dd, yyyy"); - SimpleDateFormat YYYYMMDDDASHFormat = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - SimpleDateFormat DDMONYYYYFormat = new SimpleDateFormat("dd-MMM-yyyy"); - SimpleDateFormat MONTHYYYYFormat = new SimpleDateFormat("MMMMM, yyyy"); - SimpleDateFormat MMDDYYYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); - SimpleDateFormat MMDDYYYYHHMMFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm"); - SimpleDateFormat YYYYMMDDHHMMSSFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - SimpleDateFormat YYYYMMDDHHMMFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); - SimpleDateFormat DDMONYYYYHHMMSSFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); - SimpleDateFormat DDMONYYYYHHMMFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); - SimpleDateFormat DDMONYYHHMMFormat = new SimpleDateFormat("dd-MMM-yy HH:mm"); - SimpleDateFormat MMDDYYFormat = new SimpleDateFormat("MM/dd/yy"); - SimpleDateFormat MMDDYYHHMMFormat = new SimpleDateFormat("MM/dd/yy HH:mm"); - SimpleDateFormat MMDDYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); - SimpleDateFormat MMDDYYYYHHMMZFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm z"); - SimpleDateFormat MMMMMDDYYYYHHMMSS = new SimpleDateFormat("MMMMM-dd-yyyy HH:mm:ss"); - - - - - ResultSet rs = null; - Connection conn = null; - Statement st = null; - ResultSetMetaData rsmd = null; - CreationHelper createHelper = wb.getCreationHelper(); - - if(nvl(sql_whole).length() >0 && rr.getReportType().equals(AppConstants.RT_LINEAR)) { - try { - conn = ConnectionUtils.getConnection(rr.getDbInfo()); - st = conn.createStatement(); - System.out.println("************* Map Whole SQL *************"); - System.out.println(sql_whole); - System.out.println("*****************************************"); - rs = st.executeQuery(sql_whole); - rsmd = rs.getMetaData(); - int numberOfColumns = rsmd.getColumnCount(); - HashMap colHash = new HashMap(); - DataRow dr = null; - int j = 0; - int rowCount = 0; - while(rs.next()) { - rowCount++; - row = sheet.createRow(rowNum); - cellNum = -1; - colHash = new HashMap(); - for (int i = 1; i <= numberOfColumns; i++) { - colHash.put(rsmd.getColumnLabel(i).toUpperCase(), strip.stripHtml(rs.getString(i))); - } - rd.reportDataRows.resetNext(); - dr = rd.reportDataRows.getNext(); - j = 0; - //if(rowCount%1000 == 0) wb.write(sos); - - /*if(rd.reportTotalRowHeaderCols!=null) { - //cellNum = -1; - //for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { - cellNum += 1; - //RowHeaderCol rhc = rd.reportRowHeaderCols.getRowHeaderCol(0); - //if (firstPass) - // rhc.resetNext(); - //RowHeader rh = rhc.getRowHeader(rowCount-1); - row.createCell((short) cellNum).setCellValue(rowCount); - row.getCell((short) cellNum).setCellStyle(styleDefault); - if (firstPass) - cellWidth.add(cellNum, new Integer((rowCount+"").length())); - else - cellWidth.set(cellNum, new Integer((rowCount+"").length())); - - //} // for - }*/ - firstPass = false; - //cellNum = -1; - for (dr.resetNext(); dr.hasNext();j++) { - //for (chr.resetNext(); chr.hasNext();) { - //ColumnHeader ch = chr.getNext(); - styleCell = null; - DataValue dv = dr.getNext(); - HtmlFormatter htmlFormat = dv.getCellFormatter(); - if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) - styleCell = (HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default")); - if (htmlFormat != null && dv.getFormatId() != null && styles != null) - styleCell = (HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default")); - String value = nvl((String)colHash.get(dv.getColId().toUpperCase())); - - boolean bold = false; - - if(dv.isVisible()) { - cellNum += 1; - cell = row.createCell((short) cellNum); - //System.out.println("Stripping HTML 1"); - //cell.setCellValue(strip.stripHtml(dv.getDisplayValue())); - String dataType = (String) (dataTypeMap.get(dv.getColId())); - //System.out.println("Value " + value + " " + (( dataType !=null && dataType.equals("DATE")) || (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date"))) ); - if (dataType!=null && dataType.equals("NUMBER")){ - //cellNumber = row.createCell((short) cellNum); - //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - //cellNumber.setCellValue(dv.getDisplayValue()); - //cellCurrencyNumber = row.createCell((short) cellNum); - int zInt = 0; - if (value.equals("null")){ - cell.setCellValue(zInt); - }else{ - - if ((value.indexOf("."))!= -1){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - - //if (dv.getDisplayValue().startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempDollar = dv.getDisplayValue().trim(); - tempDollar = tempDollar.replaceAll(" ", "").substring(0); - tempDollar = tempDollar.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempDollar); - //System.out.println("Before copy Value |" + tempDollar); - //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); - //System.out.println("After copy Value |" + tempDollar); - if ((tempDollar.indexOf(","))!= -1){ - tempDollar = tempDollar.replaceAll(",", ""); - } - //System.out.println("The final string 1 is "+tempDollar); - double tempDoubleDollar = 0.0; - try { - tempDoubleDollar = Double.parseDouble(tempDollar); - if(styleCell!=null) { - styleCell.setDataFormat((short) 8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleCurrencyDecimalNumber); - cell.setCellValue(tempDoubleDollar); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - //cell.setCellStyle(styleDefault); - cell.setCellValue(tempDollar); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - double tempDouble = 0.0; - try { - tempDouble = Double.parseDouble(value); - if(styleCell!=null) { - styleCell.setDataFormat((short)0x28);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDecimalNumber); - cell.setCellValue(tempDouble); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(value); - } - - } - }else { - if (!(value.equals(""))){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //if (dv.getDisplayValue().startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempInt = value.trim(); - tempInt = tempInt.replaceAll(" ", "").substring(0); - tempInt = tempInt.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempInt); - //System.out.println("Before copy Value |" + tempInt); - //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); - //System.out.println("After copy Value |" + tempInt); - if ((tempInt.indexOf(","))!= -1){ - tempInt = tempInt.replaceAll(",", ""); - } - //System.out.println("The final string INT is "+tempInt); - Long tempIntDollar = 0L; - try { - tempIntDollar = Long.parseLong(tempInt); - if(styleCell!=null) { - styleCell.setDataFormat((short) 6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleCurrencyNumber); - cell.setCellValue(tempIntDollar); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempInt); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempStr = value.trim(); - if ((tempStr.indexOf(","))!= -1){ - tempStr = tempStr.replaceAll(",", ""); - } - Long temp = 0L; - - try { - temp = Long.parseLong(tempStr); - if(styleCell!=null) { - styleCell.setDataFormat((short) 0x26);//HSSFDataFormat.getBuiltinFormat("(#,##0_);[Red](#,##0)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleNumber); - cell.setCellValue(temp); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempStr); - } - - - } - //int temp = Integer.parseInt(value.trim()); - // cell.setCellValue(temp); - //}else{ - // cell.setCellValue(strip.stripHtml(value)); - //} - } - } - } - - }else if ( ( dataType !=null && dataType.equals("DATE")) || (dv.getDisplayName()!=null && dv.getDisplayName().toLowerCase().endsWith("date")) || - (dv.getColId()!=null && dv.getColId().toLowerCase().endsWith("date")) || - (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date")) ) { - //cellDate = row.createCell((short) cellNum); - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("mm/dd/yy")); - - if(styleCell!=null) { - styleCell.setDataFormat((short) 0xe);//HSSFDataFormat.getBuiltinFormat("m/d/yy")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDate); - //String MY_DATE_FORMAT = "yyyy-MM-dd"; - //value = nvl(value).length()<=0?nvl(dv.getDisplayValue()):value; - Date date = null; - int flag = 0; - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm")); - flag = 1; - } - if(date==null) - date = MMDDYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy")); - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy h:mm:ss")); - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); - flag = 1; - } - if(date==null) - date = MMDDYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy")); - flag = 1; - } - if(date==null) - date = YYYYMMDDFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy/m/d")); - flag = 1; - } - if(date==null) - date = timestampFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy-m-d h:mm:ss")); //yyyy-MM-dd HH:mm:ss - flag = 1; - } - if(date==null) - date = MONYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("mmm yyyy")); - flag = 1; - } - if(date==null) - date = MMYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/yyyy")); - flag = 1; - } - if(date==null) - date = MMMMMDDYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("mmm/d/yyyy")); - flag = 1; - } - if(date==null) - date = MONTHYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("mmm/yyyy")); - flag = 1; - } - if(date==null) - date = YYYYMMDDHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy/m/d h:mm:ss")); - flag = 1; - } - if(date==null) - date = YYYYMMDDDASHFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy-m-d")); - flag = 1; - } - if(date==null) - date = YYYYMMDDHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy/m/d h:mm")); - flag = 1; - } - if(date==null) - date = DDMONYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("d-mmm-yyyy h:mm:ss")); - flag = 1; - } - if(date==null) - date = DDMONYYYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("d-mmm-yyyy h:mm")); - flag = 1; - } - if(date==null) - date = DDMONYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("d-mmm-yy h:mm")); - flag = 1; - } - if(date==null) - date = DDMONYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("d-mmm-yyyy")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm")); - flag = 1; - } - if(date==null) - date = MMDDYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMZFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); - flag = 1; - } - if(date==null) - date = MMMMMDDYYYYHHMMSS.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); - flag = 1; - } - - if(date!=null) { - //System.out.println("ExcelDate " + HSSFDateUtil.getExcelDate(date)); - cell.setCellValue(HSSFDateUtil.getExcelDate(date)); - try { - String str = cell.getStringCellValue(); - } catch (IllegalStateException ex) { /*cell.getCellStyle().setDataFormat((short)0);*/cell.setCellValue(value);} - } else { - /*cell.getCellStyle().setDataFormat((short)0);*/ - cell.setCellValue(value); - } - //cellDate.setCellValue(date); - //cellDate.setCellValue(value); //cellDate.setCellValue(date); - //cellDate.setCellValue(dv.getDisplayValue()); - - }else if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - //cellNumber = row.createCell((short) cellNum); - //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - //cellNumber.setCellValue(dv.getDisplayValue()); - cell = row.createCell((short) cellNum); - int zInt = 0; - if (value.equals("null")){ - cell.setCellValue(zInt); - }else{ - - if ((value.indexOf("."))!= -1){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempDollar = value.trim(); - tempDollar = tempDollar.replaceAll(" ", "").substring(0); - tempDollar = tempDollar.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempDollar); - //System.out.println("Before copy Value |" + tempDollar); - //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); - //System.out.println("After copy Value |" + tempDollar); - if ((tempDollar.indexOf(","))!= -1){ - tempDollar = tempDollar.replaceAll(",", ""); - } - //System.out.println("The final string 2IF is "+tempDollar); - double tempDoubleDollar = 0.0; - try { - tempDoubleDollar = Double.parseDouble(tempDollar); - if(styleCell!=null) { - styleCell.setDataFormat((short) 8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleCurrencyDecimalNumber); - cell.setCellValue(tempDoubleDollar); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempDollar); - } - - - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempDoubleStr = value.trim(); - tempDoubleStr = tempDoubleStr.replaceAll(" ", "").substring(0); - if ((tempDoubleStr.indexOf(","))!= -1){ - tempDoubleStr = tempDoubleStr.replaceAll(",", ""); - } - double tempDouble = 0.0; - try { - tempDouble = Double.parseDouble(tempDoubleStr); - if(styleCell!=null) { - styleCell.setDataFormat((short)0x28 );//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDecimalNumber); - cell.setCellValue(tempDouble); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempDoubleStr); - } - } - - }else { - if (!(value.equals(""))){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempInt = value.trim(); - tempInt = tempInt.replaceAll(" ", "").substring(0); - tempInt = tempInt.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempInt); - //System.out.println("Before copy Value |" + tempInt); - //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); - //System.out.println("After copy Value |" + tempInt); - if ((tempInt.indexOf(","))!= -1){ - tempInt = tempInt.replaceAll(",", ""); - } - //System.out.println("The final string INT 2 is "+tempInt); - - Long tempIntDollar = 0L; - - try { - tempIntDollar = Long.parseLong(tempInt); - if(styleCell!=null) { - styleCell.setDataFormat((short) 6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleCurrencyNumber); - cell.setCellValue(tempIntDollar); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempInt); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempStr = value.trim(); - if ((tempStr.indexOf(","))!= -1){ - tempStr = tempStr.replaceAll(",", ""); - } - Long temp = 0L; - - try { - temp = Long.parseLong(tempStr); - if(styleCell!=null) { - styleCell.setDataFormat((short) 0x26);//HSSFDataFormat.getBuiltinFormat("(#,##0_);[Red](#,##0)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleNumber); - cell.setCellValue(temp); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempStr); - } - } - //int temp = Integer.parseInt(dv.getDisplayValue().trim()); - // cell.setCellValue(temp); - //}else{ - // cell.setCellValue(strip.stripHtml(dv.getDisplayValue())); - //} - } else { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - } - } - } - - - } - else { - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("General")); - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(strip.stripHtml(value)); - } - - //if (!(value.equals(""))){ - //int temp = Integer.parseInt(value.trim()); - //cell.setCellValue(temp); - //}else{ - // cell.setCellValue(strip.stripHtml(value)); - //} - //HSSFCellStyle styleFormat = null; - //HSSFCellStyle numberStyle = null; - //HSSFFont formatFont = null; - //short fgcolor = 0; - //short fillpattern = 0; - if (cellWidth.size() > cellNum) { - if (((Integer) cellWidth.get(cellNum)).intValue() < dv - .getDisplayValue().length()) - cellWidth.set((cellNum), - (value.length()<=Globals.getMaxCellWidthInExcel())?new Integer(value.length()):new Integer(Globals.getMaxCellWidthInExcel())); - } else - cellWidth.add((cellNum), (value.length()<=Globals.getMaxCellWidthInExcel())?new Integer(value.length()):new Integer(Globals.getMaxCellWidthInExcel())); - //System.out.println("1IF "+ (dv.isBold()) + " "+ value + " " + dv.getDisplayTotal() + " " + dv.getColName() ); - if (dv.isBold()) { - if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - cell.setCellStyle(styleCurrencyTotal); - } - else { - cell.setCellStyle(styleTotal); - } - } else { - cell.setCellStyle(styleDefaultTotal); - } - bold = true; - } - //System.out.println("2IF "+ (dr.isRowFormat()) + " " + (dv.isCellFormat()) + " " + (styles!=null)); - if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) { - //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); - continue; - } - //System.out.println("3IF "+ (htmlFormat != null) + " " + (dv.getFormatId() != null) + " " + (bold == false) + " "+ (styles != null)); - if (htmlFormat != null && dv.getFormatId() != null && bold == false - && styles != null) { - //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default"))); - } //else if (bold == false) - //cell.setCellStyle(styleDefault); - } // dv.isVisible - } - rowNum += 1; - - } - - int cw = 0; - for (int i = 0; i < cellWidth.size(); i++) { - cw = ((Integer) cellWidth.get(i)).intValue() + 12; - // if(i!=cellWidth.size()-1) - sheet.setColumnWidth((short) (i), (short) ((cw * 8) / ((double) 1 / 20))); - // else - // sheet.setColumnWidth((short) (i + 1), (short) ((cw * 10) / - // ((double) 1 / 20))); - } - - // To Display Total Values for Linear report - if(rd.reportDataTotalRow!=null) { - row = sheet.createRow(rowNum); - cellNum = -1; - rd.reportTotalRowHeaderCols.resetNext(); - //for (rd.reportTotalRowHeaderCols.resetNext(); rd.reportTotalRowHeaderCols.hasNext();) { - cellNum += 1; - RowHeaderCol rhc = rd.reportTotalRowHeaderCols.getNext(); - RowHeader rh = rhc.getRowHeader(0); - row.createCell((short) cellNum).setCellValue(strip.stripHtml(rh.getRowTitle())); - row.getCell((short) cellNum).setCellStyle(styleDefaultTotal); - //} - - rd.reportDataTotalRow.resetNext(); - DataRow drTotal = rd.reportDataTotalRow.getNext(); - //cellNum = -1; - - drTotal.resetNext(); - drTotal.getNext(); - for (; drTotal.hasNext();) { - cellNum += 1; - cell = row.createCell((short) cellNum); - DataValue dv = drTotal.getNext(); - String value = dv.getDisplayValue(); - cell.setCellValue(value); - boolean bold = false; - if (dv.isBold()) { - if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - cell.setCellStyle(styleCurrencyTotal); - } else { - cell.setCellStyle(styleTotal); - } - } else { - cell.setCellStyle(styleDefaultTotal); - } - bold = true; - } - } - } - - } catch (SQLException ex) { - ex.printStackTrace(); - throw new RaptorException(ex); - } catch (ReportSQLException ex) { - throw new RaptorException(ex); - } catch (Exception ex) { - if(!(ex.getCause() instanceof java.net.SocketException) ) - throw new RaptorException (ex); - } finally { - try { - if(conn!=null) - conn.close(); - if(st!=null) - st.close(); - if(rs!=null) - rs.close(); - } catch (SQLException ex) { - throw new RaptorException(ex); - } - } - - /*if(Globals.getShowDisclaimer() && !Globals.disclaimerPositionedTopInCSVExcel()) { - rowNum += 1; - row = sheet.createRow(rowNum); - cellNum = 0; - String disclaimer = Globals.getFooterFirstLine() + " " + Globals.getFooterSecondLine(); - row.createCell((short) cellNum).setCellValue(disclaimer); - sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); - rowNum += 1; - }*/ - } else { - if(rr.getReportType().equals(AppConstants.RT_LINEAR)) { - int rowCount = 0; - for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { - DataRow dr = rd.reportDataRows.getNext(); - //List l = rd.getReportDataList(); - //for (int dataRow = 0; dataRow < l.size(); dataRow++) { - rowCount++; - - - //DataRow dr = (DataRow) l.get(dataRow); - row = sheet.createRow(rowNum); - - cellNum = -1; - - if (rr.getReportType().equals(AppConstants.RT_LINEAR) && rd.reportTotalRowHeaderCols!=null) { - rd.reportRowHeaderCols.resetNext(0); - if(rd.reportTotalRowHeaderCols!=null) { - //cellNum = -1; - //for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { - //cellNum += 1; - //RowHeaderCol rhc = rd.reportRowHeaderCols.getRowHeaderCol(0); - //if (firstPass) - // rhc.resetNext(); - //RowHeader rh = rhc.getRowHeader(rowCount-1); - //row.createCell((short) cellNum).setCellValue(rowCount); - //row.getCell((short) cellNum).setCellStyle(styleDefault); - //if (firstPass) - //cellWidth.add(cellNum, new Integer((rowCount+"").length())); - //else - //cellWidth.set(cellNum, new Integer((rowCount+"").length())); - - //} // for - } - - } else { - rd.reportRowHeaderCols.resetNext(0); - } - for (; rd.reportRowHeaderCols.hasNext();) { - cellNum += 1; - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - if (firstPass) - rhc.resetNext(); - RowHeader rh = rhc.getNext(); - row.createCell((short) cellNum).setCellValue(strip.stripHtml(rh.getRowTitle())); - row.getCell((short) cellNum).setCellStyle(styleDefault); - if (cellWidth.size() > 0) { - if (((Integer) cellWidth.get(cellNum)).intValue() < rh.getRowTitle() - .length()) - cellWidth.set(cellNum, new Integer(rh.getRowTitle().length())); - } else - cellWidth.add(cellNum, new Integer(rh.getRowTitle().length())); - - } // for - firstPass = false; - //cellNum = -1; - int j = 0; - - for (dr.resetNext(); dr.hasNext();j++) { - DataValue dv = dr.getNext(); - styleCell = null; - boolean bold = false; - String value = nvl(dv.getDisplayValue()); - value = strip.stripHtml(value); - HtmlFormatter htmlFormat = dv.getCellFormatter(); - if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) - styleCell = (HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default")); - if (htmlFormat != null && dv.getFormatId() != null && styles != null) - styleCell = (HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default")); - - if(dv.isVisible()) { - cellNum += 1; - cell = row.createCell((short) cellNum); - //System.out.println("Stripping HTML 1"); - //cell.setCellValue(strip.stripHtml(value)); - String dataType = (String) (dataTypeMap.get(dv.getColId())); - //System.out.println(" The Display Value is ********"+value + " " + dv.getDisplayTotal() + " " + dv.getColName()); - - if (dataType!=null && dataType.equals("NUMBER")){ - //cellNumber = row.createCell((short) cellNum); - //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - //cellNumber.setCellValue(value); - //cellCurrencyNumber = row.createCell((short) cellNum); - int zInt = 0; - if (value.equals("null")){ - cell.setCellValue(zInt); - }else{ - - if ((value.indexOf("."))!= -1){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempDollar = value.trim(); - tempDollar = tempDollar.replaceAll(" ", "").substring(0); - tempDollar = tempDollar.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempDollar); - //System.out.println("Before copy Value |" + tempDollar); - //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); - //System.out.println("After copy Value |" + tempDollar); - if ((tempDollar.indexOf(","))!= -1){ - tempDollar = tempDollar.replaceAll(",", ""); - } - //System.out.println("The final string 1 is "+tempDollar); - double tempDoubleDollar = 0.0; - try { - tempDoubleDollar = Double.parseDouble(tempDollar); - if(styleCell!=null) { - styleCell.setDataFormat((short) 8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleCurrencyDecimalNumber); - cell.setCellValue(tempDoubleDollar); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempDollar); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - double tempDouble = 0.0; - try { - tempDouble = Double.parseDouble(value); - if(styleCell!=null) { - styleCell.setDataFormat((short) 0x28);//HSSFDataFormat.getBuiltinFormat("(#,##0.00_);[Red](#,##0.00)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDecimalNumber); - cell.setCellValue(tempDouble); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(value); - } - - } - }else { - if (!(value.equals(""))){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempInt = value.trim(); - tempInt = tempInt.replaceAll(" ", "").substring(0); - tempInt = tempInt.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempInt); - //System.out.println("Before copy Value |" + tempInt); - //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); - //System.out.println("After copy Value |" + tempInt); - if ((tempInt.indexOf(","))!= -1){ - tempInt = tempInt.replaceAll(",", ""); - } - //System.out.println("The final string INT is "+tempInt); - Long tempIntDollar = 0L; - try { - tempIntDollar = Long.parseLong(tempInt); - if(styleCell!=null) { - styleCell.setDataFormat((short)6);//HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleCurrencyNumber); - cell.setCellValue(tempIntDollar); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempInt); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempStr = value.trim(); - if ((tempStr.indexOf(","))!= -1){ - tempStr = tempStr.replaceAll(",", ""); - } - Long temp = 0L; - - try { - temp = Long.parseLong(tempStr); - if(styleCell!=null) { - styleCell.setDataFormat((short)0x26);//HSSFDataFormat.getBuiltinFormat("(#,##0_);[Red](#,##0)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleNumber); - cell.setCellValue(temp); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempStr); - } - - - } - //int temp = Integer.parseInt(value.trim()); - // cell.setCellValue(temp); - //}else{ - // cell.setCellValue(strip.stripHtml(value)); - //} - } - } - } - - }else if ( ( dataType !=null && dataType.equals("DATE")) || (dv.getDisplayName()!=null && dv.getDisplayName().toLowerCase().endsWith("date")) || - (dv.getColId()!=null && dv.getColId().toLowerCase().endsWith("date")) || - (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date")) ) { - //cellDate = row.createCell((short) cellNum); - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("mm/dd/yy")); - - if(styleCell!=null) { - styleCell.setDataFormat((short)0xe); //HSSFDataFormat.getBuiltinFormat("m/d/yy")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDate); - //String MY_DATE_FORMAT = "yyyy-MM-dd"; - Date date = null; - int flag = 0; - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm")); - flag = 1; - } - if(date==null) - date = MMDDYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy")); - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy h:mm:ss")); - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); - flag = 1; - } - if(date==null) - date = MMDDYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy")); - flag = 1; - } - if(date==null) - date = YYYYMMDDFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy/m/d")); - flag = 1; - } - if(date==null) - date = timestampFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy-m-d h:mm:ss")); //yyyy-MM-dd HH:mm:ss - flag = 1; - } - if(date==null) - date = MONYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("mmm yyyy")); - flag = 1; - } - if(date==null) - date = MMYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/yyyy")); - flag = 1; - } - if(date==null) - date = MMMMMDDYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("mmm/d/yyyy")); - flag = 1; - } - if(date==null) - date = MONTHYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("mmm/yyyy")); - flag = 1; - } - if(date==null) - date = YYYYMMDDHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy/m/d h:mm:ss")); - flag = 1; - } - if(date==null) - date = YYYYMMDDDASHFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy-m-d")); - flag = 1; - } - if(date==null) - date = YYYYMMDDHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("yyyy/m/d h:mm")); - flag = 1; - } - if(date==null) - date = DDMONYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("d-mmm-yyyy h:mm:ss")); - flag = 1; - } - if(date==null) - date = DDMONYYYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("d-mmm-yyyy h:mm")); - flag = 1; - } - if(date==null) - date = DDMONYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("d-mmm-yy h:mm")); - flag = 1; - } - if(date==null) - date = DDMONYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("d-mmm-yyyy")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm")); - flag = 1; - } - if(date==null) - date = MMDDYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yy h:mm:ss")); - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMZFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); - flag = 1; - } - if(date==null) - date = MMMMMDDYYYYHHMMSS.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cell.getCellStyle().setDataFormat( - createHelper.createDataFormat().getFormat("m/d/yyyy h:mm")); - flag = 1; - } - - if(date!=null) { - //System.out.println("ExcelDate " + HSSFDateUtil.getExcelDate(date)); - cell.setCellValue(HSSFDateUtil.getExcelDate(date)); - try { - String str = cell.getStringCellValue(); - } catch (IllegalStateException ex) { /*cell.getCellStyle().setDataFormat((short)0);*/cell.setCellValue(value);} - } else { - /*cell.getCellStyle().setDataFormat((short)0);*/ - cell.setCellValue(value); - } - //cellDate.setCellValue(date); - //cellDate.setCellValue(value); - - }else if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - //cellNumber = row.createCell((short) cellNum); - //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - //cellNumber.setCellValue(value); - cell = row.createCell((short) cellNum); - int zInt = 0; - if (value.equals("null")){ - cell.setCellValue(zInt); - }else{ - - if ((value.indexOf("."))!= -1){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempDollar = value.trim(); - tempDollar = tempDollar.replaceAll(" ", "").substring(0); - tempDollar = tempDollar.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempDollar); - //System.out.println("Before copy Value |" + tempDollar); - //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); - //System.out.println("After copy Value |" + tempDollar); - if ((tempDollar.indexOf(","))!= -1){ - tempDollar = tempDollar.replaceAll(",", ""); - } - //System.out.println("The final string 2IF is "+tempDollar); - double tempDoubleDollar = 0.0; - try { - tempDoubleDollar = Double.parseDouble(tempDollar); - if(styleCell!=null) { - styleCell.setDataFormat((short)8);//HSSFDataFormat.getBuiltinFormat("($#,##0.00_);[Red]($#,##0.00)")); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleCurrencyDecimalNumber); - cell.setCellValue(tempDoubleDollar); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempDollar); - } - - - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempDoubleStr = value.trim(); - tempDoubleStr = tempDoubleStr.replaceAll(" ", "").substring(0); - if ((tempDoubleStr.indexOf(","))!= -1){ - tempDoubleStr = tempDoubleStr.replaceAll(",", ""); - } - double tempDouble = 0.0; - try { - tempDouble = Double.parseDouble(tempDoubleStr); - if(styleCell!=null) { - styleCell.setDataFormat((short) 0x28); // for decimal - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDecimalNumber); - cell.setCellValue(tempDouble); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempDoubleStr); - } - } - - }else { - if (!(value.equals(""))){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempInt = value.trim(); - tempInt = tempInt.replaceAll(" ", "").substring(0); - tempInt = tempInt.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempInt); - //System.out.println("Before copy Value |" + tempInt); - //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); - //System.out.println("After copy Value |" + tempInt); - if ((tempInt.indexOf(","))!= -1){ - tempInt = tempInt.replaceAll(",", ""); - } - //System.out.println("The final string INT 2 is "+tempInt); - - Long tempIntDollar = 0L; - - try { - tempIntDollar = Long.parseLong(tempInt); - if(styleCell!=null) { - styleCell.setDataFormat((short) 6); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleCurrencyNumber); - cell.setCellValue(tempIntDollar); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempInt); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempStr = value.trim(); - if ((tempStr.indexOf(","))!= -1){ - tempStr = tempStr.replaceAll(",", ""); - } - Long temp = 0L; - - try { - temp = Long.parseLong(tempStr); - if(styleCell!=null) { - styleCell.setDataFormat((short) 0x26); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleNumber); - cell.setCellValue(temp); - } catch (NumberFormatException ne) { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(tempStr); - } - } - //int temp = Integer.parseInt(value.trim()); - // cell.setCellValue(temp); - //}else{ - // cell.setCellValue(strip.stripHtml(value)); - //} - } else { - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - } - } - } - - - } - else { - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("General")); - if(styleCell!=null) { - styleCell.setWrapText(true); - cell.setCellStyle(styleCell); - } else - cell.setCellStyle(styleDefault); - cell.setCellValue(strip.stripHtml(value)); - } - - //if (!(value.equals(""))){ - //int temp = Integer.parseInt(value.trim()); - //cell.setCellValue(temp); - //}else{ - // cell.setCellValue(strip.stripHtml(value)); - //} - //HSSFCellStyle styleFormat = null; - //HSSFCellStyle numberStyle = null; - //HSSFFont formatFont = null; - //short fgcolor = 0; - //short fillpattern = 0; - if (cellWidth.size() > cellNum) { - if (((Integer) cellWidth.get(cellNum)).intValue() < dv - .getDisplayValue().length()) - cellWidth.set((cellNum), - (value.length()<=Globals.getMaxCellWidthInExcel())?new Integer(value.length()):new Integer(Globals.getMaxCellWidthInExcel())); - } else - cellWidth.add((cellNum), (value.length()<=Globals.getMaxCellWidthInExcel())?new Integer(value.length()):new Integer(Globals.getMaxCellWidthInExcel())); - //System.out.println("1IF "+ (dv.isBold()) + " "+ value + " " + dv.getDisplayTotal() + " " + dv.getColName() ); - if (dv.isBold()) { - if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - cell.setCellStyle(styleCurrencyTotal); - } - else { - cell.setCellStyle(styleTotal); - } - } else { - cell.setCellStyle(styleDefaultTotal); - } - bold = true; - } - //System.out.println("2IF "+ (dr.isRowFormat()) + " " + (dv.isCellFormat()) + " " + (styles!=null)); - if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) { - //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); - continue; - } - //System.out.println("3IF "+ (htmlFormat != null) + " " + (dv.getFormatId() != null) + " " + (bold == false) + " "+ (styles != null)); - if (htmlFormat != null && dv.getFormatId() != null && bold == false - && styles != null) { - // cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default"))); - } //else if (bold == false) - //cell.setCellStyle(styleDefault); - } // if (dv.isVisible) - } // for - - /*for (int tmp=0; tmp rowNames = dr.getRowValues(); - for(dr.resetNext(); dr.hasNext(); rowCount++ ) { - if(first) { - if(rowNames!=null) { - for(int i=0; i0) { - cellNum += 1; - row.createCell((short) cellNum).setCellValue(strip.stripHtml(dv.getDisplayValue())); - //row.getCell((short) cellNum).setCellStyle(styleDefault); - if(nvl(dv.getFormatId()).length()>0) - row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get(nvl(dv.getFormatId(),"default"))); - else - row.setRowStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); - } else { - cellNum += 1; - row.createCell((short) cellNum).setCellValue(strip.stripHtml(value)); - row.getCell((short) cellNum).setCellStyle(styleDefault); - } // end - value = dv.getDisplayValue(); - if(value.indexOf("|#")!=-1) { - String color = value.substring(value.indexOf("|")+1); - if(color.equals("#FF0000")) - row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get("red")); - else if (color.equals("#008000")) - row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get("green")); - else if (color.equals("#FFFF00")) - row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get("yellow")); - else { - row.getCell((short) cellNum).setCellStyle((HSSFCellStyle) styles.get("default")); - } - - } - } - } - rowNum += 1; - int cw = 0; - for (int i = 0; i < cellWidth.size(); i++) { - cw = ((Integer) cellWidth.get(i)).intValue() + 12; - // if(i!=cellWidth.size()-1) - sheet.setColumnWidth((short) (i), (short) ((cw * 8) / ((double) 1 / 20))); - // else - // sheet.setColumnWidth((short) (i + 1), (short) ((cw * 10) / - // ((double) 1 / 20))); - } - - - } // for - - } - - - } - - String footer = (String) session.getAttribute("FOOTER_"+index); - if(nvl(footer).length()>0) { - footer = Utils.replaceInString(footer, "
        ", " "); - footer = Utils.replaceInString(footer, "
        ", " "); - footer = Utils.replaceInString(footer, "
        ", " "); - footer = strip.stripHtml(nvl(footer).trim()); - row = sheet.createRow(rowNum); - cellNum = 0; - row.createCell((short) cellNum).setCellValue(footer); - sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); - //sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum+columnRows, (short) (cellNum))); - rowNum += 1; - } - - if(Globals.getShowDisclaimer() && !Globals.disclaimerPositionedTopInCSVExcel()) { - - rowNum += 1; - row = sheet.createRow(rowNum); - cellNum = 0; - String disclaimer = Globals.getFooterFirstLine() + " " + Globals.getFooterSecondLine(); - row.createCell((short) cellNum).setCellValue(disclaimer); - sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); - rowNum += 1; - } - - logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); - logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" - + (runtime.maxMemory() - runtime.freeMemory()) / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" - + runtime.freeMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); - return returnValue; - - } - - private void paintExcelHeader(HSSFWorkbook wb, int rowNum, int col, String reportTitle, - String reportDescr, HSSFSheet sheet) { - short s1 = 0, s2 = (short) (col-1); - rowNum += 1; - sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); - HSSFRow row = null, row1 = null; - - row = sheet.createRow(rowNum); - // Header Style - HSSFCellStyle styleHeader = wb.createCellStyle(); - styleHeader.setAlignment(HSSFCellStyle.ALIGN_CENTER); - HSSFFont font = wb.createFont(); - font.setFontHeight((short) (font_header_title_size / 0.05)); //14 - font.setFontName("Tahoma"); - font.setColor(HSSFColor.BLACK.index); - styleHeader.setFont(font); - - HSSFCell cell = row.createCell((short) 0); - cell.setCellValue(reportTitle); - cell.setCellStyle(styleHeader); - HSSFHeader header = sheet.getHeader(); - header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) 9)+" " + reportTitle); - - //header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) 9)+reportTitle+"\n"+((Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0)?reportDescr:"")); - - // Report Description - if (Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0) { - rowNum += 1; - sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); - HSSFCellStyle styleDescription = wb.createCellStyle(); - styleDescription.setAlignment(HSSFCellStyle.ALIGN_CENTER); - HSSFFont fontDescr = wb.createFont(); - fontDescr.setFontHeight((short) font_header_descr_size); - fontDescr.setFontName("Tahoma"); - fontDescr.setColor(HSSFColor.BLACK.index); - styleDescription.setFont(fontDescr); - HSSFCell cellDescr = row.createCell((short) 0); - cellDescr.setCellValue(reportDescr); - cellDescr.setCellStyle(styleHeader); - } - - if(Globals.disclaimerPositionedTopInCSVExcel()) { - rowNum += 1; - row = sheet.createRow(rowNum); - sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); - HSSFCellStyle styleDescription = wb.createCellStyle(); - styleDescription.setAlignment(HSSFCellStyle.ALIGN_CENTER); - HSSFFont fontDescr = wb.createFont(); - fontDescr.setFontHeight((short) (font_size / 0.05)); //14 - fontDescr.setFontName("Tahoma"); - fontDescr.setColor(HSSFColor.BLACK.index); - fontDescr.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - styleDescription.setFont(fontDescr); - HSSFCell cellDescr = row.createCell((short) 0); - String disclaimer = Globals.getFooterFirstLine() + " " + Globals.getFooterSecondLine(); - cellDescr.setCellValue(disclaimer); - cellDescr.setCellStyle(styleDescription); - } - - rowNum += 1; - row = sheet.createRow(rowNum); - // System.out.println(" Last Row " + wb.getSheetAt(0).getLastRowNum()); - } - - private void paintExcelFooter(HSSFWorkbook wb, int rowNum, int col, HSSFSheet sheet) { - logger.debug(EELFLoggerDelegate.debugLogger, ("excel footer")); - //HSSFSheet sheet = wb.getSheet(getSheetName()); - HSSFFooter footer = sheet.getFooter(); - footer.setLeft(HSSFFooter.font("Tahoma", "")+ HSSFFooter.fontSize((short) font_footer_size)+ "Page " + HSSFFooter.page() - + " of " + HSSFFooter.numPages() ); - footer.setCenter(HSSFFooter.font("Tahoma", "")+ HSSFFooter.fontSize((short) font_footer_size)+Globals.getFooterFirstLine()+"\n"+Globals.getFooterSecondLine()); - //footer.setCenter(HSSFFooter.font("Tahoma", "Italic")+ HSSFFooter.fontSize((short) 16))+Globals.getFooterSecondLine()); -/* footer.font("Tahoma"); - short s1 = 0, s2 = (short) (col-1); - rowNum += 1; - sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); - HSSFRow row = null, row1 = null; - - row = sheet.createRow(rowNum); - // Header Style - HSSFCellStyle styleFooter = wb.createCellStyle(); - styleFooter.setAlignment(HSSFCellStyle.ALIGN_CENTER); - HSSFFont font = wb.createFont(); - font.setFontHeight((short) (10 / 0.05)); - font.setFontName("Tahoma"); - font.setColor(HSSFColor.BLACK.index); - font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - styleFooter.setFont(font); - - HSSFCell cell = row.createCell((short) 0); - debugLogger.debug(Globals.getFooterFirstLine()); - cell.setCellValue(Globals.getFooterFirstLine()); - cell.setCellStyle(styleFooter); - - rowNum += 1; - sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); - row = sheet.createRow(rowNum); - cell = row.createCell((short) 0); - debugLogger.debug(Globals.getFooterSecondLine()); - cell.setCellValue(Globals.getFooterSecondLine()); - cell.setCellStyle(styleFooter); -*/ - logger.debug(EELFLoggerDelegate.debugLogger, ("Done")); - } - - public String saveAsExcelFile(HttpServletRequest request, ReportData rd, - ArrayList reportParamNameValues, String reportTitle, String reportDescr) { - return saveAsExcelFile(request, rd, reportParamNameValues, reportTitle, reportDescr, 2); //2 denotes ReportRuntime object should be taken from session. - } - public String saveAsExcelFile(HttpServletRequest request, ReportData rd, - ArrayList reportParamNameValues, String reportTitle, String reportDescr, int requestFlag) { - setSheetName(Globals.getSheetName()); - try { - ReportRuntime rr; - if(requestFlag == 2) - rr = (ReportRuntime) request.getSession().getAttribute( - AppConstants.SI_REPORT_RUNTIME); - else - rr = (ReportRuntime) request.getAttribute( - AppConstants.SI_REPORT_RUNTIME); - HSSFWorkbook wb = new HSSFWorkbook(); - HashMap styles = new HashMap(); - if (rr != null) - styles = loadStyles(rr, wb); - String xlsFName = AppUtils.generateUniqueFileName(request, rr.getReportName(), AppConstants.FT_XLS); - logger.debug(EELFLoggerDelegate.debugLogger, ("Xls File name " + - AppUtils.getTempFolderPath() - + xlsFName)); - FileOutputStream xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() - + xlsFName); - // BufferedWriter xlsOut = new BufferedWriter(new - // FileWriter(AppUtils - // .getTempFolderPath() - // + xlsFName)); - - int col = 0; - //System.out.println("Row Header Count " + rd.reportRowHeaderCols.getRowCount()); - //System.out.println("Total Count " + rd.getTotalColumnCount()); - - if (!rd.reportRowHeaderCols.hasNext()) - col = rd.getTotalColumnCount(); - else - col = rd.getTotalColumnCount(); - int rowNum = 0; - HSSFSheet sheet = wb.createSheet(getSheetName()); - - if (Globals.getPrintTitleInDownload()&& reportTitle != null ) { - paintExcelHeader(wb, rowNum, col, reportTitle, reportDescr, sheet); - rowNum = sheet.getLastRowNum(); - } else - rowNum = 0; - if (Globals.getPrintParamsInDownload() && rr.getParamNameValuePairsforPDFExcel(request, 1) != null) { - paintExcelParams(wb,rowNum,col,rr.getParamNameValuePairsforPDFExcel(request, 1), rr.getFormFieldComments(request), sheet, reportTitle, reportDescr); - } // if - rowNum = sheet.getLastRowNum(); - //System.out.println(" rowNum after Params " + rowNum); - paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, "", xlsOut, request); - if (Globals.getPrintFooterInDownload() ) { - rowNum = sheet.getLastRowNum(); - rowNum += 2; - paintExcelFooter(wb, rowNum, col, sheet); - } - //response.setContentType("application/vnd.ms-excel"); - //response.setHeader("Content-disposition", "attachment;filename=download_all_" - // + user_id + ".xls"); - wb.write(xlsOut); - xlsOut.flush(); - xlsOut.close(); - return xlsFName; - } catch (Exception e) { - e.printStackTrace(); - (new ErrorHandler()).processError(request, "Exception saving data to EXCEL file: " - + e.getMessage()); - return null; - } - } // saveAsExcelFile - - public void createExcelFileContent(Writer out, ReportData rd, ReportRuntime rr, HttpServletRequest request, - HttpServletResponse response, String user_id, int type) throws IOException, RaptorException { - // Adding utility for downloading Dashboard reports. - - HashMap styles = new HashMap(); - HttpSession session = request.getSession(); - ServletOutputStream sos = null; - BufferedInputStream buf = null; - HSSFWorkbook wb = null; -// if(session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) -// ReportRuntime rrDashboard = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); - String formattedDate = ""; - String xlsFName = ""; - int returnValue = 0; - boolean isDashboard = false; - if ((session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) && ( ((String) session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)).equals(rr.getReportID())) ) { - isDashboard = true; - } - if(isDashboard) { - try { - formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); - xlsFName = "dashboard"+formattedDate+user_id+".xls"; - - FileInputStream xlsIn = null; - POIFSFileSystem fileSystem = null; - buf = null; - FileOutputStream xlsOut = null; - - -/* try { - xlsIn = new FileInputStream (AppUtils.getTempFolderPath() - + xlsFName); - } - catch (FileNotFoundException e) { - System.out.println ("File not found in the specified path."); - e.printStackTrace (); - } - if(xlsIn != null) { - fileSystem = new POIFSFileSystem (xlsIn); - wb = new HSSFWorkbook(fileSystem); - } else { - xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() - + xlsFName); - wb = new HSSFWorkbook(); - } -*/ - - Map reportRuntimeMap = null; - Map reportDataMap = null; - //Map reportDisplayTypeMap = null; - reportRuntimeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); - reportDataMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); - //reportDisplayTypeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI); - HSSFSheet sheet = null; - if(reportRuntimeMap!=null) { - //ServletOutputStream sos = response.getOutputStream(); - Set setReportRuntime = reportRuntimeMap.entrySet(); - Set setReportDataMap = reportDataMap.entrySet(); - Iterator iter2 = setReportDataMap.iterator(); - int count = 0; - - for(Iterator iter = setReportRuntime.iterator(); iter.hasNext(); ) { - count++; - try { - xlsIn = new FileInputStream (AppUtils.getTempFolderPath() - + xlsFName); - } - catch (FileNotFoundException e) { - System.out.println ("File not found in the specified path."); - //e.printStackTrace (); - } - if(xlsIn != null) { - fileSystem = new POIFSFileSystem (xlsIn); - wb = new HSSFWorkbook(fileSystem); - xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() - + xlsFName); - } else { - xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() - + xlsFName); - wb = new HSSFWorkbook(); - } - - Map.Entry entryData = (Entry) iter2.next(); - Map.Entry entry = (Entry) iter.next(); - //String rep_id = (String) entry.getKey(); - ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); - ReportData rdDashRep = (ReportData) entryData.getValue(); - //styles = loadStyles(rrDashRep, wb); - int col = 0; - String reportTitle = (nvl(rrDashRep.getReportTitle()).length()>0?rrDashRep.getReportTitle():rrDashRep.getReportName()); - String reportDescr = rrDashRep.getReportDescr(); - if (!rdDashRep.reportRowHeaderCols.hasNext()) - col = rdDashRep.getTotalColumnCount(); - else - col = rdDashRep.getTotalColumnCount(); - if(col==0) col=10; - int rowNum = 0; - String formattedReportName = new HtmlStripper().stripSpecialCharacters(rrDashRep.getReportName()); - - try { - sheet = wb.createSheet(formattedReportName); - sheet.getPrintSetup().setLandscape(true); - styles = loadStyles(rrDashRep, wb); - } catch (IllegalArgumentException ex) { wb.write(xlsOut);xlsOut.flush();xlsOut.close();continue;} - - if (Globals.getPrintTitleInDownload()&& reportTitle != null ) { - paintExcelHeader(wb, rowNum, col, reportTitle, reportDescr, sheet); - rowNum = sheet.getLastRowNum(); - } else - rowNum = 0; - //getting ReportRuntime object from session - if (Globals.getPrintParamsInDownload() && rrDashRep.getParamNameValuePairsforPDFExcel(request, 1) != null) { - if(count > 1 && Globals.showParamsInAllDashboardReports()) - paintExcelParams(wb,rowNum,col,rrDashRep.getParamNameValuePairsforPDFExcel(request, 1), rrDashRep.getFormFieldComments(request), sheet, reportTitle, reportDescr); - else if (count == 1) - paintExcelParams(wb,rowNum,col,rrDashRep.getParamNameValuePairsforPDFExcel(request, 1), rrDashRep.getFormFieldComments(request), sheet, reportTitle, reportDescr); - } // if - rowNum = sheet.getLastRowNum(); - String sql_whole = rrDashRep.getWholeSQL(); - returnValue = paintExcelData(wb, rowNum, col, rdDashRep, styles,rrDashRep, sheet, sql_whole, xlsOut, request); - if( returnValue == 0 ) { - if (Globals.getPrintFooterInDownload()) { - rowNum = sheet.getLastRowNum(); - rowNum += 2; - paintExcelFooter(wb, rowNum, col, sheet); - } - //wb.write(sos); - wb.write(xlsOut); - //TODO Remove comment - xlsOut.flush(); - xlsOut.close(); - wb = null; - } else { - //xlsOut.flush(); - //xlsOut.close(); - //response.reset(); - //response.setContentType("application/vnd.ms-excel"); -// RequestDispatcher dispatcher = request.getRequestDispatcher("raptor.htm?r_action=report.message"); -// request.setAttribute("message", Globals.getUserDefinedMessageForMemoryLimitReached()); -// try { -// dispatcher.forward(request, response); -// } catch (ServletException ex) {} - } - } - - response.reset(); - response.setContentType("application/vnd.ms-excel"); - response.setHeader("Content-disposition", "attachment;filename="+"dashboard"+formattedDate+user_id+".xls"); - sos = response.getOutputStream(); - xlsIn = new FileInputStream (AppUtils.getTempFolderPath() - + xlsFName); - buf = new BufferedInputStream(xlsIn); - int readBytes = 0; - byte [] bOut = new byte [4096]; - //read from the file; write to the ServletOutputStream - //while ((readBytes = buf.read()) != -1) - while ((readBytes = buf.read (bOut, 0, 4096))> 0) { - buf.available(); - sos.write (bOut, 0, readBytes); - } - - //sos.write(readBytes); - } - } catch (IOException ex) { ex.printStackTrace(); throw ex;} - - finally { - if (sos != null) - sos.close(); - if (buf != null) - buf.close(); - } - - File f = new File (AppUtils.getTempFolderPath() - + xlsFName); - if(f.exists()) f.delete(); - - } else { - wb = new HSSFWorkbook(); - // PrintWriter xlsOut = new PrintWriter(out).; - setSheetName(Globals.getSheetName()); - //ServletOutputStream sos = response.getOutputStream(); - //PrintWriter outWriter = response.getWriter(); - if (rr != null) - styles = loadStyles(rr, wb); - /* int col = 0; - if (!rd.reportRowHeaderCols.hasNext()) - col = rd.getTotalColumnCount(); - else - col = rd.getTotalColumnCount() + 1; - int rowNum = 0; - String reportTitle = rr.getReportName(); - String reportDescr = rr.getReportDescr(); - // if (Globals.getPrintTitleInDownload() && reportTitle != null) { - HSSFSheet sheet = wb.createSheet(getSheetName()); - System.out.println(" Title " + Globals.getPrintTitleInDownload()); - - if (Globals.getPrintTitleInDownload()&& reportTitle != null ) { - paintExcelHeader(wb, rowNum, col, reportTitle, reportDescr); - rowNum = wb.getSheetAt(0).getLastRowNum(); - } else - rowNum = 0; - System.out.println(" Params " + Globals.getPrintParamsInDownload()); - if (Globals.getPrintParamsInDownload() && rr.getParamNameValuePairs() != null) { - paintExcelParams(wb,rowNum,col,rr.getParamNameValuePairs()); - } // if - paintExcelData(wb, rowNum, col, rd, styles); - rowNum = wb.getSheetAt(0).getLastRowNum(); - */ - int col = 0; - //System.out.println("Row Header Count " + rd.reportRowHeaderCols.getRowCount()); - //System.out.println("Total Count " + rd.getTotalColumnCount()); - String reportTitle = (nvl(rr.getReportTitle()).length()>0?rr.getReportTitle():rr.getReportName()); - String reportDescr = rr.getReportDescr(); - - col = getColumnCountForDownloadFile(rr,rd); - /*if (!rd.reportRowHeaderCols.hasNext()) - col = rd.getTotalColumnCount(); - else - col = rd.getTotalColumnCount(); - */ - int rowNum = 0; - HSSFSheet sheet = wb.createSheet(getSheetName()); - sheet.getPrintSetup().setLandscape(true); - - if (Globals.getPrintTitleInDownload()&& reportTitle != null ) { - paintExcelHeader(wb, rowNum, col, reportTitle, reportDescr, sheet); - rowNum = sheet.getLastRowNum(); - } else - rowNum = 0; - if (Globals.getPrintParamsInDownload() && rr.getParamNameValuePairsforPDFExcel(request, 1) != null) { - ArrayList paramsList = rr.getParamNameValuePairsforPDFExcel(request, 1); - if(paramsList.size()<=0) { - paramsList = (ArrayList) request.getSession().getAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); - } - - paintExcelParams(wb,rowNum,col,paramsList, rr.getFormFieldComments(request), sheet, reportTitle, reportDescr); - } // if - rowNum = sheet.getLastRowNum(); - - String formattedReportName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); - formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); - response.reset(); - response.setContentType("application/vnd.ms-excel"); - response.setHeader("Content-disposition", "attachment;filename="+formattedReportName+formattedDate+user_id+".xls"); - sos = response.getOutputStream(); - - if(type == 3 && rr.getSemaphoreList()==null && !(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) ) { //type = 3 is whole - //String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); - String sql_whole = rr.getWholeSQL(); - returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, sql_whole, sos, request); - } else if(type == 2) { - returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, "", sos, request); - } else { - //String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); - int downloadLimit = (rr.getMaxRowsInExcelDownload()>0)?rr.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); - String action = request.getParameter(AppConstants.RI_ACTION); - if(!(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) && !action.endsWith("session")) { - rd = rr.loadReportData(-1, AppUtils.getUserID(request), downloadLimit,request, false /*download*/); - } - if(rr.getSemaphoreList()!=null) { - if(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { - returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, "", sos, request); - } else { - rd = rr.loadReportData(-1, AppUtils.getUserID(request), downloadLimit,request, true); - returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, "", sos, request); - } - } else { - returnValue = paintExcelData(wb, rowNum, col, rd, styles,rr, sheet, rr.getWholeSQL(), sos, request); - } - } - if( returnValue == 0 ) { - if (Globals.getPrintFooterInDownload()) { - rowNum = sheet.getLastRowNum(); - rowNum += 2; - paintExcelFooter(wb, rowNum, col, sheet); - } - //Alternatively: - wb.setPrintArea( - 0, //sheet index - 0, //start column - col, //end column - 0, //start row - rowNum //end row - ); - //TODO Remove comment - wb.write(sos); - sos.flush(); - sos.close(); - wb = null; - } else { - //sos.flush(); - //sos.close(); -/* response.reset(); - - RequestDispatcher dispatcher = request.getRequestDispatcher("/raptor.htm?action=raptor&r_action=report.message"); - request.setAttribute("message", Globals.getUserDefinedMessageForMemoryLimitReached()); - try { - dispatcher.forward(request, response); - } catch (ServletException ex) {} -*/ - } - } - } - - - public void createFlatFileContent(Writer out, ReportData rd, ReportRuntime rr, - HttpServletRequest request, HttpServletResponse response, String user_id) - throws IOException, Exception { - ReportHandler rephandler = new ReportHandler(); - String reportID = rr.getReportID(); - rr = rephandler.loadReportRuntime(request, reportID); - String query = rr.getWholeSQL(); - String dbInfo = rr.getDbInfo(); - //File f = new File(request.(arg0)("/")); - DataSet ds = ConnectionUtils.getDataSet(query, dbInfo); - - //Writing Column names to the file - List l = rr.getAllColumns(); - StringBuffer allColumnsBuffer = new StringBuffer(); - DataColumnType dct = null; - - for (Iterator iter = l.iterator(); iter.hasNext();) { - dct = (DataColumnType) iter.next(); - allColumnsBuffer.append(dct.getDisplayName()); - if(iter.hasNext()) - allColumnsBuffer.append("|"); - } - rd = rr.loadReportData(-1, user_id, -1,request, true); - //PrintWriter txtOut = new PrintWriter(out); - //response.setContentType("application/notepad"); - //response.setHeader("Content-disposition", "attachment;filename=download_all_"+AppUtils.getUserID(request)+".txt"); - ServletOutputStream sos = response.getOutputStream(); - - //No Report Title for flat file. -// if (Globals.getPrintTitleInDownload() && reportTitle != null) { -// txtOut.println(); -// txtOut.println("\"" + reportTitle + "\""); -// txtOut.println(); -// if (Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0) { -// txtOut.println("\"" + reportDescr + "\""); -// txtOut.println(); -// } -// } // if - // No Params either -// int count = 0; -// if (Globals.getPrintParamsInDownload() && reportParamNameValues != null) { -// for (Iterator iter = reportParamNameValues.iterator(); iter.hasNext();) { -// count += 1; -// if(count == 1) txtOut.println(); -// IdNameValue value = (IdNameValue) iter.next(); -// txtOut.println(value.getId() + " = " + value.getName()); -// if(!iter.hasNext()) txtOut.println(); -// } // for -// } // if - - - - boolean firstPass = true; - for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { - DataRow dr = rd.reportDataRows.getNext(); - for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - if (firstPass) - rhc.resetNext(); - RowHeader rh = rhc.getNext(); - - sos.print(rh.getRowTitle()); - if(rhc.hasNext()) sos.print("|"); - } // for - firstPass = false; - - for (dr.resetNext(); dr.hasNext();) { - DataValue dv = dr.getNext(); - - sos.print( dv.getDisplayValue()); - if(dr.hasNext()) sos.print("|"); - } // for - - sos.println(); - } // for - //sos.flush(); - sos.close(); - } // createFlatFileContent - - - public void createExcel2007FileContent(Writer out, ReportData rd, ReportRuntime rr, HttpServletRequest request, - HttpServletResponse response, String user_id, int type) - throws Exception { - - // to check performance - int mb = 1024*1024; - Runtime runtime = Runtime.getRuntime(); - - logger.debug(EELFLoggerDelegate.debugLogger, ("STARTING.EXCELX DOWNLOAD....")); - logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); - logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" - + (runtime.totalMemory() - runtime.freeMemory()) / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" - + runtime.freeMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("##### END #####")); - - // Adding utility for downloading Dashboard reports. - - Map styles = new HashMap(); - HttpSession session = request.getSession(); - ServletOutputStream sos = null; - BufferedInputStream buf = null; - XSSFWorkbook wb = null; - String formattedReportName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); - String formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); - //Sheet name to be filled is taken from property. How would this be called if it is Dashboard? - //commented out since application will create and leave it blank. - //setSheetName(Globals.getSheetName()); - boolean isDashboard = false; - if ((session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) && ( ((String) session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)).equals(rr.getReportID())) ) { - isDashboard = true; - } - //boolean isDashboard = (session.getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null); - ArrayList sheetArrayList = new ArrayList(); - - Map reportRuntimeMap = null; - Map reportDataMap = null; - - ArrayList reportIDList = new ArrayList(); - - //Map reportDisplayTypeMap = null; - if(isDashboard) { - reportRuntimeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); - reportDataMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); - - if(reportRuntimeMap!=null) { - Set setReportRuntime = reportRuntimeMap.entrySet(); - for(Iterator iter = setReportRuntime.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); - reportIDList.add(rrDashRep.getReportID()); - } - } - } - - - - - int col = 0; - String reportTitle = (nvl(rr.getReportTitle()).length()>0?rr.getReportTitle():rr.getReportName()); - String reportDescr = rr.getReportDescr(); - - // Total Columns visible in excel - //col = getColumnCountForDownloadFile(rr, rd); - - int rowNum = 0; - - - XSSFSheet sheet = null; - //save the template - String filename = ""; - String extension = ""; - - String sheetRef = null; - - FileOutputStream os = null; //template file - File templateFile = null; - - if(isDashboard) { - if(reportRuntimeMap!=null) { - - FileInputStream readTemplate = null; - //Load customized styles - int count = 0; - - //If template supplied by Application - String templateFilename = rr.getTemplateFile(); - extension = templateFilename.substring(templateFilename.lastIndexOf(".")+1); - filename = formattedReportName+formattedDate+user_id; - - Set setReportRuntimeWB = reportRuntimeMap.entrySet(); - for(Iterator iter = setReportRuntimeWB.iterator(); iter.hasNext(); ) { - count++; - Map.Entry entry = (Entry) iter.next(); - ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); - os = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); - - if(count==1) { - if(nvl(rr.getTemplateFile()).length()>0) { - readTemplate = new FileInputStream(org.openecomp.portalsdk.analytics.system.AppUtils.getExcelTemplatePath()+rr.getTemplateFile()); - wb=new XSSFWorkbook(readTemplate); - } else { - //copy the os file to new file and open new file in below line - wb=new XSSFWorkbook(); - } - } else { - readTemplate = new FileInputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); - wb=new XSSFWorkbook(readTemplate); - } - if(rrDashRep!=null) - styles = loadXSSFStyles(rrDashRep, wb, styles); - String reportSheetName = new HtmlStripper().stripSpecialCharacters(rrDashRep.getReportName()); - if(nvl(reportSheetName).length()>28) - reportSheetName = reportSheetName.substring(0, 28); - sheet = wb.createSheet(count+"-"+reportSheetName); - if(!Globals.printExcelInLandscapeMode()) - sheet.getPrintSetup().setLandscape(false); - else - sheet.getPrintSetup().setLandscape(true); - wb.write(os); - os.flush(); - if(nvl(rr.getTemplateFile()).length()>0) { - readTemplate.close(); - } - os.close(); - - FileInputStream inF = new FileInputStream(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); - FileOutputStream outStream = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); - copyStream(inF, outStream); - outStream.flush(); - outStream.close(); - inF.close(); - - } - - FileInputStream xlsIn = null; - POIFSFileSystem fileSystem = null; - buf = null; - FileOutputStream xlsOut = null; - formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); - String xlsFName = "dashboard"+formattedDate+user_id+".xls"; - - Set setReportRuntime = reportRuntimeMap.entrySet(); - Set setReportDataMap = reportDataMap.entrySet(); - Iterator iter2 = setReportDataMap.iterator(); - - - //filename = templateFilename.substring(0, templateFilename.lastIndexOf("."))+"_"+formattedDate+user_id; - - count = 0; - for(Iterator iter = setReportRuntime.iterator(); iter.hasNext(); ) { - count++; - - Map.Entry entry = (Entry) iter.next(); - Map.Entry entryData = (Entry) iter2.next(); - ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); - ReportData rdDashRep = (ReportData) entryData.getValue(); - - String reportSheetName = new HtmlStripper().stripSpecialCharacters(rrDashRep.getReportName()); - if(nvl(reportSheetName).length()>28) - reportSheetName = reportSheetName.substring(0, 28); - sheet = wb.getSheet(count+"-"+reportSheetName); - sheetRef = sheet.getPackagePart().getPartName().getName(); - - //Step 2. Generate XML file. - File tmp = File.createTempFile("sheet", ".xml"); - FileOutputStream fileOutTemp = new FileOutputStream(tmp); - Writer fw = new OutputStreamWriter(fileOutTemp, XML_ENCODING); - String sql_whole = rrDashRep.getWholeSQL(); - SpreadsheetWriter sw = new SpreadsheetWriter(fw); - sw.beginSheet(); - - - generate(wb, sw, styles, rdDashRep, sql_whole, rrDashRep, request, sheet); - - - sw.endSheet(); - - fw.flush(); - fw.close(); - fileOutTemp.flush(); - fileOutTemp.close(); - - - //Step 3. Substitute the template entry with the generated data - - FileOutputStream outF = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); - templateFile = new File(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); - substitute(templateFile, tmp, sheetRef.substring(1), outF); - outF.flush(); - outF.close(); - - FileInputStream inF = new FileInputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); - FileOutputStream outStream = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); - copyStream(inF, outStream); - outStream.flush(); - outStream.close(); - inF.close(); - } - } - } else { - //If template supplied by Application - if(nvl(rr.getTemplateFile()).length()>0) { - String templateFilename = rr.getTemplateFile(); - extension = templateFilename.substring(templateFilename.lastIndexOf(".")+1); - filename = formattedReportName+formattedDate+user_id; - //filename = templateFilename.substring(0, templateFilename.lastIndexOf("."))+"_"+formattedDate+user_id; - } else - filename = formattedReportName+formattedDate+user_id; - - - if(nvl(rr.getTemplateFile()).length()<=0) { - os = new FileOutputStream(AppUtils.getTempFolderPath()+"template"+formattedDate+user_id+".xlsx"); - wb=new XSSFWorkbook(); - //Load customized styles - if (rr != null) - styles = loadXSSFStyles(rr, wb, styles); - //create data sheet - if(isDashboard) { - - } else { - - } - String reportSheetName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); - if(nvl(reportSheetName).length()>28) - reportSheetName = reportSheetName.substring(0, 28); - sheet = wb.createSheet(reportSheetName); - - //customized mode - if(!Globals.printExcelInLandscapeMode()) - sheet.getPrintSetup().setLandscape(false); - else - sheet.getPrintSetup().setLandscape(true); - //get data sheet name - sheetRef = sheet.getPackagePart().getPartName().getName(); - wb.write(os); - os.flush(); - //wb = null; - os.close(); - - } else { - os = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); - FileInputStream readTemplate = new FileInputStream(org.openecomp.portalsdk.analytics.system.AppUtils.getExcelTemplatePath()+rr.getTemplateFile()); - wb=new XSSFWorkbook(readTemplate); - if (rr != null) - styles = loadXSSFStyles(rr, wb, styles); - sheet = wb.getSheetAt(0); - if(!Globals.printExcelInLandscapeMode()) - sheet.getPrintSetup().setLandscape(false); - else - sheet.getPrintSetup().setLandscape(true); - //sheet = wb.getSheet(getSheetName()); - sheetRef = sheet.getPackagePart().getPartName().getName(); - wb.write(os); - os.flush(); - readTemplate.close(); - //wb = null; - os.close(); - } - - //Step 2. Generate XML file. - File tmp = File.createTempFile("sheet", ".xml"); - FileOutputStream fileOutTemp = new FileOutputStream(tmp); - Writer fw = new OutputStreamWriter(fileOutTemp, XML_ENCODING); - - //String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); - String sql_whole = ""; - if (!rr.getReportType().equals(AppConstants.RT_HIVE)) - sql_whole = rr.getWholeSQL(); - else - sql_whole = rr.getReportSQL(); - - SpreadsheetWriter sw = new SpreadsheetWriter(fw); - - sw.beginSheet(); - - if((rd.getDataRowCount() >= rr.getReportDataSize()) && !rr.getReportType().equals(AppConstants.RT_HIVE)) { - sql_whole=""; - } - - generate(wb, sw, styles, rd, sql_whole, rr, request, sheet); - - sw.endSheet(); - - fw.flush(); - fw.close(); - fileOutTemp.flush(); - fileOutTemp.close(); - - - //Step 3. Substitute the template entry with the generated data - - FileOutputStream outF = new FileOutputStream(AppUtils.getTempFolderPath()+ filename+"."+ nvls(extension, "xlsx")); - - if(nvl(rr.getTemplateFile()).length()>0) { - templateFile = new File(AppUtils.getTempFolderPath()+ filename+"T."+ nvls(extension, "xlsx")); - } else - templateFile = new File(AppUtils.getTempFolderPath()+"template"+formattedDate+user_id+".xlsx"); - - substitute(templateFile, tmp, sheetRef.substring(1), outF); - outF.flush(); - outF.close(); - - } - //get servlet output stream - - - response.reset(); - sos = response.getOutputStream(); - String mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; - if(extension.equals("xlsm")) - mime_type = "application/vnd.ms-excel.sheet.macroEnabled.12"; - response.setContentType(mime_type); - - response.setHeader("Content-disposition", "attachment;filename="+filename+"."+ nvls(extension, "xlsx")); - - buf = new BufferedInputStream(new FileInputStream(AppUtils.getTempFolderPath()+filename + "."+ nvls(extension, "xlsx"))); - int readBytes = 0; - - //read from the file; write to the ServletOutputStream - while ((readBytes = buf.read()) != -1) - sos.write(readBytes); - - buf.close(); - sos.flush(); - sos.close(); - logger.debug(EELFLoggerDelegate.debugLogger, ("ENDING..DOWNLOADING XLSX...")); - logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); - logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" - + (runtime.totalMemory() - runtime.freeMemory()) / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" - + runtime.freeMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("##### END #####")); - } - - /** - * - * @param zipfile the template file - * @param tmpfile the XML file with the sheet data - * @param entry the name of the sheet entry to substitute, e.g. xl/worksheets/sheet1.xml - * @param out the stream to write the result to - */ - private static void substitute(File zipfile, File tmpfile, String entry, OutputStream out) throws IOException { - ZipFile zip = new ZipFile(zipfile); - - ZipOutputStream zos = new ZipOutputStream(out); - - @SuppressWarnings("unchecked") - Enumeration en = (Enumeration) zip.entries(); - while (en.hasMoreElements()) { - ZipEntry ze = en.nextElement(); - if(!ze.getName().equals(entry)){ - zos.putNextEntry(new ZipEntry(ze.getName())); - InputStream is = zip.getInputStream(ze); - copyStream(is, zos); - is.close(); - } - } - zos.putNextEntry(new ZipEntry(entry)); - InputStream is = new FileInputStream(tmpfile); - copyStream(is, zos); - zos.flush(); - zos.close(); - is.close(); - zip.close(); - } - - private static void copyStream(InputStream in, OutputStream out) throws IOException { - byte[] chunk = new byte[1024]; - int count; - while ((count = in.read(chunk)) >=0 ) { - out.write(chunk,0,count); - } - } - - - public void createCSVFileContent(Writer out, ReportData rd, - ReportRuntime rr, HttpServletRequest request, HttpServletResponse response) - throws RaptorException { - //ArrayList reportParamNameValues = rr.getParamNameValuePairs(); - //String reportTitle = rr.getReportName(); - //String reportDescr = rr.getReportDescr(); - PrintWriter csvOut = new PrintWriter(out); - ServletOutputStream sos = null; - BufferedInputStream buf = null; - String fileName = ""; - String formattedReportName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); - String formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); - String fName = formattedReportName+formattedDate+AppUtils.getUserID(request); - boolean raw = AppUtils.getRequestFlag(request, "raw"); - String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); - - - String csvFName = fName+".csv"; - String zipFName = fName+".zip"; - if(true) { - try { - fileName = AppUtils.getTempFolderPath()+""+csvFName; - csvOut = new PrintWriter(new BufferedWriter( - new OutputStreamWriter( - new FileOutputStream(fileName), "UTF-8")), false); - } catch (FileNotFoundException fex) { - fex.printStackTrace(); - } - catch (UnsupportedEncodingException fex1) { - fex1.printStackTrace(); - } - } - HtmlStripper strip = new HtmlStripper(); - ResultSet rs = null; - //OracleConnection conn = null; - //OracleStatement st = null; - //Connection conO = null; - //Statement stO = null; - Connection conn = null; - Statement st = null; - ResultSetMetaData rsmd = null; - ColumnHeaderRow chr = null; - int mb = 1024*1024; - Runtime runtime = Runtime.getRuntime(); - String valueName = ""; - if(!raw) { - String reportTitle = (nvl(rr.getReportTitle()).length()>0?rr.getReportTitle():rr.getReportName()); - csvOut.println(); - csvOut.print("\"" + reportTitle + "\","); - csvOut.println(); - - if(Globals.disclaimerPositionedTopInCSVExcel()) { - if(Globals.getShowDisclaimer()) { - csvOut.println(); - csvOut.print("\"" + Globals.getFooterFirstLine() + "\","); - csvOut.println(); - csvOut.print("\"" + Globals.getFooterSecondLine() + "\","); - csvOut.println(); - csvOut.println(); - } - } - } - if (Globals.getPrintParamsInCSVDownload() && !raw) { - ArrayList paramsList = rr.getParamNameValuePairsforPDFExcel(request, 1); - if(paramsList.size()<=0) { - paramsList = (ArrayList) request.getSession().getAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); - } - int paramSeq = 0; - for (Iterator iter = paramsList.iterator(); iter.hasNext();) { - IdNameValue value = (IdNameValue) iter.next(); - //System.out.println("\"" + value.getId() + " = " + value.getName() + "\""); - if(nvl(value.getId()).trim().length()>0 && (!nvl(value.getId()).trim().equals("BLANK"))) { - paramSeq += 1; - if(paramSeq <= 1) { - csvOut.print("\"" + "Run-time Parameters" + "\""); - csvOut.println(); - //strBuf.append("Run-time Parameters\n"); - } - csvOut.print("\"" + value.getId() +":" + "\","); - valueName = nvl(value.getName()); - if(valueName.indexOf("~")!= -1 && valueName.startsWith("(")) { - csvOut.print("\"'" + valueName.replaceAll("~",",")+ "'\","); - } else { - if(valueName.startsWith("(") && valueName.endsWith(")")) { - csvOut.print("\"" + valueName.replaceAll("~",",").substring(1, valueName.length()-1)+ "\","); - } else - csvOut.print("\"" + valueName.replaceAll("~",",")+ "\","); - } - csvOut.println(); - - //strBuf.append(value.getId()+": "+ value.getName()+"\n"); - } - } //for - csvOut.println(); - csvOut.println(); - } - - System.out.println("##### Heap utilization statistics [MB] #####"); - System.out.println("Used Memory:" - + (runtime.maxMemory() - runtime.freeMemory()) / mb); - System.out.println("Free Memory:" - + runtime.freeMemory() / mb); - System.out.println("Total Memory:" + runtime.totalMemory() / mb); - System.out.println("Max Memory:" + runtime.maxMemory() / mb); - if (!rr.getReportType().equals(AppConstants.RT_HIVE)) - sql_whole = rr.getWholeSQL(); - else - sql_whole = rr.getReportSQL(); - if(nvl(sql_whole).length()>0) { - try { - conn = ConnectionUtils.getConnection(rr.getDbInfo()); - st = conn.createStatement(); - //conn.setDefaultRowPrefetch(1000); - //st.setFetchDirection(ResultSet.TYPE_FORWARD_ONLY); - //st.setFetchSize(1000); - System.out.println("************* Map Whole SQL *************"); - System.out.println(sql_whole); - System.out.println("*****************************************"); - rs = st.executeQuery(sql_whole); - //st.setFetchSize(1000); - rsmd = rs.getMetaData(); - int numberOfColumns = rsmd.getColumnCount(); - HashMap colHash = new HashMap(); - String title = ""; - - if(rd!=null) { - - /*if(rd.reportTotalRowHeaderCols!=null) { - csvOut.print("\"" + "#" + "\","); - }*/ - - for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { - chr = rd.reportColumnHeaderRows.getNext(); - for (chr.resetNext(); chr.hasNext();) { - ColumnHeader ch = chr.getNext(); - title = ch.getColumnTitle(); - title = Utils.replaceInString(title,"_nl_", " \n"); - if(ch.isVisible() && nvl(title).length()>0) { - csvOut.print("\"" + title + "\","); - for (int i = 1; i < ch.getColSpan(); i++) - csvOut.print(","); - } - } // for - - csvOut.println(); - } // for - int rowCount = 0; - while(rs.next()) { -/* if(runtime.freeMemory()/mb <= ((runtime.maxMemory()/mb)*Globals.getMemoryThreshold()/100) ) { - csvOut.print(Globals.getUserDefinedMessageForMemoryLimitReached() + " " + rowCount +"records out of " + rr.getReportDataSize() + " were downloaded to CSV."); - break; - } -*/ rowCount++; - //if(!raw) { - colHash = new HashMap(); - for (int i = 1; i <= numberOfColumns; i++) { - colHash.put(rsmd.getColumnLabel(i).toUpperCase(), rs.getString(i)); - } - /*if(rd.reportDataTotalRow!=null) { - csvOut.print("\"" + rowCount + "\","); - }*/ - for (chr.resetNext(); chr.hasNext();) { - ColumnHeader ch = chr.getNext(); - title = ch.getColumnTitle(); - title = Utils.replaceInString(title,"_nl_", " \n"); - - if(ch.isVisible() && nvl(title).length()>0) { - csvOut.print("\"" + strip.stripCSVHtml(nvl((String)colHash.get(ch.getColId().toUpperCase()))) + "\","); - } - - } - csvOut.println(); - /*} else { - for (int i = 1; i <= numberOfColumns; i++) { - csvOut.print("\"" + strip.stripCSVHtml( rs.getString(i)) + "\","); - } - csvOut.println(); - }*/ - - } - - if(rd.reportDataTotalRow!=null) { - for (rd.reportDataTotalRow.resetNext(); rd.reportDataTotalRow.hasNext();) { - DataRow dr = rd.reportDataTotalRow.getNext(); - csvOut.print("\"" + "Total" + "\","); - dr.resetNext();dr.getNext(); - for (; dr.hasNext();) { - DataValue dv = dr.getNext(); - if(dv.isVisible()) { - csvOut.print("\"" + strip.stripCSVHtml(dv.getDisplayValue()) + "\","); - } - } // for - - csvOut.println(); - } - } - - if(rowCount == 0) { - csvOut.print("\"No Data Found \""); - } - } else { - csvOut.print("\"No Data Found \""); - } - - } catch (SQLException ex) { - throw new RaptorException(ex); - } catch (ReportSQLException ex) { - throw new RaptorException(ex); - } catch (Exception ex) { - throw new RaptorException (ex); - } finally { - try { - if(conn!=null) - conn.close(); - if(st!=null) - st.close(); - if(rs!=null) - rs.close(); - } catch (SQLException ex) { - throw new RaptorException(ex); - } - } - - if(!raw) { - if(!Globals.disclaimerPositionedTopInCSVExcel()) { - if(Globals.getShowDisclaimer()) { - csvOut.print("\"" + Globals.getFooterFirstLine() + "\","); - csvOut.println(); - csvOut.print("\"" + Globals.getFooterSecondLine() + "\","); - csvOut.println(); - } - } - } - - // csvOut.flush(); - } else { - boolean firstPass = true; - if(rd!=null) { - if(rd.reportTotalRowHeaderCols!=null) { - csvOut.print("\"" + "#" + "\","); - } - - for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { - chr = rd.reportColumnHeaderRows.getNext(); - for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - - if (firstPass) - csvOut.print("\"" + rhc.getColumnTitle() + "\""); - csvOut.print(","); - } // for - firstPass = false; - - for (chr.resetNext(); chr.hasNext();) { - ColumnHeader ch = chr.getNext(); - if(ch.isVisible()) { - csvOut.print("\"" + ch.getColumnTitle() + "\","); - for (int i = 1; i < ch.getColSpan(); i++) - csvOut.print(","); - } - } // for - - csvOut.println(); - } // for - - firstPass = true; - int rowCount = 0; - for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { - if(rd.reportDataTotalRow!=null) { - rowCount++; - csvOut.print("\"" + rowCount + "\","); - } - - DataRow dr = rd.reportDataRows.getNext(); - - for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - if (firstPass) - rhc.resetNext(); - RowHeader rh = rhc.getNext(); - - csvOut.print("\"" + strip.stripCSVHtml(rh.getRowTitle()) + "\","); - } // for - firstPass = false; - - for (dr.resetNext(); dr.hasNext();) { - DataValue dv = dr.getNext(); - if(dv.isVisible()) - csvOut.print("\"" + strip.stripCSVHtml(dv.getDisplayValue()) + "\","); - } // for - - csvOut.println(); - } // for - if(rd.reportDataTotalRow!=null) { - for (rd.reportDataTotalRow.resetNext(); rd.reportDataTotalRow.hasNext();) { - DataRow dr = rd.reportDataTotalRow.getNext(); - csvOut.print("\"" + "Total" + "\","); - firstPass = false; - - for (dr.resetNext(); dr.hasNext();) { - DataValue dv = dr.getNext(); - if(dv.isVisible()) - csvOut.print("\"" + strip.stripCSVHtml(dv.getDisplayValue()) + "\","); - } // for - - csvOut.println(); - } - } - - if(!raw) { - if(!Globals.disclaimerPositionedTopInCSVExcel()) { - if(Globals.getShowDisclaimer()) { - csvOut.print("\"" + Globals.getFooterFirstLine() + "\","); - csvOut.println(); - csvOut.print("\"" + Globals.getFooterSecondLine() + "\","); - csvOut.println(); - } - } - } - - //csvOut.flush(); - } else { - csvOut.print("\"No Data Found \""); - } - } - csvOut.flush(); - csvOut.close(); - -/* - if (Globals.getPrintTitleInDownload() && reportTitle != null) { - csvOut.println(); - csvOut.println("\"" + reportTitle + "\""); - csvOut.println(); - if (Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0) { - csvOut.println("\"" + reportDescr + "\""); - csvOut.println(); - } - } // if - - if (Globals.getPrintParamsInDownload() && reportParamNameValues != null) { - csvOut.println(); - for (Iterator iter = reportParamNameValues.iterator(); iter.hasNext();) { - IdNameValue value = (IdNameValue) iter.next(); - csvOut.println("\"" + value.getId() + " = " + value.getName() + "\""); - } // for - csvOut.println(); - } // if -*/ - if(true && !raw) { - try { - - //final int BUFFER = 2048; - - //fis.read(buf,0,buf.length); - int size = 0; - byte[] buffer = new byte[1024]; - - //CRC32 crc = new CRC32(); - //PrintStream fos = new PrintStream(new WriterOutputStream(out)); - //BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); - //ZipOutputStream s = new ZipOutputStream(dest); - ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(AppUtils.getTempFolderPath()+""+zipFName)); - FileInputStream fis = new FileInputStream(fileName); - - //s.setLevel(6); - - ZipEntry entry = new ZipEntry(csvFName); - //crc.reset(); - zos.putNextEntry(entry); - - // read data to the end of the source file and write it to the zip - // output stream. - while ((size = fis.read(buffer, 0, buffer.length)) > 0) { - zos.write(buffer, 0, size); - } - - zos.closeEntry(); - fis.close(); - - // Finish zip process - zos.close(); - - } catch(Exception e) { - e.printStackTrace(); - } - } - - response.reset(); - java.io.File file = null; - - if(true && !raw) { - response.setContentType("application/octet-stream"); - response.setHeader("Content-disposition","attachment;filename="+fName+".zip"); - file = new java.io.File(AppUtils.getTempFolderPath()+""+fName+".zip"); - } else { - response.setContentType("application/csv"); - response.setHeader("Content-disposition","attachment;filename="+fName+".csv"); - file = new java.io.File(AppUtils.getTempFolderPath()+""+fName+".csv"); - } - - - FileInputStream fileIn = null; - int c; - try { - sos = response.getOutputStream(); - fileIn = new FileInputStream(file); - buf = new BufferedInputStream(fileIn); - byte [] bOut = new byte [4096]; - //read from the file; write to the ServletOutputStream - //while ((readBytes = buf.read()) != -1) - int readBytes = 0; - while ((readBytes = buf.read (bOut, 0, 4096))> 0) { - buf.available(); - sos.write (bOut, 0, readBytes); - } - - } catch (IOException ex) { - ex.printStackTrace(); - } - catch(Exception e) { - e.printStackTrace(); - } finally { - try { - if (sos != null) - sos.close(); - if (buf != null) - buf.close(); - } catch (Exception e1) { - e1.printStackTrace(); - } - } - - File f = new File (AppUtils.getTempFolderPath() - + fName); - if(f.exists()) f.delete(); - System.out.println("##### Heap utilization statistics [MB] #####"); - System.out.println("Used Memory:" - + (runtime.maxMemory() - runtime.freeMemory()) / mb); - logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" - + runtime.freeMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); - - } // createCSVFileContent - -/* public String saveCSVPageFile(HttpServletRequest request, ReportData rd, - ArrayList reportParamNameValues, String reportTitle, String reportDescr) { - try { - String formattedReportName = new HtmlStripper().stripSpecialCharacters(reportTitle); - String formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); - - String csvFName = formattedReportName+formattedDate+AppUtils.getUserID(request)+".csv"; - //String csvFName = AppUtils.generateFileName(request, AppConstants.FT_CSV); - - BufferedWriter csvOut = new BufferedWriter(new FileWriter(AppUtils - .getTempFolderPath() - + csvFName)); - createCSVFileContent(csvOut, rd, reportParamNameValues, reportTitle, reportDescr); - csvOut.close(); - - return csvFName; - } catch (Exception e) { - (new ErrorHandler()).processError(request, "Exception saving data to CSV file: " - + e.getMessage()); - return null; - } - } // saveCSVPageFile -*/ - -// public String saveAsFlatFile(HttpServletRequest request, ReportData rd, -// ReportRuntime rr, String reportTitle, String reportDescr) { -// try { -// String csvFName = AppUtils.generateFileName(request, AppConstants.FT_TXT); -// -// BufferedWriter txtOut = new BufferedWriter(new FileWriter(AppUtils -// .getTempFolderPath() -// + csvFName)); -// createFlatFileContent(txtOut, rd, rr, reportTitle, reportDescr); -// txtOut.close(); -// -// return csvFName; -// } catch (Exception e) { -// (new ErrorHandler()).processError(request, "Exception saving data to CSV file: " -// + e.getMessage()); -// return null; -// } -// } // saveCSVPageFile - - public String saveXMLFile(HttpServletRequest request, String reportName, String reportXML) { - try { - String xmlFName = AppUtils.generateUniqueFileName(request, reportName, AppConstants.FT_XML); - - PrintWriter xmlOut = new PrintWriter(new BufferedWriter(new FileWriter(new File( - AppUtils.getTempFolderPath() + xmlFName)))); - xmlOut.println(reportXML); - xmlOut.close(); - - //return AppUtils.getTempFolderURL() - // + java.net.URLEncoder.encode(java.net.URLDecoder.decode(xmlFName)); - return java.net.URLEncoder.encode(java.net.URLDecoder.decode(xmlFName)); - - } catch (Exception e) { - (new ErrorHandler()).processError(request, - "Exception saving XML source to file system: " + e.getMessage()); - return null; - } - } // saveXMLFile - - public ReportRuntime loadReportRuntime(HttpServletRequest request, String reportID) - throws RaptorException { - return loadReportRuntime(request, reportID, true); - } // loadReportRuntime - - public ReportRuntime loadReportRuntime(HttpServletRequest request, String reportID, - boolean prepareForExecution) throws RaptorException { - return loadReportRuntime(request, reportID, true, 2); // where 2 is adding to session - } - public ReportRuntime loadReportRuntime(HttpServletRequest request, String reportID, - boolean prepareForExecution, int requestFlag) throws RaptorException { - boolean refresh = nvl(request.getParameter(AppConstants.RI_REFRESH)).toUpperCase().startsWith("Y"); - boolean rDisplayContent = AppUtils.getRequestFlag(request, - AppConstants.RI_DISPLAY_CONTENT) - || AppUtils.getRequestFlag(request, "noFormFields"); - - ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( - AppConstants.SI_REPORT_RUNTIME); - boolean inSchedule = AppUtils.getRequestFlag(request, AppConstants.SCHEDULE_ACTION); - if (rr != null ) { - if(requestFlag == 7) { // DASH - String reportXML = ReportLoader.loadCustomReportXML(reportID); - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Report [" + reportID + "]: XML loaded")); - rr = ReportRuntime.unmarshal(reportXML, reportID, request); - rr.setParamValues(request, false,refresh); - rr.setDisplayFlags(true, true); // show content even at the first time - return rr; - } else { - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Load Report Runtime "+ reportID + " " +rr.getReportID() + " " + request.getParameter("refresh") )); - if (reportID.equals(rr.getReportID()) && (request.getParameter("refresh")==null || !request.getParameter("refresh").equals("Y"))) { - // The report runtime is already in the session - if (prepareForExecution) { - boolean resetParams = AppUtils.getRequestFlag(request, - AppConstants.RI_RESET_PARAMS); - rr.setParamValues(request, resetParams,refresh); - - if (resetParams) - rr.resetVisualSettings(); - rr.setDisplayFlags(nvl(request.getParameter(AppConstants.RI_SOURCE_PAGE)) - .length() == 0, rDisplayContent || rr.isDisplayOptionHideForm()); - } // if - - return rr; - } // if - } - } - - /* - * Cannot convert the definition => XML file not saved for preview also, - * commented code not maintained up to date ReportDefinition rdef = - * (ReportDefinition) - * request.getSession().getAttribute(AppConstants.SI_REPORT_DEFINITION); - * if(rdef!=null) if(reportID.equals(rdef.getReportID())) { // The - * report definition is in the session => create report runtime from it - * rr = new ReportRuntime(rdef, request); if(prepareForExecution) { - * request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, - * rr); - * rr.setDisplayFlags(request.getParameter(AppConstants.RI_SOURCE_PAGE)==null); } // - * if return rr; } // if - */ - - // Report is NOT in the session => load from the database - String reportXML = ReportLoader.loadCustomReportXML(reportID); - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Report [" + reportID + "]: XML loaded")); - - rr = ReportRuntime.unmarshal(reportXML, reportID, request); - if (prepareForExecution) { - String userID ; - int flag = 0; - if(request.getAttribute("schedule_email_userId") != null) { - userID = (String)request.getAttribute("schedule_email_userId"); - flag = 1; - } - else - userID = AppUtils.getUserID(request); - // If it is dashboard type then report can be viewed without specific privilege to report - String dashboardId = AppUtils.getRequestValue(request, AppConstants.RI_DASHBOARD_ID); - //System.out.println("USSSSSSSSSSSSERID " + userID); - //System.out.println("PDF " + AppUtils.getRequestNvlValue(request, "pdfAttachmentKey") ); - if(!rr.isDashboardType() && !(isReportAddedAsDashboard(request, dashboardId, rr.getReportID()))) { - if ( AppUtils.getRequestNvlValue(request, "pdfAttachmentKey").length()<=0 ) - if(flag == 1 )rr.checkUserReadAccess(request, userID); - else rr.checkUserReadAccess(request); - } - // TODO ON Demand - //rr.setXmlFileName(saveXMLFile(request, rr.getReportName(), reportXML)); - if (rDisplayContent) { - //System.out.println("In rDisplayContent "); - rr.setParamValues(request, false,true); - //if (requestFlag==2) - request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); - } - if(inSchedule) { - //System.out.println("In inSchedule "); - rr.setParamValues(request, false,false); - } - if( requestFlag == 7 ) { // DASH - rr.setDisplayFlags(true, true); - } else { - rr.setDisplayFlags(request.getParameter(AppConstants.RI_SOURCE_PAGE) == null, - rDisplayContent || rr.isDisplayOptionHideForm()); - } -// System.out.println("Report ID B4 Id in reportHandler " -// + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); -// System.out.println("requestFlag " + requestFlag); - if(requestFlag==2 && !rDisplayContent) { - //System.out.println("In Request Flag "); - request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); - rr.setParamValues(request, false, false); - } - else if(requestFlag==1) { - rr.setParamValues(request, false,refresh); - request.setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); - - } -// System.out.println("Report ID B4 Id in reportHandler " -// + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); - //request.setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); - } // if - - return rr; - } // loadReportRuntime - - private boolean isReportAddedAsDashboard(HttpServletRequest request, String dashboardId, String reportId)throws RaptorException { - if(nvl(dashboardId).length() <= 0) - return false; - String reportXML = ReportLoader.loadCustomReportXML(dashboardId); - ReportDefinition rdef = createReportDefinition(request, dashboardId, reportXML); - List l = rdef.getDashBoardReports().getReportsList(); - for (Iterator iterator = l.iterator(); iterator.hasNext();) { - Reports reports = (Reports) iterator.next(); - if(reports.getReportId().equals(reportId)) return true; - - } - return false; - } - - public ReportDefinition createReportDefinition(HttpServletRequest request, - String reportID, String reportXML) throws RaptorException { - ReportDefinition rdef = ReportDefinition.unmarshal(reportXML, reportID, request); - rdef.generateWizardSequence(request); - return rdef; - } // createReportDefinition - - public ReportDefinition loadReportDefinition(HttpServletRequest request, String reportID) - throws RaptorException { - //System.out.println("********* ReportID " + reportID); - boolean isReportIDBlank = (reportID.length() == 0 || reportID.equals("-1")); - String actionKey = nvl(request.getParameter(AppConstants.RI_ACTION), ""); - String wizardActionKey = nvl(request.getParameter(AppConstants.RI_WIZARD_ACTION), ""); - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - if(nvl(actionKey).equals("report.edit")) - rdef = null; - //ReportDefinition rdef = null; - if (rdef != null) - if (isReportIDBlank || reportID.equals(rdef.getReportID())) { - // The report definition is already in the session - return rdef; - } - - ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( - AppConstants.SI_REPORT_RUNTIME); - if (rr != null) - if (isReportIDBlank || reportID.equals(rr.getReportID())) { - // The report runtime is in the session => create report - // definition from it - rdef = new ReportDefinition(rr, request); - String userID = AppUtils.getUserID(request); - rdef.generateWizardSequence(request); - // rdef.checkUserWriteAccess(userID); - - request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); - return rdef; - } // if - - // Report is NOT in the session => load from the database - if (isReportIDBlank) - rdef = ReportDefinition.createBlank(request); - else { - String reportXML = ReportLoader.loadCustomReportXML(reportID); - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Report [" + reportID + "]: XML loaded")); - rdef = createReportDefinition(request, reportID, reportXML); - } // else - - request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); - return rdef; - } // loadReportDefinition - - public void setSheetName( String sheet_name ) { - SHEET_NAME = sheet_name; - } - - public String getSheetName() { - return SHEET_NAME; - } - - /** - * Writes spreadsheet data in a Writer. - * (YK: in future it may evolve in a full-featured API for streaming data in Excel) - */ - public static class SpreadsheetWriter { - private final Writer _out; - private int _rownum; - - public SpreadsheetWriter(Writer out){ - _out = out; - } - - public void beginSheet() throws IOException { - _out.write("" + - "" ); - _out.write("\n"); - } - - public void endSheet() throws IOException { - _out.write(""); - _out.write(""); - } - - /** - * Insert a new row - * - * @param rownum 0-based row number - */ - public void insertRow(int rownum) throws IOException { - _out.write("\n"); - this._rownum = rownum; - } - - /** - * Insert row end marker - */ - public void endRow() throws IOException { - _out.write("\n"); - } - - public void createCell(int columnIndex, String value, int styleIndex) throws IOException { - String ref = new CellReference(_rownum, columnIndex).formatAsString(); - _out.write(""); - _out.write(""+value+""); - _out.write(""); - } - - public void createCell(int columnIndex, String value) throws IOException { - createCell(columnIndex, value, -1); - } - - public void createCell(int columnIndex, double value, int styleIndex) throws IOException { - String ref = new CellReference(_rownum, columnIndex).formatAsString(); - _out.write(""); - _out.write(""+value+""); - _out.write(""); - } - - public void createCell(int columnIndex, double value) throws IOException { - createCell(columnIndex, value, -1); - } - - public void createCell(int columnIndex, Calendar value, int styleIndex) throws IOException { - createCell(columnIndex, DateUtil.getExcelDate(value, false), styleIndex); - } - } - - public int getColumnCountForDownloadFile(ReportRuntime rr, ReportData rd) { - int columnCount = 0; - for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { - ColumnHeaderRow chr = rd.reportColumnHeaderRows.getNext(); - for(chr.resetNext(); chr.hasNext(); ) { - ColumnHeader ch = chr.getNext(); - if(ch.isVisible()) { - columnCount++; - } - } - } - if(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { - for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - if(rhc.isVisible()) { - columnCount++; - } - } - } - return columnCount; - } - - - private Map loadXSSFStyles(ReportRuntime rr, XSSFWorkbook wb, Map loadedStyles) { - XSSFCellStyle styleDefault = wb.createCellStyle(); - //System.out.println("Load Styles"); - // Style default will be normal with no background - XSSFFont fontDefault = wb.createFont(); - - XSSFDataFormat xssffmt = wb.createDataFormat(); - // The default will be plain . - fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); - fontDefault.setFontHeight((short) (font_size / 0.05)); - fontDefault.setFontName("Tahoma"); - - styleDefault.setAlignment(XSSFCellStyle.ALIGN_CENTER); - styleDefault.setBorderBottom(XSSFCellStyle.BORDER_THIN); - styleDefault.setBorderTop(XSSFCellStyle.BORDER_THIN); - styleDefault.setBorderLeft(XSSFCellStyle.BORDER_THIN); - styleDefault.setBorderRight(XSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleDefault.setFillPattern(XSSFCellStyle.NO_FILL); - styleDefault.setFont(fontDefault); - ArrayList semColumnList = new ArrayList(); - List dsList = rr.getDataSourceList().getDataSource(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType element = (DataSourceType) iter.next(); - List dcList = element.getDataColumnList().getDataColumn(); - for (Iterator iterator = dcList.iterator(); iterator.hasNext();) { - DataColumnType element1 = (DataColumnType) iterator.next(); - semColumnList.add(element1.getSemaphoreId()); - - } - } - SemaphoreList semList = rr.getSemaphoreList(); - Map hashMapStyles = new HashMap();; - Map hashMapFonts = new HashMap(); - hashMapFonts.put("default", fontDefault); - hashMapStyles.put("default", styleDefault); - XSSFCellStyle styleLeftDefault = wb.createCellStyle(); - styleLeftDefault.setAlignment(XSSFCellStyle.ALIGN_LEFT); - styleLeftDefault.setBorderBottom(XSSFCellStyle.BORDER_THIN); - styleLeftDefault.setBorderTop(XSSFCellStyle.BORDER_THIN); - styleLeftDefault.setBorderLeft(XSSFCellStyle.BORDER_THIN); - styleLeftDefault.setBorderRight(XSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleLeftDefault.setFillPattern(XSSFCellStyle.NO_FILL); - styleLeftDefault.setFont(fontDefault); - hashMapStyles.put("defaultLeft", styleLeftDefault); - - - XSSFCellStyle styleDate = wb.createCellStyle(); - styleDate.setAlignment(XSSFCellStyle.ALIGN_RIGHT); - styleDate.setDataFormat(xssffmt.getFormat("d-mmm-yy")); - styleDate.setAlignment(XSSFCellStyle.ALIGN_CENTER); - styleDate.setBorderBottom(XSSFCellStyle.BORDER_THIN); - styleDate.setBorderTop(XSSFCellStyle.BORDER_THIN); - styleDate.setBorderLeft(XSSFCellStyle.BORDER_THIN); - styleDate.setBorderRight(XSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleDate.setFillPattern(XSSFCellStyle.NO_FILL); - styleDate.setFont(fontDefault); - hashMapStyles.put("date", styleDate); - - XSSFCellStyle rowHeaderStyle = wb.createCellStyle(); - XSSFFont headerFont = wb.createFont(); - headerFont.setBold(true); - rowHeaderStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); - rowHeaderStyle.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND); - rowHeaderStyle.setFont(headerFont); - rowHeaderStyle.setBorderTop(XSSFCellStyle.BORDER_THIN); - rowHeaderStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN); - rowHeaderStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN); - rowHeaderStyle.setBorderRight(XSSFCellStyle.BORDER_THIN); - hashMapStyles.put("header", rowHeaderStyle); - - - XSSFCellStyle boldStyle = wb.createCellStyle(); - //headerFont = wb.createFont(); - //headerFont.setBold(true); - boldStyle.setFont(headerFont); - boldStyle.setBorderTop(XSSFCellStyle.BORDER_THIN); - boldStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN); - boldStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN); - boldStyle.setBorderRight(XSSFCellStyle.BORDER_THIN); - boldStyle.setAlignment(HorizontalAlignment.CENTER); - hashMapStyles.put("title", boldStyle); - - XSSFCellStyle cellStyle = null; - if (semList == null || semList.getSemaphore() == null) { - hashMapStyles.put("default", styleDefault); - } /*else { - for (Iterator iter = semList.getSemaphore().iterator(); iter.hasNext();) { - SemaphoreType sem = (SemaphoreType) iter.next(); - if(!semColumnList.contains(sem.getSemaphoreId())) continue; - //System.out.println("SemphoreId ----> " + sem.getSemaphoreId()); - FormatList fList = sem.getFormatList(); - List formatList = fList.getFormat(); - for (Iterator fIter = formatList.iterator(); fIter.hasNext();) { - FormatType fmt = (FormatType) fIter.next(); - if(fmt!=null){ - //if (fmt.getLessThanValue().length() > 0) { - cellStyle = wb.createCellStyle(); - XSSFFont cellFont = wb.createFont(); - //System.out.println("Format Id " + fmt.getFormatId()); - if (nvl(fmt.getBgColor()).length() > 0) { -// System.out.println("Load Styles " + -// fmt.getFormatId() -// + " " +fmt.getBgColor() + " " + -// ExcelColorDef.getExcelColor(fmt.getBgColor())); - cellStyle.setFillForegroundColor(ExcelColorDef.getExcelColor(fmt - .getBgColor())); - cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); - } - if (nvl(fmt.getFontColor()).length() > 0) { - cellFont.setColor(ExcelColorDef.getExcelColor(fmt.getFontColor())); - } else - cellFont.setColor((short) HSSFFont.COLOR_NORMAL); - if (fmt.isBold()) - cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - if (fmt.isItalic()) - cellFont.setItalic(true); - if (fmt.isUnderline()) - cellFont.setUnderline(HSSFFont.U_SINGLE); - if(nvl(fmt.getFontFace()).length()>0) - cellFont.setFontName(fmt.getFontFace()); - else - cellFont.setFontName("Tahoma"); - //cellFont.setFontHeight((short) (10 / 0.05)); - - if(nvl(fmt.getFontSize()).length()>0) { - try { - cellFont.setFontHeight((short) (Integer.parseInt(fmt.getFontSize()) / 0.05)); - } catch(NumberFormatException e){ - cellFont.setFontHeight((short) (font_size / 0.05)); - } - } - else - cellFont.setFontHeight((short) (font_size / 0.05)); - cellStyle.setFont(cellFont); - cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); - cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); - cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); - cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); - cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); - hashMapStyles.put(fmt.getFormatId(), cellStyle); - } else { - //hashMapStyles.put(fmt.getFormatId(), styleDefault); - hashMapStyles.put("default", styleDefault); - } - } - - } - }*/ - loadedStyles.putAll(hashMapStyles); - return loadedStyles; - } - - private void generate(XSSFWorkbook wb, SpreadsheetWriter sw, Map styles, ReportData rd, String sql_whole, ReportRuntime rr, HttpServletRequest request, XSSFSheet sheet) throws Exception { - HtmlStripper strip = new HtmlStripper(); - XSSFCellStyle styleCell = null; - XSSFCellStyle styleRowCell = null; - XSSFCellStyle styleDefaultCell = null; - - styleDefaultCell = (XSSFCellStyle) styles.get("default"); - - - // to check performance - int mb = 1024*1024; - Runtime runtime = Runtime.getRuntime(); - - int rowNum = 0; - /*short s1 = 0, s2 = (short) (col-1); - rowNum += 1; - sw.insertRow(rowNum); - int styleIndex = styles.get("header").getIndex(); - sw.createCell(rowNum, reportTitle, styleIndex); - - //header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) 9)+reportTitle+"\n"+((Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0)?reportDescr:"")); - - // Report Description - if (Globals.getShowDescrAtRuntime() && nvl(reportDescr).length() > 0) { - sw.createCell(rowNum, reportDescr, styleIndex); - } - rowNum += 2; - sw.insertRow(rowNum);*/ - int cellNum = 0; - - - ColumnHeaderRow chr = null; - java.util.HashMap dataTypeMap = new java.util.HashMap(); - boolean firstPass = true; - int columnRows = rr.getVisibleColumnCount() ; - - HttpSession session = request.getSession(); - String drilldown_index = (String) session.getAttribute("drilldown_index"); - int index = 0; - try { - index = Integer.parseInt(drilldown_index); - } catch (NumberFormatException ex) { - index = 0; - } - String header = (String) session.getAttribute("TITLE_"+index); - String subtitle = (String) session.getAttribute("SUBTITLE_"+index); - if(nvl(header).length()>0) { - header = Utils.replaceInString(header, "
        ", " "); - header = Utils.replaceInString(header, "
        ", " "); - header = Utils.replaceInString(header, "
        ", " "); - header = strip.stripHtml(nvl(header).trim()); - subtitle = Utils.replaceInString(subtitle, "
        ", " "); - subtitle = Utils.replaceInString(subtitle, "
        ", " "); - subtitle = Utils.replaceInString(subtitle, "
        ", " "); - subtitle = strip.stripHtml(nvl(subtitle).trim()); - //XSSFRow row = sheet.createRow(rowNum); - sw.insertRow(rowNum); - cellNum = 0; - //XSSFCell cell = row.createCell(cellNum); - sw.createCell(cellNum, Utils.excelEncode(header)); - for (int i = 1; i <= columnRows; i++) { - sw.createCell(cellNum+i, ""); - } - sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); - sw.endRow(); -/* cell.setCellValue(Utils.excelEncode(header)); - cell.setCellStyle(styles.get("title")); -*/ //sw.createCell(cellNum,Utils.excelEncode(header), styles.get("title").getIndex()); -// sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); - rowNum += 1; -// row = sheet.createRow(rowNum); - sw.insertRow(rowNum); - cellNum = 0; -/* cell = row.createCell(cellNum); - cell.setCellValue(Utils.excelEncode(subtitle)); - cell.setCellStyle(styles.get("title")); -*/ //sw.createCell(cellNum,Utils.excelEncode(header), styles.get("title").getIndex()); - - sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); - sw.createCell(cellNum, Utils.excelEncode(subtitle)); - sw.endRow(); - //sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); -/* sw.insertRow(rowNum); - cellNum = 0; - sw.createCell(cellNum,Utils.excelEncode(subtitle), styles.get("title").getIndex()); - sheet.addMergedRegion(new CellRangeAddress(rowNum+1, rowNum+1, cellNum+1, columnRows)); - -*/ rowNum += 1; - } - cellNum = 0; - String title = ""; - for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { - sw.insertRow(rowNum); - cellNum = -1; - /*if(rd.reportTotalRowHeaderCols!=null) { - cellNum +=1; - sw.createCell(cellNum, "No.", styles.get("header").getIndex()); - - //row.getCell((short) cellNum).setCellStyle(styleDataHeader); - }*/ - chr = rd.reportColumnHeaderRows.getNext(); - - if(nvl(sql_whole).length() <= 0 || (!rr.getReportType().equals(AppConstants.RT_LINEAR))) { - - for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { - cellNum += 1; - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - title = rhc.getColumnTitle(); - title = Utils.replaceInString(title,"_nl_", " \n"); - - sw.createCell(cellNum,Utils.excelEncode(title), styles.get("header").getIndex()); - //sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum+columnRows, (short) (cellNum))); - //System.out.println(" **************** Row Header Title " + rhc.getColumnTitle() + " " + cellNum + " " ); - //System.out.println(cellNum + " " + cellWidth.size()); - } // for - - } - - firstPass = false; - for (chr.resetNext(); chr.hasNext();) { - ColumnHeader ch = chr.getNext(); - if(ch.isVisible()) { - cellNum += 1; - int colSpan = ch.getColSpan()-1; - title = ch.getColumnTitle(); - title = Utils.replaceInString(title,"_nl_", " \n"); - sw.createCell(cellNum, Utils.excelEncode(title), styles.get("header").getIndex()); - if(colSpan > 0) { - for ( int k = 1; k <= colSpan; k++ ) { - sw.createCell(cellNum+k, "", styles.get("header").getIndex()); - } - //sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (cellNum+colSpan))); - } - if(colSpan > 0) - cellNum += colSpan; - } - } // for - rowNum += 1; - } // for - - sw.endRow(); - //All the possible combinations of date format - CreationHelper createHelper = wb.getCreationHelper(); - HashMap dateFormatMap = new HashMap(); - - SimpleDateFormat MMDDYYYYFormat = new SimpleDateFormat("MM/dd/yyyy"); - SimpleDateFormat YYYYMMDDFormat = new SimpleDateFormat("yyyy/MM/dd"); - SimpleDateFormat MONYYYYFormat = new SimpleDateFormat("MMM yyyy"); - SimpleDateFormat MMYYYYFormat = new SimpleDateFormat("MM/yyyy"); - SimpleDateFormat MMMMMDDYYYYFormat = new SimpleDateFormat("MMMMM dd, yyyy"); - SimpleDateFormat YYYYMMDDDASHFormat = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - SimpleDateFormat DDMONYYYYFormat = new SimpleDateFormat("dd-MMM-yyyy"); - SimpleDateFormat MONTHYYYYFormat = new SimpleDateFormat("MMMMM, yyyy"); - SimpleDateFormat MMDDYYYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); - SimpleDateFormat MMDDYYYYHHMMFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm"); - SimpleDateFormat YYYYMMDDHHMMSSFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - SimpleDateFormat YYYYMMDDHHMMFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); - SimpleDateFormat DDMONYYYYHHMMSSFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); - SimpleDateFormat DDMONYYYYHHMMFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); - SimpleDateFormat DDMONYYHHMMFormat = new SimpleDateFormat("dd-MMM-yy HH:mm"); - SimpleDateFormat MMDDYYFormat = new SimpleDateFormat("MM/dd/yy"); - SimpleDateFormat MMDDYYHHMMFormat = new SimpleDateFormat("MM/dd/yy HH:mm"); - SimpleDateFormat MMDDYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); - SimpleDateFormat MMDDYYYYHHMMZFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm z"); - SimpleDateFormat MMMMMDDYYYYHHMMSS = new SimpleDateFormat("MMMMM-dd-yyyy HH:mm:ss"); - - short dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yyyy"); - dateFormatMap.put("MMDDYYYY", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("yyyy/MM/dd"); - dateFormatMap.put("YYYYMMDD", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MMM yyyy"); - dateFormatMap.put("MONYYYY", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MM/yyyy"); - dateFormatMap.put("MMYYYY", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MMMMM dd, yyyy"); - dateFormatMap.put("MMMMMDDYYYY", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("yyyy-MM-dd"); - dateFormatMap.put("YYYYMMDDDASH", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"); - dateFormatMap.put("timestamp", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yyyy"); - dateFormatMap.put("MONTHYYYY", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MMMMM, yyyy"); - dateFormatMap.put("MMDDYYYY", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yyyy HH:mm:ss"); - dateFormatMap.put("MMDDYYYYHHMM", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yyyy HH:mm"); - dateFormatMap.put("MMDDYYYY", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("yyyy/MM/dd HH:mm:ss"); - dateFormatMap.put("YYYYMMDDHHMMSS", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("yyyy/MM/dd HH:mm"); - dateFormatMap.put("YYYYMMDDHHMM", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yyyy HH:mm:ss"); - dateFormatMap.put("DDMONYYYYHHMMSS", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yyyy HH:mm"); - dateFormatMap.put("DDMONYYYYHHMM", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yy HH:mm"); - dateFormatMap.put("DDMONYYHHMM", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("dd-MMM-yyyy"); - dateFormatMap.put("DDMONYYYY", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yy"); - dateFormatMap.put("MMDDYY", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yy HH:mm"); - dateFormatMap.put("MMDDYYHHMM", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yy HH:mm:ss"); - dateFormatMap.put("MMDDYYHHMMSS", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MM/dd/yyyy HH:mm z"); - dateFormatMap.put("MMDDYYYYHHMMZ", new Short(dateFormat)); - dateFormat = createHelper.createDataFormat().getFormat("MMMMM-dd-yyyy HH:mm:ss"); - dateFormatMap.put("MMMMMDDYYYYHHMMSS", new Short(dateFormat)); - - ResultSet rs = null; - Connection conn = null; - Statement st = null; - ResultSetMetaData rsmd = null; - - - if(nvl(sql_whole).length() >0 && (rr.getReportType().equals(AppConstants.RT_LINEAR) || rr.getReportType().equals(AppConstants.RT_HIVE) )) { - try { - conn = ConnectionUtils.getConnection(rr.getDbInfo()); - st = conn.createStatement(); - logger.debug(EELFLoggerDelegate.debugLogger, ("************* Map Whole SQL *************")); - logger.debug(EELFLoggerDelegate.debugLogger, (sql_whole)); - logger.debug(EELFLoggerDelegate.debugLogger, ("*****************************************")); - rs = st.executeQuery(sql_whole); - rsmd = rs.getMetaData(); - int numberOfColumns = rsmd.getColumnCount(); - HashMap colHash = new HashMap(); - DataRow dr = null; - int j = 0; - int rowCount = 0; - while(rs.next()) { - - rowCount++; - - if(rowCount%10000 == 0) { - // to check performance - logger.debug(EELFLoggerDelegate.debugLogger, ("Performance check for "+rowCount+" starting**************")); - logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); - logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" - + (runtime.totalMemory() - runtime.freeMemory()) / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" - + runtime.freeMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); - System.out.println(rowCount+"TH ROW****##### END #####"); - - // - } - sw.insertRow(rowNum); - cellNum = -1; - colHash = new HashMap(); - for (int i = 1; i <= numberOfColumns; i++) { - colHash.put(rsmd.getColumnName(i).toUpperCase(), strip.stripHtml(rs.getString(i))); - } - rd.reportDataRows.resetNext(); - dr = rd.reportDataRows.getNext(); - styleRowCell = null; - if (dr.isRowFormat() && styles != null) - styleRowCell = (XSSFCellStyle) styles.get(nvl(/*dr.getFormatId(),*/"","default")); - j = 0; - //if(rowCount%1000 == 0) wb.write(sos); - - /*if(rd.reportTotalRowHeaderCols!=null) { - //cellNum = -1; - //for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { - cellNum += 1; - //RowHeaderCol rhc = rd.reportRowHeaderCols.getRowHeaderCol(0); - //if (firstPass) - // rhc.resetNext(); - //RowHeader rh = rhc.getRowHeader(rowCount-1); - sw.createCell(cellNum, rowCount, styleDefaultCell.getIndex()); - - //} // for - }*/ - firstPass = false; - //cellNum = -1; - for (dr.resetNext(); dr.hasNext();j++) { - styleCell = null; - //for (chr.resetNext(); chr.hasNext();) { - //ColumnHeader ch = chr.getNext(); - DataValue dv = dr.getNext(); - HtmlFormatter htmlFormat = dv.getCellFormatter(); - - if (htmlFormat != null && dv.getFormatId() != null && styles != null) - styleCell = (XSSFCellStyle) styles.get(nvl(/*dv.getFormatId()*/"","default")); - String value = nvl((String)colHash.get(dv.getColId().toUpperCase())); - - boolean bold = false; - - if(dv.isVisible()) { - cellNum += 1; - //System.out.println("Stripping HTML 1"); - //cell.setCellValue(strip.stripHtml(dv.getDisplayValue())); - String dataType = (String) (dataTypeMap.get(dv.getColId())); - //System.out.println("Value " + value + " " + (( dataType !=null && dataType.equals("DATE")) || (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date"))) ); - if (dataType!=null && dataType.equals("NUMBER")){ - //cellNumber = row.createCell((short) cellNum); - //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - //cellNumber.setCellValue(dv.getDisplayValue()); - //cellCurrencyNumber = row.createCell((short) cellNum); - int zInt = 0; - if (value.equals("null")){ - sw.createCell(cellNum,zInt,styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - }else{ - - if ((value.indexOf("."))!= -1){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - - //if (dv.getDisplayValue().startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempDollar = dv.getDisplayValue().trim(); - tempDollar = tempDollar.replaceAll(" ", "").substring(0); - tempDollar = tempDollar.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempDollar); - //System.out.println("Before copy Value |" + tempDollar); - //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); - //System.out.println("After copy Value |" + tempDollar); - if ((tempDollar.indexOf(","))!= -1){ - tempDollar = tempDollar.replaceAll(",", ""); - } - //System.out.println("The final string 1 is "+tempDollar); - double tempDoubleDollar = 0.0; - try { - tempDoubleDollar = Double.parseDouble(tempDollar); - if(styleRowCell!=null) - sw.createCell(cellNum, tempDoubleDollar, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempDoubleDollar, styleCell.getIndex()); - else - sw.createCell(cellNum, tempDoubleDollar, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - double tempDouble = 0.0; - try { - tempDouble = Double.parseDouble(value); - if(styleRowCell!=null) - sw.createCell(cellNum, tempDouble, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempDouble, styleCell.getIndex()); - else - sw.createCell(cellNum, tempDouble, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(value),styleRowCell.getIndex() ); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(value), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(value), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } - - } - }else { - if (!(value.equals(""))){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //if (dv.getDisplayValue().startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempInt = value.trim(); - tempInt = tempInt.replaceAll(" ", "").substring(0); - tempInt = tempInt.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempInt); - //System.out.println("Before copy Value |" + tempInt); - //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); - //System.out.println("After copy Value |" + tempInt); - if ((tempInt.indexOf(","))!= -1){ - tempInt = tempInt.replaceAll(",", ""); - } - //System.out.println("The final string INT is "+tempInt); - Long tempIntDollar = 0L; - try { - tempIntDollar = Long.parseLong(tempInt); - if(styleRowCell!=null) - sw.createCell(cellNum, tempIntDollar, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempIntDollar, styleCell.getIndex()); - else - sw.createCell(cellNum, tempIntDollar, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, tempInt, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempInt, styleCell.getIndex()); - else - sw.createCell(cellNum, tempInt, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempStr = value.trim(); - if ((tempStr.indexOf(","))!= -1){ - tempStr = tempStr.replaceAll(",", ""); - } - Long temp = 0L; - - try { - temp = Long.parseLong(tempStr); - if(styleRowCell!=null) - sw.createCell(cellNum, temp, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, temp, styleCell.getIndex()); - else - sw.createCell(cellNum, temp, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempStr), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempStr), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempStr), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } - } - } - } - } - - } else if ( ( dataType !=null && dataType.equals("DATE")) || (dv.getDisplayName()!=null && dv.getDisplayName().toLowerCase().endsWith("date")) || - (dv.getColId()!=null && dv.getColId().toLowerCase().endsWith("date")) || - (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date")) ) { - XSSFCellStyle cellStyle = null; - if(styleRowCell!=null) { - cellStyle = styleRowCell; - } else if (styleCell!=null) { - cellStyle = styleCell; - } else { - cellStyle = styles.get(nvl(/*dv.getFormatId()*/"","date")); - } - - - Date date = null; - int flag = 0; - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMMSS")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMM")); - flag = 1; - } - if(date==null) - date = MMDDYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYY")); - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYYYHHMMSS")); - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYYYHHMM")); - flag = 1; - } - if(date==null) - date = MMDDYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYYY")); - flag = 1; - } - if(date==null) - date = YYYYMMDDFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("YYYYMMDD")); - flag = 1; - } - if(date==null) - date = timestampFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("timestamp")); - flag = 1; - } - if(date==null) - date = MONYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MONYYYY")); - flag = 1; - } - if(date==null) - date = MMYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMYYYY")); - flag = 1; - } - if(date==null) - date = MMMMMDDYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMMMMDDYYYY")); - flag = 1; - } - if(date==null) - date = MONTHYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MONTHYYYY")); - flag = 1; - } - if(date==null) - date = YYYYMMDDHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("YYYYMMDDHHMMSS")); - flag = 1; - } - if(date==null) - date = YYYYMMDDDASHFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("YYYYMMDDDASH")); - flag = 1; - } - if(date==null) - date = YYYYMMDDHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("YYYYMMDDHHMM")); - flag = 1; - } - if(date==null) - date = DDMONYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("DDMONYYYYHHMMSS")); - flag = 1; - } - if(date==null) - date = DDMONYYYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("DDMONYYYYHHMM")); - flag = 1; - } - if(date==null) - date = DDMONYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("DDMONYYHHMM")); - flag = 1; - } - if(date==null) - date = DDMONYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("DDMONYYYY")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMMSS")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMM")); - flag = 1; - } - if(date==null) - date = MMDDYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYY")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMM")); - flag = 1; - } - if(date==null) - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYHHMMSS")); - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMZFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMDDYYYYHHMMZ")); - flag = 1; - } - if(date==null) - date = MMMMMDDYYYYHHMMSS.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - cellStyle.setDataFormat(dateFormatMap.get("MMMMMDDYYYYHHMMSS")); - flag = 1; - } - - if(date!=null) { - //System.out.println("ExcelDate " + HSSFDateUtil.getExcelDate(date)); - Calendar cal=Calendar.getInstance(); - cal.setTime(date); - //sw.createCell(cellNum, cal,styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - //if(styleRowCell!=null) - sw.createCell(cellNum, cal, cellStyle.getIndex()); - //else if (styleCell!=null) - //sw.createCell(cellNum, cal, cellStyle.getIndex()); - //else - //sw.createCell(cellNum, cal, cellStyle.getIndex()); - } else { - //cell.getCellStyle().setDataFormat((short)0); - //if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(value), cellStyle.getIndex()); - //else if (styleCell!=null) - //sw.createCell(cellNum, Utils.excelEncode(value), cellStyle.getIndex()); - //else - //sw.createCell(cellNum, Utils.excelEncode(value), cellStyle.getIndex()); - - } - //cellDate.setCellValue(date); - //cellDate.setCellValue(value); //cellDate.setCellValue(date); - //cellDate.setCellValue(dv.getDisplayValue()); - - } else if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - //cellNumber = row.createCell((short) cellNum); - //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - //cellNumber.setCellValue(dv.getDisplayValue()); - int zInt = 0; - if (value.equals("null")){ - if(styleRowCell!=null) - sw.createCell(cellNum, zInt, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, zInt, styleCell.getIndex()); - else - sw.createCell(cellNum, zInt, styleDefaultCell.getIndex()); - - } else { - - if ((value.indexOf("."))!= -1){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempDollar = value.trim(); - tempDollar = tempDollar.replaceAll(" ", "").substring(0); - tempDollar = tempDollar.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempDollar); - //System.out.println("Before copy Value |" + tempDollar); - //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); - //System.out.println("After copy Value |" + tempDollar); - if ((tempDollar.indexOf(","))!= -1){ - tempDollar = tempDollar.replaceAll(",", ""); - } - //System.out.println("The final string 2IF is "+tempDollar); - double tempDoubleDollar = 0.0; - try { - tempDoubleDollar = Double.parseDouble(tempDollar); - if(styleRowCell!=null) - sw.createCell(cellNum, tempDoubleDollar,styleRowCell.getIndex() ); - else if (styleCell!=null) - sw.createCell(cellNum, tempDoubleDollar, styleCell.getIndex()); - else - sw.createCell(cellNum, tempDoubleDollar, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } - - - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempDoubleStr = value.trim(); - tempDoubleStr = tempDoubleStr.replaceAll(" ", "").substring(0); - if ((tempDoubleStr.indexOf(","))!= -1){ - tempDoubleStr = tempDoubleStr.replaceAll(",", ""); - } - double tempDouble = 0.0; - try { - tempDouble = Double.parseDouble(tempDoubleStr); - if(styleRowCell!=null) - sw.createCell(cellNum, tempDouble, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempDouble, styleCell.getIndex()); - else - sw.createCell(cellNum, tempDouble, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } - } - - }else { - if (!(value.equals(""))){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempInt = value.trim(); - tempInt = tempInt.replaceAll(" ", "").substring(0); - tempInt = tempInt.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempInt); - //System.out.println("Before copy Value |" + tempInt); - //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); - //System.out.println("After copy Value |" + tempInt); - if ((tempInt.indexOf(","))!= -1){ - tempInt = tempInt.replaceAll(",", ""); - } - //System.out.println("The final string INT 2 is "+tempInt); - - Long tempIntDollar = 0L; - - try { - tempIntDollar = Long.parseLong(tempInt); - if(styleRowCell!=null) - sw.createCell(cellNum, tempIntDollar,styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempIntDollar,styleCell.getIndex()); - else - sw.createCell(cellNum, tempIntDollar,styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempInt), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempInt),styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempInt), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempStr = value.trim(); - if ((tempStr.indexOf(","))!= -1){ - tempStr = tempStr.replaceAll(",", ""); - } - Long temp = 0L; - - try { - temp = Long.parseLong(tempStr); - if(styleRowCell!=null) - sw.createCell(cellNum, temp, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, temp, styleCell.getIndex()); - else - sw.createCell(cellNum, temp, styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempStr), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempStr), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempStr), styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - - } - } - } else { - sw.createCell(cellNum, "", styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - } - } - } - - - } - else { - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("General")); - if(styleRowCell!=null) - sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styleCell.getIndex()); - else { - if(nvl(value).startsWith(" ")) - sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styles.get(nvl(/*dv.getFormatId(),*/"","defaultLeft")).getIndex()); - else - sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - - } - - } - - if (dv.isBold()) { - if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //cell.setCellStyle(styleCurrencyTotal); - } - else { - //cell.setCellStyle(styleTotal); - } - } else { - //cell.setCellStyle(styleDefaultTotal); - } - bold = true; - } - //System.out.println("2IF "+ (dr.isRowFormat()) + " " + (dv.isCellFormat()) + " " + (styles!=null)); - if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) { - //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); - continue; - } - //System.out.println("3IF "+ (htmlFormat != null) + " " + (dv.getFormatId() != null) + " " + (bold == false) + " "+ (styles != null)); - if (htmlFormat != null && dv.getFormatId() != null && bold == false - && styles != null) { - //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(/*dv.getFormatId()*/"","default"))); - } //else if (bold == false) - //cell.setCellStyle(styleDefault); - } // dv.isVisible - - } - rowNum += 1; - sw.endRow(); - - } - if(rd.reportTotalRowHeaderCols!=null) { - rowCount++; - sw.insertRow(rowNum); - cellNum = -1; - rd.reportTotalRowHeaderCols.resetNext(); - cellNum += 1; - RowHeaderCol rhc = rd.reportTotalRowHeaderCols.getNext(); - RowHeader rh = rhc.getRowHeader(0); - if (dr.isRowFormat() && styles != null) - styleRowCell = (XSSFCellStyle) styles.get(nvl(/*dr.getFormatId(),*/"","default")); - - if(styleRowCell!=null) - sw.createCell(cellNum, strip.stripHtml(rh.getRowTitle()), styleRowCell.getIndex()); - else - sw.createCell(cellNum, strip.stripHtml(rh.getRowTitle()), styleDefaultCell.getIndex()); - rd.reportDataTotalRow.resetNext(); - //rd.reportDataTotalRow.getNext(); - DataRow drTotal = rd.reportDataTotalRow.getNext(); - if(drTotal!=null) { - drTotal.resetNext(); drTotal.getNext(); - for (; drTotal.hasNext();) { - DataValue dv = drTotal.getNext(); - if(dv.isVisible()) { - cellNum += 1; - styleCell = null; - String value = dv.getDisplayValue(); - sw.createCell(cellNum,value,styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - } - } - rowNum += 1; - sw.endRow(); - } - - - - - -/* // To Display Total Values for Linear report - if(rd.reportDataTotalRow!=null) { - row = sheet.createRow(rowNum); - cellNum = -1; - rd.reportTotalRowHeaderCols.resetNext(); - //for (rd.reportTotalRowHeaderCols.resetNext(); rd.reportTotalRowHeaderCols.hasNext();) { - cellNum += 1; - RowHeaderCol rhc = rd.reportTotalRowHeaderCols.getNext(); - RowHeader rh = rhc.getRowHeader(0); - row.createCell((short) cellNum).setCellValue(strip.stripHtml(rh.getRowTitle())); - row.getCell((short) cellNum).setCellStyle(styleDefaultTotal); - //} - - DataRow drTotal = rd.reportDataTotalRow.getNext(); - //cellNum = -1; - for (drTotal.resetNext(); drTotal.hasNext();j++) { - cellNum += 1; - cell = row.createCell((short) cellNum); - DataValue dv = drTotal.getNext(); - String value = dv.getDisplayValue(); - cell.setCellValue(value); - boolean bold = false; - if (dv.isBold()) { - if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - cell.setCellStyle(styleCurrencyTotal); - } else { - cell.setCellStyle(styleTotal); - } - } else { - cell.setCellStyle(styleDefaultTotal); - } - bold = true; - } - } - }*/ - - } catch (SQLException ex) { - throw new RaptorException(ex); - } catch (ReportSQLException ex) { - throw new RaptorException(ex); - } catch (Exception ex) { - if(!(ex.getCause() instanceof java.net.SocketException) ) - throw new RaptorException (ex); - } finally { - try { - if(conn!=null) - conn.close(); - if(st!=null) - st.close(); - if(rs!=null) - rs.close(); - } catch (SQLException ex) { - throw new RaptorException(ex); - } - } - - String footer = (String) session.getAttribute("FOOTER_"+index); - if(nvl(footer).length()>0) { - footer = Utils.replaceInString(footer, "
        ", " "); - footer = Utils.replaceInString(footer, "
        ", " "); - footer = Utils.replaceInString(footer, "
        ", " "); - footer = strip.stripHtml(nvl(footer).trim()); - rowNum += 1; - sw.insertRow(rowNum); - cellNum = 0; - sw.createCell(cellNum, footer.replaceAll("&", "&"), styleDefaultCell.getIndex()); - sw.endRow(); - rowNum += 1; - } - - if(Globals.getShowDisclaimer()) { - rowNum += 1; - sw.insertRow(rowNum); - cellNum = 0; - - sw.createCell(cellNum, org.openecomp.portalsdk.analytics.system.Globals.getFooterFirstLine().replaceAll("&", "&"), styleDefaultCell.getIndex()); - sw.endRow(); - rowNum += 1; - sw.insertRow(rowNum); - cellNum = 0; - sw.createCell(cellNum, org.openecomp.portalsdk.analytics.system.Globals.getFooterSecondLine().replaceAll("&", "&"), styleDefaultCell.getIndex()); - sw.endRow(); - } - - } else { - //start data from rd - - int rowCount = 0; - DataRow dr = null; - for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { - rowCount++; - - - dr = rd.reportDataRows.getNext(); - sw.insertRow(rowNum); - - cellNum = -1; - - if (rr.getReportType().equals(AppConstants.RT_LINEAR) && rd.reportTotalRowHeaderCols!=null) { - rd.reportRowHeaderCols.resetNext(0); - if(rd.reportTotalRowHeaderCols!=null) { - //cellNum = -1; - //for (rd.reportRowHeaderCols.resetNext(); rd.reportRowHeaderCols.hasNext();) { - //a commented to suppress rownum - //a cellNum += 1; - //RowHeaderCol rhc = rd.reportRowHeaderCols.getRowHeaderCol(0); - //if (firstPass) - // rhc.resetNext(); - //RowHeader rh = rhc.getRowHeader(rowCount-1); - //a sw.createCell(cellNum, rowCount, styleDefaultCell.getIndex()); - //} // for - } - - } - firstPass = false; - //cellNum = -1; - int j = 0; - - for (dr.resetNext(); dr.hasNext();j++) { - DataValue dv = dr.getNext(); - styleCell = null; - boolean bold = false; - String value = nvl(dv.getDisplayValue()); - value = strip.stripHtml(value); - HtmlFormatter htmlFormat = dv.getCellFormatter(); - if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) - styleCell = (XSSFCellStyle) styles.get(nvl(/*dr.getFormatId(),*/"","default")); - if (htmlFormat != null && dv.getFormatId() != null && styles != null) - styleCell = (XSSFCellStyle) styles.get(nvl(/*dv.getFormatId(),*/"","default")); - - if(dv.isVisible()) { - cellNum += 1; - //cell = row.createCell((short) cellNum); - //System.out.println("Stripping HTML 1"); - //cell.setCellValue(strip.stripHtml(value)); - String dataType = (String) (dataTypeMap.get(dv.getColId())); - //System.out.println(" The Display Value is ********"+value + " " + dv.getDisplayTotal() + " " + dv.getColName()); - - if (dataType!=null && dataType.equals("NUMBER")){ - //cellNumber = row.createCell((short) cellNum); - //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - //cellNumber.setCellValue(value); - //cellCurrencyNumber = row.createCell((short) cellNum); - int zInt = 0; - if (value.equals("null")){ - sw.createCell(cellNum,zInt,styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - }else{ - - if ((value.indexOf("."))!= -1){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempDollar = value.trim(); - tempDollar = tempDollar.replaceAll(" ", "").substring(0); - tempDollar = tempDollar.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempDollar); - //System.out.println("Before copy Value |" + tempDollar); - //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); - //System.out.println("After copy Value |" + tempDollar); - if ((tempDollar.indexOf(","))!= -1){ - tempDollar = tempDollar.replaceAll(",", ""); - } - //System.out.println("The final string 1 is "+tempDollar); - double tempDoubleDollar = 0.0; - try { - tempDoubleDollar = Double.parseDouble(tempDollar); - if(styleRowCell!=null) - sw.createCell(cellNum, tempDoubleDollar, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempDoubleDollar, styleCell.getIndex()); - else - sw.createCell(cellNum, tempDoubleDollar, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - double tempDouble = 0.0; - try { - tempDouble = Double.parseDouble(value); - if(styleRowCell!=null) - sw.createCell(cellNum, tempDouble, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempDouble, styleCell.getIndex()); - else - sw.createCell(cellNum, tempDouble, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(value),styleRowCell.getIndex() ); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(value), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(value), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - - } - }else { - if (!(value.equals(""))){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempInt = value.trim(); - tempInt = tempInt.replaceAll(" ", "").substring(0); - tempInt = tempInt.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempInt); - //System.out.println("Before copy Value |" + tempInt); - //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); - //System.out.println("After copy Value |" + tempInt); - if ((tempInt.indexOf(","))!= -1){ - tempInt = tempInt.replaceAll(",", ""); - } - //System.out.println("The final string INT is "+tempInt); - Long tempIntDollar = 0L; - try { - tempIntDollar = Long.parseLong(tempInt); - if(styleRowCell!=null) - sw.createCell(cellNum, tempIntDollar, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempIntDollar, styleCell.getIndex()); - else - sw.createCell(cellNum, tempIntDollar, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, tempInt, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempInt, styleCell.getIndex()); - else - sw.createCell(cellNum, tempInt, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempStr = value.trim(); - if ((tempStr.indexOf(","))!= -1){ - tempStr = tempStr.replaceAll(",", ""); - } - Long temp = 0L; - - try { - temp = Long.parseLong(tempStr); - if(styleRowCell!=null) - sw.createCell(cellNum, temp, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, temp, styleCell.getIndex()); - else - sw.createCell(cellNum, temp, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempStr), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempStr), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempStr), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - - - } - //int temp = Integer.parseInt(value.trim()); - // cell.setCellValue(temp); - //}else{ - // cell.setCellValue(strip.stripHtml(value)); - //} - } - } - } - - }else if ( ( dataType !=null && dataType.equals("DATE")) || (dv.getDisplayName()!=null && dv.getDisplayName().toLowerCase().endsWith("date")) || - (dv.getColId()!=null && dv.getColId().toLowerCase().endsWith("date")) || - (dv.getColName()!=null && dv.getColName().toLowerCase().endsWith("date")) ) { - Date date = null; - int flag = 0; - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = YYYYMMDDFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = timestampFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MONYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMMMMDDYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MONTHYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = YYYYMMDDHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = YYYYMMDDDASHFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = YYYYMMDDHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = DDMONYYYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = DDMONYYYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = DDMONYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = DDMONYYYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYHHMMFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYHHMMSSFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMDDYYYYHHMMZFormat.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - if(date==null) - date = MMMMMDDYYYYHHMMSS.parse(value, new ParsePosition(0)); - if(date != null && flag == 0) { - flag = 1; - } - - - if(date!=null) { - Calendar cal=Calendar.getInstance(); - cal.setTime(date); - //sw.createCell(cellNum, cal,styles.get(nvl(/*dv.getFormatId()*/"","default")).getIndex()); - if(styleRowCell!=null) - sw.createCell(cellNum, cal, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, cal, styleCell.getIndex()); - else - sw.createCell(cellNum, cal, styles.get(nvl(/*dv.getFormatId()*/"","date")).getIndex()); - - } else { - /*cell.getCellStyle().setDataFormat((short)0);*/ - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(value), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(value), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(value), styles.get(nvl(/*dv.getFormatId(),*/"","date")).getIndex()); - - } - //cellDate.setCellValue(date); - //cellDate.setCellValue(value); - - }else if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - //cellNumber = row.createCell((short) cellNum); - //cellNumber.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - //cellNumber.setCellValue(value); - int zInt = 0; - if (value.equals("null")){ - if(styleRowCell!=null) - sw.createCell(cellNum, zInt, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, zInt, styleCell.getIndex()); - else - sw.createCell(cellNum, zInt, styleDefaultCell.getIndex()); - } else { - - if ((value.indexOf("."))!= -1){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempDollar = value.trim(); - tempDollar = tempDollar.replaceAll(" ", "").substring(0); - tempDollar = tempDollar.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempDollar); - //System.out.println("Before copy Value |" + tempDollar); - //tempDollar = String.copyValueOf(tempDollar.toCharArray(), 1, tempDollar.length()-1); - //System.out.println("After copy Value |" + tempDollar); - if ((tempDollar.indexOf(","))!= -1){ - tempDollar = tempDollar.replaceAll(",", ""); - } - //System.out.println("The final string 2IF is "+tempDollar); - double tempDoubleDollar = 0.0; - try { - tempDoubleDollar = Double.parseDouble(tempDollar); - if(styleRowCell!=null) - sw.createCell(cellNum, tempDoubleDollar,styleRowCell.getIndex() ); - else if (styleCell!=null) - sw.createCell(cellNum, tempDoubleDollar, styleCell.getIndex()); - else - sw.createCell(cellNum, tempDoubleDollar, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempDollar), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - - - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempDoubleStr = value.trim(); - tempDoubleStr = tempDoubleStr.replaceAll(" ", "").substring(0); - if ((tempDoubleStr.indexOf(","))!= -1){ - tempDoubleStr = tempDoubleStr.replaceAll(",", ""); - } - double tempDouble = 0.0; - try { - tempDouble = Double.parseDouble(tempDoubleStr); - if(styleRowCell!=null) - sw.createCell(cellNum, tempDouble, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempDouble, styleCell.getIndex()); - else - sw.createCell(cellNum, tempDouble, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempDoubleStr), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - } - - }else { - if (!(value.equals(""))){ - if ((value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //if (value.startsWith("$")){ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("($#,##0.00);($#,##0.00)")); - String tempInt = value.trim(); - tempInt = tempInt.replaceAll(" ", "").substring(0); - tempInt = tempInt.replaceAll("\\$", "").substring(0); - //System.out.println("SUBSTRING |" + tempInt); - //System.out.println("Before copy Value |" + tempInt); - //tempInt = String.copyValueOf(tempInt.toCharArray(), 1, tempInt.length()-1); - //System.out.println("After copy Value |" + tempInt); - if ((tempInt.indexOf(","))!= -1){ - tempInt = tempInt.replaceAll(",", ""); - } - //System.out.println("The final string INT 2 is "+tempInt); - - Long tempIntDollar = 0L; - - try { - tempIntDollar = Long.parseLong(tempInt); - if(styleRowCell!=null) - sw.createCell(cellNum, tempIntDollar,styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, tempIntDollar,styleCell.getIndex()); - else - sw.createCell(cellNum, tempIntDollar,styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempInt), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempInt),styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempInt), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - }else{ - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00")); - String tempStr = value.trim(); - if ((tempStr.indexOf(","))!= -1){ - tempStr = tempStr.replaceAll(",", ""); - } - Long temp = 0L; - - try { - temp = Long.parseLong(tempStr); - if(styleRowCell!=null) - sw.createCell(cellNum, temp, styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, temp, styleCell.getIndex()); - else - sw.createCell(cellNum, temp, styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } catch (NumberFormatException ne) { - if(styleRowCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempStr), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, Utils.excelEncode(tempStr), styleCell.getIndex()); - else - sw.createCell(cellNum, Utils.excelEncode(tempStr), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - } - //int temp = Integer.parseInt(value.trim()); - // cell.setCellValue(temp); - //}else{ - // cell.setCellValue(strip.stripHtml(value)); - //} - } else { - sw.createCell(cellNum, "", styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - } - } - - - } - else { - //styleDefault.setDataFormat(HSSFDataFormat.getBuiltinFormat("General")); - if(styleRowCell!=null) - sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styleRowCell.getIndex()); - else if (styleCell!=null) - sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styleCell.getIndex()); - else - sw.createCell(cellNum, strip.stripHtml(Utils.excelEncode(value)), styles.get(nvl(/*dv.getFormatId(),*/"","default")).getIndex()); - } - - //if (!(value.equals(""))){ - //int temp = Integer.parseInt(value.trim()); - //cell.setCellValue(temp); - //}else{ - // cell.setCellValue(strip.stripHtml(value)); - //} - //HSSFCellStyle styleFormat = null; - //HSSFCellStyle numberStyle = null; - //HSSFFont formatFont = null; - //short fgcolor = 0; - //short fillpattern = 0; - //System.out.println("1IF "+ (dv.isBold()) + " "+ value + " " + dv.getDisplayTotal() + " " + dv.getColName() ); - if (dv.isBold()) { - if((dv.getDisplayTotal()!=null && dv.getDisplayTotal().equals("SUM(")) || (dv.getColName()!=null && dv.getColName().indexOf("999")!=-1)){ - if (value!=null && (value.trim().startsWith("$")) || (value.trim().startsWith("-$") )) { - //cell.setCellStyle(styleCurrencyTotal); - } - else { - //cell.setCellStyle(styleTotal); - } - } else { - //cell.setCellStyle(styleDefaultTotal); - } - bold = true; - } - //System.out.println("2IF "+ (dr.isRowFormat()) + " " + (dv.isCellFormat()) + " " + (styles!=null)); - if ((dr.isRowFormat() && !dv.isCellFormat()) && styles != null) { - //cell.setCellStyle((HSSFCellStyle) styles.get(nvl(dr.getFormatId(),"default"))); - continue; - } - //System.out.println("3IF "+ (htmlFormat != null) + " " + (dv.getFormatId() != null) + " " + (bold == false) + " "+ (styles != null)); - if (htmlFormat != null && dv.getFormatId() != null && bold == false - && styles != null) { - // cell.setCellStyle((HSSFCellStyle) styles.get(nvl(/*dv.getFormatId()*/"","default"))); - } //else if (bold == false) - //cell.setCellStyle(styleDefault); - } // if (dv.isVisible) - } // for - - /*for (int tmp=0; tmp0) { - footer = Utils.replaceInString(footer, "
        ", " "); - footer = Utils.replaceInString(footer, "
        ", " "); - footer = Utils.replaceInString(footer, "
        ", " "); - footer = strip.stripHtml(nvl(footer).trim()); - rowNum += 1; - sw.insertRow(rowNum); - cellNum = 0; - sw.createCell(cellNum, footer.replaceAll("&", "&"), styleDefaultCell.getIndex()); - sw.endRow(); - rowNum += 1; - } - - - if(Globals.getShowDisclaimer()) { - rowNum += 1; - sw.insertRow(rowNum); - cellNum = 0; - - sw.createCell(cellNum, org.openecomp.portalsdk.analytics.system.Globals.getFooterFirstLine().replaceAll("&", "&"), styleDefaultCell.getIndex()); - sw.endRow(); - rowNum += 1; - sw.insertRow(rowNum); - cellNum = 0; - sw.createCell(cellNum, org.openecomp.portalsdk.analytics.system.Globals.getFooterSecondLine().replaceAll("&", "&"), styleDefaultCell.getIndex()); - sw.endRow(); - } - - - } - // end data from rd - } - - // System.out.println(" Last Row " + wb.getSheetAt(0).getLastRowNum()); - } - - private void paintXSSFExcelParams(XSSFWorkbook wb,int rowNum,int col,ArrayList paramsList, String customizedParamInfo, XSSFSheet sheet, String reportTitle, String reportDescr) throws IOException { - //HSSFSheet sheet = wb.getSheet(getSheetName()); - int cellNum = 0; - XSSFRow row = null; - short s1 = 0, s2 = (short) 1; - HtmlStripper strip = new HtmlStripper(); - // Name Style - XSSFCellStyle styleName = wb.createCellStyle(); - //styleName.setFillBackgroundColor(HSSFColor.GREY_80_PERCENT.index); - styleName.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index); - //styleName.setFillPattern(HSSFCellStyle.SPARSE_DOTS); - styleName.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleName.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleName.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleName.setBorderRight(HSSFCellStyle.BORDER_THIN); - styleName.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleName.setDataFormat((short)0); - XSSFFont font = wb.createFont(); - font.setFontHeight((short) (font_size / 0.05)); - font.setFontName("Tahoma"); - font.setColor(HSSFColor.BLACK.index); - font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - styleName.setFont(font); - //Data Style - - // Create some fonts. - XSSFFont fontDefault = wb.createFont(); - // Initialize the styles & fonts. - // The default will be plain . - fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); - fontDefault.setFontHeight((short) (font_size / 0.05)); - fontDefault.setFontName("Tahoma"); - fontDefault.setItalic(true); - // Style default will be normal with no background - XSSFCellStyle styleValue = wb.createCellStyle(); - styleValue.setDataFormat((short)0); - styleValue.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleValue.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleValue.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleValue.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleValue.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleValue.setFillForegroundColor(HSSFColor.YELLOW.index); - styleValue.setFillPattern(HSSFCellStyle.NO_FILL); - styleValue.setFont(fontDefault); - XSSFCell cell = null; - XSSFCellStyle styleDescription = wb.createCellStyle(); - styleDescription.setAlignment(HSSFCellStyle.ALIGN_CENTER); -// styleDescription.setBorderBottom(HSSFCellStyle.BORDER_THIN); -// styleDescription.setBorderTop(HSSFCellStyle.BORDER_THIN); -// styleDescription.setBorderRight(HSSFCellStyle.BORDER_THIN); -// styleDescription.setBorderLeft(HSSFCellStyle.BORDER_THIN); - XSSFFont fontDescr = wb.createFont(); - fontDescr.setFontHeight((short) (font_header_descr_size / 0.05)); - fontDescr.setFontName("Tahoma"); - fontDescr.setColor(HSSFColor.BLACK.index); - fontDescr.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - styleDescription.setFont(font); - XSSFCell cellDescr = null; - int paramSeq = 0; - Header header = sheet.getHeader(); - StringBuffer strBuf = new StringBuffer(); - if(!Globals.customizeFormFieldInfo() || customizedParamInfo.length()<=0) { - for (Iterator iter = paramsList.iterator(); iter.hasNext();) { - IdNameValue value = (IdNameValue) iter.next(); - //System.out.println("\"" + value.getId() + " = " + value.getName() + "\""); - if(nvl(value.getId()).trim().length()>0 && (!nvl(value.getId()).trim().equals("BLANK"))) { - paramSeq += 1; - if(paramSeq <= 1) { - row = sheet.createRow(++rowNum); - cell = row.createCell((short) 0); - sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, s1, s2)); - cellDescr = row.createCell((short) 0); - cellDescr.setCellValue("Run-time Parameters"); - cellDescr.setCellStyle(styleDescription); - - - strBuf.append(reportTitle+"\n"); - //strBuf.append("Run-time Parameters\n"); - } - row = sheet.createRow(++rowNum); - cellNum = 0; - //System.out.println("RowNum " + rowNum + " " + value.getId() + " " +value.getName()); - cell = row.createCell((short) cellNum); - cell.setCellValue(value.getId()); - cell.setCellStyle(styleName); - cellNum += 1; - cell = row.createCell((short) cellNum); - cell.setCellValue(value.getName().replaceAll("~",",")); - cell.setCellStyle(styleValue); - - //strBuf.append(value.getId()+": "+ value.getName()+"\n"); - } - } //for - } else { - strBuf.append(reportTitle+"\n"); - Document document = new Document(); - document.open(); - HTMLWorker worker = new HTMLWorker(document); - StyleSheet style = new StyleSheet(); - style.loadTagStyle("body", "leading", "16,0"); - ArrayList p = HTMLWorker.parseToList(new StringReader(customizedParamInfo), style); - String name = ""; - String token = ""; - String value = ""; - String s = ""; - PdfPTable pdfTable = null; - for (int k = 0; k < p.size(); ++k){ - if(p.get(k) instanceof Paragraph) - s = ((Paragraph)p.get(k)).toString(); - else { /*if ((p.get(k) instanceof PdfPTable))*/ - pdfTable = ((PdfPTable)p.get(k)); - } - //todo: Logic for parsing pdfTable should be added after upgrading to iText 5.0.0 - //s = Utils.replaceInString(s, ",", "|"); - s = s.replaceAll(",", "|"); - s = s.replaceAll("~", ","); - if(s.indexOf(":")!= -1) { - //System.out.println("|"+s+"|"); - row = sheet.createRow(++rowNum); - cell = row.createCell((short) 0); - sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, s1, s2)); - cellDescr = row.createCell((short) 0); - cellDescr.setCellValue("Run-time Parameters"); - cellDescr.setCellStyle(styleDescription); - - //strBuf.append("Run-time Parameters\n"); - StringTokenizer st = new StringTokenizer(s.trim(), "|"); - while(st.hasMoreTokens()) { - token = st.nextToken(); - token = token.trim(); - if (!(token.trim().equals("|") || token.trim().equals("]]") || token.trim().equals("]") || token.trim().equals("[") )) { - if(token.endsWith(":")) { - name = token; - name = name.substring(0, name.length()-1); - if(name.startsWith("[")) - name = name.substring(1); - value = st.nextToken(); - if(nvl(value).endsWith("]"))value = nvl(value).substring(0, nvl(value).length()-1); - } /*else if(name != null && name.length() > 0) { - value = st.nextToken(); - if(value.endsWith("]]"))value = value.substring(0, value.length()-1); - }*/ - if(name!=null && name.trim().length()>0) { - row = sheet.createRow((short) ++rowNum); - cellNum = 0; - cell = row.createCell((short) cellNum); - cell.setCellValue(name.trim()); - cell.setCellStyle(styleName); - cellNum += 1; - cell = row.createCell((short) cellNum); - cell.setCellValue(value.trim()); - cell.setCellStyle(styleValue); - //strBuf.append(name.trim()+": "+ value.trim()+"\n"); - } -/* if(token.endsWith(":") && (value!=null && value.trim().length()<=0) && (name!=null && name.trim().length()>0 && name.endsWith(":"))) { - name = name.substring(0, name.indexOf(":")+1); - //value = token.substring(token.indexOf(":")+1); - row = sheet.createRow((short) ++rowNum); - cellNum = 0; - cell = row.createCell((short) cellNum); - cell.setCellValue(name.trim()); - cell.setCellStyle(styleName); - cellNum += 1; - cell = row.createCell((short) cellNum); - cell.setCellValue(value.trim()); - cell.setCellStyle(styleValue); - - //strBuf.append(name.trim()+": "+ value.trim()+"\n"); - value = ""; - name = ""; - } -*/ } - int cw = 0; - cw = name.trim().length() + 12; - // if(i!=cellWidth.size()-1) - if(sheet.getColumnWidth((short)0)< (short) name.trim().length()) - sheet.setColumnWidth((short)0, (short) name.trim().length()); - if(sheet.getColumnWidth((short)1)< (short) value.trim().length()) - sheet.setColumnWidth((short)1, (short) value.trim().length()); - name = ""; - value = ""; - - } - - try { - SimpleDateFormat oracleDateFormat = new SimpleDateFormat("MM/dd/yyyy kk:mm:ss"); - Date sysdate = oracleDateFormat.parse(ReportLoader.getSystemDateTime()); - SimpleDateFormat dtimestamp = new SimpleDateFormat(Globals.getScheduleDatePattern()); - - row = sheet.createRow((short) ++rowNum); - cellNum = 0; - cell = row.createCell((short) cellNum); - cell.setCellValue("Report Date/Time"); - cell.setCellStyle(styleName); - cellNum += 1; - cell = row.createCell((short) cellNum); - - cell.setCellValue(dtimestamp.format(sysdate)+" "+Globals.getTimeZone()); - cell.setCellStyle(styleValue); - - } catch(Exception ex) { - //ex.printStackTrace(); - } - - - } - } - - -/* Iterator iter1 = paramsList.iterator(); - s1 = 0; s2 = (short)10; - if(iter1.hasNext()) { - row = sheet.createRow((short) ++rowNum); - cellNum = 0; - cell = row.createCell((short) cellNum); - sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); - cell.setCellValue(strip.stripHtml(customizedParamInfo)); - } -*/ -/* rowNum += 2; - row = sheet.createRow(rowNum);*/ - } // if - Iterator iterCheck = paramsList.iterator(); - if(iterCheck.hasNext()) { - rowNum += 2; - row = sheet.createRow(rowNum); - } - header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) font_header_title_size)+strBuf.toString()); - } - - // Trying different --> - public void createHTMLFileContent(Writer out, ReportData rd, - ReportRuntime rr, String sql_whole, HttpServletRequest request, HttpServletResponse response) - throws RaptorException, IOException { - //response.setContentType("application/vnd.ms-excel"); - //response.setHeader("Content-disposition", - // "attachment; filename=" + - // "Example.xls" ); - PrintWriter csvOut = response.getWriter(); - HtmlStripper strip = new HtmlStripper(); - ResultSet rs = null; - Connection conn = null; - Statement st = null; - ResultSetMetaData rsmd = null; - ColumnHeaderRow chr = null; - int mb = 1024*1024; - Runtime runtime = Runtime.getRuntime(); - csvOut.println("\n" + - "" + rr.getReportName() + "\n" + - "\n" ); - System.out.println("HTML-Excel Generation Triggered: " + new java.util.Date()); - csvOut.print("
        ").addClass("node-cell").attr("colspan", 2); + var $childNodes = $node.children("ul:first").children("li"); + var $nodeDiv; + + if($childNodes.length > 1) { + $nodeCell.attr("colspan", $childNodes.length * 2); + } + // Draw the node + // Get the contents - any markup except li and ul allowed + var $nodeContent = $node.clone() + .children("ul,li") + .remove() + .end() + .html(); + + var new_node_id = $node.attr("id"); + if (typeof new_node_id !== 'undefined' && new_node_id !== false) { + $nodeDiv = $("
        ").addClass("node").attr("id", $node.attr("id")).append($nodeContent); + }else{ + $nodeDiv = $("
        ").addClass("node").append($nodeContent); + } + + // Expand and contract nodes + if ($childNodes.length > 0) { + $nodeDiv.click(function() { + var $this = $(this); + var $tr = $this.closest("tr"); + + if($tr.hasClass('contracted')){ + $this.css('cursor','n-resize'); + $tr.removeClass('contracted').addClass('expanded'); + $tr.nextAll("tr").css('visibility', ''); + }else{ + $this.css('cursor','s-resize'); + $tr.removeClass('expanded').addClass('contracted'); + $tr.nextAll("tr").css('visibility', 'hidden'); + } + }); + } + + $nodeCell.append($nodeDiv); + $nodeRow.append($nodeCell); + $tbody.append($nodeRow); + + if($childNodes.length > 0) { + // if it can be expanded then change the cursor + $nodeDiv.css('cursor','n-resize').addClass('expanded'); + + // recurse until leaves found (-1) or to the level specified + if(opts.depth == -1 || (level+1 < opts.depth)) { + var $downLineRow = $("
        ").attr("colspan", $childNodes.length*2); + $downLineRow.append($downLineCell); + + // draw the connecting line from the parent node to the horizontal line + $downLine = $("
        ").addClass("line down"); + $downLineCell.append($downLine); + $tbody.append($downLineRow); + + // Draw the horizontal lines + var $linesRow = $("
          
        "); + $td.attr("colspan", 2); + // recurse through children lists and items + buildNode($(this), $td, level+1, opts); + $childNodesRow.append($td); + }); + + } + $tbody.append($childNodesRow); + } + + // any classes on the LI element get copied to the relevant node in the tree + // apart from the special 'collapsed' class, which collapses the sub-tree at this point + if ($node.attr('class') != undefined) { + var classList = $node.attr('class').split(/\s+/); + $.each(classList, function(index,item) { + if (item == 'collapsed') { + $nodeRow.nextAll('tr').css('display', 'none'); + $nodeRow.removeClass('expanded'); + $nodeRow.addClass('contracted'); + $nodeDiv.css('cursor','s-resize'); + } else { + $nodeDiv.addClass(item); + } + }); + } + + $table.append($tbody); + $appendTo.append($table); + + /* Prevent trees collapsing if a link inside a node is clicked */ + $nodeDiv.children('a').click(function(e){ + console.log(e); + e.stopPropagation(); + }); + }; + +})(jQuery); diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/prettify.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/prettify.js new file mode 100644 index 00000000..eef5ad7e --- /dev/null +++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/org_chart/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p' + //+ '' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + ' ' + + '
        ' + + '
        ' + + ' ' + + ' ' + + ' ' + + '
        ' + + '
        ' + + '
        ' + + ' ' , + replace: true, + // restrict usage to element only since we use attributes for APIs + restrict: 'EA', + require: 'ngModel', + // new isolate scope + scope: { + mSearch : '=ngModel' + ,updateparent: '&' + ,jsonForOption : '=' + ,jsonForOperator : '=' + ,searchId : '=' + }, + link: function(scope, iElement, iAttrs){ + scope.optionsSizeArray = []; + scope.sId = ''; + //scope.options = JSON.parse(JSON.stringify(iAttrs.jsonForOption)); + //scope.operators = JSON.parse(iAttrs.operators); + + scope.$watch("jsonForOption", function(newval, oldval) { + scope.options = JSON.parse(JSON.stringify(oldval)); + console.log('1'); + scope.evalRepeatIndex(scope.options.length); + console.log('2'); + + }); + + scope.evalRepeatIndex = function(size){ + for(index = 0; index < size; index++) { + scope.optionsSizeArray.push(index); + } + }; + + scope.$watch("jsonForOperator", function(newval, oldval) { + scope.operators = JSON.parse(JSON.stringify(oldval)); + + }); + + if(getParameterByName("search")!=null && getParameterByName("search")!=''){ + if((getParameterByName("location")!=null && getParameterByName("location")!='')){ + scope.searchValue[0]=JSON.parse(JSON.stringify(getParameterByName("location"))); + scope.valueOptions[0]={index:0,value:'Location Name',title:"Location Name",alias:'Location Name'}; + scope.compareOptions[0]={index:1,value:'Contains',title:"Contains",alias:'Contains'}; + }else if((getParameterByName("userLastName")!=null && getParameterByName("userLastName")!='')){ + scope.searchValue[0]=JSON.parse(JSON.stringify(getParameterByName("userLastName"))); + scope.valueOptions[0]= {index: 0, value: 'Last Name', title: 'Last Name', alias:'Last Name'}; + scope.compareOptions[0]={index:1,value:'Contains',title:"Contains",alias:'Contains'}; + } + } + scope.$watch("searchId", function(newval, oldval) { + scope.sId = oldval; + scope.hideDiv(); + }); + + scope.showHide = function(div){ + if(div != 0){ + $("#s1").css('display', 'none'); + } + return true; + }; + + + scope.hideDiv = function(){ + console.log('3'); + console.log(scope.optionsSizeArray); + + + for (i = 1; i < scope.optionsSizeArray.length; i++) { + var element = "#"+scope.sId+i; + $(element).css('display', 'none'); + } + + console.log('4'); + + }; + + + $(function() { + scope.hideDiv(); + }); + + }, + + controller: function ($scope) { + + $scope.addSearch = function(searchId, index, optionsLength){ + console.log('5'); + + for(var i = 0; i<=optionsLength.length ;i++){ + var element = "#"+searchId+i; + if($(element).css('display') == 'none'){ + $(element).css('display', 'inline'); + break; + } + }; + console.log('6'); + + }; + + $scope.remove = function(searchId, index){ + var remove = "#"+searchId+index; + if(index!=0) + $(remove).css("display", "none"); + var v ={ + index: 0, + value: '', + title: 'Select', + alias:'' + }; + $scope.valueOptions[index]=v; + $scope.compareOptions[index]=v; + $scope.searchValue[index]=""; + }; + + $scope.search = function() { + var data = { + valueOptions : $scope.valueOptions, + compareOptions : $scope.compareOptions, + searchValue : $scope.searchValue + }; + }; + + var data = { + valueOptions : $scope.valueOptions, + compareOptions : $scope.compareOptions, + searchValue : $scope.searchValue + }; + + $scope.mSearch = data; + $scope.valueOptions=[]; + $scope.compareOptions=[]; + $scope.searchValue=[]; + } + } + + }); + + app.directive('phoneNumberMask', [function(){ + return { + restrict: 'A', + require: '?ngModel', + scope: { + ngModel : '=' + }, + link: function(scope, el, attrs){ + scope.$watch(attrs.phoneNumberMask, function(newValue, oldValue) { + + if(scope.ngModel) + scope.ngModel= scope.ngModel.replace(/(\+1)?(\d{3})(\d{3})(\d{4})/, '$2.$3.$4'); + $(el).mask("999.999.9999"); + }); + scope.$watch("ngModel", function() { + var current = $(el).val(); + if(scope.ngModel && /^(\+1)?\d{3,}$/.test(scope.ngModel)) + scope.ngModel= scope.ngModel.replace(/(\+1)?(\d{3})(\d{3})(\d{4})/, '$2.$3.$4'); + + }); + }, + }; + }]); + + app.directive('allowOnlyNumber', [function(){ + return { + require: 'ngModel', + link: function(scope, element, attrs, modelCtrl) { + modelCtrl.$parsers.push(function (inputValue) { + if (inputValue == undefined) return ''; + var transformedInput = inputValue.replace(/[^0-9]/g, ''); + if (transformedInput!=inputValue) { + modelCtrl.$setViewValue(transformedInput); + modelCtrl.$render(); + } + + return transformedInput; + }); + } + }; + }]); + + app.directive('showProcessing', function(){ + return { + restrict: 'A', + link: function(scope, elem, attrs) { + elem.bind('click', function() { + $(".overlayed").css("display","inline"); + $(".loadingId").css("display","inline"); + }); + } + } + }); + +app.directive("searchCriteria", function() { + return { + // replace custom element with html5 markup + template: '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + '
        ' + + ' ' + + '
        ' + + '
        ' + + '
        ' + + ' ' + + ' ' + + ' ' + + '
        ' + + '
        ' + + '
        ' , + replace: true, + // restrict usage to element only since we use attributes for APIs + restrict: 'EA', + require: 'ngModel', + // new isolate scope + scope: { + mSearch : '=ngModel', + updateparent: '&' + ,options : '=jsonForOption' + ,operators : '=jsonForOperator' + }, + + controller: function ($scope) { + $scope.isShown = [true]; + $scope.searchCriterion = []; + $scope.valueOptions=[]; + $scope.compareOptions=[]; + $scope.searchValue=[]; + $scope.availableOperators=[]; + $scope.availableValues=[]; + $scope.availableOptions = []; + //init + $scope.insertEmptyOption = function(arr){ + var hasEmpty = false; + $.each(arr, function(i, a){ + if(a.value ===''){ + hasEmpty = true; + } + }); + if(!hasEmpty){ + $.each(arr, function(i, a){ + a.index +=1; + }); + arr.unshift({index: 0, value: '', title: 'Select', alias:'Select'}); + } + }; + $scope.findFirstOption = function(arr){ + + }; + $scope.insertEmptyOption($scope.options); + $scope.insertEmptyOption($scope.operators); + + for(var i = 0, l= $scope.options.length; i 0){ + $.each($scope.valueOptions, function(i, a){ + if(a){ + var v = a.value; + if(v){ + var s= $.grep(selectedOptions, function(e){ return e.value === v }); + + if(s.length ===1){ + s[0].occurs += 1; + }else{ + selectedOptions.push({value: v, occurs:1}); + } + } + var o= $.grep($scope.options, function(e){ return e.value === v }); + if(o.length ===1){ + if("operators" in o[0]){ + $scope.availableOperators[i]=o[0].operators; + $scope.insertEmptyOption($scope.availableOperators[i]); + }else{ + $scope.availableOperators[i]=$scope.operators; + } + if("values" in o[0]){ + $scope.availableValues[i]=o[0].values; + }else{ + $scope.availableValues[i]=[]; + } + } + } + }); + for(var j = 0 , l = $scope.availableOptions.length; j 0 && s[0].occurs >= maxOccurs && ($scope.valueOptions[j] && $scope.valueOptions[j].value !== s[0].value)){// reach limit + }else{ + newOptions.push({index: aoi, value: a.value, title: a.title, alias:a.alias}); + aoi += 1; + } + }); + $scope.availableOptions[j] = newOptions; + if(isFirst){ + if($scope.availableValues[j].length>0) + $scope.searchValue[j]= $scope.availableValues[j][0]; + else + $scope.searchValue[j]=""; + + $scope.compareOptions[j]= $scope.availableOperators[j][0]; + } + }; + + } + if(typeof index !== 'undefined' && !isFirst){ + if($scope.availableValues[index].length>0) + $scope.searchValue[index]= $scope.availableValues[index][0]; + else + $scope.searchValue[index]=""; + } + }; + + $scope.updateAvailableOptions(undefined, true); + $.each($scope.availableOptions, function(j, a){ + $scope.valueOptions[j]= a[0]; + }); + $scope.addSearchCriteria = function(index){ + for(var i = 0 , l =$scope.isShown.length; i ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + '' + + '' + + ' ' + + '' + + ' ' + + ' ' + + '' + + '
        {{availableTitle}}{{userTitle}}
        ' + + '
        ' + + ' ' + + '
        ' + + '
        ' + + ' ' + + ' ' + + '

        ' + + ' ' + + '

        ' + + ' ' + + '

        ' + + ' ' + + '
        ' + + '
        ' + + ' ' + + '
        ' + + '
        ' + + '', + replace: true, + // restrict usage to element only since we use attributes for APIs + restrict: 'EA', + // new isolate scope + scope: { + chosenIds : '=assignedUsers' + ,availableUsers : '=' + ,userTitle : '=' + ,availableTitle : '=' + ,oneMax : '=?' + }, + link: function(scope, iElement, attrs){ + + scope.$watch("userTitle", function(newval, oldval) { + scope.userTitle = newval; + }); + scope.$watch("availableTitle", function(newval, oldval) { + scope.availableTitle = newval; + }); + + scope.$watch("availableUsers", function(newval, oldval) { + scope.availableUsers = newval; + scope.canditateIds= scope.getArrayRemoved(scope.availableUsers, scope.chosenIds); + }); + + }, + + controller: function ($scope) { + $scope.getArrayRemoved = function(from, removed){ + var retArray = (from)? from:[]; + if(retArray && retArray.length >0 && removed){ + for(var i = 0, l = removed.length; i= 0; i--){ + if(!$scope.chosenIds) + $scope.chosenIds=[]; + $scope.chosenIds.push(dataFromTableData[i]); + $scope.canditateIds.splice(i,1); + + } + var dataFromChoosonTable = $scope.chosenIds; + for (var i = dataFromChoosonTable.length - 1; i >= 0; i--){ + if(dataFromChoosonTable[i].available){ + $scope.chosenIds[i].available=false; + } + } + }; + + $scope.removeAll = function() { + var dataFromTableData = $scope.chosenIds; + for (var i = dataFromTableData.length - 1; i >= 0; i--){ + $scope.canditateIds.push(dataFromTableData[i]); + $scope.chosenIds.splice(i,1); + + } + var dataFromChoosonTable = $scope.canditateIds; + for (var i = dataFromChoosonTable.length - 1; i >= 0; i--){ + if(dataFromChoosonTable[i].available){ + $scope.canditateIds[i].available=false; + } + } + }; + + $scope.chooseSelected = function() { + + var dataFromTableData = $scope.canditateIds; + + for (var i = dataFromTableData.length - 1; i >= 0; i--){ + + if(dataFromTableData[i].available){ + if(!$scope.chosenIds) + $scope.chosenIds=[]; + $scope.chosenIds.push(dataFromTableData[i]); + $scope.canditateIds.splice(i,1); + + } + } + var dataFromChoosonTable = $scope.chosenIds; + for (var i = dataFromChoosonTable.length - 1; i >= 0; i--){ + if(dataFromChoosonTable[i].available){ + $scope.chosenIds[i].available=false; + } + } + }; + $scope.removeSelected = function() { + + var dataFromTableData = $scope.chosenIds; + + for (var i = dataFromTableData.length - 1; i >= 0; i--){ + if(dataFromTableData[i].available){ + $scope.canditateIds.push(dataFromTableData[i]); + $scope.chosenIds.splice(i,1); + + } + } ; + var dataFromChoosonTable = $scope.canditateIds; + for (var i = dataFromChoosonTable.length - 1; i >= 0; i--){ + if(dataFromChoosonTable[i].available){ + $scope.canditateIds[i].available=false; + } + } + }; + $scope.checkCanditate = function(index) { + if($scope.oneMax){ + for (var i = $scope.canditateIds.length - 1; i >= 0; i--){ + if(i != index) + $scope.canditateIds[i].available=false; + } + } + }; + + + } + } + }); + app.directive("selectString", function() { + return { + // replace custom element with html5 markup + template: '
        ' + + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '' + + '' + + '' + + ' ' + + '' + + ' ' + + ' ' + + '' + + '
        {{availableTitle}}{{assignedTitle}}
        ' + + '
        ' + + ' ' + + '
        ' + + '
        ' + + ' ' + + '

        ' + + ' ' + + '

        ' + + ' ' + + '

        ' + + ' ' + + '
        ' + + '
        ' + + ' ' + + '
        ' + + '
        ' + + '
        ', + replace: true, + // restrict usage to element only since we use attributes for APIs + restrict: 'EA', + // new isolate scope + scope: { + chosenIds : '=assignedOptions' + ,availableOptions : '=' + ,availableTitle : '@' + ,assignedTitle : '@' + }, + link: function(scope, iElement, attrs){ + scope.$watch("availableOptions", function(newval, oldval) { + scope.availableOptions = newval; + scope.canditateIds= scope.getArrayRemoved(scope.availableOptions, scope.chosenIds); + }); + + }, + + controller: function ($scope) { + $scope.getArrayRemoved = function(from, removed){ + var retArray = (from)? from:[]; + if(retArray && retArray.length >0 && removed){ + for(var i = 0, l = removed.length; i= 0; i--){ + if(!$scope.chosenIds) + $scope.chosenIds=[]; + $scope.chosenIds.push(dataFromTableData[i]); + $scope.canditateIds.splice(i,1); + + } + }; + + $scope.removeAll = function() { + var dataFromTableData = $scope.chosenIds; + for (var i = dataFromTableData.length - 1; i >= 0; i--){ + $scope.canditateIds.push(dataFromTableData[i]); + $scope.chosenIds.splice(i,1); + + } + }; + + $scope.chooseSelected = function() { + + var dataFromTableData = $scope.canditateIds; + + for (var i = dataFromTableData.length - 1; i >= 0; i--){ + + if(dataFromTableData[i].available){ + if(!$scope.chosenIds) + $scope.chosenIds=[]; + $scope.chosenIds.push(dataFromTableData[i]); + $scope.canditateIds.splice(i,1); + + } + } + }; + $scope.removeSelected = function() { + + var dataFromTableData = $scope.chosenIds; + + for (var i = dataFromTableData.length - 1; i >= 0; i--){ + if(dataFromTableData[i].available){ + $scope.canditateIds.push(dataFromTableData[i]); + $scope.chosenIds.splice(i,1); + + } + } ; + }; + + } + } + }); + function getParameterByName(name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), + results = regex.exec(location.search); + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); + }; + + app.directive("time", function() { + return { + // replace custom element with html5 markup + template: '
        ' + + ' ' + + '
        ' + + '
        ', + replace: true, + // restrict usage to element only since we use attributes for APIs + restrict: 'EA', + // new isolate scope + scope: { + value : '=' + ,validTime : '=?' + }, + link: function(scope, iElement, attrs){ + }, + + controller: function ($scope) { + $scope.timeStr=''; + $scope.ampm=null; + var am ={index: 0, value: 'AM', title: 'AM', alias:'Name2'}; + var pm = {index: 1, value: 'PM', title: 'PM', alias:'Name'}; + $scope.ampmOptions=[ + am, + pm, + ] + $scope.parseTimeStr= function(str){ + if(str){ + try{ + var date; + if(/^(\d*):(\d*)$/.test(str)){ + var hh = Number(str.match(/^(\d+)/)[1]); + var mm = Number(str.match(/:(\d+)/)[1]); + date = new Date(1970, 0, 1, hh, mm, 0); + }else{ + date = new Date(str); + } + var hours = date.getHours(); + var minutes = date.getMinutes(); + var ampm = hours >= 12 ?pm : am; + hours = hours % 12; + hours = hours ? hours : 12; // the hour '0' should be '12' + minutes = minutes < 10 ? '0'+minutes : minutes; + hours = hours < 10 ? '0'+hours : hours; + var strTime = hours + ':' + minutes ; + + + $scope.timeStr =strTime; + $scope.ampm = ampm; + if (typeof $scope.validTime != 'undefined'){ + $scope.validTime=true; + } + }catch(err){ + if (typeof $scope.validTime != 'undefined'){ + $scope.validTime=false; + } + } + }else{ + $scope.timeStr = "12:00"; + $scope.ampm =am; + } + }; + $scope.parseTimeStr($scope.value); + $scope.parseValue = function(){ + try{ + var date; + var hh = Number($scope.timeStr.match(/^(\d+)/)[1]); + var mm = Number($scope.timeStr.match(/:(\d+)/)[1]); + + if(hh<=12 && hh>0 && mm>=0 && mm<=59){ + + if($scope.ampm.value=='PM'&& hh<12) hh = hh+12; + if($scope.ampm.value=='AM'&& hh==12) hh = hh-12; + mm = mm < 10 ? '0'+mm : mm; + hh = hh < 10 ? '0'+hh : hh; + $scope.value= hh+":"+mm; + if (typeof $scope.validTime != 'undefined'){ + $scope.validTime=true; + } + }else{ + if (typeof $scope.validTime != 'undefined'){ + $scope.validTime=false; + } + } + + }catch(err){ + if (typeof $scope.validTime != 'undefined'){ + $scope.validTime=false; + } + } + }; + } + } + }); \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/.gitignore b/ecomp-sdk/epsdk-core/.gitignore new file mode 100644 index 00000000..aa0c881b --- /dev/null +++ b/ecomp-sdk/epsdk-core/.gitignore @@ -0,0 +1,5 @@ +/target +/bin/ +/.settings/ +.project +.classpath diff --git a/ecomp-sdk/epsdk-core/README.md b/ecomp-sdk/epsdk-core/README.md new file mode 100644 index 00000000..d2320a3d --- /dev/null +++ b/ecomp-sdk/epsdk-core/README.md @@ -0,0 +1,168 @@ +# ECOMP Portal SDK Core + +## Overview + +This is the Maven project for the ECOMP Portal SDK Core library, +which is distributed as epsdk-core-N.N.N.jar. This library +requires Hibernate and Spring, and provides many features +such as data access, session management, logging, on-boarding +and more. Most of these features are demonstrated in the +ECOMP SDK web application. + +## Release Notes + +### OpenECOMP Distributions + +Build 1.2.8, ?? ??? 2017 +* put new entries here * + +Build 1.2.7, 10 Apr 2017 +- Moved all annotated controllers to epsdk-common from epsdk-core +- Update shared context service for revised Portal endpoint path; drop separate property + +Build 1.2.6, 23 Mar 2017 +- DE273039 Adjust MenuListController to get OrgUserID from session, not cookie + +Build 1.2.5, 16 Mar 2017 +- No changes + +Build 1.2.4, 10 Mar 2017 +- No changes + +Build 1.2.3, 8 Mar 2017 +- No changes + +Build 1.2.2, 6 Mar 2017 +- US872039 Revise Element Map feature to drop absolute filesystem path in property file + +Build 1.2.1, 2 Mar 2017 +- US845636 Extend user-import controller to detect and return message on failure +- Move UEB/Cambria library and demonstration use classes into core (from FW) +- Exclude all log4j dependencies in core pom file +- Remove references to ATTUID in UserUtils.java comments +- Remove logback.xml from src/main/resources +- Extend HibernateMappingLocatable and HibernateConfiguration to allow config of packages to scan +- Extend MenuListController.java to send content-type application/json + +Build 1.2.0, 9 Feb 2017 +- Change group to org.openecomp.ecompsdkos; restart version numbering for open-source distribution + +### Closed-Source Distributions + +The following history is preserved for the benefit of partner application teams. + +Version 4.3.5, 2 Feb 2017 +- DE260606 Extend role controller to check existing roles when creating a new one + +Version 4.3.4 13 Jan 2017 +- No changes + +Version 4.3.3, 11 Jan 2017 +- DE239065 Adjust fix that initializes the start & stop timestamp on first call to loggers + +Version 4.3.2, 9 Jan 2017 +- DE261061 Remove System.out.println() debug output statements + +Version 4.3.1, 3 Jan 2017 +- DE239065 Initialize the start & stop timestamp on first call to the audit and metrics loggers + +Version 4.2.1, 15 Dec 2016 +- DE255409 trim trailing space on values fetched from Portal, System properties +- DE257028 add a constant value and modify the hibernate mapping to AuditLog class + +Version 4.1.4, 22 Nov 2016 +- DE250794 add trace-level logging methods to EELFLoggerDelegate +- US811188 add constants to AuditLog class + +Version 4.1.3, 14 Nov 2016 +- DE250319 All controllers that require user info should be Restricted within session +- Restore exclusion in pom to avoid pulling in outdated HttpServlet and other jars, + which cause compile errors in SDK-App depending on Maven repository contents. + +Version 4.1.2, 14 Nov 2016 +- US777777 enhance network map mime type in ElementModelController + +Version 4.1.1, 3 Nov 2016 +- No changes. + +Version 3.3.3, 13 Oct 2016 +- DE240192 show useful message if cache configuration file is missing +- DE238612 new property app\_base\_url for apps using WebJunction address + +Version 3.3.2, 26 Sep 2016 +- US710856 remove stray System.out.println statement and minor logging improvements. + +Version 3.3.1, 22 Sep 2016 +- DE224872 fix errors shown in browser on profile page +- Show Quantum license information at top-right of screen +- Moved R Notebook controllers to SDK-Workflow project +- US710856 updated aspect-oriented programming (AOP) logging support, + including the EELFLoggerDelegate and other classes. +- Updated favorites, functional menu, menu list, and profile controllers. +- Updated EELF Library to 0.0.5, the latest available version. +- US772823 Introduce Audit Log +- Remove some JFree code as open-source prep +- DE224872 fix errors shown in browser on profile page +- DE216279 fix behavior of pagination on profile page + +Version 3.2.2, 4 Aug 2016 +- New feature: R Cloud integration via a guard notebook +- New feature: fetch functional menu via REST +- Remove Spring annotation from OnBoardingApiServiceImpl class +- Extend EELFLoggerDelegate with methods that accept a throwable +- Revise logger to remove class name from MDC after logging +- DE215237, fix script error on menu admin page +- DE214174, refresh menu contents after edit +- Moved MockApplicationContextTestSuite class into core, out of sdk-app +- Support application name at top of left menu +- DE210771, fix the multiple/invalid role assignment behavior +- New class for the error message returned as JSON +- Return error as JSON in case of unauthenticated request +- Removed database creation scripts used by ECOMP Portal +- Improved the shared context feature + +Version 3.2.1, 12 Jul 2016 + - Use EELF loggers to be compliant with ECOMP project guidelines + - Log controller requests to the audit log + - Add alarm codes to the error log + - Correct popup issue in profile page + - Change the functional menu to show only user's first name + - Show 20 items by default in the functional menu + - Refresh the left menu after items are edited + - Correct problem that prevented deletion of a role + - Correct problem of missing country on Webphone import + - US693240, support link-only onboarding + - Extend logging to use instance_uuid from properties file + - Show favorites menu items + - Include logging ApplicationCodes.properties file in jar + - Use EELFLoggingDelegate to ensure class names are shown + - DE205174, correct problems in role functions + - Remove Apache commons logging + - Create new users as active (not inactive) + - Move database scripts for SDK-App out of core, into app + - Adjust OnBoardingApiServiceImpl to return null if user not found (for Portal) + - Fix ASE editor position + - Correct validation of menu entries + +Version 3.1.1, 15 Jun 2016 + - Add custom logging filter to reduce UEB logging quantity + - Fix admin/menu popup behavior + - Correct hibernate mapping for user class and table + +Version 2.2.0, 14 Jun 2016 + - Analytics and Workflow factored out of SDK-core library + - Add application logout feature + - Enhancements for DROOLS + - Move DROOLs files to core and add library to POM + - Revise logging for compliance with ECOMP guidelines + - Revise error responses from REST interface to be JSON + - Adjust HTML template for profile page + - Rename war directory to src/main/webapp + - Show error information if user is not found + - Split database scripts into Portal/SDK versions + - Add client for new shared context feature in Portal + - Revise favorites implementation to use app-to-app REST comms + - Exclude commons-logging and log4j libraries in POM + - Remove try/catch/discard block for exception in DataAccessServiceImpl + + diff --git a/ecomp-sdk/epsdk-core/license/licenses.properties b/ecomp-sdk/epsdk-core/license/licenses.properties new file mode 100644 index 00000000..4b0e28e7 --- /dev/null +++ b/ecomp-sdk/epsdk-core/license/licenses.properties @@ -0,0 +1 @@ +my_license=My license diff --git a/ecomp-sdk/epsdk-core/license/my_license/header.txt b/ecomp-sdk/epsdk-core/license/my_license/header.txt new file mode 100644 index 00000000..c026b6b7 --- /dev/null +++ b/ecomp-sdk/epsdk-core/license/my_license/header.txt @@ -0,0 +1,11 @@ +Licensed 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. diff --git a/ecomp-sdk/epsdk-core/license/my_license/license.txt b/ecomp-sdk/epsdk-core/license/my_license/license.txt new file mode 100644 index 00000000..bf326153 --- /dev/null +++ b/ecomp-sdk/epsdk-core/license/my_license/license.txt @@ -0,0 +1,4 @@ +name=my_license +description= +licenseURL= +headerURL= \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/pom.xml b/ecomp-sdk/epsdk-core/pom.xml new file mode 100644 index 00000000..354f9bb7 --- /dev/null +++ b/ecomp-sdk/epsdk-core/pom.xml @@ -0,0 +1,406 @@ + + + 4.0.0 + + + org.openecomp.ecompsdkos + epsdk-project + 1.1.0-SNAPSHOT + + + + epsdk-core + + jar + ECOMP Portal SDK Core + Core SDK library with controllers, interceptors, utilities, etc. + https://wiki.onap.org/display/DW/Portal + + + + 6.4.0.Final + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + ${skiptests} + + **/Test*.java + **/*Test.java + **/*TestCase.java + + + classpath: + + + + + + + + + + + + + + org.openecomp.ecompsdkos + epsdk-fw + ${project.version} + + + commons-logging + commons-logging + + + + + + + org.drools + drools-compiler + ${drools.version} + + + + + org.springframework + spring-core + ${springframework.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-web + ${springframework.version} + + + org.springframework + spring-webmvc + ${springframework.version} + + + org.springframework + spring-tx + ${springframework.version} + + + org.springframework + spring-context-support + ${springframework.version} + + + org.springframework + spring-orm + ${springframework.version} + + + org.springframework + spring-test + ${springframework.version} + + + org.springframework + spring-aop + ${springframework.version} + + + org.springframework.boot + spring-boot-starter + 1.3.0.RELEASE + + + org.slf4j + log4j-over-slf4j + + + ch.qos.logback + logback-classic + + + + + + org.aspectj + aspectjrt + 1.8.9 + + + + org.aspectj + aspectjweaver + 1.8.9 + + + + + + org.hibernate + hibernate-core + ${hibernate.version} + + + org.hibernate + hibernate-validator + 5.1.3.Final + + + + javax.servlet + javax.servlet-api + 3.1.0 + + + javax.servlet.jsp + javax.servlet.jsp-api + 2.3.1 + + + javax.servlet + jstl + 1.2 + + + + org.slf4j + jcl-over-slf4j + 1.7.12 + + + + org.slf4j + log4j-over-slf4j + 1.7.12 + + + com.mchange + c3p0 + 0.9.5.2 + + + + org.apache.tiles + tiles-core + 3.0.5 + + + org.apache.tiles + tiles-jsp + 3.0.5 + + + + org.yaml + snakeyaml + 1.15 + + + + com.fasterxml.jackson.core + jackson-annotations + 2.6.3 + + + com.fasterxml.jackson.core + jackson-core + 2.6.3 + + + com.fasterxml.jackson.core + jackson-databind + 2.6.3 + + + mysql + mysql-connector-java + 5.1.22 + + + + org.apache.jcs + jcs + 1.3 + + + * + * + + + + + + org.apache.tomcat + tomcat-websocket + 8.0.28 + provided + + + + concurrent + concurrent + 1.3.2 + + + * + * + + + + + + junit + junit + 4.12 + + + + + + commons-codec + commons-codec + 1.10 + + + commons-lang + commons-lang + 2.6 + + + + + org.quartz-scheduler + quartz + 2.2.1 + + + + c3p0 + c3p0 + + + + + + org.bouncycastle + bcprov-jdk16 + 1.45 + + + + + org.elasticsearch + elasticsearch + 2.2.0 + + + io.searchbox + jest + 2.0.0 + + + commons-logging + commons-logging + + + + + + com.att.eelf + eelf-core + 1.0.0 + + + + + com.att.nsa + cambriaClient + 0.0.1 + + + log4j + log4j + + + log4j + apache-log4j-extras + + + org.slf4j + slf4j-log4j12 + + + + + + + + diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/FusionObject.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/FusionObject.java new file mode 100644 index 00000000..8258913f --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/FusionObject.java @@ -0,0 +1,111 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core; + +/** + *

        + * Title: FusionObject + *

        + * + *

        + * Description: This interface is implemented by all top-level support classes + * of each package in FUSION. This allows all top-level support classes to have + * some commonality for easier maintenance. + *

        + * + *

        + * Copyright: Copyright (c) 2007 + *

        + * + * @version 1.1 + */ +public interface FusionObject { + + public class Parameters { + // HashMap parameters passed to the Service and Dao tiers + public static final String PARAM_USERID = "userId"; + public static final String PARAM_HTTP_REQUEST = "request"; + public static final String PARAM_FILTERS = "filters"; + public static final String PARAM_CLIENT_DEVICE = "client_device"; + // Request parameters passed in the Web tier + public static final String REQUEST_PARAM_DISPLAY_SUCCESS_MESSAGE = "display_success_message"; + } + + /** + *

        + * Title: FusionObject.Utilities + *

        + * + *

        + * Description: Inner class that has some utility functions available for + * any class that implements it. + *

        + * + *

        + * Copyright: Copyright (c) 2007 + *

        + * + * @version 1.1 + */ + public class Utilities { + /** + * nvl - replaces a string value with an empty string if null. + * + * @param s + * String - the string value that needs to be checked + * @return String - returns the original string value if not null. + * Otherwise an empty string ("") is returned. + */ + public static String nvl(String s) { + return (s == null) ? "" : s; + } + + /** + * nvl - replaces a string value with a default value if null. + * + * @param s + * String - the string value that needs to be checked + * @param sDefault + * String - the default value + * @return String - returns the original string value if not null. + * Otherwise the default value is returned. + */ + public static String nvl(String s, String sDefault) { + return nvl(s).equals("") ? sDefault : s; + } + + /** + * Tests the specified string for nullity. + * + * @param a + * String to test for nullity. + * @return True if the specified string is null, empty or the 4-character + * sequence "null" (ignoring case); otherwise false. + */ + public static boolean isNull(String a) { + if ((a == null) || (a.length() == 0) || a.equalsIgnoreCase("null")) + return true; + else + return false; + } + + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/auth/LoginStrategy.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/auth/LoginStrategy.java new file mode 100644 index 00000000..0378101a --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/auth/LoginStrategy.java @@ -0,0 +1,131 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.auth; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.openecomp.portalsdk.core.command.LoginBean; +import org.openecomp.portalsdk.core.menu.MenuProperties; +import org.openecomp.portalsdk.core.onboarding.exception.PortalAPIException; +import org.openecomp.portalsdk.core.onboarding.listener.PortalTimeoutHandler; +import org.openecomp.portalsdk.core.service.LoginService; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.web.support.AppUtils; +import org.openecomp.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.util.WebUtils; + +public abstract class LoginStrategy { + + public static final String DEFAULT_SUCCESS_VIEW = "welcome"; + public static final String DEFAULT_FAILURE_VIEW = "login"; + private static final String JSESSIONID = "JSESSIONID"; + + public static final String EP_SERVICE = "EPService"; + public static final String USER_ID = "UserId"; + public static final String ERROR_MESSAGE_KEY = "error"; + + @Autowired + private LoginService loginService; + + public abstract ModelAndView doLogin(HttpServletRequest request, HttpServletResponse response) throws Exception; + + public abstract String getUserId(HttpServletRequest request) throws PortalAPIException; + + public ModelAndView doExternalLogin(HttpServletRequest request, HttpServletResponse response) throws Exception { + + invalidateExistingSession(request); + + Map model = new HashMap(); + LoginBean commandBean = new LoginBean(); + String loginId = request.getParameter("loginId"); + String password = request.getParameter("password"); + commandBean.setLoginId(loginId); + commandBean.setLoginPwd(password); + HashMap additionalParamsMap = new HashMap(); + + // Get the client device type and pass it into LoginService for audit + // logging. + /** + * ClientDeviceType clientDevice = (ClientDeviceType)request.getAttribut + * (SystemProperties.getProperty(SystemProperties.CLIENT_DEVICE_ATTRIBUTE_NAME)); + * additionalParamsMap.put(Parameters.PARAM_CLIENT_DEVICE, + * clientDevice); + **/ + commandBean = loginService.findUser(commandBean, + (String) request.getAttribute(MenuProperties.MENU_PROPERTIES_FILENAME_KEY), additionalParamsMap); + + if (commandBean.getUser() == null) { + String loginErrorMessage = (commandBean.getLoginErrorMessage() != null) ? commandBean.getLoginErrorMessage() + : "login.error.external.invalid"; + model.put("error", loginErrorMessage); + + String[] errorCodes = new String[1]; + errorCodes[0] = loginErrorMessage; + + return new ModelAndView("login_external", "model", model); + + } else { + // store the currently logged in user's information in the session + UserUtils.setUserSession(request, commandBean.getUser(), commandBean.getMenu(), + commandBean.getBusinessDirectMenu(), + SystemProperties.getProperty(SystemProperties.LOGIN_METHOD_BACKDOOR)); + initateSessionMgtHandler(request); + + // user has been authenticated, now take them to the welcome page + // return new ModelAndView("redirect:/profile_search"); + return new ModelAndView("redirect:welcome.htm"); + + } + } + + protected void invalidateExistingSession(HttpServletRequest request){ + request.getSession().invalidate(); + } + + protected String getJessionId(HttpServletRequest request) { + Cookie ep = WebUtils.getCookie(request, JSESSIONID); + if (ep == null) { + return request.getSession().getId(); + } + return ep.getValue(); + + } + + protected void initateSessionMgtHandler(HttpServletRequest request) { + String jSessionId = getJessionId(request); + PortalTimeoutHandler.sessionCreated(jSessionId, jSessionId, AppUtils.getSession(request)); + } + + public LoginService getLoginService() { + return loginService; + } + + public void setLoginService(LoginService loginService) { + this.loginService = loginService; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/LoginBean.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/LoginBean.java new file mode 100644 index 00000000..37df8db1 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/LoginBean.java @@ -0,0 +1,193 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.command; + +import java.util.Set; + +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.domain.support.FusionCommand; + +public class LoginBean extends FusionCommand { + + private String loginId; + private String loginPwd; + private String hrid; + private String userid; + private String siteAccess; + private String loginErrorMessage; + + private User user; + @SuppressWarnings("rawtypes") + private Set menu; + @SuppressWarnings("rawtypes") + private Set businessDirectMenu; + + /** + * getLoginId + * + * @return String + */ + public String getLoginId() { + return loginId; + } + + /** + * getLoginPwd + * + * @return String + */ + public String getLoginPwd() { + return loginPwd; + } + + /** + * getMenu + * + * @return Set + */ + @SuppressWarnings("rawtypes") + public Set getMenu() { + return menu; + } + + /** + * getUser + * + * @return User + */ + public User getUser() { + return user; + } + + /** + * getHrid + * + * @return String + */ + public String getHrid() { + return hrid; + } + + /** + * getSiteAccess + * + * @return String + */ + public String getSiteAccess() { + return siteAccess; + } + + /** + * getBusinessDirectMenu + * + * @return Set + */ + @SuppressWarnings("rawtypes") + public Set getBusinessDirectMenu() { + return businessDirectMenu; + } + + /** + * getLoginErrorMessage + * + * @return String + */ + public String getLoginErrorMessage() { + return loginErrorMessage; + } + + /** + * setLoginId + * + * @param loginId String + */ + public void setLoginId(String loginId) { + this.loginId = loginId; + } + + /** + * setLoginPwd + * + * @param loginPwd String + */ + public void setLoginPwd(String loginPwd) { + this.loginPwd = loginPwd; + } + + @SuppressWarnings("rawtypes") + public void setMenu(Set menu) { + this.menu = menu; + } + + /** + * setUser + * + * @param user User + */ + public void setUser(User user) { + this.user = user; + } + + /** + * setHrid + * + * @param hrid String + */ + public void setHrid(String hrid) { + this.hrid = hrid; + } + + /** + * setSiteAccess + * + * @param siteAccess String + */ + public void setSiteAccess(String siteAccess) { + this.siteAccess = siteAccess; + } + + /** + * setBusinessDirectMenu + * + * @param businessDirectMenu Set + */ + @SuppressWarnings("rawtypes") + public void setBusinessDirectMenu(Set businessDirectMenu) { + this.businessDirectMenu = businessDirectMenu; + } + + /** + * setLoginErrorMessage + * + * @param loginErrorMessage String + */ + public void setLoginErrorMessage(String loginErrorMessage) { + this.loginErrorMessage = loginErrorMessage; + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/PostDroolsBean.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/PostDroolsBean.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/PostDroolsBean.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/PostDroolsBean.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/PostSearchBean.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/PostSearchBean.java new file mode 100644 index 00000000..68806b39 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/PostSearchBean.java @@ -0,0 +1,375 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.command; + +import java.util.List; + +import org.openecomp.portalsdk.core.command.support.SearchBase; +import org.openecomp.portalsdk.core.domain.User; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +@JsonSerialize +public class PostSearchBean extends SearchBase { + + private User user = null; + private User userOrig = null; + private String[] selected; + private String[] postHrid; + private String[] postOrgUserId; + private String[] postFirstName; + private String[] postLastName; + private String[] postOrgCode; + private String[] postPhone; + private String[] postEmail; + private String[] postAddress1; + private String[] postAddress2; + private String[] postCity; + private String[] postState; + private String[] postZipCode; + private String[] postLocationClli; + private String[] postBusinessCountryCode; + private String[] postBusinessCountryName; + private String[] postDepartment; + private String[] postDepartmentName; + private String[] postBusinessUnit; + private String[] postBusinessUnitName; + private String[] postJobTitle; + private String[] postOrgManagerUserId; + private String[] postCommandChain; + private String[] postCompanyCode; + private String[] postCompany; + private String[] postCostCenter; + private String[] postSiloStatus; + private String[] postFinancialLocCode; + + + @SuppressWarnings("rawtypes") + public PostSearchBean() { + this(null); + } // PostSearchBean + + @SuppressWarnings("rawtypes") + public PostSearchBean(List items) { + super(items); + + user = new User(); + userOrig = new User(); + + setSortBy1(""); + setSortBy1Orig(""); + + //setSortByList(...); + } // PostSearchBean + + + public String getFirstName() { return user.getFirstName(); } + public String getLastName() { return user.getLastName(); } + public String getHrid() { return user.getHrid(); } + public String getOrgUserId() { return user.getOrgUserId(); } + public String getOrgCode() { return user.getOrgCode(); } + public String getEmail() { return user.getEmail(); } + public String getOrgManagerUserId() { return user.getOrgManagerUserId(); } + + public String getFirstNameOrig() { return user.getFirstName(); } + public String getLastNameOrig() { return user.getLastName(); } + public String getHridOrig() { return user.getHrid(); } + public String getOrgUserIdOrig() { return user.getOrgUserId(); } + public String getOrgCodeOrig() { return user.getOrgCode(); } + public String getEmailOrig() { return user.getEmail(); } + public String getOrgManagerUserIdOrig() { return user.getOrgManagerUserId(); } + + + public User getUser() { return user; } + + public String[] getPostEmail() { + return postEmail; + } + + public String[] getPostFirstName() { + return postFirstName; + } + + public String[] getPostHrid() { + return postHrid; + } + + public String[] getPostLastName() { + return postLastName; + } + + public String[] getPostOrgCode() { + return postOrgCode; + } + + public String[] getPostPhone() { + return postPhone; + } + + public String[] getPostOrgUserId() { + return postOrgUserId; + } + + public String[] getSelected() { + return selected; + } + + public String[] getPostAddress1() { + return postAddress1; + } + + public String[] getPostBusinessCountryCode() { + return postBusinessCountryCode; + } + + public String[] getPostCity() { + return postCity; + } + + public String[] getPostCommandChain() { + return postCommandChain; + } + + public String[] getPostCompany() { + return postCompany; + } + + public String[] getPostCompanyCode() { + return postCompanyCode; + } + + public String[] getPostDepartment() { + return postDepartment; + } + + public String[] getPostDepartmentName() { + return postDepartmentName; + } + + public String[] getPostBusinessCountryName() { + return postBusinessCountryName; + } + + public String[] getPostJobTitle() { + return postJobTitle; + } + + public String[] getPostLocationClli() { + return postLocationClli; + } + + public String[] getPostOrgManagerUserId() { + return postOrgManagerUserId; + } + + public String[] getPostState() { + return postState; + } + + public String[] getPostZipCode() { + return postZipCode; + } + + public void setFirstName(String value) { user.setFirstName(value); } + public void setLastName(String value) { user.setLastName(value); } + public void setHrid(String value) { user.setHrid(value); } + public void setOrgUserId(String value) { user.setOrgUserId(value); } + public void setOrgCode(String value) { user.setOrgCode(value); } + public void setEmail(String value) { user.setEmail(value); } + public void setOrgManagerUserId(String value) { user.setOrgManagerUserId(value); } + + public void setFirstNameOrig(String value) { userOrig.setFirstName(value); } + public void setLastNameOrig(String value) { userOrig.setLastName(value); } + public void setHridOrig(String value) { userOrig.setHrid(value); } + public void setOrgUserIdOrig(String value) { userOrig.setOrgUserId(value); } + public void setOrgCodeOrig(String value) { userOrig.setOrgCode(value); } + public void setEmailOrig(String value) { userOrig.setEmail(value); } + public void setOrgManagerUserIdOrig(String value) { userOrig.setOrgManagerUserId(value); } + + public void setUser(User value) { this.user = value; } + + public void setPostEmail(String[] postEmail) { + this.postEmail = postEmail; + } + + public void setPostFirstName(String[] postFirstName) { + this.postFirstName = postFirstName; + } + + public void setPostHrid(String[] postHrid) { + this.postHrid = postHrid; + } + + public void setPostLastName(String[] postLastName) { + this.postLastName = postLastName; + } + + public void setPostOrgCode(String[] postOrgCode) { + this.postOrgCode = postOrgCode; + } + + public void setPostPhone(String[] postPhone) { + this.postPhone = postPhone; + } + + public void setPostOrgUserId(String[] postOrgUserId) { + this.postOrgUserId = postOrgUserId; + } + + public void setSelected(String[] selected) { + this.selected = selected; + } + + public void setPostAddress1(String[] postAddress1) { + this.postAddress1 = postAddress1; + } + + public void setPostBusinessCountryCode(String[] postBusinessCountryCode) { + this.postBusinessCountryCode = postBusinessCountryCode; + } + + public void setPostCity(String[] postCity) { + this.postCity = postCity; + } + + public void setPostCommandChain(String[] postCommandChain) { + this.postCommandChain = postCommandChain; + } + + public void setPostCompany(String[] postCompany) { + this.postCompany = postCompany; + } + + public void setPostCompanyCode(String[] postCompanyCode) { + this.postCompanyCode = postCompanyCode; + } + + public void setPostDepartment(String[] postDepartment) { + this.postDepartment = postDepartment; + } + + public void setPostDepartmentName(String[] postDepartmentName) { + this.postDepartmentName = postDepartmentName; + } + + public void setPostBusinessCountryName(String[] postBusinessCountryName) { + this.postBusinessCountryName = postBusinessCountryName; + } + + public void setPostJobTitle(String[] postJobTitle) { + this.postJobTitle = postJobTitle; + } + + public void setPostLocationClli(String[] postLocationClli) { + this.postLocationClli = postLocationClli; + } + + public void setPostOrgManagerUserId(String[] postOrgManagerUserId) { + this.postOrgManagerUserId = postOrgManagerUserId; + } + + public void setPostState(String[] postState) { + this.postState = postState; + } + + public void setPostZipCode(String[] postZipCode) { + this.postZipCode = postZipCode; + } + + public String[] getPostAddress2() { + return postAddress2; + } + + public void setPostAddress2(String[] postAddress2) { + this.postAddress2 = postAddress2; + } + + public User getUserOrig() { + return userOrig; + } + + public void setUserOrig(User userOrig) { + this.userOrig = userOrig; + } + + public String[] getPostBusinessUnit() { + return postBusinessUnit; + } + + public void setPostBusinessUnit(String[] postBusinessUnit) { + this.postBusinessUnit = postBusinessUnit; + } + + public String[] getPostBusinessUnitName() { + return postBusinessUnitName; + } + + public void setPostBusinessUnitName(String[] postBusinessUnitName) { + this.postBusinessUnitName = postBusinessUnitName; + } + + public String[] getPostCostCenter() { + return postCostCenter; + } + + public void setPostCostCenter(String[] postCostCenter) { + this.postCostCenter = postCostCenter; + } + + public String[] getPostSiloStatus() { + return postSiloStatus; + } + + public void setPostSiloStatus(String[] postSiloStatus) { + this.postSiloStatus = postSiloStatus; + } + + public String[] getPostFinancialLocCode() { + return postFinancialLocCode; + } + + public void setPostFinancialLocCode(String[] postFinancialLocCode) { + this.postFinancialLocCode = postFinancialLocCode; + } + + public void resetSearch() { + super.resetSearch(); + setUser(new User()); + } // resetSearch + + + public boolean isCriteriaUpdated() { + if(user==null&&userOrig==null) + return false; + else if(user==null||userOrig==null) + return true; + else + return (! ( + Utilities.nvl(user.getFirstName()).equals(Utilities.nvl(userOrig.getFirstName()))&& + Utilities.nvl(user.getLastName()).equals(Utilities.nvl(userOrig.getLastName()))&& + //Utilities.nvl(user.getHrid()).equals(Utilities.nvl(userOrig.getHrid()))&& + Utilities.nvl(user.getOrgUserId()).equals(Utilities.nvl(userOrig.getOrgUserId()))&& + Utilities.nvl(user.getOrgCode()).equals(Utilities.nvl(userOrig.getOrgCode()))&& + Utilities.nvl(user.getEmail()).equals(Utilities.nvl(userOrig.getEmail()))&& + Utilities.nvl(user.getOrgManagerUserId()).equals(Utilities.nvl(userOrig.getOrgManagerUserId()))&& + true)); + } // isCriteriaUpdated + +} // PostSearchBean diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/UserRowBean.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/UserRowBean.java new file mode 100644 index 00000000..fb6c2eab --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/UserRowBean.java @@ -0,0 +1,85 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.command; + +import org.openecomp.portalsdk.core.domain.User; + +public class UserRowBean extends User { + + /** + * + */ + private static final long serialVersionUID = -2724597119083972190L; + private String sessionId; + private String lastAccess; + private String remaining; + private String loginTime; + private String LastLoginTime; + + + public String getLastAccess(){ + return this.lastAccess; + } + + + public void setLastAccess(String lastAccess){ + this.lastAccess = lastAccess; + } + + + public String getRemaining(){ + return this.remaining; + } + + + public void setRemaining(String remaining){ + this.remaining = remaining; + } + + + public String getSessionId() { + return sessionId; + } + + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + + public String getLoginTime() { + return loginTime; + } + + + public void setLoginTime(String loginTime) { + this.loginTime = loginTime; + } + + + public String getLastLoginTime() { + return LastLoginTime; + } + + + public void setLastLoginTime(String lastLoginTime) { + LastLoginTime = lastLoginTime; + } +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/support/SearchBase.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/support/SearchBase.java new file mode 100644 index 00000000..f2f5408b --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/support/SearchBase.java @@ -0,0 +1,270 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.command.support; + +import java.util.*; + +import org.openecomp.portalsdk.core.domain.support.FusionCommand; + +public abstract class SearchBase extends FusionCommand { + + public static String SORT_BY_MODIFIER_DESC = "D"; + public static String SORT_BY_MODIFIER_ASC = "A"; + public static String SORT_BY_MODIFIER_DESC_IMAGE_NAME = "sort_desc.gif"; + public static String SORT_BY_MODIFIER_ASC_IMAGE_NAME = "sort_asc.gif"; + + + private String sortBy1 = null; + private String sortBy2 = null; + private String sortBy3 = null; + + private String sortBy1Orig = null; + private String sortBy2Orig = null; + private String sortBy3Orig = null; + + private String sortByModifier1 = null; + private String sortByModifier2 = null; + private String sortByModifier3 = null; + + private String sortByModifier1Orig = null; + private String sortByModifier2Orig = null; + private String sortByModifier3Orig = null; + + private String accessType = "WRITE"; //null; + + private String submitAction = ""; + private String masterId = ""; + private String detailId = ""; + + private String showResult = "Y"; + + private SearchResult searchResult = null; + private boolean sortingUpdated; + + @SuppressWarnings("rawtypes") + public SearchBase(List items) { + searchResult = (items == null) ? (new SearchResult()) : (new SearchResult(items)); + } // SearchBase + + + public String getSortBy1() { + return sortBy1; + } + + public String getSortBy2() { + return sortBy2; + } + + public String getSortBy3() { + return sortBy3; + } + + public String getSortBy1Orig() { + return sortBy1; + } + + public String getSortBy2Orig() { + return sortBy2; + } + + public String getSortBy3Orig() { + return sortBy3; + } + + public String getAccessType() { + return accessType; + } + + public String getSubmitAction() { + return submitAction; + } + + public String getMasterId() { + return masterId; + } + + public String getDetailId() { + return detailId; + } + + public String getShowResult() { + return showResult; + } + + //public ArrayList getSortByList() { return sortByList; } + + public SearchResult getSearchResult() { + return searchResult; + } + + public String getSortByModifier1() { + return sortByModifier1; + } + + public String getSortByModifier1Orig() { + return sortByModifier1; + } + + public String getSortByModifier2() { + return sortByModifier2; + } + + public String getSortByModifier2Orig() { + return sortByModifier2; + } + + public String getSortByModifier3() { + return sortByModifier3; + } + + public String getSortByModifier3Orig() { + return sortByModifier3; + } + + public int getPageNo() { + return (isCriteriaUpdated() || isSortingUpdated()) ? 0 : getSearchResult().getPageNo(); + } + + public int getPageSize() { + return getSearchResult().getPageSize(); + } + + public int getDataSize() { + return getSearchResult().getDataSize(); + } + + public int getNewDataSize() { + return isCriteriaUpdated() ? -1 : getDataSize(); + } + + + public void setSortBy1(String sortBy1) { + this.sortBy1 = sortBy1; + } + + public void setSortBy2(String sortBy2) { + this.sortBy2 = sortBy2; + } + + public void setSortBy3(String sortBy3) { + this.sortBy3 = sortBy3; + } + + public void setSortBy1Orig(String sortBy1Orig) { + this.sortBy1Orig = sortBy1Orig; + } + + public void setSortBy2Orig(String sortBy2Orig) { + this.sortBy2Orig = sortBy2Orig; + } + + public void setSortBy3Orig(String sortBy3Orig) { + this.sortBy3Orig = sortBy3Orig; + } + + public void setAccessType(String accessType) { + this.accessType = accessType; + } + + public void setSubmitAction(String submitAction) { + this.submitAction = submitAction; + } + + public void setMasterId(String masterId) { + this.masterId = masterId; + } + + public void setDetailId(String detailId) { + this.detailId = detailId; + } + + public void setShowResult(String showResult) { + this.showResult = showResult; + } + + public void setSearchResult(SearchResult searchResult) { + this.searchResult = searchResult; + } + + public void setSortByModifier1(String sortByModifier1) { + this.sortByModifier1 = sortByModifier1; + } + + public void setSortByModifier1Orig(String sortByModifier1Orig) { + this.sortByModifier1Orig = sortByModifier1Orig; + } + + public void setSortByModifier2(String sortByModifier2) { + this.sortByModifier2 = sortByModifier2; + } + + public void setSortByModifier2Orig(String sortByModifier2Orig) { + this.sortByModifier2Orig = sortByModifier2Orig; + } + + public void setSortByModifier3(String sortByModifier3) { + this.sortByModifier3 = sortByModifier3; + } + + public void setSortByModifier3Orig(String sortByModifier3Orig) { + this.sortByModifier3Orig = sortByModifier3Orig; + } + + public void setSortingUpdated(boolean sortingUpdated) { + this.sortingUpdated = sortingUpdated; + } + + public void setPageNo(int pageNo) { + getSearchResult().setPageNo(pageNo); + } + + public void setPageSize(int pageSize) { + getSearchResult().setPageSize(pageSize); + } + + public void setDataSize(int dataSize) { + getSearchResult().setDataSize(dataSize); + } + + + public void resetSearch() { + setSortBy1(null); + setSortBy2(null); + setSortBy3(null); + setSortByModifier1(SearchBase.SORT_BY_MODIFIER_ASC); + setSortByModifier2(SearchBase.SORT_BY_MODIFIER_ASC); + setSortByModifier3(SearchBase.SORT_BY_MODIFIER_ASC); + setPageNo(0); + setDataSize( -1); + } // resetSearch + + + public abstract boolean isCriteriaUpdated(); + + public boolean isSortingUpdated() { + return (!(Utilities.nvl(sortBy1).equals(Utilities.nvl(sortBy1Orig)) && + Utilities.nvl(sortBy2).equals(Utilities.nvl(sortBy2Orig)) && + Utilities.nvl(sortBy3).equals(Utilities.nvl(sortBy3Orig)) && + Utilities.nvl(sortByModifier1).equals(Utilities.nvl(sortByModifier1Orig)) && + Utilities.nvl(sortByModifier2).equals(Utilities.nvl(sortByModifier2Orig)) && + Utilities.nvl(sortByModifier3).equals(Utilities.nvl(sortByModifier3Orig)))); + } // isSortingUpdated + +} // SearchBase diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/support/SearchResult.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/support/SearchResult.java new file mode 100644 index 00000000..286b39cb --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/command/support/SearchResult.java @@ -0,0 +1,67 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.command.support; + +import java.util.*; + +@SuppressWarnings("rawtypes") +public class SearchResult extends ArrayList implements java.io.Serializable { + /** + * + */ + private static final long serialVersionUID = -451947878984459011L; + private int pageNo = 0; + private int pageSize = 50; + private int dataSize = -1; + + private String accessType = null; + + //private boolean empty = true; // Overrides collections [isEmpty] with searchResult present/not present logic + + + public SearchResult() {} + + @SuppressWarnings("unchecked") + public SearchResult(List items) { + super(items); + } // SearchResult + + /*public SearchResult(boolean empty) { + this(); + this.empty = empty; + } // SearchResult*/ + + + public int getPageNo() { return pageNo; } + public int getPageSize() { return pageSize; } + public int getDataSize() { return dataSize; } + + public int getSize() { return size(); } // for Struts bean property access + //public boolean isEmpty() { return empty; } + + public String getAccessType() { return accessType; } + + public void setPageNo(int pageNo) { this.pageNo=pageNo; } + public void setPageSize(int pageSize) { this.dataSize=pageSize; } + public void setDataSize(int dataSize) { this.dataSize=dataSize; } + + public void setAccessType(String accessType) { this.accessType = accessType; } + +} // SearchResult diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/AppConfig.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/AppConfig.java new file mode 100644 index 00000000..118b0e56 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/AppConfig.java @@ -0,0 +1,313 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.conf; + +import java.util.ArrayList; +import java.util.List; + +import javax.sql.DataSource; + +import org.openecomp.portalsdk.core.interceptor.ResourceInterceptor; +import org.openecomp.portalsdk.core.interceptor.SessionTimeoutInterceptor; +import org.openecomp.portalsdk.core.lm.FusionLicenseManager; +import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; +import org.openecomp.portalsdk.core.logging.format.AppMessagesEnum; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.menu.MenuBuilder; +import org.openecomp.portalsdk.core.onboarding.util.CipherUtil; +import org.openecomp.portalsdk.core.service.DataAccessService; +import org.openecomp.portalsdk.core.service.DataAccessServiceImpl; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.web.support.AppUtils; +import org.openecomp.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Bean; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.servlet.view.JstlView; +import org.springframework.web.servlet.view.UrlBasedViewResolver; +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; +import org.springframework.web.servlet.view.tiles3.TilesView; + +import com.mchange.v2.c3p0.ComboPooledDataSource; + +/** + * Configures Spring features in the ECOMP Portal SDK including request + * interceptors and view resolvers. Application should subclass and override + * methods as needed. + */ +public class AppConfig extends WebMvcConfigurerAdapter implements Configurable, ApplicationContextAware { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AppConfig.class); + + private final List tileDefinitions = new ArrayList(); + protected ApplicationContext appApplicationContext = null; + + public AppConfig() { + //loads all default fields and marks logging + //has been started for each log file type. + initGlobalLocalContext(); + } + + /** + * Creates and returns a new instance of a secondary (order=2) + * {@link ViewResolver} that finds files by adding prefix "/WEB-INF/jsp/" + * and suffix ".jsp" to the base view name. + * + * @return New instance of {@link ViewResolver}. + */ + @Bean + public ViewResolver viewResolver() { + InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); + viewResolver.setViewClass(JstlView.class); + viewResolver.setPrefix("/WEB-INF/jsp/"); + viewResolver.setSuffix(".jsp"); + viewResolver.setOrder(2); + return viewResolver; + } + + /** + * Loads all the default logging fields into the + * global MDC context and marks each log file type + * that logging has been started. + */ + private void initGlobalLocalContext() { + logger.init(); + } + + /* + * Any requests from the url pattern /static/**, Spring will look for the + * resources from the /static/ Same as in xml + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + // registry.addResourceHandler("/static/**").addResourceLocations("/static/"); + registry.addResourceHandler("/**").addResourceLocations("/"); + } + + /** + * Creates and returns a new instance of a {@link DataAccessService} class. + * + * @return New instance of {@link DataAccessService}. + */ + @Bean + public DataAccessService dataAccessService() { + return new DataAccessServiceImpl(); + } + + /** + * Creates and returns a new instance of a {@link SystemProperties} class. + * + * @return New instance of {@link SystemProperties}. + */ + @Bean + public SystemProperties systemProperties() { + return new SystemProperties(); + } + + /** + * Creates and returns a new instance of a {@link MenuBuilder} class. + * + * @return New instance of {@link MenuBuilder}. + */ + @Bean + public MenuBuilder menuBuilder() { + return new MenuBuilder(); + } + + /** + * Creates and returns a new instance of a {@link UserUtils} class. + * + * @return New instance of {@link UserUtils}. + */ + @Bean + public UserUtils userUtil() { + return new UserUtils(); + } + + /** + * Creates and returns a new instance of an {@link AppUtils} class. + * + * @return New instance of {@link AppUtils}. + */ + @Bean + public AppUtils appUtils() { + return new AppUtils(); + } + + /** + * Creates and returns a new instance of a {@link TilesConfigurer} class. + * + * @return New instance of {@link TilesConfigurer}. + */ + @Bean + public TilesConfigurer tilesConfigurer() { + TilesConfigurer tilesConfigurer = new TilesConfigurer(); + tilesConfigurer.setDefinitions(tileDefinitions()); + tilesConfigurer.setCheckRefresh(true); + return tilesConfigurer; + } + + /** + * + * Application Data Source + * + * @return DataSource Object + */ + + @Bean + public DataSource dataSource() throws Exception { + systemProperties(); + ComboPooledDataSource dataSource = new ComboPooledDataSource(); + try { + dataSource.setDriverClass(SystemProperties.getProperty(SystemProperties.DB_DRIVER)); + dataSource.setJdbcUrl(SystemProperties.getProperty(SystemProperties.DB_CONNECTIONURL)); + dataSource.setUser(SystemProperties.getProperty(SystemProperties.DB_USERNAME)); + // dataSource.setPassword(SystemProperties.getProperty(SystemProperties.DB_PASSWOR)); + String password = SystemProperties.getProperty(SystemProperties.DB_PASSWOR); + if (SystemProperties.containsProperty(SystemProperties.DB_ENCRYPT_FLAG)) { + String encryptFlag = SystemProperties.getProperty(SystemProperties.DB_ENCRYPT_FLAG); + if (encryptFlag != null && encryptFlag.equalsIgnoreCase("true")) { + password = CipherUtil.decrypt(password); + } + } + dataSource.setPassword(password); + dataSource + .setMinPoolSize(Integer.parseInt(SystemProperties.getProperty(SystemProperties.DB_MIN_POOL_SIZE))); + dataSource + .setMaxPoolSize(Integer.parseInt(SystemProperties.getProperty(SystemProperties.DB_MAX_POOL_SIZE))); + dataSource.setIdleConnectionTestPeriod( + Integer.parseInt(SystemProperties.getProperty(SystemProperties.IDLE_CONNECTION_TEST_PERIOD))); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "Error initializing database, verify database settings in properties file: " + + UserUtils.getStackTrace(e),AlarmSeverityEnum.CRITICAL); + logger.error(EELFLoggerDelegate.debugLogger, "Error initializing database, verify database settings in properties file: " + + UserUtils.getStackTrace(e),AlarmSeverityEnum.CRITICAL); + // Raise an alarm that opening a connection to the database is + // failed. + logger.logEcompError(AppMessagesEnum.BeDaoSystemError); + throw e; + } + return dataSource; + } + + /* + * TODO: Check whether it is appropriate to extend the list of tile + * definitions at every invocation. + */ + protected String[] tileDefinitions() { + tileDefinitions.add("/WEB-INF/fusion/defs/definitions.xml"); + tileDefinitions.addAll(addTileDefinitions()); + + return tileDefinitions.toArray(new String[0]); + } + + /** + * Creates and returns a new empty list. This method should be overridden by + * child classes. + * + * @return An empty list. + */ + public List addTileDefinitions() { + return new ArrayList(); + } + + /** + * Creates and returns a new instance of a primary (order=1) + * {@link UrlBasedViewResolver} that finds files using the contents of + * definitions.xml files. + * + * @return New instance of {@link UrlBasedViewResolver} + */ + @Bean + public UrlBasedViewResolver tileViewResolver() { + UrlBasedViewResolver viewResolver = new UrlBasedViewResolver(); + viewResolver.setViewClass(TilesView.class); + viewResolver.setOrder(1); + return viewResolver; + } + + /** + * Adds new instances of the following interceptors to the specified + * interceptor registry: {@link SessionTimeoutInterceptor}, + * {@link ResourceInterceptor} + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new SessionTimeoutInterceptor()) + .excludePathPatterns(getExcludeUrlPathsForSessionTimeout()); + registry.addInterceptor(resourceInterceptor()); + } + + /** + * Creates and returns a new instance of a {@link ResourceInterceptor}. + * + * @return New instance of {@link ResourceInterceptor} + */ + @Bean + public ResourceInterceptor resourceInterceptor() { + return new ResourceInterceptor(); + } + + private String[] excludeUrlPathsForSessionTimeout = {}; + + /** + * Gets the array of Strings that are paths excluded for session timeout. + * + * @return Array of String + */ + public String[] getExcludeUrlPathsForSessionTimeout() { + return excludeUrlPathsForSessionTimeout; + } + + /** + * Sets the array of Strings that are paths excluded for session timeout. + */ + public void setExcludeUrlPathsForSessionTimeout(final String... excludeUrlPathsForSessionTimeout) { + this.excludeUrlPathsForSessionTimeout = excludeUrlPathsForSessionTimeout; + } + + /** + * Creates and returns a new instance of a {@link FusionLicenseManager}. + * + * @return New instance of {@link FusionLicenseManager}. +// @Bean + public FusionLicenseManager fusionLicenseManager() { + return new FusionLicenseManager(new LicenseableClassImpl()); + } + */ + + /* + * (non-Javadoc) + * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + appApplicationContext = applicationContext; + + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/AppInitializer.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/AppInitializer.java new file mode 100644 index 00000000..82e449f1 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/AppInitializer.java @@ -0,0 +1,69 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.conf; + +import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +public abstract class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AppInitializer.class); + private final String activeProfile = "src"; + + @Override + protected WebApplicationContext createServletApplicationContext() { + WebApplicationContext context = super.createServletApplicationContext(); + + try { + + ((ConfigurableEnvironment) context.getEnvironment()).setActiveProfiles(activeProfile); + } catch (Exception e) { + + logger.error(EELFLoggerDelegate.errorLogger, "Unable to set the active profile" + e.getMessage(),AlarmSeverityEnum.MAJOR); + throw e; + + } + + return context; + } + + @Override + protected Class[] getRootConfigClasses() { + return null; + } + + @Override + protected Class[] getServletConfigClasses() { + + return new Class[] { AppConfig.class }; + } + + /* + * URL request will direct to the Spring dispatcher for processing + */ + @Override + protected String[] getServletMappings() { + return new String[] { "/" }; + } + +} \ No newline at end of file diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/Configurable.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/Configurable.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/Configurable.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/Configurable.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/HibernateConfiguration.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/HibernateConfiguration.java new file mode 100644 index 00000000..8a3459d1 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/HibernateConfiguration.java @@ -0,0 +1,139 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.conf; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.sql.DataSource; + +import org.hibernate.SessionFactory; +import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.orm.hibernate4.HibernateTransactionManager; +import org.springframework.orm.hibernate4.LocalSessionFactoryBean; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.mchange.v2.c3p0.ComboPooledDataSource; + +@Configuration +@EnableTransactionManagement +public class HibernateConfiguration { + + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(HibernateConfiguration.class); + + @Autowired + private HibernateMappingLocatable hbMappingLocatable; + + @Autowired + private DataSource dataSource; + + @Bean + public LocalSessionFactoryBean sessionFactory() { + LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(dataSource); + sessionFactory.setPackagesToScan(hbMappingLocatable.getPackagesToScan()); + sessionFactory.setHibernateProperties(getHibernateProperties()); + sessionFactory.setMappingLocations(hbMappingLocatable.getMappingLocations()); + return sessionFactory; + } + + /** + * Builds a properties object with Hibernate properties in te system.properties file. + * + * @return Properties object + */ + private Properties getHibernateProperties() { + Properties properties = new Properties(); + properties.put("hibernate.dialect", SystemProperties.getProperty(SystemProperties.HB_DIALECT)); + properties.put("hibernate.show_sql", SystemProperties.getProperty(SystemProperties.HB_SHOW_SQL)); + return properties; + } + + @SuppressWarnings("rawtypes") + @Bean + public Map dataSourceMap() throws Exception { + Connection conn = null; + Statement stmt = null; + Map dataSourceMap = new HashMap(); + + try { + conn = dataSource.getConnection(); + stmt = conn.createStatement(); + String sql; + sql = "SELECT schema_id,datasource_type,connection_url,user_name,password,driver_class,min_pool_size,max_pool_size,idle_connection_test_period FROM schema_info"; + ResultSet rs = stmt.executeQuery(sql); + + while (rs.next()) { + ComboPooledDataSource dataSource = new ComboPooledDataSource(); + dataSource.setDriverClass(rs.getString("driver_class")); + dataSource.setJdbcUrl(rs.getString("connection_url")); + dataSource.setUser(rs.getString("user_name")); + dataSource.setPassword(rs.getString("password")); + dataSource.setMinPoolSize(rs.getInt("min_pool_size")); + dataSource.setMaxPoolSize(rs.getInt("max_pool_size")); + dataSource.setIdleConnectionTestPeriod(rs.getInt("idle_connection_test_period")); + dataSourceMap.put(rs.getString("schema_id"), dataSource); + } + rs.close(); + stmt.close(); + conn.close(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, + "Error initializing database, verify database settings in properties file: " + e.getMessage(), + AlarmSeverityEnum.CRITICAL); + e.printStackTrace(); + dataSourceMap = null; + throw e; + } finally { + try { + if (stmt != null) + stmt.close(); + } catch (SQLException se2) { + } + try { + if (conn != null) + conn.close(); + } catch (SQLException se) { + se.printStackTrace(); + } + } + + return dataSourceMap; + } + + @Bean + @Autowired + public HibernateTransactionManager transactionManager(SessionFactory s) { + HibernateTransactionManager txManager = new HibernateTransactionManager(); + txManager.setSessionFactory(s); + return txManager; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/HibernateMappingLocatable.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/HibernateMappingLocatable.java new file mode 100644 index 00000000..94aed111 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/conf/HibernateMappingLocatable.java @@ -0,0 +1,43 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.conf; + +import org.springframework.core.io.Resource; + +/** + * Defines methods used by developers to supply Hibernate configuration. + */ +public interface HibernateMappingLocatable { + + /** + * Gets Hibernate mapping locations. + * + * @return Array of Resource objects (usually ClassPathResource that's a + * file) which contain Hibernate mapping information. + */ + public Resource [] getMappingLocations(); + + /** + * Gets package names. + * + * @return Array of Java package names to scan for classes with Hibernate annotations. + */ + public String [] getPackagesToScan(); +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FusionBaseController.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/controller/FusionBaseController.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FusionBaseController.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/controller/FusionBaseController.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedBaseController.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedBaseController.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedBaseController.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedBaseController.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedRESTfulBaseController.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedRESTfulBaseController.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedRESTfulBaseController.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/controller/RestrictedRESTfulBaseController.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/UnRestrictedBaseController.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/controller/UnRestrictedBaseController.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/UnRestrictedBaseController.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/controller/UnRestrictedBaseController.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/AbstractDao.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/AbstractDao.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/AbstractDao.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/AbstractDao.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDao.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDao.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDao.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDao.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDaoImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDaoImpl.java new file mode 100644 index 00000000..4dd2711e --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDaoImpl.java @@ -0,0 +1,51 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.dao; + +import java.util.List; + +import org.hibernate.Criteria; +import org.hibernate.criterion.Restrictions; +import org.openecomp.portalsdk.core.dao.AbstractDao; +import org.openecomp.portalsdk.core.domain.Profile; +import org.springframework.stereotype.Repository; + +@Repository("profileDao") +public class ProfileDaoImpl extends AbstractDao implements ProfileDao{ + + + public List findAll() { + Criteria crit = getSession().createCriteria(Profile.class); + @SuppressWarnings("unchecked") + List p = crit.list(); + + return p; + } + + + public Profile getProfile(int id) { + Criteria crit = getSession().createCriteria(Profile.class); + crit.add(Restrictions.eq("id", id)); + Profile profile = (Profile) crit.uniqueResult(); + + return profile; + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/hibernate/ModelOperationsCommon.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/hibernate/ModelOperationsCommon.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/hibernate/ModelOperationsCommon.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/hibernate/ModelOperationsCommon.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/support/FusionDao.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/support/FusionDao.java new file mode 100644 index 00000000..086a8da0 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/dao/support/FusionDao.java @@ -0,0 +1,36 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.dao.support; + +import org.hibernate.SessionFactory; + +import org.openecomp.portalsdk.core.FusionObject; + +public class FusionDao implements FusionObject { + private SessionFactory sessionFactory; + + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public SessionFactory getSessionFactory() { + return this.sessionFactory; + } +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/App.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/App.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/App.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/App.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/AuditLog.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/AuditLog.java new file mode 100644 index 00000000..1b1326b6 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/AuditLog.java @@ -0,0 +1,106 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain; + +import java.util.Date; + +import org.openecomp.portalsdk.core.domain.support.DomainVo; + +public class AuditLog extends DomainVo { + + /** + * + */ + private static final long serialVersionUID = 1L; + public static final String CD_ACTIVITY_LOGIN = "login"; + public static final String CD_ACTIVITY_LOGOUT = "logout"; + public static final String CD_ACTIVITY_MOBILE_LOGIN = "mobile_login"; + public static final String CD_ACTIVITY_MOBILE_LOGOUT = "mobile_logout"; + + /*-------Profile activities -----------*/ + public static final String CD_ACTIVITY_ROLE_ADD = "add_role"; + public static final String CD_ACTIVITY_ROLE_REMOVE = "remove_role"; + public static final String CD_ACTIVITY_CHILD_ROLE_ADD = "add_child_role"; + public static final String CD_ACTIVITY_CHILD_ROLE_REMOVE = "remove_child_role"; + public static final String CD_ACTIVITY_ROLE_ADD_FUNCTION = "add_role_function"; + public static final String CD_ACTIVITY_ROLE_REMOVE_FUNCTION = "remove_role_function"; + public static final String CD_ACTIVITY_USER_ROLE_ADD = "add_user_role"; + public static final String CD_ACTIVITY_USER_ROLE_REMOVE = "remove_user_role"; + + /*Audit activities*/ + public static final String CD_ACTIVITY_FUNCTIONAL_ACCESS = "functional_access"; + public static final String CD_ACTIVITY_TAB_ACCESS = "tab_access"; + public static final String CD_ACTIVITY_APP_ACCESS = "app_access"; + public static final String CD_ACTIVITY_LEFT_MENU_ACCESS = "left_menu_access"; + + + private String activityCode; + private String affectedRecordId; + private String comments; + private Date auditDate; + private Long userId; + + public AuditLog() { + setCreated(new Date()); + } + + public String getActivityCode() { + return activityCode; + } + + public String getComments() { + return comments; + } + + public String getAffectedRecordId() { + return affectedRecordId; + } + + public void setActivityCode(String activityCode) { + this.activityCode = activityCode; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public void setAffectedRecordId(String affectedRecordId) { + this.affectedRecordId = affectedRecordId; + } + + public Date getAuditDate() { + return auditDate; + } + + public void setAuditDate(Date auditDate) { + this.auditDate = auditDate; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/BroadcastMessage.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/BroadcastMessage.java new file mode 100644 index 00000000..42122dbd --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/BroadcastMessage.java @@ -0,0 +1,124 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain; + +import java.util.*; + +import org.openecomp.portalsdk.core.domain.support.DomainVo; + +public class BroadcastMessage extends DomainVo { + + /** + * + */ + + private static final long serialVersionUID = 1L; + public BroadcastMessage() { + } + + public static final String ID_MESSAGE_LOCATION_LOGIN = "10"; + public static final String ID_MESSAGE_LOCATION_WELCOME = "20"; + + private String messageText; + private Integer locationId; + private Date startDate; + private Date endDate; + private Integer sortOrder; + private Boolean active; + private String siteCd; + + public Boolean getActive() { + return active; + } + + public Date getEndDate() { + return endDate; + } + + public Integer getLocationId() { + return locationId; + } + + public String getMessageText() { + return messageText; + } + + public Integer getSortOrder() { + return sortOrder; + } + + public Date getStartDate() { + return startDate; + } + + public String getSiteCd() { + return siteCd; + } + + + public void setActive(Boolean active) { + this.active = active; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public void setLocationId(Integer locationId) { + this.locationId = locationId; + } + + public void setMessageText(String messageText) { + this.messageText = messageText; + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public void setSiteCd(String siteCd) { + this.siteCd = siteCd; + } + + + public int compareTo(Object obj){ + Integer c1 = getLocationId(); + Integer c2 = ((BroadcastMessage)obj).getLocationId(); + + if (c1.compareTo(c2) == 0) { + c1 = getSortOrder(); + c2 = ((BroadcastMessage)obj).getSortOrder(); + + if (c1.compareTo(c2) == 0) { + Long c3 = getId(); + Long c4 = ((BroadcastMessage)obj).getId(); + + return c3.compareTo(c4); + } + } + + return c1.compareTo(c2); + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/DomainVo.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/DomainVo.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/DomainVo.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/DomainVo.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/FnMenu.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/FnMenu.java new file mode 100644 index 00000000..d9aaf43d --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/FnMenu.java @@ -0,0 +1,141 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain; + + +import org.openecomp.portalsdk.core.domain.support.DomainVo; + +/** + *

        RoleFunction.java

        + * + *

        Represents a role function data object.

        + * + * @version 1.0 + */ +public class FnMenu extends DomainVo { + /** + * + */ + private static final long serialVersionUID = 1L; + public FnMenu() {} + + private Integer menuId; + private String label; + private Integer parentId; + private String action; + private String functionCd; + private Integer sortOrder; + private String servlet; + private String queryString; + private String externalUrl; + private String target; + private String active; + private String separator; + private String imageSrc; + private String menuSetCode; + + public Integer getMenuId() { + return menuId; + } + public void setMenuId(Integer menuId) { + this.menuId = menuId; + } + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + public Integer getParentId() { + return parentId; + } + public void setParentId(Integer parentId) { + this.parentId = parentId; + } + public String getAction() { + return action; + } + public void setAction(String action) { + this.action = action; + } + public String getFunctionCd() { + return functionCd; + } + public void setFunctionCd(String functionCd) { + this.functionCd = functionCd; + } + public Integer getSortOrder() { + return sortOrder; + } + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + public String getServlet() { + return servlet; + } + public void setServlet(String servlet) { + this.servlet = servlet; + } + public String getQueryString() { + return queryString; + } + public void setQueryString(String queryString) { + this.queryString = queryString; + } + public String getExternalUrl() { + return externalUrl; + } + public void setExternalUrl(String externalUrl) { + this.externalUrl = externalUrl; + } + public String getTarget() { + return target; + } + public void setTarget(String target) { + this.target = target; + } + public String getActive() { + return active; + } + public void setActive(String active) { + this.active = active; + } + public String getSeparator() { + return separator; + } + public void setSeparator(String separator) { + this.separator = separator; + } + public String getImageSrc() { + return imageSrc; + } + public void setImageSrc(String imageSrc) { + this.imageSrc = imageSrc; + } + public String getMenuSetCode() { + return menuSetCode; + } + public void setMenuSetCode(String menuSetCode) { + this.menuSetCode = menuSetCode; + } + + + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/FusionVo.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/FusionVo.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/FusionVo.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/FusionVo.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/LoginBean.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/LoginBean.java new file mode 100644 index 00000000..f20eb4a8 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/LoginBean.java @@ -0,0 +1,187 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain; + +import java.util.Set; + +import org.openecomp.portalsdk.core.domain.support.FusionCommand; + +@SuppressWarnings("rawtypes") +public class LoginBean extends FusionCommand { + + private String loginId; + private String loginPwd; + private String hrid; + private String orgUserId; + private String siteAccess; + private String loginErrorMessage; + + private User user; + private Set menu; + private Set businessDirectMenu; + + /** + * getLoginId + * + * @return String + */ + public String getLoginId() { + return loginId; + } + + /** + * getLoginPwd + * + * @return String + */ + public String getLoginPwd() { + return loginPwd; + } + + /** + * getMenu + * + * @return Set + */ + public Set getMenu() { + return menu; + } + + /** + * getUser + * + * @return User + */ + public User getUser() { + return user; + } + + /** + * getHrid + * + * @return String + */ + public String getHrid() { + return hrid; + } + + /** + * getSiteAccess + * + * @return String + */ + public String getSiteAccess() { + return siteAccess; + } + + /** + * getBusinessDirectMenu + * + * @return Set + */ + public Set getBusinessDirectMenu() { + return businessDirectMenu; + } + + /** + * getLoginErrorMessage + * + * @return String + */ + public String getLoginErrorMessage() { + return loginErrorMessage; + } + + public String getOrgUserId() { + return orgUserId; + } + + /** + * setLoginId + * + * @param loginId String + */ + public void setLoginId(String loginId) { + this.loginId = loginId; + } + + /** + * setLoginPwd + * + * @param loginPwd String + */ + public void setLoginPwd(String loginPwd) { + this.loginPwd = loginPwd; + } + + public void setMenu(Set menu) { + this.menu = menu; + } + + /** + * setUser + * + * @param user User + */ + public void setUser(User user) { + this.user = user; + } + + /** + * setHrid + * + * @param hrid String + */ + public void setHrid(String hrid) { + this.hrid = hrid; + } + + /** + * setSiteAccess + * + * @param siteAccess String + */ + public void setSiteAccess(String siteAccess) { + this.siteAccess = siteAccess; + } + + /** + * setBusinessDirectMenu + * + * @param businessDirectMenu Set + */ + public void setBusinessDirectMenu(Set businessDirectMenu) { + this.businessDirectMenu = businessDirectMenu; + } + + /** + * setLoginErrorMessage + * + * @param loginErrorMessage String + */ + public void setLoginErrorMessage(String loginErrorMessage) { + this.loginErrorMessage = loginErrorMessage; + } + + public void setOrgUserId(String orgUserId) { + this.orgUserId = orgUserId; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/Lookup.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/Lookup.java new file mode 100644 index 00000000..aa7d036c --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/Lookup.java @@ -0,0 +1,85 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain; + +import java.io.Serializable; + +import org.openecomp.portalsdk.core.domain.support.NameValueId; + +public class Lookup extends FusionVo implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private NameValueId nameValueId = new NameValueId(); + + public Lookup() {} + + public Lookup(String label, String value) { + this(); + setLabel(label); + setValue(value); + } + + public String getValue() { + return getNameValueId().getVal(); + } + + public String getLabel() { + return getNameValueId().getLab(); + } + + public void setValue(String value) { + getNameValueId().setVal(value); + } + + public void setLabel(String label) { + getNameValueId().setLab(label); + } + + public NameValueId getNameValueId() { + return nameValueId; + } + + public void setNameValueId(NameValueId nameValueId) { + this.nameValueId = nameValueId; + } + + // required by ZK for to set the selectedItems of Listboxes (used heavily for -style drop-downs) + public int hashCode() { + int hash = getUrl().hashCode(); + hash = hash + getFunctionCd().hashCode(); + + return hash; + } + + public boolean equals( Object obj ) { + boolean equivalent = false; + + UrlsAccessible lookup = (UrlsAccessible)obj; + if( lookup.getUrl().equals(getUrl()) && lookup.getFunctionCd().equals(getFunctionCd())) { + equivalent = true; + } + + return equivalent; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessibleKey.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessibleKey.java new file mode 100644 index 00000000..fc0b36ce --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessibleKey.java @@ -0,0 +1,90 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain; + +import java.io.*; + + +public class UrlsAccessibleKey implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String url; + private String functionCd; + + public UrlsAccessibleKey() { + } + + public UrlsAccessibleKey(String url, String functionCd) { + setUrl(url); + setFunctionCd(functionCd); + } + + + public String getUrl() { + return url; + } + + + public String getFunctionCd() { + return functionCd; + } + + + public void setUrl(String url) { + this.url = url; + } + + + public void setFunctionCd(String functionCd) { + this.functionCd = functionCd; + } + + + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null) { + return false; + } + + if (!(o instanceof UrlsAccessibleKey)) { + return false; + } + + final UrlsAccessibleKey key = (UrlsAccessibleKey)o; + + if (getFunctionCd().equals(key.getFunctionCd()) & getUrl().equals(key.getUrl())) { + return true; + } + + return false; + } + + + public int hashCode() { + return getUrl().hashCode() + getFunctionCd().hashCode(); + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/User.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/User.java new file mode 100644 index 00000000..06c4d59e --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/User.java @@ -0,0 +1,584 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain; + + +import java.util.Date; +import java.util.Iterator; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.openecomp.portalsdk.core.domain.support.DomainVo; + +/** + *

        User.java

        + * + *

        Represents a user data object.

        + * + * @version 1.0 + */ +public class User extends DomainVo { + + /** + * + */ + private static final long serialVersionUID = 1L; + private Long orgId; + private Long managerId; + private String firstName; + private String middleInitial; + private String lastName; + private String phone; + private String fax; + private String cellular; + private String email; + private Long addressId; + private String alertMethodCd; + private String hrid; + private String orgUserId; + private String orgCode; + private String address1; + private String address2; + private String city; + private String state; + private String zipCode; + private String country; + private String orgManagerUserId; + private String locationClli; + private String businessCountryCode; + private String businessCountryName; + private String businessUnit; + private String businessUnitName; + private String department; + private String departmentName; + private String companyCode; + private String company; + private String zipCodeSuffix; + private String jobTitle; + private String commandChain; + private String siloStatus; + private String costCenter; + private String financialLocCode; + + + + private String loginId; + private String loginPwd; + private Date lastLoginDate; + private boolean active; + private boolean internal; + private Long selectedProfileId; + private Long timeZoneId; + private boolean online; + private String chatId; + + private Set userApps = new TreeSet(); + + private Set pseudoRoles = new TreeSet(); + + + public User() {} + + public Long getAddressId() { + return addressId; + } + + public String getAlertMethodCd() { + return alertMethodCd; + } + + public String getCellular() { + return cellular; + } + + public String getEmail() { + return email; + } + + public String getFax() { + return fax; + } + + public String getFirstName() { + return firstName; + } + + public String getHrid() { + return hrid; + } + + public Date getLastLoginDate() { + return lastLoginDate; + } + + public String getLastName() { + return lastName; + } + + public String getFullName() { + return getFirstName() + " " + getLastName(); + } + + public String getLoginId() { + return loginId; + } + + public String getLoginPwd() { + return loginPwd; + } + + public Long getManagerId() { + return managerId; + } + + public String getMiddleInitial() { + return middleInitial; + } + + public String getOrgCode() { + return orgCode; + } + + public Long getOrgId() { + return orgId; + } + + public String getPhone() { + return phone; + } + + public String getOrgUserId() { + return orgUserId; + } + + public boolean getActive() { + return active; + } + + public boolean getInternal() { + return internal; + } + + public String getAddress1() { + return address1; + } + + public String getAddress2() { + return address2; + } + + public String getCity() { + return city; + } + + public String getCountry() { + return country; + } + + public String getState() { + return state; + } + + public String getZipCode() { + return zipCode; + } + + public String getBusinessCountryCode() { + return businessCountryCode; + } + + public String getCommandChain() { + return commandChain; + } + + public String getCompany() { + return company; + } + + public String getCompanyCode() { + return companyCode; + } + + public String getDepartment() { + return department; + } + + public String getJobTitle() { + return jobTitle; + } + + public String getLocationClli() { + return locationClli; + } + + public String getOrgManagerUserId() { + return orgManagerUserId; + } + + public String getZipCodeSuffix() { + return zipCodeSuffix; + } + + public String getBusinessCountryName() { + return businessCountryName; + } + + public Set getPseudoRoles() { + return pseudoRoles; + } + + public Long getSelectedProfileId() { + return selectedProfileId; + } + + public void setAddressId(Long addressId) { + this.addressId = addressId; + } + + public void setAlertMethodCd(String alertMethodCd) { + this.alertMethodCd = alertMethodCd; + } + + public void setCellular(String cellular) { + this.cellular = cellular; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setFax(String fax) { + this.fax = fax; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public void setHrid(String hrid) { + this.hrid = hrid; + } + + public void setLastLoginDate(Date lastLoginDate) { + this.lastLoginDate = lastLoginDate; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public void setLoginId(String loginId) { + this.loginId = loginId; + } + + public void setLoginPwd(String loginPwd) { + this.loginPwd = loginPwd; + } + + public void setManagerId(Long managerId) { + this.managerId = managerId; + } + + public void setMiddleInitial(String middleInitial) { + this.middleInitial = middleInitial; + } + + public void setOrgCode(String orgCode) { + this.orgCode = orgCode; + } + + public void setOrgId(Long orgId) { + this.orgId = orgId; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public void setOrgUserId(String orgUserId) { + this.orgUserId = orgUserId; + } + + public void setActive(boolean active) { + this.active = active; + } + + public void setInternal(boolean internal) { + this.internal = internal; + } + + public void setAddress1(String address1) { + this.address1 = address1; + } + + public void setAddress2(String address2) { + this.address2 = address2; + } + + public void setCity(String city) { + this.city = city; + } + + public void setCountry(String country) { + this.country = country; + } + + public void setState(String state) { + this.state = state; + } + + public void setZipCode(String zipCode) { + this.zipCode = zipCode; + } + + public void setBusinessCountryCode(String businessCountryCode) { + this.businessCountryCode = businessCountryCode; + } + + public void setCommandChain(String commandChain) { + this.commandChain = commandChain; + } + + public void setCompany(String company) { + this.company = company; + } + + public void setCompanyCode(String companyCode) { + this.companyCode = companyCode; + } + + public void setDepartment(String department) { + this.department = department; + } + + public void setJobTitle(String jobTitle) { + this.jobTitle = jobTitle; + } + + public void setLocationClli(String locationClli) { + this.locationClli = locationClli; + } + + public void setOrgManagerUserId(String orgManagerUserId) { + this.orgManagerUserId = orgManagerUserId; + } + + public void setZipCodeSuffix(String zipCodeSuffix) { + this.zipCodeSuffix = zipCodeSuffix; + } + + public void setBusinessCountryName(String businessCountryName) { + this.businessCountryName = businessCountryName; + } + + public void setPseudoRoles(Set pseudoRoles) { + this.pseudoRoles = pseudoRoles; + } + + public void setSelectedProfileId(Long selectedProfileId) { + this.selectedProfileId = selectedProfileId; + } + + public Long getTimeZoneId() { + return timeZoneId; + } + + public void setTimeZoneId(Long timeZoneId) { + this.timeZoneId = timeZoneId; + } + + public String getBusinessUnit() { + return businessUnit; + } + + public void setBusinessUnit(String businessUnit) { + this.businessUnit = businessUnit; + } + + public String getSiloStatus() { + return siloStatus; + } + + public void setSiloStatus(String siloStatus) { + this.siloStatus = siloStatus; + } + + public String getCostCenter() { + return costCenter; + } + + public void setCostCenter(String costCenter) { + this.costCenter = costCenter; + } + + public String getFinancialLocCode() { + return financialLocCode; + } + + public void setFinancialLocCode(String financialLocCode) { + this.financialLocCode = financialLocCode; + } + + public String getBusinessUnitName() { + return businessUnitName; + } + + public void setBusinessUnitName(String businessUnitName) { + this.businessUnitName = businessUnitName; + } + + public String getDepartmentName() { + return departmentName; + } + + public void setDepartmentName(String departmentName) { + this.departmentName = departmentName; + } + + public int compareTo(Object obj){ + User user = (User)obj; + + String c1 = getLastName() + getFirstName() + getMiddleInitial(); + String c2 = user.getLastName() + user.getFirstName() + user.getMiddleInitial(); + + return c1.compareTo(c2); + } + + public boolean isOnline() { + return online; + } + + public void setOnline(boolean online) { + this.online = online; + } + + public String getChatId() { + return chatId; + } + + public void setChatId(String chatId) { + this.chatId = chatId; + } + + public Set getUserApps() { + return userApps; + } + + public void setUserApps(Set userApps) { + this.userApps = userApps; + } + + @SuppressWarnings("unchecked") + public void addAppRoles(App app, SortedSet roles) { + if(roles!=null){ + //add all + Set userApps = new TreeSet(); + Iterator itr = roles.iterator(); + while(itr.hasNext()){ + Role role = (Role) itr.next(); + UserApp userApp = new UserApp(); + userApp.setUserId(this.id); + userApp.setApp(app); + userApp.setRole(role); + userApps.add(userApp); + } + setUserApps(userApps); + } else { + //remove all + this.userApps.clear(); + } + + + } + + @SuppressWarnings("unchecked") + public SortedSet getAppRoles(App app) { + SortedSet roles = new TreeSet(); + Set apps = getUserApps(); + Iterator appsItr = apps.iterator(); + UserApp userApp = null; + //getting default app + while(appsItr.hasNext()){ + UserApp tempUserApp = (UserApp)appsItr.next(); + if(tempUserApp.getApp().getId().equals(app.getId())){ + userApp = tempUserApp; + roles.add(userApp.getRole()); + } + } + return roles; + } + + public SortedSet getRoles() { + App app = new App(); + app.setId(new Long(1)); + app.setName("Default"); + return getAppRoles(app); + } + + public UserApp getDefaultUserApp(){ + Set apps = getUserApps(); + Iterator appsItr = apps.iterator(); + UserApp userApp = null; + //getting default app + while(appsItr.hasNext()){ + UserApp tempApp = (UserApp)appsItr.next(); + if(tempApp.equals(new Long(1))){ + userApp = tempApp; + break; + } + } + return userApp; + } + + public void setRoles(SortedSet roles) { + App app = new App(); + app.setId(new Long(1)); + app.setName("Default"); + addAppRoles(app,roles); + } + + public void removeRole(Long roleId) { + Set apps = getUserApps(); + Iterator appsItr = apps.iterator(); + //getting default app + while(appsItr.hasNext()){ + UserApp tempUserApp = (UserApp)appsItr.next(); + if(tempUserApp.getRole().getId().equals(roleId)){ + appsItr.remove(); + } + } + + } + + @SuppressWarnings("unchecked") + public void addRole(Role role){ + if(role!=null){ + SortedSet roles = getRoles(); + if(roles==null){ + roles = new TreeSet(); + } + roles.add(role); + setRoles(roles); + } + + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UserApp.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UserApp.java new file mode 100644 index 00000000..cfadd995 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UserApp.java @@ -0,0 +1,111 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain; + +import java.util.Set; +import java.util.TreeSet; + +// Generated Aug 27, 2014 5:51:36 PM by Hibernate Tools 3.4.0.CR1 + +/** + * FnUserRole generated by hbm2java + */ +@SuppressWarnings("rawtypes") +public class UserApp implements java.io.Serializable, Comparable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private Long userId; + private App app; + private Role role; + private Short priority; + + public UserApp() { + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public App getApp() { + return app; + } + + public void setApp(App app) { + this.app = app; + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + public Short getPriority() { + return this.priority; + } + + public void setPriority(Short priority) { + this.priority = priority; + } + + public boolean equals(Object other) { + if ((this == other)) + return true; + if ((other == null)) + return false; + if (!(other instanceof UserApp)) + return false; + UserApp castOther = (UserApp) other; + + return (this.getUserId().equals(castOther.getUserId())) + && (this.getApp().getId().equals(castOther.getApp().getId())) + && (this.getRole().getId().equals(castOther.getRole().getId())) + && ((this.priority==null && castOther.getPriority()==null) || this.getPriority().equals(castOther.getPriority())); + } + + public int hashCode() { + int result = 17; + + result = 37 * result + (int) (this.getUserId()==null ? 0 : this.getUserId().intValue()); + result = 37 * result + (int) (this.getApp().getId()==null ? 0 : this.getApp().getId().intValue()); + result = 37 * result + (int) (this.getRole().getId()==null ? 0 : this.getRole().getId().intValue()); + result = 37 * result + (int) (this.priority==null ? 0 : this.priority); + return result; + } + + public int compareTo(Object other){ + UserApp castOther = (UserApp) other; + + Long c1 = (this.getUserId()==null ? 0 : this.getUserId()) + (this.getApp()==null||this.getApp().getId()==null ? 0 : this.getApp().getId()) + (this.getRole()==null||this.getRole().getId()==null ? 0 : this.getRole().getId()) + (this.priority==null ? 0 : this.priority); + Long c2 = (castOther.getUserId()==null ? 0 : castOther.getUserId()) + (castOther.getApp()==null||castOther.getApp().getId()==null ? 0 : castOther.getApp().getId()) + (castOther.getRole()==null||castOther.getRole().getId()==null ? 0 : castOther.getRole().getId()) + (castOther.priority==null ? 0 : castOther.priority); + + return c1.compareTo(c2); + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UserAppId.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UserAppId.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UserAppId.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/UserAppId.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/sessionmgt/TimeoutVO.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/sessionmgt/TimeoutVO.java new file mode 100644 index 00000000..0f6c3876 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/sessionmgt/TimeoutVO.java @@ -0,0 +1,63 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain.sessionmgt; + +public class TimeoutVO implements Comparable{ + + private String jSessionId; + private Long sessionTimOutMilliSec; + + public TimeoutVO(){ + + } + + public TimeoutVO(String _jSessionId, Long _sessionTimOutMilliSec) { + setjSessionId(_jSessionId); + setSessionTimOutMilliSec(_sessionTimOutMilliSec); + + } + + public String getjSessionId() { + return jSessionId; + } + + public void setjSessionId(String jSessionId) { + this.jSessionId = jSessionId; + } + + public Long getSessionTimOutMilliSec() { + return sessionTimOutMilliSec; + } + + public void setSessionTimOutMilliSec(Long sessionTimOutMilliSec) { + this.sessionTimOutMilliSec = sessionTimOutMilliSec; + } + + @Override + public int compareTo(TimeoutVO o) { + return sessionTimOutMilliSec.compareTo(o.sessionTimOutMilliSec); + } + + + + + + +} \ No newline at end of file diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Attribute.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Attribute.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Attribute.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Attribute.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/CollaborateList.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/CollaborateList.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/CollaborateList.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/CollaborateList.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Container.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Container.java new file mode 100644 index 00000000..88a9fa71 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Container.java @@ -0,0 +1,331 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain.support; + +import java.util.List; +import java.util.Map; + +public class Container { + + String id; + + public String name; + + Size size; + + Position p; + + public Map containerRowCol; + + public Map elementRowCol; + + int numOfRows; + + int numOfCols; + + double sum = 0; + + double interEleWd; + + double interEleH; + + double interEleToContainerWd; + + double interEleToContainerH; + + double interEleToInnerContainerWd; + + double interEleToInnerContainerH; + + public double top; + + public double left; + + public double height; + + public double width; + + public String visibilityType; + + + + + + public Container(String id, String name, int numOfRows, int numOfCols, double interEleWd, double interEleH, + double interEleToContainerWd, double interEleToContainerH, double interEleToInnerContainerWd, + double interEleToInnerContainerH) { + + this.id = id; + this.name = name; + this.numOfRows = numOfRows; + this.numOfCols = numOfCols; + this.interEleWd = interEleWd; + this.interEleH = interEleH; + this.interEleToContainerWd = interEleToContainerWd; + this.interEleToContainerH = interEleToContainerH; + this.interEleToInnerContainerWd = interEleToInnerContainerWd; + this.interEleToInnerContainerH = interEleToInnerContainerH; + + } + + + public List innerCList; + + public List elementList; + + public Container() { + + } + + + + public Map getContainerRowCol() { + return containerRowCol; + } + + + + + public Map getElementRowCol() { + return elementRowCol; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + public void setInnerContainer(Map innerCon) { + containerRowCol = innerCon; + } + + public void setElements(Map innerE) { + elementRowCol = innerE; + } + + + public Position getP() { + return p; + } + + public void setP(Position p) { + this.p = p; + } + + + public void setTop(double top) { + this.top = top; + } + + + public void setLeft(double left) { + this.left = left; + } + + + public void setHeight(double height) { + this.height = height; + } + + + public void setWidth(double width) { + this.width = width; + } + + + public void setInnerCList(List innerCList) { + this.innerCList = innerCList; + } + + + + public void setElementList(List elementList) { + this.elementList = elementList; + } + + public void setVisibilityType(String visibilityType) { + this.visibilityType = visibilityType; + } + + public Size computeSize() { + Size size = new Size(); + double width = 0; + double height = 0; + // System.out.println("Inside computesize"); + for (int i = 0; i0; chk--) { + if (containerRowCol.containsKey(String.valueOf(k)+ String.valueOf(chk-1))) { + if (containerRowCol.get(String.valueOf(k)+ String.valueOf(chk-1)).computeSize().getWidth() + + containerRowCol.get(String.valueOf(k)+ String.valueOf(chk-1)).getP().getX() > p.x) { + ysum+= containerRowCol.get(String.valueOf(k)+ String.valueOf(chk-1)).computeSize().getHeight(); + break; + } + } + } + } + + } + if (this.getName().equals("Broadworks complex") || this.getName().equals("Application Servers") + || this.getName().equals("Call Session Control") || this.getName().equals("GMLC Provider") || this.getName().equals("Neo") || this.getName().equals("Support")) { + p.y = this.getP().getY()+ysum+i*interEleH+interEleToInnerContainerH+1; + } else { + // System.out.println("element name "+e.getName()+" this.getP().getY() "+this.getP().getY() + // +" ysum " +ysum+" i*interEleH "+i*interEleH+" interEleToContainerH " +interEleToContainerH); + if (e.getName().equals("")) { + p.y = this.getP().getY()+ysum+i*interEleH+(interEleToContainerH); + //System.out.println("test element name "+this.getName()+" Container height "+this.computeSize().getHeight()+" this.getP().getY() "+this.getP().getY() + // +" ysum " +ysum+" i*interEleH "+i*interEleH+" interEleToContainerH-3 " +interEleToContainerH+" p.y "+p.y); + }else + p.y = this.getP().getY()+ysum+i*interEleH+interEleToContainerH; + // System.out.println(e.getName()+"My contain this.getP().getY() "+this.getP().getY() + // +"elements Y "+p.y); + } + xsum+= e.computeSize().getWidth(); + e.setP(p); + //System.out.println("my element name "+e.getName()+" e.getP().getX() "+e.getP().getX()); + //System.out.println(); + } + } + xsum = 0; + } + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Domain.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Domain.java new file mode 100644 index 00000000..a21ff395 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Domain.java @@ -0,0 +1,259 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain.support; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class Domain { + // Unique identifier of the domain + String id; + // List cList; + + public String name; + Size size; + Position p; + + //Attribute1 at; + + public Position getP() { + return p; + } + + public void setP(Position p) { + this.p = p; + } + + //Horizontal space between a pair of containers + double interContWd = 1.0; + //Vertical space between a pair of containers + double interContH; + double domainToLayoutWd; + double domainToContH; + double domainToLayoutH; + int numOfRowsofContainer; + int numOfColsofContainer; + boolean indexChanged; + Map containerRowCol; + public Domain(String id, String name, double interContWd, double interContH, double domainToLayoutWd, + double domainToLayoutH, double domainToContH, int numOfRowsofContainer, int numOfColsofContainer) { + this.id = id; + this.name = name; + this.interContWd = interContWd; + this.interContH = interContH; + this.domainToLayoutWd = domainToLayoutWd; + this.domainToLayoutH = domainToLayoutH; + this.domainToContH = domainToContH; + this.numOfRowsofContainer = numOfRowsofContainer; + this.numOfColsofContainer = numOfColsofContainer; + // at = new Attribute1(); + } + + + + + public double top; + + public double left; + + public double height; + + public double width; + + public List containerList; + + public double newXafterColl; + + public double YafterColl; + + public void setNewXafterColl(double newXafterColl) { + this.newXafterColl = newXafterColl; + } + + public double getNewXafterColl() { + return newXafterColl; + } + + public double getYafterColl() { + return YafterColl; + } + + public void setYafterColl(double yafterColl) { + YafterColl = yafterColl; + } + + public void setDomainToLayoutWd(double domainToLayoutWd) { + this.domainToLayoutWd = domainToLayoutWd; + } + + public double getDomainToLayoutWd() { + return domainToLayoutWd; + } + + public double getTop() { + return top; + } + + public void setTop(double top) { + this.top = top; + } + + public double getLeft() { + return left; + } + + public void setLeft(double left) { + this.left = left; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public double getWidth() { + return width; + } + + public void setWidth(double width) { + this.width = width; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setContainers(Map containerRowCol) { + this.containerRowCol = containerRowCol; + } + + public Map getContainerRowCol() { + return containerRowCol; + } + + + /* public Attribute1 getAt() { + return at; + } + + public void setAt(Attribute1 at) { + this.at = at; + }*/ + + public void setContainerList(List containerList) { + // new ArrayList(); + this.containerList = containerList; + } + + + +/* public boolean isCollapsed() { + return collapsed; + } + + public void setCollapsed(boolean collapsed) { + this.collapsed = collapsed; + }*/ + + public boolean isIndexChanged() { + return indexChanged; + } + + public void setIndexChanged(boolean indexChanged) { + this.indexChanged = indexChanged; + } + + //Compute the size of any domain + public Size computeSize() { + size = new Size(); + size.setHeight(5); + double width = 0; + for (int i = 0; i < numOfRowsofContainer; i++) { + if (containerRowCol!=null && containerRowCol.containsKey(String.valueOf(i)+String.valueOf(numOfColsofContainer-1))) { + for (int j = 0; j < numOfColsofContainer; j++) { + width+=containerRowCol.get(String.valueOf(i)+String.valueOf(j)).computeSize().getWidth(); + } + break; + } + + } + width+=(numOfColsofContainer-1)*interContWd; + if (this.getName().equals("VNI")) + size.setWidth(width-4); + else + size.setWidth(width); + return size; + } + + public void computeConatinerPositions() { + + double xsum = 0; + double ysum = 0; + for (int i=0; i< numOfRowsofContainer; i++){ + for (int j=0; j0 && containerRowCol.containsKey(String.valueOf(k)+ String.valueOf(j-1)) && + !containerRowCol.get(String.valueOf(i)+ String.valueOf(j)).getName().equals("AIC - Alpharetta")) { + ysum+= containerRowCol.get(String.valueOf(k)+ String.valueOf(j-1)).computeSize().getHeight(); + } + } + //System.out.println("C name "+c.getName()+" ysum "+ysum+" domainToLayoutH "+domainToLayoutH+" this.computeSize().getHeight() "+ + // this.computeSize().getHeight()+" domainToContH "+domainToContH+" interContH "+interContH); + p.y = domainToLayoutH+ysum+this.computeSize().getHeight()+ + domainToContH+i*interContH; + + c.setP(p); + xsum+= c.computeSize().getWidth(); + + } + } + xsum = 0; + + } + + } + +} + + diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/DomainVo.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/DomainVo.java new file mode 100644 index 00000000..369cc4cd --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/DomainVo.java @@ -0,0 +1,166 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain.support; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Date; +import java.util.Set; + +import org.openecomp.portalsdk.core.domain.FusionVo; + + +/* Super class from which all data objects descend */ +public class DomainVo extends FusionVo implements Serializable, Cloneable, Comparable { + + protected Long id; + protected Date created; + protected Date modified; + protected Long createdId; + protected Long modifiedId; + protected Long rowNum; + + protected Serializable auditUserId; + + Set auditTrail = null; + + public DomainVo() {} + + + public void setId(Long i) { + id = i; + } + + public void setCreated(Date created) { + this.created = created; + } + + public void setModified(Date modified) { + this.modified = modified; + } + + public void setCreatedId(Long createdId) { + this.createdId = createdId; + } + + public void setModifiedId(Long modifiedId) { + this.modifiedId = modifiedId; + } + + public void setAuditUserId(Serializable auditUserId) { + this.auditUserId = auditUserId; + } + + public void setRowNum(Long rowNum) { + this.rowNum = rowNum; + } + + public void setAuditTrail(Set auditTrail) { + this.auditTrail = auditTrail; + } + + public Long getId() { + return id; + } + + public Date getCreated() { + return created; + } + + public Date getModified() { + return modified; + } + + public Long getCreatedId() { + return createdId; + } + + public Long getModifiedId() { + return modifiedId; + } + + public Serializable getAuditUserId() { + return auditUserId; + } + + public Long getRowNum() { + return rowNum; + } + + public Set getAuditTrail() { + return auditTrail; + } + + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + + public Object copy() { + return copy(false); + } + + + public Object copy(boolean isIdNull) { + // let's create a "copy" of the object using serialization + ByteArrayOutputStream baos = null; + ByteArrayInputStream bais = null; + ObjectOutputStream oos = null; + ObjectInputStream ois = null; + + DomainVo newVo = null; + + try { + + baos = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(baos); + oos.writeObject(this); + + bais = new ByteArrayInputStream(baos.toByteArray()); + ois = new ObjectInputStream(bais); + newVo = (DomainVo)ois.readObject(); + + if (isIdNull) { + newVo.setId(null); + } + + } + catch (Exception e) { + e.printStackTrace(); + } + + return newVo; + } + + + + public int compareTo(Object obj){ + Long c1 = getId(); + Long c2 = ((DomainVo)obj).getId(); + + return (c1 == null || c2 == null) ? 1 : c1.compareTo(c2); + } + + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Element.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Element.java new file mode 100644 index 00000000..567487de --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Element.java @@ -0,0 +1,165 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain.support; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Element { + + public String id; + public String name; + + public double top; + + public double left; + + public double height; + + public String imgFileName; + + public String borderType; + + public String bgColor; + + public ElementDetails details; + + //public List details; + + + public void setBgColor(String bgColor) { + this.bgColor = bgColor; + } + + public void setId(String id) { + this.id = id; + } + + public void setTop(double top) { + this.top = top; + } + + public void setLeft(double left) { + this.left = left; + } + + public void setHeight(double height) { + this.height = height; + } + + public void setWidth(double width) { + this.width = width; + } + + + public double width; + + + public String getId() { + return id; + } + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + Position p; + + public Position getP() { + return p; + } + + public void setP(Position p) { + this.p = p; + } + + + + public Element(String id, String name, String imgPath, String bgColor, String logical_group, String display_longname, + String description, String primary_function, String key_interfaces, String location, String vendor, String vendor_shortname) { + this.id = id; + this.name = name; + this.imgFileName = imgPath; + this.bgColor = bgColor; + + + } + + public Element(String id, String name) { + this.id = id; + this.name = name; + } + + public Element(String id, String name, String imgFilename, String bgColor, String borderType, ElementDetails details) { + this.id = id; + this.name = name; + this.imgFileName = imgFilename; + this.bgColor = bgColor; + this.borderType = borderType; + this.details = details; + + } + + + public void setBorderType(String borderType) { + this.borderType = borderType; + } + + public String getImgFileName() { + return imgFileName; + } + + public void setImgFileName(String imgFileName) { + this.imgFileName = imgFileName; + } + + public String getBorderType() { + return borderType; + } + + + + public ElementDetails getDetails() { + return details; + } + + + + public void setDetails(ElementDetails details) { + this.details = details; + } + + public Size computeSize() { + Size size= new Size(); + size.setWidth(0.5*7.0); + size.setHeight(0.5*3.0); + // size.setWidth(0.5*10.0); + // size.setHeight(0.5*6.0); + return size; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/ElementDetails.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/ElementDetails.java new file mode 100644 index 00000000..0e22d639 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/ElementDetails.java @@ -0,0 +1,71 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain.support; + +import java.util.HashMap; +import java.util.Map; + +public class ElementDetails { + public String logical_group; + public String display_longname; + public String description; + public String primary_function; + public String network_function; + public String key_interfaces; + public String location; + public String vendor; + public String vendor_shortname; + public String enclosingContainer; + + +// public Map details1; + +// public ElementDetails(Map details) { + + // this.details = new HashMap(); + // this.details1 = details; +// } + + + + + + public ElementDetails(String logical_group, String display_longname, String description, String primary_function, String network_function, + String key_interfaces, String location, String vendor, String vendor_shortname, String enclosingContainer) { + + this.logical_group = logical_group; + this.display_longname = display_longname; + this.description = description; + this.primary_function = primary_function; + this.network_function = network_function; + this.key_interfaces = key_interfaces; + this.location = location; + this.vendor = vendor; + this.vendor_shortname = vendor_shortname; + this.enclosingContainer = enclosingContainer; + } + + public void setLogical_group(String logical_group) { + this.logical_group = logical_group; + } + + + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/FusionCommand.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/FusionCommand.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/FusionCommand.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/FusionCommand.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Layout.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Layout.java new file mode 100644 index 00000000..0d78e5dd --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Layout.java @@ -0,0 +1,1209 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain.support; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +public class Layout { + //width of the screen +// double width; + //height of the screen; +// double height; + // Total number of domains present on the screen and assume that + + public Map domainRowCol; + + Map originalDomainRowCol; + + //Horizontal space between a pair of domains + double interDomainWd; + //Vertical space between a pair of domains + double interDomainH; + //Computing the co-ordinates of any domain + int numberofRowsofDomains; + + int numberofColsofDomains; + + Map collapsedDomains; + + List collapsedDomainsNewList; + + public List getCollapsedDomainsNewList() { + return collapsedDomainsNewList; + } + + public void setCollapsedDomainsNewList(List collapsedDomainsNewList) { + this.collapsedDomainsNewList = collapsedDomainsNewList; + } + + public void setCollapsedDomains(Map collapsedDomains) { + this.collapsedDomains = collapsedDomains; + } + + public Map getCollapsedDomains() { + return collapsedDomains; + } + + public int getNumberofColsofDomains() { + return numberofColsofDomains; + } + + public void setNumberofColsofDomains(int numberofColsofDomains) { + this.numberofColsofDomains = numberofColsofDomains; + } + + public Layout(Map domainRowCol, double interDomainWd, double interDomainH, + int numberofRowsofDomains, int numberofColsofDomains) { + + this.domainRowCol = domainRowCol; + this.interDomainWd = interDomainWd; + this.interDomainH = interDomainH; + this.numberofRowsofDomains = numberofRowsofDomains; + this.numberofColsofDomains = numberofColsofDomains; + this.collapsedDomains = new HashMap(); + this.originalDomainRowCol = new TreeMap(); + //nline + this.collapsedDomainsNewList = new ArrayList(); + } + + public Map getDomainRowCol() { + return domainRowCol; + } + + public void setDomainRowCol(Map domainRowCol) { + this.domainRowCol = domainRowCol; + } + + + public void computeDomainPositions() { + double xsum = 0; + double domainTolayout = 10.6; + for (int i=0; i< numberofRowsofDomains; i++){ + for (int j=0; j 0) + p.x+= accountForPlusSpaceBefore(d); + xsum+=d.computeSize().getWidth(); + double ysum=0; + for (int k=0; k enclosedContainers = d.getContainerRowCol(); + for (Map.Entry entry : enclosedContainers.entrySet()) { + if (entry.getKey().equals("00")) { + double containerX = entry.getValue().getP().getX(); + p.x = containerX; + double ysum=0; + for (int k=0; k updatedRC = new HashMap(); + + for (Map.Entry copyEntry : domainRowCol.entrySet()) { + updatedRC.put(copyEntry.getKey(), copyEntry.getValue()); + // System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); + } + + Map updatedRCSorted = new TreeMap(updatedRC); + + Map collapsedDomainMap = getCollapsedDomains(); + + List collapsedDomainNewL = getCollapsedDomainsNewList(); + + + if (collapsedDomainNewL.size() == 0) { + for (Map.Entry copyEntry : domainRowCol.entrySet()) { + originalDomainRowCol.put(copyEntry.getKey(), copyEntry.getValue()); + // System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); + } + } + + + Map updatedRCSortedTrunc = new TreeMap(); + + int colToDelete = 0; + for (Map.Entry entry : updatedRCSorted.entrySet()) { + if (entry.getValue().getName().equals(domainsToCollapse)) { + if (entry.getValue().isIndexChanged()) { + collapsedDomainMap.put("0"+String.valueOf(Integer.parseInt(entry.getKey())+1), entry.getValue()); + + } + //Domain toRemove = entry.getValue(); + else { + collapsedDomainMap.put(entry.getKey(),entry.getValue()); + } + + collapsedDomainNewL.add(entry.getValue()); + setNumberofColsofDomains(getNumberofColsofDomains()-1); + updatedRC.remove(entry.getKey()); + colToDelete = Character.getNumericValue(entry.getKey().toCharArray()[1]); + break; + } + } + + + for (Map.Entry copyEntry : updatedRCSorted.entrySet()) { + updatedRCSortedTrunc.put(copyEntry.getKey(), copyEntry.getValue()); + //System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); + } + + for (Map.Entry rmv : updatedRCSorted.entrySet()) { + if (Character.getNumericValue(rmv.getKey().toCharArray()[1]) <= colToDelete) { + updatedRCSortedTrunc.remove(rmv.getKey()); + } + } + + + /* for (Map.Entry entry : updatedRCSortedTrunc.entrySet()) { + System.out.println("Sorted key: "+entry.getKey()+" Sorted value: "+entry.getValue().getName()); + }*/ + + for (Map.Entry updateOthers : updatedRCSortedTrunc.entrySet()) { + char update[] = updateOthers.getKey().toCharArray(); + int charToupdate = Character.getNumericValue(update[1]); + --charToupdate; + String resultRowCol = String.valueOf(update[0])+String.valueOf(charToupdate); + updateOthers.getValue().setIndexChanged(true); + updatedRC.put(resultRowCol, updateOthers.getValue()); + updatedRC.remove(updateOthers.getKey()); + + } + setDomainRowCol(updatedRC); + + /* for (Map.Entry entry : updatedRC.entrySet()) { + System.out.println("Sorted key: "+entry.getKey()+" Sorted value: "+entry.getValue().getName()); + }*/ + + double currDistFromLftM = 11.0; + int orgColofCollapsedd = -1; + int orgColofDisplayedd = -1; + for (Map.Entry cd : updatedRC.entrySet()) { + /*for (Domain pl : collapsedDomainNewL) { + for (Map.Entry colCheck : originalDomainRowCol.entrySet()) { + if (colCheck.getValue().getName().equals(pl.getName())) { + orgColofCollapsedd = Character.getNumericValue(colCheck.getKey().toCharArray()[1]); + break; + } + } + + for (Map.Entry colCheckk : originalDomainRowCol.entrySet()) { + if (colCheckk.getValue().getName().equals(cd.getValue().getName())) { + orgColofDisplayedd = Character.getNumericValue(colCheckk.getKey().toCharArray()[1]); + break; + } + } + + if (orgColofCollapsedd < orgColofDisplayedd) { + currDistFromLftM+= 3; + } + }*/ + Domain d = cd.getValue(); + double accountPlus = accountForPlusSpaceBefore(d); + // currDistFromLftM+= accountForPlusSpaceBefore(d); + d.setDomainToLayoutWd(currDistFromLftM+accountPlus); + d.computeConatinerPositions(); + for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { + Container c = entry1.getValue(); + c.computeSize(); + c.computeElementPositions(); + if (c.getContainerRowCol() != null) { + for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { + Container inner = entryInner.getValue(); + inner.computeElementPositions(); + } + } + } + currDistFromLftM += d.computeSize().getWidth()+2; + + } + + + + + //nline + // Insert method invocation + updatePlusPosition(collapsedDomainNewL, updatedRC); + + //order changed + setCollapsedDomains(collapsedDomainMap); + setCollapsedDomainsNewList(collapsedDomainNewL); + + + computeDomainPositionsModified(); + return this; + } + + + + public Layout collapseDomainNew(String domainsToCollapse) { + + if(domainsToCollapse == null || domainsToCollapse.isEmpty()) + return null; + + Map updatedRC = new HashMap(); + + for (Map.Entry copyEntry : domainRowCol.entrySet()) { + updatedRC.put(copyEntry.getKey(), copyEntry.getValue()); + //System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); + } + + Map updatedRCSorted = new TreeMap(updatedRC); + + Map collapsedDomainMap = getCollapsedDomains(); + + List collapsedDomainNewL = getCollapsedDomainsNewList(); + + + if (collapsedDomainNewL.size() == 0) { + for (Map.Entry copyEntry : domainRowCol.entrySet()) { + originalDomainRowCol.put(copyEntry.getKey(), copyEntry.getValue()); + // System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); + } + } + + + Map updatedRCSortedTrunc = new TreeMap(); + + int colToDelete = 0; + for (Map.Entry entry : updatedRCSorted.entrySet()) { + if (entry.getValue().getName().equals(domainsToCollapse)) { + if (entry.getValue().isIndexChanged()) { + collapsedDomainMap.put("0"+String.valueOf(Integer.parseInt(entry.getKey())+1), entry.getValue()); + + } + //Domain toRemove = entry.getValue(); + else { + collapsedDomainMap.put(entry.getKey(),entry.getValue()); + } + + collapsedDomainNewL.add(entry.getValue()); + setNumberofColsofDomains(getNumberofColsofDomains()-1); + updatedRC.remove(entry.getKey()); + colToDelete = Character.getNumericValue(entry.getKey().toCharArray()[1]); + break; + } + } + + + for (Map.Entry copyEntry : updatedRCSorted.entrySet()) { + updatedRCSortedTrunc.put(copyEntry.getKey(), copyEntry.getValue()); + //System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); + } + + for (Map.Entry rmv : updatedRCSorted.entrySet()) { + if (Character.getNumericValue(rmv.getKey().toCharArray()[1]) <= colToDelete) { + updatedRCSortedTrunc.remove(rmv.getKey()); + } + } + + + /* for (Map.Entry entry : updatedRCSortedTrunc.entrySet()) { + System.out.println("Sorted key: "+entry.getKey()+" Sorted value: "+entry.getValue().getName()); + }*/ + + for (Map.Entry updateOthers : updatedRCSortedTrunc.entrySet()) { + char update[] = updateOthers.getKey().toCharArray(); + int charToupdate = Character.getNumericValue(update[1]); + --charToupdate; + String resultRowCol = String.valueOf(update[0])+String.valueOf(charToupdate); + updateOthers.getValue().setIndexChanged(true); + updatedRC.put(resultRowCol, updateOthers.getValue()); + updatedRC.remove(updateOthers.getKey()); + + } + setDomainRowCol(updatedRC); + + double currDistFromLftM = 11.0; + + boolean isDisplayed; + for (Map.Entry orgEntry : originalDomainRowCol.entrySet()) { + isDisplayed = false; + for (Map.Entry cd : updatedRC.entrySet()) { + if (cd.getValue().getName().equals(orgEntry.getValue().getName())) { + Domain d = cd.getValue(); + d.setDomainToLayoutWd(currDistFromLftM); + d.computeConatinerPositions(); + for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { + Container c = entry1.getValue(); + c.computeSize(); + c.computeElementPositions(); + if (c.getContainerRowCol() != null) { + for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { + Container inner = entryInner.getValue(); + inner.computeElementPositions(); + } + } + } + currDistFromLftM += d.computeSize().getWidth()+1; + isDisplayed = true; + break; + } + } + + if (!isDisplayed) { + Domain myCollapsed = orgEntry.getValue(); + myCollapsed.setNewXafterColl(currDistFromLftM); + myCollapsed.setYafterColl(myCollapsed.getP().getY()); + currDistFromLftM += 4; + } + } + + setCollapsedDomains(collapsedDomainMap); + setCollapsedDomainsNewList(collapsedDomainNewL); + + + computeDomainPositionsModified(); + return this; + + } + + + public Layout collapseDomain(String domainsToCollapse) { + + Map updatedRC = new HashMap(); + + for (Map.Entry copyEntry : domainRowCol.entrySet()) { + updatedRC.put(copyEntry.getKey(), copyEntry.getValue()); + //System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); + } + + Map updatedRCSorted = new TreeMap(updatedRC); + + Map collapsedDomainMap = getCollapsedDomains(); + + if (collapsedDomainMap.size() == 0) { + for (Map.Entry copyEntry : domainRowCol.entrySet()) { + originalDomainRowCol.put(copyEntry.getKey(), copyEntry.getValue()); + // System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); + } + } + + + // List collapsedDomainsList = getCollapsedDomains(); + + /* for (Map.Entry entry : updatedRCSorted.entrySet()) { + System.out.println("Sorted Key: "+entry.getKey()); + }*/ + + double prevDomXCordinate = 0.0; + Map updatedRCSortedTrunc = new TreeMap(); + // for (String dToCollapse : domainsToCollapse) { + int colToDelete = 0; + for (Map.Entry entry : updatedRCSorted.entrySet()) { + if (entry.getValue().getName().equals(domainsToCollapse)) { + if (entry.getValue().isIndexChanged()) + collapsedDomainMap.put("0"+String.valueOf(Integer.parseInt(entry.getKey())+1), entry.getValue()); + //Domain toRemove = entry.getValue(); + else + collapsedDomainMap.put(entry.getKey(),entry.getValue()); + prevDomXCordinate = entry.getValue().getP().getX(); + entry.getValue().getP().setX(prevDomXCordinate-2); + // toRemove.setCollapsed(true); + setNumberofColsofDomains(getNumberofColsofDomains()-1); + updatedRC.remove(entry.getKey()); + colToDelete = Character.getNumericValue(entry.getKey().toCharArray()[1]); + // collapsedDomainList.put(entry.getKey(),entry.getValue()); + break; + } + } + + /* for (Map.Entry entry : updatedRC.entrySet()) { + System.out.println("Sorted key: "+entry.getKey()+" Sorted value: "+entry.getValue().getName()); + }*/ + + setCollapsedDomains(collapsedDomainMap); + + for (Map.Entry copyEntry : updatedRCSorted.entrySet()) { + updatedRCSortedTrunc.put(copyEntry.getKey(), copyEntry.getValue()); + //System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); + } + + for (Map.Entry rmv : updatedRCSorted.entrySet()) { + if (Character.getNumericValue(rmv.getKey().toCharArray()[1]) <= colToDelete) { + updatedRCSortedTrunc.remove(rmv.getKey()); + } + } + + + /* for (Map.Entry entry : updatedRCSortedTrunc.entrySet()) { + System.out.println("Sorted key: "+entry.getKey()+" Sorted value: "+entry.getValue().getName()); + }*/ + + for (Map.Entry updateOthers : updatedRCSortedTrunc.entrySet()) { + // if (!updateOthers.getValue().getName().equals(dToCollapse)) { + // if ((int)updateOthers.getKey().toCharArray()[1] > colToDelete) { + char update[] = updateOthers.getKey().toCharArray(); + int charToupdate = Character.getNumericValue(update[1]); + --charToupdate; + String resultRowCol = String.valueOf(update[0])+String.valueOf(charToupdate); + // update[1] = (char)charToupdate; + // updatedRC.put(String.valueOf(update), updateOthers.getValue()); + updateOthers.getValue().setIndexChanged(true); + updatedRC.put(resultRowCol, updateOthers.getValue()); + updatedRC.remove(updateOthers.getKey()); + // } + // } + } + + // } + setDomainRowCol(updatedRC); + + + + for (Map.Entry entry : updatedRCSortedTrunc.entrySet()) { + Domain d = entry.getValue(); + // if (d.getName().equals("Datacenter with AIC") || d.getName().equals("VNI")) { + // d.setDomainToLayoutWd(d.getDomainToLayoutWd()-33); + if (collapsedDomains.size() == 2 && collapsedDomains.containsKey("00") && collapsedDomains.containsKey("01") && domainsToCollapse.equals("RAN")) { + if (d.getName().equals("USP")) + d.setDomainToLayoutWd(prevDomXCordinate); + else if (d.getName().equals("VNI")) + d.setDomainToLayoutWd(prevDomXCordinate+8); + else + d.setDomainToLayoutWd(prevDomXCordinate+10); + //System.out.println("Inside RAN EPC"); + } + else if (domainsToCollapse.equals("RAN") && !d.getName().equals("EPC") && collapsedDomains.size() < 3) + d.setDomainToLayoutWd(prevDomXCordinate+11); + else if (domainsToCollapse.equals("RAN") && collapsedDomains.size() == 3 && collapsedDomains.containsKey("01") && collapsedDomains.containsKey("04")) { + if (d.getName().equals("USP")) + d.setDomainToLayoutWd(prevDomXCordinate); + else + d.setDomainToLayoutWd(prevDomXCordinate+10); + } + + else if (collapsedDomains.containsKey("00") && collapsedDomains.size() == 3 && collapsedDomains.containsKey("01") && collapsedDomains.containsKey("02")) { + //System.out.println("Inside test"); + if (d.getName().equals("VNI")) + d.setDomainToLayoutWd(prevDomXCordinate+10); + else + d.setDomainToLayoutWd(prevDomXCordinate); + + } + + else if (collapsedDomains.containsKey("00") && collapsedDomains.size() == 3 && collapsedDomains.containsKey("01") && collapsedDomains.containsKey("03")) { + //System.out.println("Inside test"); + if (d.getName().equals("VNI")) + d.setDomainToLayoutWd(prevDomXCordinate+10); + else + d.setDomainToLayoutWd(prevDomXCordinate); + + } + + + + else { + d.setDomainToLayoutWd(prevDomXCordinate); + } + d.computeConatinerPositions(); + prevDomXCordinate = d.getP().getX(); + for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { + Container c = entry1.getValue(); + c.computeSize(); + c.computeElementPositions(); + if (c.getContainerRowCol() != null) { + for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { + Container inner = entryInner.getValue(); + inner.computeElementPositions(); + } + } + } + // } + // System.out.println("Sorted key: "+entry.getKey()+" Sorted value: "+entry.getValue().getName()); + } + // setNumberofColsofDomains(getNumberofColsofDomains()-1); + computeDomainPositions(); + return this; + /* CoordinateMain cm = new CoordinateMain(); + try { + cm.convertToYAML(this); + } catch (Exception e) { + + }*/ + + } + + public Layout uncollapseDomainModified(String domainToUnCollapse) { + Map currentDomainsSorted = new TreeMap(domainRowCol); + Map updateDomains = new TreeMap(); + Map collapsedDomainList = getCollapsedDomains(); + Map collapsedDomainListSorted = new TreeMap(collapsedDomainList); + + List domainstoUpd = new ArrayList(); + + int colToUnCollapse = 99; + + Domain domainToInsert = null; + + if (collapsedDomains.size() == 0) { + for (Map.Entry unindexDomain : originalDomainRowCol.entrySet()) { + Domain dm = unindexDomain.getValue(); + dm.setIndexChanged(false); + } + } + + + for (Map.Entry entry : collapsedDomainListSorted.entrySet()) { + if (entry.getValue().getName().equals(domainToUnCollapse)) { + colToUnCollapse = Character.getNumericValue(entry.getKey().toCharArray()[1]); + domainToInsert = entry.getValue(); + collapsedDomainList.remove(entry.getKey()); + break; + } + } + + domainstoUpd.add(domainToInsert); + + //for (Map.Entry e : originalDomainRowCol.entrySet()) + // System.out.println("Original key value"+e.getKey()+":"+e.getValue().getName()); + + int lastKeyCol = -1; + for (Map.Entry entry : originalDomainRowCol.entrySet()) { + int currcol = Character.getNumericValue(entry.getKey().toCharArray()[1]); + if (currcol < colToUnCollapse) { + for (Map.Entry currDomainsEntry : currentDomainsSorted.entrySet()) { + if (currDomainsEntry.getValue().getName().equals(entry.getValue().getName())) { + updateDomains.put(currDomainsEntry.getKey(), currDomainsEntry.getValue()); + lastKeyCol = Character.getNumericValue(currDomainsEntry.getKey().toCharArray()[1]); + break; + } + } + } else { + String newKey = "0"+String.valueOf(lastKeyCol+1); + if (currcol == colToUnCollapse) { + updateDomains.put(newKey, domainToInsert); + ++lastKeyCol; + } else { + for (Map.Entry currDomainsEnt : currentDomainsSorted.entrySet()) { + if (currDomainsEnt.getValue().getName().equals(entry.getValue().getName())) { + updateDomains.put(newKey, currDomainsEnt.getValue()); + domainstoUpd.add(currDomainsEnt.getValue()); + ++lastKeyCol; + // lastKeyCol = Character.getNumericValue(currDomainsEntry.getKey().toCharArray()[1]); + break; + } + } + } + + } + } + + setNumberofColsofDomains(getNumberofColsofDomains()+1); + setDomainRowCol(updateDomains); + setCollapsedDomains(collapsedDomainList); + + //for (Map.Entry e : updateDomains.entrySet()) + // System.out.println("me Updatedomains key value"+e.getKey()+":"+e.getValue().getName()); + + // for (int i = 1; i < domainstoUpd.size(); i++) { + for (int i = 0; i < domainstoUpd.size(); i++) { + Domain d = domainstoUpd.get(i); + double newX = 0.0; + if (i+1 < domainstoUpd.size()) + // newX = domainstoUpd.get(i-1).getP().getX()+domainstoUpd.get(i-1).computeSize().getWidth()+5; + newX = domainstoUpd.get(i+1).getP().getX(); + //d.setDomainToLayoutWd(domainstoUpd.get(i+1).getP().getX()); + else + newX = domainstoUpd.get(i).getP().getX()+32; + // d.setDomainToLayoutWd(domainstoUpd.get(i).getP().getX()+38); + /* if (i > 0) { + if (d.getWidth() < domainstoUpd.get(i-1).getWidth()) + newX+= domainstoUpd.get(i-1).getWidth() - d.getWidth(); + else if (d.getWidth() > domainstoUpd.get(i-1).getWidth()) + newX-= d.getWidth() - domainstoUpd.get(i-1).getWidth() ; + } else { + if (d.getWidth() < domainInserted.getWidth()) + newX+= domainInserted.getWidth() - d.getWidth(); + else if (d.getWidth() > domainInserted.getWidth()) + newX-= d.getWidth() - domainInserted.getWidth() ; + }*/ + if (d.getName().equals("Datacenter with AIC")) + newX+= 2; + d.setDomainToLayoutWd(newX); + /* if (i == 0) + d.setDomainToLayoutWd(domainInserted.getP().getX()+domainInserted.getWidth()); + else + d.setDomainToLayoutWd(domainstoUpd.get(i-1).getP().getX()+domainstoUpd.get(i-1).getWidth());*/ + d.computeConatinerPositions(); + for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { + Container c = entry1.getValue(); + c.computeSize(); + c.computeElementPositions(); + if (c.getContainerRowCol() != null) { + for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { + Container inner = entryInner.getValue(); + inner.computeElementPositions(); + } + } + } + // } + // System.out.println("Sorted key: "+entry.getKey()+" Sorted value: "+entry.getValue().getName()); + } + + computeDomainPositions(); + return this; + + } + + + + public Layout uncollapseDomain(String domainToCollapse) { + Map currentDomainsSorted = new TreeMap(domainRowCol); + Map updateDomains = new TreeMap(); + Map collapsedDomainList = getCollapsedDomains(); + Map collapsedDomainListSorted = new TreeMap(collapsedDomainList); + + List domainstoUpd = new ArrayList(); + /* for (Map.Entry entry : collapsedDomainListSorted.entrySet()) { + if (entry.getValue().getName().equals("domainToCollapse")) { + if (currentDomainsSorted != null) { + if (!currentDomainsSorted.containsKey(entry.getKey())) { + updateDomains.put(entry.getKey(), entry.getValue()); + collapsedDomainList.remove(entry.getKey()); + break; + } else { + int colToUnCollapse = Character.getNumericValue(entry.getKey().toCharArray()[1]); + for (Map.Entry curr : currentDomainsSorted.entrySet()) { + if (Character.getNumericValue(curr.getKey().toCharArray()[1]) < colToUnCollapse) { + updateDomains.put(curr.getKey(),curr.getValue()); + } else { + updateDomains.put(curr.getKey()+1,curr.getValue()); + + } + } + updateDomains.put(entry.getKey(), entry.getValue()); + } + } + + + } + }*/ + + Domain domainInserted = null; + for (Map.Entry entry : collapsedDomainListSorted.entrySet()) { + if (entry.getValue().getName().equals(domainToCollapse)) { + domainInserted = entry.getValue(); + if (currentDomainsSorted != null) { + int colToUnCollapse = Character.getNumericValue(entry.getKey().toCharArray()[1]); + for (Map.Entry curr : currentDomainsSorted.entrySet()) { + if (Character.getNumericValue(curr.getKey().toCharArray()[1]) < colToUnCollapse) { + updateDomains.put(curr.getKey(),curr.getValue()); + } else { + updateDomains.put("0"+String.valueOf(Integer.parseInt(curr.getKey())+1),curr.getValue()); + domainstoUpd.add(curr.getValue()); + } + } + } + updateDomains.put(entry.getKey(), entry.getValue()); + collapsedDomainList.remove(entry.getKey()); + break; + + } + } + setNumberofColsofDomains(getNumberofColsofDomains()+1); + setDomainRowCol(updateDomains); + setCollapsedDomains(collapsedDomainList); + + //for (Map.Entry e : updateDomains.entrySet()) + // System.out.println("Updatedomains key value"+e.getKey()+":"+e.getValue().getName()); + + + for (int i = 0; i < domainstoUpd.size(); i++) { + Domain d = domainstoUpd.get(i); + double newX = 0.0; + if (i+1 < domainstoUpd.size()) + newX = domainstoUpd.get(i+1).getP().getX(); + //d.setDomainToLayoutWd(domainstoUpd.get(i+1).getP().getX()); + else + newX = domainstoUpd.get(i).getP().getX()+38; + // d.setDomainToLayoutWd(domainstoUpd.get(i).getP().getX()+38); + /* if (i > 0) { + if (d.getWidth() < domainstoUpd.get(i-1).getWidth()) + newX+= domainstoUpd.get(i-1).getWidth() - d.getWidth(); + else if (d.getWidth() > domainstoUpd.get(i-1).getWidth()) + newX-= d.getWidth() - domainstoUpd.get(i-1).getWidth() ; + } else { + if (d.getWidth() < domainInserted.getWidth()) + newX+= domainInserted.getWidth() - d.getWidth(); + else if (d.getWidth() > domainInserted.getWidth()) + newX-= d.getWidth() - domainInserted.getWidth() ; + }*/ + if (d.getName().equals("Datacenter with AIC")) + newX+= 5; + d.setDomainToLayoutWd(newX); + /* if (i == 0) + d.setDomainToLayoutWd(domainInserted.getP().getX()+domainInserted.getWidth()); + else + d.setDomainToLayoutWd(domainstoUpd.get(i-1).getP().getX()+domainstoUpd.get(i-1).getWidth());*/ + d.computeConatinerPositions(); + for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { + Container c = entry1.getValue(); + c.computeSize(); + c.computeElementPositions(); + if (c.getContainerRowCol() != null) { + for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { + Container inner = entryInner.getValue(); + inner.computeElementPositions(); + } + } + } + // } + // System.out.println("Sorted key: "+entry.getKey()+" Sorted value: "+entry.getValue().getName()); + } + + computeDomainPositions(); + return this; + } + + public Layout uncollapseDomainNew(String domainToUnCollapse) { + Map currentDomainsSorted = new TreeMap(domainRowCol); + Map updateDomains = new TreeMap(); + Map collapsedDomainList = getCollapsedDomains(); + Map collapsedDomainListSorted = new TreeMap(collapsedDomainList); + + List domainstoUpd = new ArrayList(); + + //nline + List collapsedDomainNewLL = getCollapsedDomainsNewList(); + + int colToUnCollapse = 99; + + Domain domainToInsert = null; + + //nline + // if (collapsedDomains.size() == 0) { + if (collapsedDomainNewLL.size() == 0) { + for (Map.Entry unindexDomain : originalDomainRowCol.entrySet()) { + Domain dm = unindexDomain.getValue(); + dm.setIndexChanged(false); + } + } + + + for (Map.Entry entry : originalDomainRowCol.entrySet()) { + if (entry.getValue().getName().equals(domainToUnCollapse)) { + colToUnCollapse = Character.getNumericValue(entry.getKey().toCharArray()[1]); + domainToInsert = entry.getValue(); + collapsedDomainList.remove(entry.getKey()); + //nline + collapsedDomainNewLL.remove(entry.getValue()); + break; + } + } + + domainstoUpd.add(domainToInsert); + + // for (Map.Entry e : originalDomainRowCol.entrySet()) + // System.out.println("Original key value"+e.getKey()+":"+e.getValue().getName()); + + int lastKeyCol = -1; + for (Map.Entry entry : originalDomainRowCol.entrySet()) { + int currcol = Character.getNumericValue(entry.getKey().toCharArray()[1]); + if (currcol < colToUnCollapse) { + for (Map.Entry currDomainsEntry : currentDomainsSorted.entrySet()) { + if (currDomainsEntry.getValue().getName().equals(entry.getValue().getName())) { + updateDomains.put(currDomainsEntry.getKey(), currDomainsEntry.getValue()); + lastKeyCol = Character.getNumericValue(currDomainsEntry.getKey().toCharArray()[1]); + break; + } + } + } else { + String newKey = "0"+String.valueOf(lastKeyCol+1); + if (currcol == colToUnCollapse) { + updateDomains.put(newKey, domainToInsert); + ++lastKeyCol; + } else { + for (Map.Entry currDomainsEnt : currentDomainsSorted.entrySet()) { + if (currDomainsEnt.getValue().getName().equals(entry.getValue().getName())) { + updateDomains.put(newKey, currDomainsEnt.getValue()); + domainstoUpd.add(currDomainsEnt.getValue()); + ++lastKeyCol; + // lastKeyCol = Character.getNumericValue(currDomainsEntry.getKey().toCharArray()[1]); + break; + } + } + } + + } + } + + setNumberofColsofDomains(getNumberofColsofDomains()+1); + setDomainRowCol(updateDomains); + + //for (Map.Entry e : updateDomains.entrySet()) + // System.out.println("me Updatedomains key value"+e.getKey()+":"+e.getValue().getName()); + + + + double currDistFromLftMargin = 11.0; + for (Map.Entry cd : updateDomains.entrySet()) { + Domain d = cd.getValue(); + double accountPlus = accountForPlusSpaceBefore(d); + d.setDomainToLayoutWd(currDistFromLftMargin+accountPlus); + d.computeConatinerPositions(); + for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { + Container c = entry1.getValue(); + c.computeSize(); + c.computeElementPositions(); + if (c.getContainerRowCol() != null) { + for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { + Container inner = entryInner.getValue(); + inner.computeElementPositions(); + } + } + } + currDistFromLftMargin += d.computeSize().getWidth()+2; + + } + + //nline + updatePlusPosition(collapsedDomainNewLL, updateDomains); + + //order changed + setCollapsedDomains(collapsedDomainList); + + //nline + setCollapsedDomainsNewList(collapsedDomainNewLL); + + + computeDomainPositionsModified(); + return this; + + } + + public Layout uncollapseDomainNew1(String domainToUnCollapse) { + + if(domainToUnCollapse == null || domainToUnCollapse.isEmpty()) + return null; + + Map currentDomainsSorted = new TreeMap(domainRowCol); + Map updateDomains = new TreeMap(); + Map collapsedDomainList = getCollapsedDomains(); + Map collapsedDomainListSorted = new TreeMap(collapsedDomainList); + + List domainstoUpd = new ArrayList(); + + //nline + List collapsedDomainNewLL = getCollapsedDomainsNewList(); + + int colToUnCollapse = 99; + + Domain domainToInsert = null; + + //nline + // if (collapsedDomains.size() == 0) { + if (collapsedDomainNewLL.size() == 0) { + for (Map.Entry unindexDomain : originalDomainRowCol.entrySet()) { + Domain dm = unindexDomain.getValue(); + dm.setIndexChanged(false); + } + } + + + for (Map.Entry entry : originalDomainRowCol.entrySet()) { + if (entry.getValue().getName().equals(domainToUnCollapse)) { + colToUnCollapse = Character.getNumericValue(entry.getKey().toCharArray()[1]); + domainToInsert = entry.getValue(); + collapsedDomainList.remove(entry.getKey()); + //nline + collapsedDomainNewLL.remove(entry.getValue()); + break; + } + } + + domainstoUpd.add(domainToInsert); + + //for (Map.Entry e : originalDomainRowCol.entrySet()) + // System.out.println("Original key value"+e.getKey()+":"+e.getValue().getName()); + + int lastKeyCol = -1; + for (Map.Entry entry : originalDomainRowCol.entrySet()) { + int currcol = Character.getNumericValue(entry.getKey().toCharArray()[1]); + if (currcol < colToUnCollapse) { + for (Map.Entry currDomainsEntry : currentDomainsSorted.entrySet()) { + if (currDomainsEntry.getValue().getName().equals(entry.getValue().getName())) { + updateDomains.put(currDomainsEntry.getKey(), currDomainsEntry.getValue()); + lastKeyCol = Character.getNumericValue(currDomainsEntry.getKey().toCharArray()[1]); + break; + } + } + } else { + String newKey = "0"+String.valueOf(lastKeyCol+1); + if (currcol == colToUnCollapse) { + updateDomains.put(newKey, domainToInsert); + ++lastKeyCol; + } else { + for (Map.Entry currDomainsEnt : currentDomainsSorted.entrySet()) { + if (currDomainsEnt.getValue().getName().equals(entry.getValue().getName())) { + updateDomains.put(newKey, currDomainsEnt.getValue()); + domainstoUpd.add(currDomainsEnt.getValue()); + ++lastKeyCol; + // lastKeyCol = Character.getNumericValue(currDomainsEntry.getKey().toCharArray()[1]); + break; + } + } + } + + } + } + + setNumberofColsofDomains(getNumberofColsofDomains()+1); + setDomainRowCol(updateDomains); + + //for (Map.Entry e : updateDomains.entrySet()) + // System.out.println("me Updatedomains key value"+e.getKey()+":"+e.getValue().getName()); + + + + + double currDistFromLftM = 11.0; + + boolean isDisplayed; + for (Map.Entry orgEntry : originalDomainRowCol.entrySet()) { + isDisplayed = false; + for (Map.Entry cd : updateDomains.entrySet()) { + if (cd.getValue().getName().equals(orgEntry.getValue().getName())) { + Domain d = cd.getValue(); + d.setDomainToLayoutWd(currDistFromLftM); + d.computeConatinerPositions(); + for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { + Container c = entry1.getValue(); + c.computeSize(); + c.computeElementPositions(); + if (c.getContainerRowCol() != null) { + for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { + Container inner = entryInner.getValue(); + inner.computeElementPositions(); + } + } + } + currDistFromLftM += d.computeSize().getWidth()+1; + isDisplayed = true; + break; + } + } + + if (!isDisplayed) { + Domain myCollapsed = orgEntry.getValue(); + myCollapsed.setNewXafterColl(currDistFromLftM); + currDistFromLftM += 4; + } + } + + // plus.setNewXafterColl(distOfCollFrmLft+1.5); + + //order changed + setCollapsedDomains(collapsedDomainList); + + //nline + setCollapsedDomainsNewList(collapsedDomainNewLL); + + + computeDomainPositionsModified(); + return this; + + } + + + + + + + + + + + + + + + private void updatePlusPosition(List collapsedDNewL, Map displayedDomainMap) { + List copyCollapseList = new ArrayList(); + + for (Domain copyCollapse : collapsedDNewL) { + copyCollapseList.add(copyCollapse); + } + + //double distOfCollFrmLft = 0.0; + int orgColofCollapsed = -1; + int orgColofDisplayed = -1; + int orgColofDisplayedOtherPlus = -1; + int orgColofInterDomainPlus = -1; + List dsplyList = new ArrayList(); + + for (Domain plus : collapsedDNewL) { + double distOfCollFrmLft = 0.0; + for (Map.Entry colCheck : originalDomainRowCol.entrySet()) { + if (colCheck.getValue().getName().equals(plus.getName())) { + orgColofCollapsed = Character.getNumericValue(colCheck.getKey().toCharArray()[1]); + break; + } + } + for (Map.Entry displayedEntry : displayedDomainMap.entrySet()) { + + for (Map.Entry colCheck1 : originalDomainRowCol.entrySet()) { + if (colCheck1.getValue().getName().equals(displayedEntry.getValue().getName())) { + orgColofDisplayed = Character.getNumericValue(colCheck1.getKey().toCharArray()[1]); + break; + } + } + if (orgColofDisplayed < orgColofCollapsed) { + distOfCollFrmLft+= displayedEntry.getValue().computeSize().getWidth(); + + + /* if (dsplyList.size() > 0) { + Domain lastAdded = dsplyList.get(dsplyList.size()-1); + int orgColofLastAdded = -1; + for (Map.Entry colCh : originalDomainRowCol.entrySet()) { + if (colCh.getValue().getName().equals(lastAdded.getName())) { + orgColofLastAdded = Character.getNumericValue(colCh.getKey().toCharArray()[1]); + break; + } + } + if (Math.abs(orgColofDisplayed - orgColofLastAdded) == 1) { + boolean adjDomainsWithPlus = false; + for (Domain colp : copyCollapseList) { + if (!colp.getName().equals(plus.getName())) { + for (Map.Entry colCk2 : originalDomainRowCol.entrySet()) { + if (colCk2.getValue().getName().equals(colp.getName())) { + orgColofInterDomainPlus = Character.getNumericValue(colCk2.getKey().toCharArray()[1]); + break; + } + } + if (orgColofInterDomainPlus > orgColofLastAdded && orgColofInterDomainPlus < orgColofDisplayed) { + adjDomainsWithPlus = true; + break; + } + } + } + if (!adjDomainsWithPlus) + distOfCollFrmLft+=interDomainWd; + } + } + dsplyList.add(displayedEntry.getValue()); */ + + + + } + + } + + for (Domain collp : copyCollapseList) { + if (!collp.getName().equals(plus.getName())) { + for (Map.Entry colCheck2 : originalDomainRowCol.entrySet()) { + if (colCheck2.getValue().getName().equals(collp.getName())) { + orgColofDisplayedOtherPlus = Character.getNumericValue(colCheck2.getKey().toCharArray()[1]); + break; + } + } + if (orgColofDisplayedOtherPlus < orgColofCollapsed) { + distOfCollFrmLft+=3.0; + } + } + } + + plus.setNewXafterColl(distOfCollFrmLft+1.5); + + + } + } + + + private double accountForPlusSpaceBefore(Domain d) { + + int orgColofCollapsed = 0; + int orgColofDisplayed = 0; + double distFromLftM = 0.0; + + for (Map.Entry colCheckk : originalDomainRowCol.entrySet()) { + if (colCheckk.getValue().getName().equals(d.getName())) { + orgColofDisplayed = Character.getNumericValue(colCheckk.getKey().toCharArray()[1]); + break; + } + } + + for (Domain collapsed : getCollapsedDomainsNewList()) { + for (Map.Entry colCheck : originalDomainRowCol.entrySet()) { + if (colCheck.getValue().getName().equals(collapsed.getName())) { + orgColofCollapsed = Character.getNumericValue(colCheck.getKey().toCharArray()[1]); + break; + } + } + + if (orgColofCollapsed < orgColofDisplayed) { + distFromLftM+= 2; + } + } + return distFromLftM; + + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/NameValueId.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/NameValueId.java new file mode 100644 index 00000000..fcb9f726 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/NameValueId.java @@ -0,0 +1,94 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.domain.support; + +import java.io.Serializable; + + +public class NameValueId implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String lab; + private String val; + + public NameValueId() { + } + + public NameValueId(String value, String label) { + setVal(value); + setLab(label); + } + + + public String getLab() { + return lab; + } + + + public String getVal() { + return val; + } + + + public void setLab(String label) { + this.lab = label; + } + + + public void setVal(String value) { + this.val = value; + } + + + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null) { + return false; + } + + if (!(o instanceof NameValueId)) { + return false; + } + + final NameValueId nameValueId = (NameValueId)o; + + if (!getVal().equals(nameValueId.getVal())) { + return false; + } + + if (!getLab().equals(nameValueId.getLab())) { + return false; + } + + return true; + } + + + public int hashCode() { + return getVal().hashCode(); + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Position.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Position.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Position.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Position.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Size.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Size.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Size.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/domain/support/Size.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleService.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleServiceImpl.java new file mode 100644 index 00000000..2aa0d1f2 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleServiceImpl.java @@ -0,0 +1,58 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.drools; + + +/** + * + * This is POC test class to execute sample rules + */ +public class DroolsRuleServiceImpl implements DroolsRuleService{ + + + private String state; + private String resultsString; + + public DroolsRuleServiceImpl() { + + } + + public void init(String... params) { + this.state = params[0]; + } + + + + public String getState() { + return state; + } + + public String accessLabel() { + return "Drools POC Test"; + } + + public String getResultsString() { + return resultsString; + } + + public void setResultsString(String resultsString) { + this.resultsString = resultsString; + } +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/FusionExceptionResolver.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/FusionExceptionResolver.java new file mode 100644 index 00000000..a2b4363a --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/FusionExceptionResolver.java @@ -0,0 +1,50 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.exception; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.servlet.ModelAndView; + +@ControllerAdvice +public class FusionExceptionResolver { + + @ExceptionHandler(UrlAccessRestrictedException.class) + public ModelAndView handleUrlAccessException(UrlAccessRestrictedException ex) { + ModelAndView model = new ModelAndView("error"); + model.addObject("errMsg", ex.getMessage()); + return model; + + } + @ExceptionHandler(SessionExpiredException.class) + public ModelAndView handleSessionException(SessionExpiredException ex) { + ModelAndView model = new ModelAndView("error"); + model.addObject("errMsg", ex.getMessage()); + return model; + } + @ExceptionHandler(Exception.class) + public ModelAndView handleAllException(Exception ex) { + ModelAndView model = new ModelAndView("error"); + model.addObject("errMsg", ex.getMessage()); + return model; + + } + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/SessionExpiredException.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/SessionExpiredException.java new file mode 100644 index 00000000..f4a19a9e --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/SessionExpiredException.java @@ -0,0 +1,35 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.exception; + +import org.openecomp.portalsdk.core.exception.support.FusionRuntimeException; + +public class SessionExpiredException extends FusionRuntimeException { + + /** + * + */ + private static final long serialVersionUID = 1L; + public static final String MESSAGE = "Your session has expired. Please login again."; + + public SessionExpiredException() { + super(MESSAGE); + } +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/UrlAccessRestrictedException.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/UrlAccessRestrictedException.java new file mode 100644 index 00000000..adc56118 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/UrlAccessRestrictedException.java @@ -0,0 +1,35 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.exception; + +import org.openecomp.portalsdk.core.exception.support.FusionRuntimeException; + +public class UrlAccessRestrictedException extends FusionRuntimeException { + + /** + * + */ + private static final long serialVersionUID = 1L; + public static final String MESSAGE = "Authorization Denied"; + + public UrlAccessRestrictedException() { + super(MESSAGE); + } +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionException.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionException.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionException.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionException.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionRuntimeException.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionRuntimeException.java new file mode 100644 index 00000000..91a733d4 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionRuntimeException.java @@ -0,0 +1,35 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.exception.support; + +public class FusionRuntimeException extends RuntimeException implements FusionException { + /** + * + */ + private static final long serialVersionUID = 1L; + public FusionRuntimeException() { + this(""); + } + + public FusionRuntimeException(String message) { + super(message); + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/interceptor/ResourceInterceptor.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/interceptor/ResourceInterceptor.java new file mode 100644 index 00000000..ec6e4b6c --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/interceptor/ResourceInterceptor.java @@ -0,0 +1,167 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.interceptor; + +import java.net.HttpURLConnection; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.openecomp.portalsdk.core.controller.FusionBaseController; +import org.openecomp.portalsdk.core.domain.App; +import org.openecomp.portalsdk.core.exception.UrlAccessRestrictedException; +import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.objectcache.AbstractCacheManager; +import org.openecomp.portalsdk.core.onboarding.listener.PortalTimeoutHandler; +import org.openecomp.portalsdk.core.onboarding.util.CipherUtil; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; +import org.openecomp.portalsdk.core.service.DataAccessService; +import org.openecomp.portalsdk.core.service.LoginService; +import org.openecomp.portalsdk.core.service.WebServiceCallService; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +public class ResourceInterceptor extends HandlerInterceptorAdapter { + public static final String APP_METADATA = "APP.METADATA"; + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ResourceInterceptor.class); + + @Autowired + private DataAccessService dataAccessService; + @Autowired + private LoginService loginService; + @Autowired + private WebServiceCallService webServiceCallService; + + private AbstractCacheManager cacheManager; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + String uri = request.getRequestURI(); + String url = uri.substring(uri.indexOf("/", 1) + 1); + logger.info(EELFLoggerDelegate.debugLogger, "Url - " + url); + logger.info(EELFLoggerDelegate.debugLogger, "lastIndexOf - " + uri.substring(uri.lastIndexOf("/") + 1)); + if (handler instanceof HandlerMethod) { + HandlerMethod method = (HandlerMethod) handler; + FusionBaseController controller = (FusionBaseController) method.getBean(); + if (!controller.isAccessible()) { + if (controller.isRESTfulCall()) { + // check user authentication for RESTful calls + String secretKey = null; + try { + if (!webServiceCallService.verifyRESTCredential(secretKey, request.getHeader("username"), + request.getHeader("password"))) { + logger.error(EELFLoggerDelegate.errorLogger, "Error accesing RESTful service. Un-authorized",AlarmSeverityEnum.MINOR); + throw new UrlAccessRestrictedException(); + } + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "Error authenticating RESTful service :" + e,AlarmSeverityEnum.MINOR); + //throw new UrlAccessRestrictedException(); + HttpSession httpSession = request.getSession(); + ((HttpServletResponse) response).setStatus(HttpURLConnection.HTTP_UNAUTHORIZED); + return false; + } + } + if (!UserUtils.isUrlAccessible(request, url)) { + logger.error(EELFLoggerDelegate.errorLogger, "Error accesing URL. Un-authorized",AlarmSeverityEnum.MINOR); + throw new UrlAccessRestrictedException(); + } + } + } + + logger.debug("successfully authorized rest call"); + logger.info(EELFLoggerDelegate.debugLogger, "successfully authorized rest call"); + handleSessionUpdates(request); + logger.debug("handled session updates for synchronization"); + logger.info(EELFLoggerDelegate.debugLogger, "handled session updates for synchronization"); + return super.preHandle(request, response, handler); + } + + /** + * + * @param request + */ + protected void handleSessionUpdates(HttpServletRequest request) { + + App app = null; + Object appObj = getCacheManager().getObject(APP_METADATA); + if (appObj == null) { + app = findApp(); + getCacheManager().putObject(APP_METADATA, app); + + } else { + app = (App) appObj; + } + + String ecompRestURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL); + String decreptedPwd = ""; + try { + decreptedPwd = CipherUtil.decrypt(app.getAppPassword(), + SystemProperties.getProperty(SystemProperties.Decryption_Key)); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "Could not decrypt Password" + e.getMessage(),AlarmSeverityEnum.MINOR); + } + + PortalTimeoutHandler.handleSessionUpdatesNative(request, app.getUsername(), decreptedPwd, + PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY), ecompRestURL, null); + } + + public App findApp() { + List list = null; + StringBuffer criteria = new StringBuffer(); + criteria.append(" where id = 1"); + list = getDataAccessService().getList(App.class, criteria.toString(), null, null); + return (list == null || list.size() == 0) ? null : (App) list.get(0); + } + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + public LoginService getLoginService() { + return loginService; + } + + public void setLoginService(LoginService loginService) { + this.loginService = loginService; + } + + @Autowired + public void setCacheManager(AbstractCacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + public AbstractCacheManager getCacheManager() { + return cacheManager; + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/interceptor/SessionTimeoutInterceptor.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/interceptor/SessionTimeoutInterceptor.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/interceptor/SessionTimeoutInterceptor.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/interceptor/SessionTimeoutInterceptor.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/interfaces/SecurityInterface.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/interfaces/SecurityInterface.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/interfaces/SecurityInterface.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/interfaces/SecurityInterface.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/listener/ApplicationContextListener.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/listener/ApplicationContextListener.java new file mode 100644 index 00000000..0cc99f0e --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/listener/ApplicationContextListener.java @@ -0,0 +1,49 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.listener; + +import javax.servlet.ServletContext; +import javax.servlet.annotation.WebListener; + +import org.openecomp.portalsdk.core.lm.FusionLicenseManager; +import org.openecomp.portalsdk.core.lm.FusionLicenseManagerUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +@WebListener +@Component +public class ApplicationContextListener implements ApplicationListener { + + @Autowired + ServletContext context; + @Autowired + FusionLicenseManager lm; + @Autowired + FusionLicenseManagerUtils fusionLicenseManagerUtils; + + + public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent ) { + int licenseStatus = fusionLicenseManagerUtils.verifyLicense(context); + context.setAttribute("licenseVerification", licenseStatus); + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/listener/CollaborateListBindingListener.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/listener/CollaborateListBindingListener.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/listener/CollaborateListBindingListener.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/listener/CollaborateListBindingListener.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/listener/UserSessionListener.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/listener/UserSessionListener.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/listener/UserSessionListener.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/listener/UserSessionListener.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/FusionLicenseManager.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/FusionLicenseManager.java new file mode 100644 index 00000000..eb371575 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/FusionLicenseManager.java @@ -0,0 +1,60 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.lm; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; + +//import de.schlichtherle.license.LicenseContent; + +public interface FusionLicenseManager { + + + public static final int DEVELOPER_LICENSE = 0; + public static final int EXPIRED_LICENSE = 1; + public static final int VALID_LICENSE = 2; + public static final int INVALID_LICENSE = 3; + public static final int OPENSOURCE_LICENSE = 4; + + public void initKeyStoreParam(); + + public void initCipherParam(); + + public void initLicenseParam(); + + public void doInitWork(); + + public int installLicense(); + + public int verifyLicense(ServletContext context); + + //public LicenseContent createLicenseContent(Map clientInfoMap, List ipAddressList); + + public void generateLicense(Map clientInfoMap, List ipAddressList) throws Exception; + + public String nvl(String s); + + public Date getExpiredDate(); + + public void setExpiredDate(Date expiredDate); +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/FusionLicenseManagerUtils.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/FusionLicenseManagerUtils.java new file mode 100644 index 00000000..538709e8 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/FusionLicenseManagerUtils.java @@ -0,0 +1,74 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.lm; + +import java.util.Date; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.util.SystemProperties; +//import org.openecomp.portalapp.lm.FusionLicenseManagerImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.support.RequestContextUtils; + +@Component +public class FusionLicenseManagerUtils { + + @Autowired + private FusionLicenseManager licenseManager; + + @Autowired + private SystemProperties sysProps; + static { + } + + public int verifyLicense(ServletContext context) { + if(sysProps == null) { + try { + sysProps = new SystemProperties(); + sysProps.setServletContext(context); +// sysProps.load(); +// licenseManager = new FusionLicenseManagerImpl(new LicenseableClassImpl()); + System.out.println(licenseManager); + licenseManager.installLicense(); + } + catch(Exception ex) { + ex.printStackTrace(); + } + } + + + +// WebApplicationContext ctx =RequestContextUtils.getWebApplicationContext(request); +// int flag = ((FusionLicenseManager)ctx.getBean("fusionLicenseManager")).verifyLicense(request); +// logger.debug("****************FLAG ******************** " + flag); +// return flag; +// return 2; + return licenseManager.verifyLicense(context); + } + + public static Date getLicenseExpiryDate(HttpServletRequest request) { + WebApplicationContext ctx =RequestContextUtils.getWebApplicationContext(request); + return ((FusionLicenseManager)ctx.getBean("fusionLicenseManager")).getExpiredDate(); + } +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/LicenseableClass.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/LicenseableClass.java new file mode 100644 index 00000000..296a1609 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/lm/LicenseableClass.java @@ -0,0 +1,38 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.lm; + +import java.io.*; + +/** + * created by Alvin Alexander of http://devdaily.com. + * modified by Sundar Ramalingam + */ +public interface LicenseableClass +{ + public String getApplicationName(); + public InputStream getPublicKeystoreAsInputStream() throws FileNotFoundException; + public String getAlias(); + public String getPublicKeystorePassword(); + public String getKeyPasswd(); + public String getCipherParamPassword(); + public Class getClassToLicense(); + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/AuditLog.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/AuditLog.java new file mode 100644 index 00000000..6cb661b1 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/AuditLog.java @@ -0,0 +1,32 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.logging.aspect; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuditLog { + String value() default ""; +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAdvice.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAdvice.java new file mode 100644 index 00000000..da4e2aff --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAdvice.java @@ -0,0 +1,234 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.logging.aspect; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.logging.format.AuditLogFormatter; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.service.AppService; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.util.SystemProperties.SecurityEventTypeEnum; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Autowired; + +import com.att.eelf.configuration.Configuration; + +@org.springframework.context.annotation.Configuration +public class EELFLoggerAdvice { + + @Autowired + AppService appService; + + EELFLoggerDelegate adviceLogger = EELFLoggerDelegate.getLogger(EELFLoggerAdvice.class); + + // DateTime Format according to the ECOMP Application Logging Guidelines. + private static final SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + + /** + * Gets the current date and time in expected ECOMP log format. + * + * @return Current date and time + */ + public static String getCurrentDateTimeUTC() { + String currentDateTime = ecompLogDateFormat.format(new Date()); + return currentDateTime; + } + + /** + * + * @param securityEventType + * @param args + * @param passOnArgs + * @return One-element array containing an empty String object. + */ + public Object[] before(SecurityEventTypeEnum securityEventType, Object[] args, Object[] passOnArgs) { + try { + String className = ""; + if (passOnArgs[0] != null) { + className = passOnArgs[0].toString(); + } + + String methodName = ""; + if (passOnArgs[1] != null) { + methodName = passOnArgs[1].toString(); + } + + String appName = appService.getDefaultAppName(); + if (appName == null || appName == "") { + appName = SystemProperties.SDK_NAME; + } + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className); + + // Initialize Request defaults only for controller methods. + MDC.put(className + methodName + SystemProperties.METRICSLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC()); + MDC.put(SystemProperties.TARGET_ENTITY, appName + "_BE"); + MDC.put(SystemProperties.TARGET_SERVICE_NAME, methodName); + if (securityEventType != null) { + MDC.put(className + methodName + SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC()); + HttpServletRequest req = null; + if (args[0] != null && args[0] instanceof HttpServletRequest) { + req = (HttpServletRequest) args[0]; + logger.setRequestBasedDefaultsIntoGlobalLoggingContext(req, appName); + } + } + logger.debug(EELFLoggerDelegate.debugLogger, (methodName + " was invoked.")); + } catch (Exception e) { + adviceLogger.error(EELFLoggerDelegate.errorLogger, + "Exception occurred in EELFLoggerAdvice.before() method. Details: " + e.getMessage()); + } + + return new Object[] { "" }; + } + + /** + * + * @param securityEventType + * @param result + * @param args + * @param returnArgs + * @param passOnArgs + */ + public void after(SecurityEventTypeEnum securityEventType, String result, Object[] args, Object[] returnArgs, + Object[] passOnArgs) { + try { + String className = ""; + if (passOnArgs[0] != null) { + className = passOnArgs[0].toString(); + } + + String methodName = ""; + if (passOnArgs[1] != null) { + methodName = passOnArgs[1].toString(); + } + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className); + + String appName = appService.getDefaultAppName(); + if (appName == null || appName == "") { + appName = SystemProperties.SDK_NAME; + } + + if (MDC.get(SystemProperties.TARGET_SERVICE_NAME) == null + || MDC.get(SystemProperties.TARGET_SERVICE_NAME) == "") { + MDC.put(SystemProperties.TARGET_SERVICE_NAME, methodName); + } + + if (MDC.get(SystemProperties.TARGET_ENTITY) == null || MDC.get(SystemProperties.TARGET_ENTITY) == "") { + MDC.put(SystemProperties.TARGET_ENTITY, appName + "_BE"); + } + + MDC.put(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP, + MDC.get(className + methodName + SystemProperties.METRICSLOG_BEGIN_TIMESTAMP)); + MDC.put(SystemProperties.METRICSLOG_END_TIMESTAMP, getCurrentDateTimeUTC()); + this.calculateDateTimeDifference(MDC.get(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP), + MDC.get(SystemProperties.METRICSLOG_END_TIMESTAMP)); + + logger.info(EELFLoggerDelegate.metricsLogger, methodName + " operation is completed."); + logger.debug(EELFLoggerDelegate.debugLogger, "Finished executing " + methodName + "."); + + if (securityEventType != null) { + + MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, + MDC.get(className + methodName + SystemProperties.AUDITLOG_BEGIN_TIMESTAMP)); + MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, getCurrentDateTimeUTC()); + this.calculateDateTimeDifference(MDC.get(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP), + MDC.get(SystemProperties.AUDITLOG_END_TIMESTAMP)); + + this.logSecurityMessage(logger, securityEventType, result, methodName); + + // clear when finishes audit logging + MDC.remove(Configuration.MDC_KEY_REQUEST_ID); + MDC.remove(SystemProperties.PARTNER_NAME); + MDC.remove(SystemProperties.MDC_LOGIN_ID); + MDC.remove(SystemProperties.PROTOCOL); + MDC.remove(SystemProperties.FULL_URL); + MDC.remove(Configuration.MDC_SERVICE_NAME); + MDC.remove(SystemProperties.RESPONSE_CODE); + MDC.remove(SystemProperties.STATUS_CODE); + MDC.remove(className + methodName + SystemProperties.AUDITLOG_BEGIN_TIMESTAMP); + MDC.remove(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP); + MDC.remove(SystemProperties.AUDITLOG_END_TIMESTAMP); + } + + MDC.remove(className + methodName + SystemProperties.METRICSLOG_BEGIN_TIMESTAMP); + MDC.remove(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP); + MDC.remove(SystemProperties.METRICSLOG_END_TIMESTAMP); + MDC.remove(SystemProperties.MDC_TIMER); + MDC.remove(SystemProperties.TARGET_ENTITY); + MDC.remove(SystemProperties.TARGET_SERVICE_NAME); + } catch (Exception e) { + adviceLogger.error(EELFLoggerDelegate.errorLogger, + "Exception occurred in EELFLoggerAdvice.after() method. Details: " + e.getMessage()); + } + } + + /** + * + * @param logger + * @param securityEventType + * @param result + * @param restMethod + */ + private void logSecurityMessage(EELFLoggerDelegate logger, SecurityEventTypeEnum securityEventType, String result, + String restMethod) { + StringBuilder additionalInfoAppender = new StringBuilder(); + String auditMessage = ""; + + additionalInfoAppender.append(String.format("%s request was received.", restMethod)); + + // Status code + MDC.put(SystemProperties.STATUS_CODE, result); + + String fullURL = MDC.get(SystemProperties.FULL_URL); + if (fullURL != null && fullURL != "") { + additionalInfoAppender.append(" Request-URL:" + MDC.get(SystemProperties.FULL_URL)); + } + + auditMessage = AuditLogFormatter.getInstance().createMessage(MDC.get(SystemProperties.PROTOCOL), + securityEventType.name(), MDC.get(SystemProperties.MDC_LOGIN_ID), additionalInfoAppender.toString()); + + logger.info(EELFLoggerDelegate.auditLogger, auditMessage); + } + + /** + * + * @param beginDateTime + * @param endDateTime + */ + private void calculateDateTimeDifference(String beginDateTime, String endDateTime) { + if (beginDateTime != null && endDateTime != null) { + try { + Date beginDate = ecompLogDateFormat.parse(beginDateTime); + Date endDate = ecompLogDateFormat.parse(endDateTime); + String timeDifference = String.format("%d ms", endDate.getTime() - beginDate.getTime()); + MDC.put(SystemProperties.MDC_TIMER, timeDifference); + } catch (Exception e) { + adviceLogger.error(EELFLoggerDelegate.errorLogger, + "Exception occurred in EELFLoggerAdvice.calculateDateTimeDifference() method. Details: " + + e.getMessage()); + } + } + } +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAspect.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAspect.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAspect.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAspect.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/MetricsLog.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/MetricsLog.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/MetricsLog.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/aspect/MetricsLog.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/AlarmSeverityEnum.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/AlarmSeverityEnum.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/AlarmSeverityEnum.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/AlarmSeverityEnum.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/AppMessagesEnum.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/AppMessagesEnum.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/AppMessagesEnum.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/AppMessagesEnum.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ApplicationCodes.properties b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ApplicationCodes.properties similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ApplicationCodes.properties rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ApplicationCodes.properties diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/AuditLogFormatter.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/AuditLogFormatter.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/AuditLogFormatter.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/AuditLogFormatter.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorCodesEnum.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorCodesEnum.java new file mode 100644 index 00000000..549d3262 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorCodesEnum.java @@ -0,0 +1,89 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.logging.format; + +import com.att.eelf.i18n.EELFResolvableErrorEnum; +//import com.att.eelf.i18n.EELFResourceManager; + +public enum ErrorCodesEnum implements EELFResolvableErrorEnum { + BERESTAPIAUTHENTICATIONERROR, + BEHTTPCONNECTIONERROR_ONE_ARGUMENT, + BEUEBAUTHENTICATIONERROR_ONE_ARGUMENT, + + INTERNALAUTHENTICATIONINFO_ONE_ARGUMENT, + INTERNALAUTHENTICATIONWARNING_ONE_ARGUMENT, + INTERNALAUTHENTICATIONERROR_ONE_ARGUMENT, + INTERNALAUTHENTICATIONFATAL_ONE_ARGUMENT, + + BEHEALTHCHECKRECOVERY, + BEHEALTHCHECKMYSQLRECOVERY, + BEHEALTHCHECKUEBCLUSTERRECOVERY, + FEHEALTHCHECKRECOVERY, + BeHEALTHCHECKERROR, + + BEHEALTHCHECKMYSQLERROR, + BEHEALTHCHECKUEBCLUSTERERROR, + FEHEALTHCHECKERROR, + BEUEBCONNECTIONERROR_ONE_ARGUMENT, + BEUEBUNKOWNHOSTERROR_ONE_ARGUMENT, + BEUEBREGISTERONBOARDINGAPPERROR, + + INTERNALCONNECTIONINFO_ONE_ARGUMENT, + INTERNALCONNECTIONWARNING_ONE_ARGUMENT, + INTERNALCONNECTIONERROR_ONE_ARGUMENT, + INTERNALCONNECTIONFATAL_ONE_ARGUMENT, + + BEUEBOBJECTNOTFOUNDERROR_ONE_ARGUMENT, + BEUSERMISSINGERROR_ONE_ARGUMENT, + + BEUSERINACTIVEWARNING_ONE_ARGUMENT, + BEUSERADMINPRIVILEGESINFO_ONE_ARGUMENT, + + BEINVALIDJSONINPUT, + BEINCORRECTHTTPSTATUSERROR, + + BEINITIALIZATIONERROR, + BEUEBSYSTEMERROR, + BEDAOSYSTEMERROR, + BESYSTEMERROR, + BEEXECUTEROLLBACKERROR, + + FEHTTPLOGGINGERROR, + FEPORTALSERVLETERROR, + BEDAOCLOSESESSIONERROR, + + BERESTAPIGENERALERROR, + FEHEALTHCHECKGENERALERROR, + + INTERNALUNEXPECTEDINFO_ONE_ARGUMENT, + INTERNALUNEXPECTEDWARNING_ONE_ARGUMENT, + INTERNALUNEXPECTEDERROR_ONE_ARGUMENT, + INTERNALUNEXPECTEDFATAL_ONE_ARGUMENT, + + ; + + /** + * Static initializer to ensure the resource bundles for this class are loaded... + * Here this application loads messages from three bundles + */ + //static { + // EELFResourceManager.loadMessageBundle("com/att/fusion/core/logging/format/ApplicationCodes"); + //} +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorSeverityEnum.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorSeverityEnum.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorSeverityEnum.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorSeverityEnum.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorTypeEnum.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorTypeEnum.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorTypeEnum.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorTypeEnum.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/logic/EELFLoggerDelegate.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/logic/EELFLoggerDelegate.java new file mode 100644 index 00000000..319caf3c --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/logging/logic/EELFLoggerDelegate.java @@ -0,0 +1,484 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.logging.logic; + +import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY; +import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID; +import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; +import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN; +import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + +import java.net.InetAddress; +import java.text.MessageFormat; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.logging.aspect.EELFLoggerAdvice; +import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; +import org.openecomp.portalsdk.core.logging.format.AppMessagesEnum; +import org.openecomp.portalsdk.core.logging.format.ErrorSeverityEnum; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.web.support.UserUtils; +import org.slf4j.MDC; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.configuration.SLF4jWrapper; + +public class EELFLoggerDelegate extends SLF4jWrapper implements EELFLogger { + + public static EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger(); + public static EELFLogger applicationLogger = EELFManager.getInstance().getApplicationLogger(); + public static EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger(); + public static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + public static EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger(); + private String className; + private static ConcurrentMap classMap = new ConcurrentHashMap(); + + public EELFLoggerDelegate(String _className) { + super(_className); + className = _className; + } + + /** + * Convenience method that gets a logger for the specified class. + * + * @see #getLogger(String) + * + * @param clazz + * @return Instance of EELFLoggerDelegate + */ + public static EELFLoggerDelegate getLogger(Class clazz) { + return getLogger(clazz.getName()); + } + + /** + * Gets a logger for the specified class name. If the logger does not + * already exist in the map, this creates a new logger. + * + * @param className + * If null or empty, uses EELFLoggerDelegate as the class name. + * @return Instance of EELFLoggerDelegate + */ + public static EELFLoggerDelegate getLogger(String className) { + if (className == null || className == "") + className = EELFLoggerDelegate.class.getName(); + EELFLoggerDelegate delegate = classMap.get(className); + if (delegate == null) { + delegate = new EELFLoggerDelegate(className); + classMap.put(className, delegate); + } + return delegate; + } + + /** + * Logs a message at the lowest level: trace. + * + * @param logger + * @param msg + */ + public void trace(EELFLogger logger, String msg) { + if (logger.isTraceEnabled()) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.trace(msg); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + } + + /** + * Logs a message with parameters at the lowest level: trace. + * + * @param logger + * @param msg + * @param arguments + */ + public void trace(EELFLogger logger, String msg, Object... arguments) { + if (logger.isTraceEnabled()) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.trace(msg, arguments); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + } + + /** + * Logs a message and throwable at the lowest level: trace. + * + * @param logger + * @param msg + * @param th + */ + public void trace(EELFLogger logger, String msg, Throwable th) { + if (logger.isTraceEnabled()) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.trace(msg, th); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + } + + /** + * Logs a message at the second-lowest level: debug. + * + * @param logger + * @param msg + */ + public void debug(EELFLogger logger, String msg) { + if (logger.isDebugEnabled()) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.debug(msg); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + } + + /** + * Logs a message with parameters at the second-lowest level: debug. + * + * @param logger + * @param msg + * @param arguments + */ + public void debug(EELFLogger logger, String msg, Object... arguments) { + if (logger.isDebugEnabled()) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.debug(msg, arguments); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + } + + /** + * Logs a message and throwable at the second-lowest level: debug. + * + * @param logger + * @param msg + * @param th + */ + public void debug(EELFLogger logger, String msg, Throwable th) { + if (logger.isDebugEnabled()) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.debug(msg, th); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + } + + /** + * Logs a message at info level. + * + * @param logger + * @param msg + */ + public void info(EELFLogger logger, String msg) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.info(msg); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Logs a message with parameters at info level. + * + * @param logger + * @param msg + * @param arguments + */ + public void info(EELFLogger logger, String msg, Object... arguments) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.info(msg, arguments); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Logs a message and throwable at info level. + * + * @param logger + * @param msg + * @param th + */ + public void info(EELFLogger logger, String msg, Throwable th) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.info(msg, th); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Logs a message at warn level. + * + * @param logger + * @param msg + */ + public void warn(EELFLogger logger, String msg) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.warn(msg); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Logs a message with parameters at warn level. + * + * @param logger + * @param msg + * @param arguments + */ + public void warn(EELFLogger logger, String msg, Object... arguments) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.warn(msg, arguments); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Logs a message and throwable at warn level. + * + * @param logger + * @param msg + * @param th + */ + public void warn(EELFLogger logger, String msg, Throwable th) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.warn(msg, th); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Logs a message at error level. + * + * @param logger + * @param msg + */ + public void error(EELFLogger logger, String msg) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.error(msg); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Logs a message with parameters at error level. + * + * @param logger + * @param msg + * @param arguments + */ + public void error(EELFLogger logger, String msg, Object... arguments) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.warn(msg, arguments); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Logs a message and throwable at error level. + * + * @param logger + * @param msg + * @param th + */ + public void error(EELFLogger logger, String msg, Throwable th) { + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.warn(msg, th); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Logs a message with the associated alarm severity at error level. + * + * @param logger + * @param msg + * @param severtiy + */ + public void error(EELFLogger logger, String msg, AlarmSeverityEnum severtiy) { + MDC.put(MDC_ALERT_SEVERITY, severtiy.name()); + MDC.put(SystemProperties.MDC_CLASS_NAME, className); + logger.error(msg); + MDC.remove(MDC_ALERT_SEVERITY); + MDC.remove(SystemProperties.MDC_CLASS_NAME); + } + + /** + * Initializes the logger context. + */ + public void init() { + setGlobalLoggingContext(); + final String msg = "############################ Logging is started. ############################"; + // These loggers emit the current date-time without being told. + info(applicationLogger, msg); + error(errorLogger, msg); + debug(debugLogger, msg); + // Audit and metrics logger must be told start AND stop times + final String currentDateTime = EELFLoggerAdvice.getCurrentDateTimeUTC(); + // Set the MDC with audit properties + MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, currentDateTime); + MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, currentDateTime); + info(auditLogger, msg); + MDC.remove(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP); + MDC.remove(SystemProperties.AUDITLOG_END_TIMESTAMP); + // Set the MDC with metrics properties + MDC.put(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP, currentDateTime); + MDC.put(SystemProperties.METRICSLOG_END_TIMESTAMP, currentDateTime); + info(metricsLogger, msg); + MDC.remove(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP); + MDC.remove(SystemProperties.METRICSLOG_END_TIMESTAMP); + } + + /** + * Logs a standard message identified by the specified enum, using the + * specified parameters, at error level. Alarm and error severity are taken + * from the specified enum argument. + * + * @param epMessageEnum + * @param param + */ + public void logEcompError(AppMessagesEnum epMessageEnum, String... param) { + try { + AlarmSeverityEnum alarmSeverityEnum = epMessageEnum.getAlarmSeverity(); + ErrorSeverityEnum errorSeverityEnum = epMessageEnum.getErrorSeverity(); + + MDC.put(MDC_ALERT_SEVERITY, alarmSeverityEnum.name()); + MDC.put("ErrorCode", epMessageEnum.getErrorCode()); + MDC.put("ErrorDescription", epMessageEnum.getErrorDescription()); + + String resolution = this.formatMessage(epMessageEnum.getDetails() + " " + epMessageEnum.getResolution(), + (Object[]) param); + if (errorSeverityEnum == ErrorSeverityEnum.WARN) { + errorLogger.warn(resolution); + } else if (errorSeverityEnum == ErrorSeverityEnum.INFO) { + errorLogger.info(resolution); + } else { + errorLogger.error(resolution); + } + } catch (Exception e) { + errorLogger.error("Failed to log the error code. Details: " + UserUtils.getStackTrace(e)); + } finally { + MDC.remove("ErrorCode"); + MDC.remove("ErrorDescription"); + MDC.remove(MDC_ALERT_SEVERITY); + } + } + + /** + * Builds a message using a template string and the arguments. + * + * @param message + * @param args + * @return + */ + private String formatMessage(String message, Object... args) { + StringBuilder sbFormattedMessage = new StringBuilder(); + if (args != null && args.length > 0 && message != null && message != "") { + MessageFormat mf = new MessageFormat(message); + sbFormattedMessage.append(mf.format(args)); + } else { + sbFormattedMessage.append(message); + } + + return sbFormattedMessage.toString(); + } + + /** + * Loads all the default logging fields into the MDC context. + */ + private void setGlobalLoggingContext() { + MDC.put(MDC_SERVICE_INSTANCE_ID, ""); + MDC.put(MDC_ALERT_SEVERITY, AlarmSeverityEnum.INFORMATIONAL.toString()); + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName()); + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + MDC.put(MDC_INSTANCE_UUID, SystemProperties.getProperty(SystemProperties.INSTANCE_UUID)); + } catch (Exception e) { + } + } + + public static void mdcPut(String key, String value) { + MDC.put(key, value); + } + + public static String mdcGet(String key) { + return MDC.get(key); + } + + public static void mdcRemove(String key) { + MDC.remove(key); + } + + /** + * Loads the RequestId/TransactionId into the MDC which it should be + * receiving with an each incoming REST API request. Also, configures few + * other request based logging fields into the MDC context. + * + * @param req + * @param appName + */ + public void setRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req, String appName) { + // Load the default fields + setGlobalLoggingContext(); + + // Load the request based fields + if (req != null) { + // Load the Request into MDC context. + String requestId = UserUtils.getRequestId(req); + MDC.put(MDC_KEY_REQUEST_ID, requestId); + + // Load user agent into MDC context, if available. + String accessingClient = "Unknown"; + accessingClient = req.getHeader(SystemProperties.USERAGENT_NAME); + if (accessingClient != null && accessingClient != "" && (accessingClient.contains("Mozilla") + || accessingClient.contains("Chrome") || accessingClient.contains("Safari"))) { + accessingClient = appName + "_FE"; + } + MDC.put(SystemProperties.PARTNER_NAME, accessingClient); + + // Protocol, Rest URL & Rest Path + String restURL = ""; + MDC.put(SystemProperties.FULL_URL, SystemProperties.UNKNOWN); + MDC.put(SystemProperties.PROTOCOL, SystemProperties.HTTP); + restURL = UserUtils.getFullURL(req); + if (restURL != null && restURL != "") { + MDC.put(SystemProperties.FULL_URL, restURL); + if (restURL.toLowerCase().contains("https")) { + MDC.put(SystemProperties.PROTOCOL, SystemProperties.HTTPS); + } + } + + // Rest Path + MDC.put(MDC_SERVICE_NAME, req.getServletPath()); + + // Client IPAddress i.e. IPAddress of the remote host who is making + // this request. + String clientIPAddress = ""; + clientIPAddress = req.getHeader("X-FORWARDED-FOR"); + if (clientIPAddress == null) { + clientIPAddress = req.getRemoteAddr(); + } + MDC.put(SystemProperties.CLIENT_IP_ADDRESS, clientIPAddress); + + // Load loginId into MDC context. + MDC.put(SystemProperties.MDC_LOGIN_ID, "Unknown"); + + String loginId = ""; + User user = UserUtils.getUserSession(req); + if (user != null) { + loginId = user.getLoginId(); + } + + if (loginId != null && loginId != "") { + MDC.put(SystemProperties.MDC_LOGIN_ID, loginId); + } + } + } +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/menu/MenuBuilder.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/menu/MenuBuilder.java new file mode 100644 index 00000000..d856e7ee --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/menu/MenuBuilder.java @@ -0,0 +1,163 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.menu; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.FusionObject; +import org.openecomp.portalsdk.core.domain.MenuData; +import org.openecomp.portalsdk.core.service.DataAccessService; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.factory.annotation.Autowired; + +@SuppressWarnings("rawtypes") +public class MenuBuilder implements FusionObject { + + @Autowired + private DataAccessService dataAccessService; + + public MenuBuilder() { + } + + @SuppressWarnings("unchecked") + public Set getMenu(String menuSetName, DataAccessService dataAccessService) { + + Set menu = null; + MenuData root = null; + + HashMap params = new HashMap(); + + params.put("menu_set_cd", menuSetName); + + // execute a query of the latest configuration of the FN_MENU table for the given menu_set_cd. + List menuItems = dataAccessService.executeNamedQuery(SystemProperties.getProperty(SystemProperties.MENU_QUERY_NAME), params, null); + + Iterator i = menuItems.iterator(); + if (i.hasNext()) { + root = (MenuData)i.next(); + menu = root.getChildMenus(); + } + + return menu; + } + + @SuppressWarnings("unchecked") + public Set getMenu(String menuSetName) { + + Set menu = null; + MenuData root = null; + + HashMap params = new HashMap(); + + params.put("menu_set_cd", menuSetName); + + // execute a query of the latest configuration of the FN_MENU table for the given menu_set_cd. + List menuItems = getDataAccessService().executeNamedQuery(SystemProperties.getProperty(SystemProperties.MENU_QUERY_NAME), params, null); + + Iterator i = menuItems.iterator(); + if (i.hasNext()) { + root = (MenuData)i.next(); + menu = root.getChildMenus(); + } + + return menu; + } + + public static Set filterMenu(Set menus, HttpServletRequest request) { + Iterator j = menus.iterator(); + + while (j.hasNext()) { + MenuData menuItem = (MenuData)j.next(); + + if (!UserUtils.isAccessible(request, menuItem.getFunctionCd())) { + // remove the menu if the user doesn't have access to it + j.remove(); + } + else { + // if an accessible menu has a child menu, let's filter that recursively + + Set childMenus = menuItem.getChildMenus(); + if (childMenus != null && childMenus.size() > 0) { + filterMenu(childMenus, request); + } + + } + } + + return menus; + } + + + public static String getUrlHtml(MenuData menuData) { + String html = ""; + + if (menuData.getExternalUrl() != null && menuData.getExternalUrl().length() > 0) { + html = menuData.getExternalUrl(); + } + else if (menuData.getServlet() != null && menuData.getServlet().length() > 0) { + html = "/" + menuData.getServlet(); + } + else if (menuData.getAction() != null && menuData.getAction().length() > 0) { + html = "/" + menuData.getAction(); + } + + return html; + } + + + public static String getTargetHtml(MenuData menuData) { + String html = ""; + + if (menuData.getTarget() != null && menuData.getTarget().length() > 0) { + html = "target=\"" + menuData.getTarget() + "\""; + } + + return html; + } + + + public static String getQueryStringHtml(MenuData menuData) { + String html = ""; + + if (menuData.getQueryString() != null && menuData.getQueryString().length() > 0) { + html = "?" + menuData.getQueryString(); + } + + return html; + } + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + +} + + diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/menu/MenuProperties.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/menu/MenuProperties.java new file mode 100644 index 00000000..e55baeb4 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/menu/MenuProperties.java @@ -0,0 +1,114 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.menu; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Properties; + +import javax.servlet.ServletContext; + +import org.openecomp.portalsdk.core.util.SystemProperties; + + +/* + MenuProperties contains a list of constants used during the creation, + privilege screening, and rendering of the application menu. +*/ +public class MenuProperties { + private MenuProperties() { + // cannot instantiate + } + + @SuppressWarnings("rawtypes") + private static HashMap menuProperties = new HashMap(); + + // keys used to reference values in the menu.properties file + public static final String WIDTH = "width"; + public static final String LEFT_POSITION = "left_position"; + public static final String TOP_POSITION = "top_position"; + public static final String FONT_COLOR = "font_color"; + public static final String MOUSEOVER_FONT_COLOR = "mouseover_font_color"; + public static final String BACKGROUND_COLOR = "background_color"; + public static final String MOUSEOVER_BACKGROUND_COLOR = "mouseover_background_color"; + public static final String BORDER_COLOR = "border_color"; + public static final String SEPARATOR_COLOR = "separator_color"; + public static final String IMAGE_SRC = "image_src"; + public static final String IMAGE_SRC_LEFT = "image_src_left"; + public static final String IMAGE_SRC_OVER = "image_src_over"; + public static final String IMAGE_SRC_LEFT_OVER = "image_src_left_over"; + public static final String EVALUATE_UPON_TREE_SHOW = "evaluate_upon_tree_show"; + public static final String EVALUATE_UPON_TREE_HIDE = "evaluate_upon_tree_hide"; + public static final String TOP_IS_PERMANENT = "top_is_permanent"; + public static final String TOP_IS_HORIZONTAL = "top_is_horizontal"; + public static final String TREE_IS_HORIZONTAL = "tree_is_horizontal"; + public static final String POSITION_UNDER = "position_under"; + public static final String TOP_MORE_IMAGES_VISIBLE = "top_more_images_visible"; + public static final String TREE_MORE_IMAGES_VISIBLE = "tree_more_images_visible"; + public static final String RIGHT_TO_LEFT = "right_to_left"; + public static final String DISPLAY_ON_CLICK = "display_on_click"; + public static final String TOP_IS_VARIABLE_WIDTH = "top_is_variable_width"; + public static final String TREE_IS_VARIABLE_WIDTH = "tree_is_variable_width"; + public static final String TOP_KEEP_IN_WINDOW_X = "top_keep_in_window_x"; + public static final String TOP_KEEP_IN_WINDOW_Y = "top_keep_in_window_y"; + public static final String MENU_ID_ADMIN = "menu_id_admin"; + public static final String MENU_ID_LOGOUT = "menu_id_logout"; + public static final String MENU_FRAME = "menu_frame"; + public static final String MAIN_FRAME = "main_frame"; + public static final String NESTED_MAIN_FRAME = "nested_main_frame"; + public static final String ROLE_FUNCTIONS_TAG = "role_functions_tag"; + + public static final String MAX_DISPLAYABLE_ADMIN_MENU_SORT_ORDER = "max_displayable_admin_menu_sort_order"; + public static final String MENU_PROPERTIES_FILENAME_KEY = "menu_properties_filename"; + public static final String DEFAULT_SERVLET_NAME = "dispatcher"; + public static final String DEFAULT_TARGET = "_self"; + + public static final String TOP_MENU_CLASS = "top_menu_class"; + public static final String TOP_MENU_LINK_CLASS = "top_menu_link_class"; + + public static final String ON_MOUSE_OUT_TRAILER = "on_mouse_out_trailer"; + public static final String ON_MOUSE_OVER_TRAILER = "on_mouse_over_trailer"; + public static final String ON_CLICK_TRAILER = "on_click_trailer"; + + public static final String MENU_ID_PREFIX = "menu_id_prefix"; + + + @SuppressWarnings("unchecked") + public static void loadFromFile(ServletContext servletContext, String filename, String menuSetName) throws IOException { + Properties p = new Properties(); + + if (filename == null) { + filename = SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_PROPERTIES_NAME); + } + + p.load(servletContext.getResourceAsStream(SystemProperties.getProperty(SystemProperties.MENU_PROPERTIES_FILE_LOCATION) + filename)); + menuProperties.put(menuSetName, p); + } // loadMenuProperties + + public static String getProperty(String key) { + return getProperty(key, SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_SET_NAME)); + } + + public static String getProperty(String key, String menuSetName) { + Properties p = (Properties)menuProperties.get(menuSetName); + return p.getProperty(key); + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/AbstractCacheManager.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/AbstractCacheManager.java new file mode 100644 index 00000000..7c553ad5 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/AbstractCacheManager.java @@ -0,0 +1,60 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.objectcache; + +import java.io.*; + +import org.openecomp.portalsdk.core.objectcache.support.*; + + +public abstract class AbstractCacheManager implements FusionCacheManager { + public AbstractCacheManager() { + super(); + // TODO Auto-generated constructor stub + } + + public Object getObject(String key) { + // TODO Auto-generated method stub + return null; + } + + public void putObject(String key, Object objectToCache) { + // TODO Auto-generated method stub + } + + public boolean isObjectInCache(String key) { + // TODO Auto-generated method stub + return false; + } + + public void removeObject(String key) { + // TODO Auto-generated method stub + } + + public void clearCache() { + // TODO Auto-generated method stub + } + + public void configure() throws IOException { + // TODO Auto-generated method stub + + } +} + diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheEventHandler.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheEventHandler.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheEventHandler.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheEventHandler.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheManager.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheManager.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheManager.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/jcs/JCSCacheManager.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/support/FusionCacheManager.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/support/FusionCacheManager.java new file mode 100644 index 00000000..dee566e3 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/objectcache/support/FusionCacheManager.java @@ -0,0 +1,36 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.objectcache.support; + +import java.io.*; + +import org.openecomp.portalsdk.core.FusionObject; + +public interface FusionCacheManager extends FusionObject { + + Object getObject(String key); + void putObject(String key, Object objectToCache); + boolean isObjectInCache(String key); + + void removeObject(String key); + void clearCache(); + void configure() throws IOException; +} + diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/client/AppContextManager.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/client/AppContextManager.java new file mode 100644 index 00000000..1f54a8ec --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/client/AppContextManager.java @@ -0,0 +1,45 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.client; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * + * + * Use this class to get access to ApplicationContext for classes who were not created by Spring. + */ + + +@Component +public class AppContextManager implements ApplicationContextAware{ + private static ApplicationContext _appCtx; + + @Override + public void setApplicationContext(ApplicationContext ctx){ + _appCtx = ctx; + } + + public static ApplicationContext getAppContext(){ + return _appCtx; + } +} \ No newline at end of file diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/session/TestClass.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/session/TestClass.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/session/TestClass.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/session/TestClass.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/sso/TestClass.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/sso/TestClass.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/sso/TestClass.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/sso/TestClass.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java new file mode 100644 index 00000000..e9921d18 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java @@ -0,0 +1,155 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.LinkedList; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; + +import com.att.nsa.cambria.client.CambriaClientBuilders; +import com.att.nsa.cambria.client.CambriaConsumer; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Provides a consumer that reads messages from a UEB topic. Intended to be + * passed to a separate thread as its runnable object. + */ +public class Consumer implements Runnable { + + private final Log logger = LogFactory.getLog(getClass()); + + private final LinkedList urlList = Helper.uebUrlList(); + private final ConcurrentLinkedQueue queue; + private final WaitingRequestersQueueList waitingRequestersList; + private final String consumerKey, consumerSecret, topicName, consumerGroupName; + + /** + * Accepts coordinates needed to subscribe to a UEB topic, as well as the + * queues for passing along messages that arrive. + * + * @param consumerKey + * UEB key used to subscribe to the topic + * @param consumerSecret + * UEB secret used to subscribe to the topic + * @param topicName + * UEB topic name + * @param queue + * Queue to receive UEB messages. All inbound messages are + * enqueued here; ignored if null. + * @param waitingRequestersList + * Collection of queues to receive UEB messages that arrive in + * response to requests; i.e., emulating a synchronous request + * via pub/sub. + */ + public Consumer(String consumerKey, String consumerSecret, String topicName, String consumerGroupName, + ConcurrentLinkedQueue queue, WaitingRequestersQueueList waitingRequestersList) { + this.consumerKey = consumerKey; + this.consumerSecret = consumerSecret; + this.topicName = topicName; + this.consumerGroupName = consumerGroupName; + this.queue = queue; + this.waitingRequestersList = waitingRequestersList; + } + + /** + * Subscribes to a topic using credentials as supplied to the constructor. + * Distributes messages appropriately as they arrive: + *
          + *
        • If the queue is not null, adds the message to the queue. + *
        • If the message's getMsgId() method returns non-null and the ID is + * found in the collection of waiting requesters, adds the message in that + * requester's queue. + *
        + * + * This is intended to be called in a long running thread as a listener for + * any published messages on a topic. Typical async pub/sub model. We use a + * filter of "0" to prevent collisions with P2P messages with unique filter + * ids. + */ + protected void consume() throws IOException, UebException, GeneralSecurityException { + final String id = UUID.randomUUID().toString(); + + CambriaConsumer cc = null; + cc = new CambriaClientBuilders.ConsumerBuilder() + .usingHosts(urlList) + .authenticatedBy(consumerKey, consumerSecret) + .onTopic (topicName) + .knownAs (consumerGroupName,id) + .waitAtServer (15*1000) + .receivingAtMost (1000) + .build(); + + while (true) { + for (String msg : cc.fetch()) { + logger.debug(" <== consume from topicName " + topicName + " msg: " + msg); + UebMsg uebMsg = new ObjectMapper().readValue(msg, UebMsg.class); + if (queue != null) { + // Add to general queue allowing listeners to act on any + // incoming messages. We don't know if a listener is + // also going to be a responder to a synchronous + // request. So put all received messages on the general + // listener queue. + queue.add(uebMsg); + if (logger.isDebugEnabled()) + logger.debug("Added msg to queue " + this.queue + " queue count = " + queue.size() + " msg :" + + uebMsg.getPayload()); + } + if (waitingRequestersList != null && uebMsg.getMsgId() != null) { + // If a msgId is present, this could be a synchronous + // reply. Here we add it to the waiting requester's + // queue if we find a requester waiting for this msgId. + if (!(uebMsg.getMsgId() + .equals(PortalApiProperties.getProperty(PortalApiConstants.ECOMP_DEFAULT_MSG_ID)))) { + waitingRequestersList.addMsg(uebMsg.getMsgId(), uebMsg); + } + } + } + if (Thread.interrupted()) { + logger.warn(Thread.currentThread() + " interrupted, exiting"); + break; + } + Helper.sleep(10); + } + + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + consume(); + } catch (Exception ex) { + Thread t = Thread.currentThread(); + t.getUncaughtExceptionHandler().uncaughtException(t, ex); + } + } + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java new file mode 100644 index 00000000..7cf3e91c --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java @@ -0,0 +1,61 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Provides a convenience method for fetching the functional menu for a user + * from the ECOMP Portal via UEB. + */ +public class FunctionalMenu { + + private static final Log logger = LogFactory.getLog(FunctionalMenu.class); + + /** + * Makes a synchronous call to ECOMP Portal to get JSON with the functional + * menu, which arrives as the payload of the returned UEB message. + * + * @param userId + * User ID as known on the ECOMP Portal for customizing the + * functional menu appropriately + * @return JSON with functional menu + * @throws UebException + */ + public static String get(String userId) throws UebException { + String returnString = null; + logger.info("Making use of UEB communication and Requesting functional menu for user " + userId); + UebMsg funcMenuUebMsg = null; + UebMsg msg = new UebMsg(); + msg.putMsgType(UebMsgTypes.UEB_MSG_TYPE_GET_FUNC_MENU); + msg.putUserId(userId); + funcMenuUebMsg = UebManager.getInstance().requestReply(msg); + if (funcMenuUebMsg != null) { + if (funcMenuUebMsg.getPayload().startsWith("Error:")) { + logger.error("getFunctionalMenu received an error in UEB msg = " + funcMenuUebMsg.getPayload()); + } else { + returnString = funcMenuUebMsg.getPayload(); + } + } + return returnString; + } + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java new file mode 100644 index 00000000..6e6b4ae8 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java @@ -0,0 +1,64 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +import java.util.LinkedList; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; + +/** + * Provides utility methods. + */ +public class Helper { + + private static final Log logger = LogFactory.getLog(Helper.class); + + /** + * Parses a comma-separated list of UEB servers from properties file into a + * list. + * + * @return List of UEB server names + */ + public static LinkedList uebUrlList() { + LinkedList urlList = null; + String url = PortalApiProperties.getProperty(PortalApiConstants.UEB_URL_LIST); + if (url == null) { + logger.error("uebUrlList: failed to get property " + PortalApiConstants.UEB_URL_LIST); + return null; + } + urlList = new LinkedList(); + for (String u : url.split(",")) { + urlList.add(u.trim()); + } + return urlList; + } + + public static void sleep(int milliseconds) { + try { + Thread.sleep(milliseconds); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java new file mode 100644 index 00000000..8dbdda2b --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java @@ -0,0 +1,125 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.GeneralSecurityException; +import java.util.LinkedList; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; + +import com.att.nsa.cambria.client.CambriaBatchingPublisher; +import com.att.nsa.cambria.client.CambriaClientBuilders; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; + +/** + * Provides a publisher that sends messages to a UEB topic. + * + * Utilizes AT&T's UEB/Cambria subscriber/publisher messaging service. + */ +public class Publisher { + + private final Log logger = LogFactory.getLog(getClass()); + + protected final LinkedList urlList = Helper.uebUrlList(); + + private final String topicName; + private final String publisherKey; + private final String publisherSecret; + + /** + * Accepts coordinates needed to publish to a UEB topic. + * + * @param publisherKey + * UEB key used to publish to the topic + * @param publisherSecret + * UEB secret used to publish to the topic + * @param topicName + * UEB topic name + */ + public Publisher(String publisherKey, String publisherSecret, String topicName) { + this.publisherKey = publisherKey; + this.publisherSecret = publisherSecret; + this.topicName = topicName; + logger.info("Publisher instantiated for topic " + topicName); + } + + /** + * Creates a publisher, subscribes to the topic, sends the specified message + * to the topic, then closes the publisher. This ensures that the single + * message goes immediately. UEB is designed for high throughput and tries + * to batch up multiple messages in each send, but this method wants the + * single message to go immediately. + * + * @param uebMsg + * Message object to send as the payload. + * @throws UebException + * If anything goes wrong, including JSON serialization of the + * specified message object. + */ + public void send(UebMsg uebMsg) throws UebException { + String msg = null; + + CambriaBatchingPublisher pub; + try { + pub = new CambriaClientBuilders.PublisherBuilder() + .authenticatedBy(publisherKey, publisherSecret).usingHosts(urlList).onTopic(topicName).build(); + } catch (MalformedURLException e1) { + logger.error("pub.build Exception ", e1); + throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, e1, topicName, null, msg); + } catch (GeneralSecurityException e1) { + logger.error("pub.build Exception ", e1); + throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, e1, topicName, null, msg); + } + + try { + ObjectWriter mapper = new ObjectMapper().writer().withDefaultPrettyPrinter(); + msg = mapper.writeValueAsString(uebMsg); + } catch (JsonProcessingException e) { + throw new UebException(PortalApiConstants.ECOMP_UEB_INVALID_MSG, topicName, null, null); + } + + try { + logger.debug("Publishing to " + topicName + " msg: " + msg); + int NumSent = pub.send(PortalApiConstants.ECOMP_GENERAL_UEB_PARTITION, msg); + if (NumSent == 0) { + throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, topicName, null, msg); + } + } catch (IOException ex) { + logger.error("Failed to publish", ex); + throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, ex, topicName, null, msg); + } + + try { + // close the publisher to make sure everything's sent before exiting + pub.close(5, TimeUnit.SECONDS); + } catch (Exception ex) { + logger.error("pub.close Exception ", ex); + throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, ex, topicName, null, msg); + } + + } +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java new file mode 100644 index 00000000..6919236f --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java @@ -0,0 +1,77 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * A thin wrapper around ConcurrentHashMap that stores a queue for each + * Requester that is waiting for a Reply. When a reply is received that has a + * matching msgId, that requesters queue is populated with the reply message. + * + * Primarily for Portal core to track the remote applications that have placed + * requests; never used by those applications. + */ +public class PublisherList { + + private final Log logger = LogFactory.getLog(getClass()); + + private final Map map; + + public PublisherList() { + map = new ConcurrentHashMap<>(); + } + + public void addPublisherToMap(String topicName, Publisher publisher) { + if (this.map.containsKey(topicName)) { + logger.error("Publisher already exists for " + topicName); + } else { + this.map.put(topicName, publisher); + } + } + + public Publisher getPublisher(String topicName) { + return this.map.get(topicName); + } + + public void removePublisherFromMap(String topicName) { + this.map.remove(topicName); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Map contains " + this.map.size() + " Publishers."); + for (Map.Entry entry : this.map.entrySet()) { + String key = entry.getKey().toString(); + Publisher pub = entry.getValue(); + sb.append("Entry msgId, " + key + " publisher" + pub); + } + return sb.toString(); + } + + public int size() { + return this.map.size(); + } + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java new file mode 100644 index 00000000..8593b5bb --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java @@ -0,0 +1,135 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.LinkedList; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; + +import com.att.nsa.apiClient.http.HttpClient; +import com.att.nsa.apiClient.http.HttpException; +import com.att.nsa.cambria.client.CambriaClient.CambriaApiException; +import com.att.nsa.cambria.client.CambriaClientBuilders; +import com.att.nsa.cambria.client.CambriaClientFactory; +import com.att.nsa.cambria.client.CambriaTopicManager; + +/** + * Provides methods to facilitate creating topics, and adding publishers and + * subscribers to existing topics. + * + * Utilizes UEB/Cambria subscriber/publisher messaging service. + */ +public class TopicManager { + + private final Log logger = LogFactory.getLog(getClass()); + + /** + * Creates a topic with the specified information. + * + * @param key + * Topic key + * @param secret + * Topic secret key + * @param topicName + * Topic name + * @param topicDescription + * Topic description + * @throws HttpException + * @throws CambriaApiException + * @throws IOException + */ + public void createTopic(String key, String secret, String topicName, String topicDescription) + throws HttpException, CambriaApiException, IOException { + final LinkedList urlList = Helper.uebUrlList(); + if (logger.isInfoEnabled()) { + logger.info("==> createTopic"); + logger.info("topicName: " + topicName); + logger.info("topicDescription: " + topicDescription); + } + CambriaTopicManager tm =null; + try { + tm = CambriaClientFactory.createTopicManager(null, urlList, key, secret); + } catch (GeneralSecurityException e) { + logger.error("pub.build Exception ", e); + throw new CambriaApiException(topicName); + } + tm.createTopic(topicName, topicDescription, 1, 1); + } + + /** + * Modifies the specified topic to accept a subscriber using the specified + * key. + * + * @param topicOwnerKey + * @param topicOwnerSecret + * @param subscriberKey + * @param topicName + * @throws HttpException + * @throws CambriaApiException + * @throws IOException + */ + public void addSubscriber(String topicOwnerKey, String topicOwnerSecret, String subscriberKey, String topicName) + throws HttpException, CambriaApiException, IOException { + logger.info("==> addSubscriber to topic " + topicName); + final LinkedList urlList = Helper.uebUrlList(); + CambriaTopicManager tm = null; + try { + tm = new CambriaClientBuilders.TopicManagerBuilder().usingHosts(urlList).authenticatedBy(topicOwnerKey, topicOwnerSecret).build(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + //old version num : CambriaClientFactory.createTopicManager(urlList, topicOwnerKey,topicOwnerSecret); + tm.allowConsumer(topicName, subscriberKey); + } + + /** + * Modifies the specified topic to accept a publisher using the specified + * key. + * + * @param topicOwnerKey + * @param topicOwnerSecret + * @param publisherKey + * @param topicName + * @throws HttpException + * @throws CambriaApiException + * @throws IOException + */ + + @SuppressWarnings("deprecation") + public void addPublisher(String topicOwnerKey, String topicOwnerSecret, String publisherKey, String topicName) + throws HttpException, CambriaApiException, IOException { + logger.info("==> addPublisher to topic " + topicName); + final LinkedList urlList = Helper.uebUrlList(); + CambriaTopicManager tm =null; + try { + tm = CambriaClientFactory.createTopicManager(HttpClient.ConnectionType.HTTPS, urlList, topicOwnerKey, + topicOwnerSecret); + } catch (GeneralSecurityException e) { + logger.error("pub.build Exception ", e); + throw new CambriaApiException(topicName); + } + tm.allowProducer(topicName, publisherKey); + } +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java new file mode 100644 index 00000000..875ba58d --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java @@ -0,0 +1,65 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +/** + * Stores UEB-specific information including topic, message ID and message body. + */ +public class UebException extends Exception { + + private static final long serialVersionUID = 1L; + private String topicName = null; + private String msgId = null; + private String msg = null; + + public UebException(String errorMsg, String topicName, String msgId, String msg) { + super(errorMsg); + this.topicName = topicName; + this.msgId = msgId; + this.msg = msg; + } + + public UebException(String errorMsg, Throwable ex, String topicName, String msgId, String msg) { + super(errorMsg, ex); + this.topicName = topicName; + this.msgId = msgId; + this.msg = msg; + } + + public UebException(String msg, Throwable ex) { + super(msg, ex); + } + + public UebException(Throwable ex) { + super(ex); + } + + public String getUebMsg() { + return this.msg; + } + + public String getTopicName() { + return this.topicName; + } + + public String getMsgId() { + return this.msgId; + } +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java new file mode 100644 index 00000000..7bf6de35 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java @@ -0,0 +1,358 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +import java.io.IOException; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; + +/** + * Manages UEB interactions and provides methods for publishing requests, + * replies and others. + */ +public class UebManager { + + private final Log logger = LogFactory.getLog(getClass()); + + private WaitingRequestersQueueList waitingRequestersQueueList; + private PublisherList publisherList = new PublisherList(); + private static UebManager uebManager = null; + + private final String inTopicName; + private final String consumerGroupName; + private final String outTopicName; + private final String appUebKey; + private final String appUebSecret; + + private Publisher appPublisher; + private Thread listenerThread; + private boolean bThisIsEcompPortalServer = false; + + /** + * Constructor initializes fields and validates values obtained from + * properties. + * + * The picture below is a simplified view of the relationships among ECOMP + * Portal and applications communicating via UEB: + * + *
        +	*                      ECOMP out to many.
        +	*                      App out to only ECOMP.
        +	*
        +	*  |----------------|<---------------------------------------------   
        +	*  |                |                                         | |  |
        +	*  |                |---------------------------> App 1 ------  |  |
        +	*  |  ECOMP Portal  |---------------------------> App 2 ---------  |
        +	*  |                |                            ...               |
        +	*  |                |---------------------------> App n -----------
        +	*  |----------------|
        +	 * 
        + * + * @throws IOException + */ + protected UebManager() throws UebException { + waitingRequestersQueueList = null; + listenerThread = null; + outTopicName = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_PORTAL_INBOX_NAME); + inTopicName = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME); + appUebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + appUebSecret = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_SECRET); + String consGrp = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_CONSUMER_GROUP_NAME); + + if (outTopicName == null || outTopicName.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.ECOMP_PORTAL_INBOX_NAME, null, null, + null); + if (inTopicName == null || inTopicName.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME, null, + null, null); + if (consGrp == null || consGrp.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_CONSUMER_GROUP_NAME, null, + null, null); + if (appUebKey == null || appUebKey.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_KEY, null, null, null); + if (appUebSecret == null || appUebSecret.length() == 0) + throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_SECRET, null, null, null); + List uebUrlList = Helper.uebUrlList(); + if (uebUrlList == null || uebUrlList.size() == 0) + throw new UebException("Failed to get property" + PortalApiConstants.UEB_URL_LIST, null, null, null); + // A bit of magic: if consumer group is a magic token, generate one. + consumerGroupName = (PortalApiConstants.UEB_APP_CONSUMER_GROUP_NAME_GENERATOR.equals(consGrp) + ? UUID.randomUUID().toString() : consGrp); + } + + /** + * Gets the static instance, creating it if necessary. + * + * @return Instance of UebManager + * @throws IOException + */ + public static synchronized UebManager getInstance() throws UebException { + if (uebManager == null) { + uebManager = new UebManager(); + } + return uebManager; + } + + /** + * Answers whether the getInstance() method has previously been called. + * + * @return True if a static instance is available, else false. + */ + public static boolean isInstanceAvailable() { + return uebManager != null; + } + + /** + * Creates a list of waiting requesters, creates and a consumer using cached + * information, and starts a new thread to run the consumer that listens for + * messages published to the inbound topic configured in the constructor. + * + * @param inboxQueue + * Queue supplied to the consumer. If not null, the consumer will + * enqueue every message it receives. + */ + public void initListener(ConcurrentLinkedQueue inboxQueue) throws UebException { + waitingRequestersQueueList = new WaitingRequestersQueueList(); + Consumer runnable = new Consumer(appUebKey, appUebSecret, inTopicName, consumerGroupName, inboxQueue, + waitingRequestersQueueList); + this.listenerThread = new Thread(runnable, "UEBConsumerThread"); + this.listenerThread.start(); + Helper.sleep(400); // UEB functions more reliably when we give this some + // time + + logger.info("UEBManager instance starting... " + inTopicName + " listener thread " + + this.listenerThread.getName() + " state = " + this.listenerThread.getState()); + + /* + * ECOMP Portal manages a dynamic list of outbound topics and so the + * outTopicName is initialized in this logic with the same value as the + * inbound topic. The real outbound topics name will be added to the + * publisher list for ECOMP Portal. For an SDK/App instance only one + * publisher is needed, appPublisher. + */ + if (inTopicName.equalsIgnoreCase(outTopicName)) { + this.bThisIsEcompPortalServer = true; + } else { + appPublisher = new Publisher(appUebKey, appUebSecret, outTopicName); + Helper.sleep(400); + } + } + + /** + * Creates and adds a publisher to the list for the specified topic. This + * should only be called by the ECOMP Portal App, other Apps have just one + * publisher and use appPublisher + * + * @param topicName + */ + public void addPublisher(String topicName) { + logger.info("UEBManager adding publisher for " + topicName); + Publisher outBoxToAppPublisher = new Publisher(appUebKey, appUebSecret, topicName); + publisherList.addPublisherToMap(topicName, outBoxToAppPublisher); + } + + /** + * Removes a publisher from the list for the specified topic. + * + * This should only be called by the ECOMP Portal App, other Apps have just + * one publisher and use appPublisher + * + * @param topicName + */ + public void removePublisher(String topicName) { + logger.info("UEBManager removing publisher for " + topicName); + publisherList.removePublisherFromMap(topicName); + } + + /** + * Adds the default ECOMP message ID to the message and sends the message to + * the topic. + * + * @param msg + * @throws UebException + */ + public void publish(UebMsg msg) throws UebException { + msg.putMsgId(PortalApiConstants.ECOMP_DEFAULT_MSG_ID); + appPublisher.send(msg); + } + + /** + * Sends the message using the default publisher. + * + * @param msg + * @throws UebException + */ + public void publishReply(UebMsg msg) throws UebException { + // Caller populates msgId with the echoed value from the request + appPublisher.send(msg); + } + + /** + * Sends the message using the appropriate publisher for the specified + * topic. + * + * @param msg + * @param topicName + * @throws UebException + */ + public void publishEP(UebMsg msg, String topicName) throws UebException { + Publisher publisher = publisherList.getPublisher(topicName); + if (publisher != null) { + msg.putMsgId(PortalApiConstants.ECOMP_DEFAULT_MSG_ID); + publisher.send(msg); + } + } + + /** + * Publishes a reply using the appropriate publisher for the specified + * topic. + * + * @param msg + * @param topicName + * @throws UebException + */ + public void publishReplyEP(UebMsg msg, String topicName) throws UebException { + // Caller populates msgId with the echoed value from the request + Publisher publisher = publisherList.getPublisher(topicName); + if (publisher != null) { + publisher.send(msg); + } + } + + /** + * Sends the specified message using the specified publisher, and waits for + * a reply. Retransmits if no reply is received in 5 seconds; gives up after + * 3 retries. + * + * @param msg + * @param publisher + * @return Message from a remote publisher, or null if timeout happens. + * @throws UebException + */ + public UebMsg requestReplyUsingPublisher(UebMsg msg, Publisher publisher) throws UebException { + UebMsg reply = null; + if (waitingRequestersQueueList == null) { + logger.error("requestReplyUsingPublisher called but listener thread not initialized"); + } else { + // Storing a non-default message ID identifies this as a synchronous + // request + msg.putMsgId(UUID.randomUUID().toString()); + + /* + * Create a queue for this request, the consumer thread will insert + * the reply on this queue + */ + LinkedBlockingQueue replyQueue = new LinkedBlockingQueue(); + waitingRequestersQueueList.addQueueToMap(msg.getMsgId(), replyQueue); + + /* + * Send the request + */ + publisher.send(msg); + + /* + * Wait for reply up to 3 * 5 = 15 seconds + */ + int reTransmits = 0; + int maxRetransmits = 3; + int retransmitTimeMs = 5000; + long sendTimeStamp = System.currentTimeMillis(); + while (reTransmits < maxRetransmits) { + if ((reply = replyQueue.poll()) != null) + break; + + long now = System.currentTimeMillis(); + if (now - sendTimeStamp > retransmitTimeMs) { + logger.debug("Retransmitting send... msg = " + msg.getPayload() + msg.getMsgId()); + publisher.send(msg); + sendTimeStamp = System.currentTimeMillis(); + reTransmits++; + } + } + waitingRequestersQueueList.removeQueueFromMap(msg.getMsgId()); + if (reTransmits == maxRetransmits) + throw new UebException(PortalApiConstants.ECOMP_UEB_TIMEOUT_ERROR, inTopicName, null, msg.toString()); + + } + return reply; + } + + /** + * Sends the specified message using the default publisher and waits for a + * reply. + * + * @param msg + * @return Message from a remote publisher, or null if timeout happens. + * @throws UebException + */ + public UebMsg requestReply(UebMsg msg) throws UebException { + return requestReplyUsingPublisher(msg, appPublisher); + } + + /** + * Sends the specified message using the publisher appropriate for the + * specified topic name, and waits for a reply. + * + * @param msg + * @param topicName + * @return Message from a remote publisher, or null if timeout happens. + * @throws UebException + */ + public UebMsg requestReplyEP(UebMsg msg, String topicName) throws UebException { + UebMsg returnMsg = null; + Publisher publisher = publisherList.getPublisher(topicName); + if (publisher != null) { + returnMsg = requestReplyUsingPublisher(msg, publisher); + } + return returnMsg; + } + + /** + * Publishes the payload as a UEB widget-notification message on the default + * publisher. Intended for use by Apps inter widget communication, not EP + * itself. + * + * @param payload + * @param userId + */ + public void postWidgetNotification(String payload, String userId) throws UebException { + UebMsg msg = new UebMsg(); + msg.putPayload(payload); + msg.putUserId(userId); + msg.putMsgType(UebMsgTypes.UEB_MSG_TYPE_WIDGET_NOTIFICATION); + this.publish(msg); + } + + /** + * Interrupts the long-running thread that runs the consumer. + */ + public void shutdown() { + if (this.listenerThread != null) { + this.listenerThread.interrupt(); + } + } +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java new file mode 100644 index 00000000..da18c4f8 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java @@ -0,0 +1,119 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class UebMsg { + + private final Log logger = LogFactory.getLog(getClass()); + + private String version; + private String msgId; + private long timeStamp; + private String payload; + private String msgType; + private String userId; + private String sourceTopicName; + private String sourceIP; + private String sourceHostName; + + /** + * Creates a new object and populates the fields source IP, source topic, + * time stamp, version, and message id. + */ + public UebMsg() { + InetAddress ip; + try { + ip = InetAddress.getLocalHost(); + // Do not attempt to get name, why wait on DNS every time? + // sourceHostName = ip.getHostName(); + sourceIP = ip.getHostAddress(); + } catch (UnknownHostException e) { + sourceHostName = "unknown"; + sourceIP = "unknown"; + } + + this.timeStamp = System.currentTimeMillis(); + this.version = "1.0"; + this.msgId = PortalApiConstants.ECOMP_DEFAULT_MSG_ID; + this.payload = "empty payload content"; + this.sourceTopicName = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME); + if (this.sourceTopicName == null) + logger.error("Failed to get property " + PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME); + } + + public void putMsgId(String msgId) { + this.msgId = msgId; + } + + public String getMsgId() { + return msgId; + } + + public void putPayload(String payload) { + this.payload = payload; + } + + public String getPayload() { + return payload; + } + + public void putMsgType(String msgType) { + this.msgType = msgType; + } + + public String getMsgType() { + return this.msgType; + } + + public void putUserId(String userId) { + this.userId = userId; + } + + public String getUserId() { + return this.userId; + } + + public void putSourceTopicName(String topic) { + this.sourceTopicName = topic; + } + + public String getSourceTopicName() { + return this.sourceTopicName; + } + + @Override + public String toString() { + return "UebMsg [version=" + version + ", msgId=" + msgId + ", timeStamp=" + timeStamp + ", msgType=" + msgType + + ", userId=" + userId + ", sourceTopicName=" + sourceTopicName + ", sourceIP=" + sourceIP + + ", sourceHostName=" + sourceHostName + "]" + System.lineSeparator() + "payload=" + payload; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java new file mode 100644 index 00000000..28ab327f --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java @@ -0,0 +1,28 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +/** + * Publishes constants used in the UEB package. + */ +public interface UebMsgTypes { + public static final String UEB_MSG_TYPE_GET_FUNC_MENU = "uebMsgTypeGetFuncMenu"; + public static final String UEB_MSG_TYPE_WIDGET_NOTIFICATION = "uebMsgTypeWidgetNotification"; +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java new file mode 100644 index 00000000..db0ee1b9 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java @@ -0,0 +1,73 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * A thin wrapper around ConcurrentHashMap that stores a queue for each + * Requester that is waiting for a Reply. When a reply is received that has a + * matching msgId, that requesters queue is populated with the reply message. + * + * Primarily for the UebManager to track requests while it waits for responses. + */ +public class WaitingRequestersQueueList { + private final Log logger = LogFactory.getLog(getClass()); + + private final Map> map; + + public WaitingRequestersQueueList() { + map = new ConcurrentHashMap<>(); + } + + public void addQueueToMap(String msgId, LinkedBlockingQueue queue) { + this.map.put(msgId, queue); + } + + public void addMsg(String msgId, UebMsg message) { + LinkedBlockingQueue queue = this.map.get(msgId); + if (queue != null) { + queue.add(message); + } else { + logger.warn("Did not find entry in WaitingRequestersQueueList for msgId " + msgId); + } + } + + public void removeQueueFromMap(String msgId) { + this.map.remove(msgId); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Map contains " + this.map.size() + " Publishers."); + for (Map.Entry> entry : this.map.entrySet()) { + String key = entry.getKey().toString(); + LinkedBlockingQueue queue = entry.getValue(); + sb.append("Entry msgId, " + key + " queue " + queue); + } + return sb.toString(); + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/HttpStatusAndResponse.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/HttpStatusAndResponse.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/HttpStatusAndResponse.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/HttpStatusAndResponse.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/PortalRestClientBase.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/PortalRestClientBase.java new file mode 100644 index 00000000..b74d87c4 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/PortalRestClientBase.java @@ -0,0 +1,171 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.restful.client; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.http.Consts; +import org.apache.http.HttpEntity; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.openecomp.portalsdk.core.domain.App; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.onboarding.util.CipherUtil; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; +import org.openecomp.portalsdk.core.service.AppService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Provides a basic client to access a REST endpoint at the Portal via get or + * post. Usage caveats: + *
          + *
        1. Must be auto-wired by Spring, because this in turn auto-wires a + * data-access service to read application credentials from the FN_APP table. + *
        2. If HTTP access is used and the server uses a self-signed certificate, the + * local trust store must be extended appropriately. The HTTP client throws + * exceptions if the JVM cannot validate the server certificate. + *
        + */ +@Component +public class PortalRestClientBase { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PortalRestClientBase.class); + + @Autowired + AppService appService; + + /** + * Constructs and sends a GET request for the URI, with REST application + * credentials in the header as the Portal expects. + * + * @param uri + * URI of the service + * @return Result of the get; null if an error happens + * @throws URISyntaxException + * @throws IOException + * @throws ClientProtocolException + */ + public HttpStatusAndResponse getRestWithCredentials(final URI uri) throws Exception { + + String uebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + App app = appService.getDefaultApp(); + if (uebKey == null || app == null || app.getUsername() == null || app.getAppPassword() == null) + throw new Exception("Missing one or more required properties and/or database entries"); + String decryptedPassword = CipherUtil.decrypt(app.getAppPassword()); + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(uri); + httpGet.setHeader("uebkey", uebKey); + httpGet.setHeader("username", app.getUsername()); + httpGet.setHeader("password", decryptedPassword); + + String responseJson = null; + CloseableHttpResponse response = null; + try { + logger.info(EELFLoggerDelegate.debugLogger, "GET from " + uri); + response = httpClient.execute(httpGet); + logger.info(EELFLoggerDelegate.debugLogger, "Status is " + response.getStatusLine()); + if (response.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK) + logger.info(EELFLoggerDelegate.debugLogger, "Status is " + response.getStatusLine().toString()); + HttpEntity entity = response.getEntity(); + if (entity == null) { + logger.info(EELFLoggerDelegate.debugLogger, "Entity is null!"); + } else { + // entity content length is never set. + // this naively tries to read everything. + responseJson = EntityUtils.toString(entity); + logger.info(EELFLoggerDelegate.debugLogger, responseJson); + EntityUtils.consume(entity); + } + } finally { + if (response != null) + response.close(); + } + if (response == null) + return null; + return new HttpStatusAndResponse(response.getStatusLine().getStatusCode(), responseJson); + } + + /** + * Constructs and sends a POST request using the specified body, with REST + * application credentials in the header as the Portal expects. + * + * @param uri + * REST endpoint + * @param json + * Content to post + * @return Result of the post; null if an error happens + * @throws Exception + */ + public HttpStatusAndResponse postRestWithCredentials(final URI uri, final String json) throws Exception { + + String uebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + App app = appService.getDefaultApp(); + if (uebKey == null || app == null || app.getUsername() == null || app.getAppPassword() == null) + throw new Exception("Missing one or more required properties and/or database entries"); + + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(uri); + httpPost.setHeader("uebkey", uebKey); + httpPost.setHeader("username", app.getUsername()); + httpPost.setHeader("password", app.getAppPassword()); + + StringEntity postEntity = new StringEntity(json, ContentType.create("application/json", Consts.UTF_8)); + httpPost.setEntity(postEntity); + + String responseJson = null; + CloseableHttpResponse response = null; + try { + logger.info(EELFLoggerDelegate.debugLogger, "POST to " + uri); + response = httpClient.execute(httpPost); + logger.info(EELFLoggerDelegate.debugLogger, "Status is " + response.getStatusLine()); + if (response.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK) + throw new Exception("Status is " + response.getStatusLine().toString()); + + HttpEntity entity = response.getEntity(); + if (entity == null) { + logger.info(EELFLoggerDelegate.debugLogger, "Entity is null!"); + } else { + // entity content length is never set. + // this naively tries to read everything. + responseJson = EntityUtils.toString(entity); + logger.info(EELFLoggerDelegate.debugLogger, responseJson); + EntityUtils.consume(entity); + } + } finally { + if (response != null) + response.close(); + } + return new HttpStatusAndResponse(response.getStatusLine().getStatusCode(), responseJson); + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/SharedContextRestClient.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/SharedContextRestClient.java new file mode 100644 index 00000000..91f4652a --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/restful/client/SharedContextRestClient.java @@ -0,0 +1,351 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.restful.client; + +import java.net.URI; +import java.util.HashMap; +import java.util.List; + +import org.apache.http.client.utils.URIBuilder; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; +import org.openecomp.portalsdk.core.restful.domain.SharedContext; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Provides convenience methods to use the shared-context service at Portal. + * This hides all JSON; instead it accepts and returns Java objects. Usage + * caveats (repeated from superclass): + *
          + *
        1. Must be auto-wired by Spring, because this in turn auto-wires a data + * access service to read application credentials from the FN_APP table. + *
        2. If HTTP access is used and the server uses a self-signed certificate, the + * local trust store must be extended appropriately. The HTTP client throws + * exceptions if the JVM cannot validate the server certificate. + *
        + */ +@Component +public class SharedContextRestClient extends PortalRestClientBase { + + @Autowired + SystemProperties systemProperties; + + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SharedContextRestClient.class); + + /** + * Reusable JSON (de)serializer + */ + private final ObjectMapper mapper = new ObjectMapper(); + + /** + * Builds the URl for the shared context service using the portal.properties + * value for the AUXAPI endpoint. + * + * @throws Exception + * if the ECOMP_REST_URL property is not found + */ + private String getSharedContextUrl() throws Exception { + String restUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL); + if (restUrl == null || restUrl.length() == 0) + throw new Exception("getSharedContextUrl: no property " + PortalApiConstants.ECOMP_REST_URL); + String contextUrl = restUrl + (restUrl.endsWith("/") ? "" : "/") + "context/"; + return contextUrl; + } + + /** + * Gets the shared-context value for the specified context ID and key. + * + * @param contextId + * An Ecomp Portal session ID + * @param key + * Key for the shared-context entry; e.g., "lastName" + * @return SharedContext object; null if not found. + * @throws Exception + */ + public SharedContext getContextValue(String contextId, String key) throws Exception { + HttpStatusAndResponse hsr = getContext("get", contextId, key); + logger.info(EELFLoggerDelegate.debugLogger, "getSharedContext: resp is " + hsr); + if (hsr == null) { + logger.error(EELFLoggerDelegate.applicationLogger, "getContextValue: unexpected null response"); + return null; + } + SharedContext jsonObj = null; + try { + jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); + } catch (JsonMappingException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "getContextValue: failed to map response onto object" + ex.getMessage()); + } catch (JsonParseException ex) { + logger.info(EELFLoggerDelegate.applicationLogger, + "getContextValue: failed to parse response" + ex.getMessage()); + } + if (jsonObj != null && jsonObj.getResponse() != null) + return null; + return jsonObj; + } + + /** + * Gets user information for the specified context ID. + * + * @param contextId + * An Ecomp Portal session ID + * @return List of SharedContext objects corresponding to the following + * keys: USER_FIRST_NAME, USER_LAST_NAME, USER_EMAIL and + * USER_ORGUSERID; empty if none were found; null if an error + * happens. + * @throws Exception + */ + public List getUserContext(String contextId) throws Exception { + HttpStatusAndResponse hsr = getContext("get_user", contextId, null); + logger.info(EELFLoggerDelegate.debugLogger, "getUserContext: resp is " + hsr); + if (hsr == null) { + logger.error(EELFLoggerDelegate.applicationLogger, "getUserContext: unexpected null response"); + return null; + } + List jsonList = null; + try { + TypeReference> typeRef = new TypeReference>() { + }; + jsonList = mapper.readValue(hsr.getResponse(), typeRef); + } catch (JsonMappingException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "getUserContext: failed to map response onto object" + ex.getMessage()); + } catch (JsonParseException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "getUserContext: failed to parse response" + ex.getMessage()); + } + return jsonList; + } + + /** + * Checks whether a shared-context entry exists for the specified context ID + * and key. + * + * @param contextId + * An Ecomp Portal session ID + * @param key + * Key for the shared-context entry; e.g., "lastName" + * @return True if the object exists, false otherwise; null on error. + * @throws Exception + */ + public Boolean checkSharedContext(String contextId, String key) throws Exception { + HttpStatusAndResponse hsr = getContext("check", contextId, key); + logger.info(EELFLoggerDelegate.debugLogger, "checkSharedContext: resp is " + hsr); + if (hsr == null) { + logger.error(EELFLoggerDelegate.applicationLogger, "checkSharedContext: unexpected null response"); + return null; + } + String response = null; + try { + SharedContext jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); + response = jsonObj.getResponse(); + } catch (JsonMappingException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "checkSharedContext: failed to map response onto object" + ex.getMessage()); + } catch (JsonParseException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "checkSharedContext: failed to parse response" + ex.getMessage()); + } + if (response == null) + return null; + return ("exists".equals(response)); + } + + /** + * Removes a shared-context entry with the specified context ID and key. + * + * @param contextId + * An Ecomp Portal session ID + * @param key + * Key for the shared-context entry; e.g., "lastName" + * @return True if the entry was removed, false otherwise; null on error. + * @throws Exception + */ + public Boolean removeSharedContext(String contextId, String key) throws Exception { + HttpStatusAndResponse hsr = getContext("remove", contextId, key); + logger.info(EELFLoggerDelegate.debugLogger, "removeSharedContext: resp is " + hsr); + if (hsr == null) { + logger.error(EELFLoggerDelegate.applicationLogger, "removeSharedContext: unexpected null response"); + return null; + } + SharedContext jsonObj = null; + try { + jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); + } catch (JsonMappingException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "removeSharedContext: failed to map response onto object" + ex.getMessage()); + } catch (JsonParseException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "removeSharedContext: failed to parse response" + ex.getMessage()); + } + if (jsonObj == null) + return null; + String response = jsonObj.getResponse(); + return ("removed".equals(response)); + } + + /** + * Clears the shared context for the specified context ID; i.e., removes all + * key-value pairs. + * + * @param contextId + * An Ecomp Portal session ID + * @return Number of key-value pairs removed; -1 if not found or any + * problems occur. + * @throws Exception + */ + public int clearSharedContext(String contextId) throws Exception { + HttpStatusAndResponse hsr = getContext("remove", contextId, null); + logger.info(EELFLoggerDelegate.debugLogger, "clearSharedContext: resp is " + hsr); + if (hsr == null) { + logger.error(EELFLoggerDelegate.applicationLogger, "clearSharedContext: unexpected null response"); + return -1; + } + SharedContext jsonObj = null; + try { + jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); + } catch (JsonMappingException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "clearSharedContext: failed to map response onto object" + ex.getMessage()); + } catch (JsonParseException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "clearSharedContext: failed to parse response" + ex.getMessage()); + } + if (jsonObj == null) + return -1; + String response = jsonObj.getResponse(); + if (response == null) + return -1; + return Integer.parseInt(response); + } + + /** + * Creates a shared-context entry. + * + * @param contextId + * An Ecomp Portal session ID + * @param key + * Key for the shared-context entry; e.g., "lastName" + * @param value + * Value for the entry + * @throws Exception + * @return True if the object previously existed, false otherwise; null if + * any problem happened. + */ + public Boolean setSharedContext(String contextId, String key, String value) throws Exception { + String body = buildContext(contextId, key, value); + HttpStatusAndResponse hsr = postContext("set", body); + logger.info(EELFLoggerDelegate.debugLogger, "setSharedContext: resp is " + hsr); + if (hsr == null) { + logger.error(EELFLoggerDelegate.applicationLogger, "setSharedContext: unexpected null response"); + return null; + } + SharedContext jsonObj = null; + try { + jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); + } catch (JsonMappingException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "setSharedContext: failed to map response onto object" + ex.getMessage()); + } catch (JsonParseException ex) { + logger.error(EELFLoggerDelegate.applicationLogger, + "setSharedContext: failed to parse response" + ex.getMessage()); + } + if (jsonObj == null) + return null; + String response = jsonObj.getResponse(); + return ("replaced".equals(response)); + } + + /** + * Builds the full URL with the specified parameters, then calls the method + * that adds credentials and GETs. + * + * @param requestPath + * @param contextId + * @param contextKey + * @return HttpStatusAndResponse object; may be null. + * @throws Exception + */ + private HttpStatusAndResponse getContext(String requestPath, String contextId, String contextKey) throws Exception { + URIBuilder uriBuilder = new URIBuilder(getSharedContextUrl() + requestPath); + uriBuilder.addParameter("context_id", contextId); + if (contextKey != null) + uriBuilder.addParameter("ckey", contextKey); + final URI uri = uriBuilder.build(); + return getRestWithCredentials(uri); + } + + /** + * Builds the full URL, then calls the method that adds credentials and + * POSTs. + * + * @param requestPath + * @param contextId + * @param contextKey + * @return HttpStatusAndResponse object; may be null. + * @throws Exception + */ + private HttpStatusAndResponse postContext(String requestPath, String json) throws Exception { + URIBuilder uriBuilder = new URIBuilder(getSharedContextUrl() + requestPath); + URI uri = uriBuilder.build(); + return postRestWithCredentials(uri, json); + } + + /** + * Builds a JSON block with a single shared-context entry. + * + * @param cxid + * Context ID + * @param ckey + * Context Key + * @param cvalue + * Context value + * @return JSON block + */ + private String buildContext(String cxid, String ckey, String cvalue) throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + HashMap stringMap = new HashMap(); + stringMap.put("context_id", cxid); + stringMap.put("ckey", ckey); + stringMap.put("cvalue", cvalue); + String json = mapper.writeValueAsString(stringMap); + return json; + } + + // Simple test scaffold + public static void main(String[] args) throws Exception { + // ObjectMapper mapper = new ObjectMapper(); + // SharedContext cxt = mapper.readValue("{ \"response\":\"foo\" }", + // SharedContext.class); + SharedContextRestClient client = new SharedContextRestClient(); + SharedContext get = client.getContextValue("abc", "123"); + System.out.println("Get yields " + get.toString()); + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/scheduler/CoreRegister.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/scheduler/CoreRegister.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/scheduler/CoreRegister.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/scheduler/CoreRegister.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/scheduler/CronRegistry.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/scheduler/CronRegistry.java new file mode 100644 index 00000000..dfd9a817 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/scheduler/CronRegistry.java @@ -0,0 +1,125 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.scheduler; + +import java.text.ParseException; +import java.util.Map; + +import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.quartz.CronTrigger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.quartz.CronTriggerFactoryBean; +import org.springframework.scheduling.quartz.JobDetailFactoryBean; +import org.springframework.scheduling.quartz.QuartzJobBean; + +import com.mchange.v2.c3p0.ComboPooledDataSource; + +public abstract class CronRegistry { + + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CronRegistry.class); + protected JobDetailFactoryBean jobDetailFactory; + protected CronTriggerFactoryBean cronTriggerFactory; + + private ComboPooledDataSource dataSource; + + public CronRegistry() { + try { + jobDetailFactoryBean(); + cronTriggerFactoryBean(); + } + catch(Exception e) { + logger.error(EELFLoggerDelegate.debugLogger, e.getMessage()); + } + } + + //@Autowired + public CronRegistry(ComboPooledDataSource dataSource) { + try { + this.dataSource = dataSource; + jobDetailFactoryBean(); + cronTriggerFactoryBean(); + } + catch(Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AlarmSeverityEnum.MAJOR); + } + } + + //@Autowired + public CronRegistry(Object... initializeObjects) { + try { + initializeObjects(initializeObjects); + jobDetailFactoryBean(); + cronTriggerFactoryBean(); + } + catch(Exception e) { + logger.info(EELFLoggerDelegate.errorLogger, e.getMessage()); + } + } + + protected void initializeObjects(Object... initializeObjects) { + } + + public abstract JobDetailFactoryBean jobDetailFactoryBean() throws ParseException; + + protected JobDetailFactoryBean jobDetailFactoryBean(String groupName, String jobName, + Class jobClass, Map map) { + + jobDetailFactory = new JobDetailFactoryBean(); + jobDetailFactory.setJobClass(jobClass); + jobDetailFactory.setJobDataAsMap(map); + jobDetailFactory.setGroup(groupName); + jobDetailFactory.setName(jobName); + jobDetailFactory.afterPropertiesSet(); + + return jobDetailFactory; + } + + public abstract CronTriggerFactoryBean cronTriggerFactoryBean() throws ParseException; + + protected CronTriggerFactoryBean cronTriggerFactoryBean(String groupName, String triggerName, String cronExpression) throws ParseException { + cronTriggerFactory = new CronTriggerFactoryBean(); + cronTriggerFactory.setJobDetail(jobDetailFactory.getObject()); + cronTriggerFactory.setStartDelay(3000); + cronTriggerFactory.setName(triggerName); + cronTriggerFactory.setGroup(groupName); + logger.info(EELFLoggerDelegate.applicationLogger, triggerName + " Scheduled: " + cronExpression); + cronTriggerFactory.setCronExpression( cronExpression); //"0 * * * * ? *" + cronTriggerFactory.afterPropertiesSet(); + return cronTriggerFactory; + } + + public CronTrigger getTrigger() { + return cronTriggerFactory.getObject(); + } + + + public void setDataSource(ComboPooledDataSource dataSource) { + this.dataSource = dataSource; + } + + + public ComboPooledDataSource getDataSource() { + return dataSource; + } + + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/scheduler/Registerable.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/scheduler/Registerable.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/scheduler/Registerable.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/scheduler/Registerable.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AppService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AppService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AppService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AppService.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AppServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AppServiceImpl.java new file mode 100644 index 00000000..b06b36fc --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AppServiceImpl.java @@ -0,0 +1,106 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.List; + +import org.openecomp.portalsdk.core.domain.App; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("appService") +@Transactional +public class AppServiceImpl implements AppService{ + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AppServiceImpl.class); + + @Autowired + private DataAccessService dataAccessService; + + /** + * Loads the appName once from database and + * keep refers to it as required. + */ + private static String defaultAppName = ""; + + /* + * (non-Javadoc) + * @see org.openecomp.portalsdk.core.service.AppService#getApps() + */ + @SuppressWarnings("unchecked") + @Override + public List getApps() { + return getDataAccessService().getList(App.class, null); + } + + /* + * (non-Javadoc) + * @see org.openecomp.portalsdk.service.AppService#getApp(long) + */ + @Override + public App getApp(Long appId) { + return (App)getDataAccessService().getDomainObject(App.class, appId, null); + } + + /* + * (non-Javadoc) + * @see org.openecomp.portalsdk.service.AppService#getApp() + */ + @Override + public App getDefaultApp() { + return getApp(1L); + } + + /** + * Gets the data access service. + * @return DataAccessService + */ + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + /** + * Sets the data access service. + * @param dataAccessService + */ + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + /** + * Fetches the application name once from database + * and keep refers to the same name later on as required. + * @return Default Application Name + */ + @Override + public String getDefaultAppName() { + if (AppServiceImpl.defaultAppName==null || AppServiceImpl.defaultAppName=="") { + App app = getApp(1L); + if (app!=null) { + AppServiceImpl.defaultAppName = app.getName(); + } else { + logger.warn(EELFLoggerDelegate.errorLogger, ("Unable to locate the app information from the database.")); + } + } + return AppServiceImpl.defaultAppName; + } +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AuditService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AuditService.java new file mode 100644 index 00000000..b228d1b1 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AuditService.java @@ -0,0 +1,37 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.HashMap; + +import org.openecomp.portalsdk.core.domain.AuditLog; + +public interface AuditService { + /** + * + * Update log data in database + * + * @param auditLog + * @param additionalParams + */ + + @SuppressWarnings("rawtypes") + void logActivity(AuditLog auditLog, HashMap additionalParams); +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AuditServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AuditServiceImpl.java new file mode 100644 index 00000000..433cd2ac --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/AuditServiceImpl.java @@ -0,0 +1,50 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.HashMap; + +import org.openecomp.portalsdk.core.domain.AuditLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("auditService") +@Transactional +public class AuditServiceImpl implements AuditService { + public AuditServiceImpl() {} + + @Autowired + private DataAccessService dataAccessService; + + @SuppressWarnings("rawtypes") + public void logActivity(AuditLog auditLog, HashMap additionalParams) { + getDataAccessService().saveDomainObject(auditLog, additionalParams); + } + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/BroadcastService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/BroadcastService.java new file mode 100644 index 00000000..66315b92 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/BroadcastService.java @@ -0,0 +1,36 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.*; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.domain.BroadcastMessage; + +@SuppressWarnings("rawtypes") +public interface BroadcastService { + HashMap getBcModel(HttpServletRequest request); + Hashtable getBroadcastMessages(); + void loadMessages(); + BroadcastMessage getBroadcastMessage(HttpServletRequest request); + void saveBroadcastMessage(BroadcastMessage broadcastMessage); + void removeBroadcastMessage(BroadcastMessage broadcastMessage); +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/BroadcastServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/BroadcastServiceImpl.java new file mode 100644 index 00000000..92a77507 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/BroadcastServiceImpl.java @@ -0,0 +1,250 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.Calendar; +import java.util.Collections; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.domain.BroadcastMessage; +import org.openecomp.portalsdk.core.domain.Lookup; +import org.openecomp.portalsdk.core.service.support.FusionService; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.web.support.AppUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.ServletRequestBindingException; +import org.springframework.web.bind.ServletRequestUtils; + +@SuppressWarnings("rawtypes") +@Service("broadcastService") +@Transactional +public class BroadcastServiceImpl extends FusionService implements BroadcastService { + + public BroadcastServiceImpl() { + } + + @Autowired + private DataAccessService dataAccessService; + private static Hashtable broadcastMessages = new Hashtable(); + + @SuppressWarnings("unchecked") + public void loadMessages() { + List messageLocations = AppUtils.getLookupListNoCache("fn_lu_message_location", "message_location_id", "message_location_descr", "", "message_location_id"); + + for (int i=0; i < messageLocations.size(); i++) { + Lookup location = (Lookup)messageLocations.get(i); + String locationId = location.getValue(); + + broadcastMessages.put(locationId, getPersistedBroadcastMessages(locationId)); + } + } + + public HashMap getBcModel(HttpServletRequest request){ + HashMap bcModel = new HashMap(); + + List items = null; + int messageId = ServletRequestUtils.getIntParameter(request, "message_id", 0); + String task = ServletRequestUtils.getStringParameter(request, "task", "get"); + + // delete or toggle activation on the selected record (if applicable) + if (messageId != 0 && (task.equals("delete") || task.equals("toggleActive"))) { + BroadcastMessage message = (BroadcastMessage)getDataAccessService().getDomainObject(BroadcastMessage.class, new Long(messageId), null); + + if (task.equals("delete")) { + getDataAccessService().deleteDomainObject(message, null); + } + else if (task.equals("toggleActive")) { + HashMap additionalParams = new HashMap(); + additionalParams.put(Parameters.PARAM_HTTP_REQUEST, request); + + message.setActive(new Boolean(!message.getActive().booleanValue())); + getDataAccessService().saveDomainObject(message, additionalParams); + } + loadMessages(); + } + + items = getDataAccessService().getList(BroadcastMessage.class, null); + Collections.sort(items); + bcModel.put("messagesList", packageMessages(items)); + + List locations = AppUtils.getLookupList("fn_lu_message_location", "message_location_id", "message_location_descr", "", "message_location_id"); + bcModel.put("messageLocations", locations); + + if ("true".equals(SystemProperties.getProperty(SystemProperties.CLUSTERED))) { + List sites = AppUtils.getLookupList("fn_lu_broadcast_site", "broadcast_site_cd", "broadcast_site_descr", "", "broadcast_site_descr"); + bcModel.put("broadcastSites", sites); + } + + return bcModel; + } + + @SuppressWarnings("unchecked") + private HashMap packageMessages(List messages) { + HashMap messagesList = new HashMap(); + Set locationMessages = null; + + Integer previousLocationId = null; + + for (int i=0; i < messages.size(); i++) { + BroadcastMessage message = (BroadcastMessage)messages.get(i); + + if (!message.getLocationId().equals(previousLocationId)) { + if (previousLocationId != null) { + messagesList.put(previousLocationId.toString(), locationMessages); + } + + locationMessages = new TreeSet(); + previousLocationId = message.getLocationId(); + } + + locationMessages.add(message); + } + + if (previousLocationId != null) { + messagesList.put(previousLocationId.toString(), locationMessages); + } + + return messagesList; + } + + + @SuppressWarnings("unchecked") + private List getPersistedBroadcastMessages(String locationId) { + HashMap params = new HashMap(); + + + + params.put("location_id", new Integer(locationId)); + + Calendar calInstanceToday = Calendar.getInstance(); + calInstanceToday.set(Calendar.HOUR, 0); + calInstanceToday.set(Calendar.MINUTE, 0); + calInstanceToday.set(Calendar.SECOND, 0); + params.put("today_date", calInstanceToday.getTime()); + + return getDataAccessService().executeNamedQuery("broadcastMessages", params, null); + } + + public Hashtable getBroadcastMessages() { + return broadcastMessages; + } + + public static List getBroadcastMessages(String locationId) { + return (List)broadcastMessages.get(locationId); + } + + public static String displayMessages(String locationId) { + return displayServerMessages(locationId, null); + } + + public static String displayServerMessages(String locationId, String siteCd) { + StringBuffer html = new StringBuffer(); + + List messages = getBroadcastMessages(locationId); + + for (int i=0; i < messages.size(); i++) { + BroadcastMessage message = (BroadcastMessage)messages.get(i); + + if ((message.getSiteCd() == null) || ((message.getSiteCd() != null) && message.getSiteCd().equals(siteCd))) { + html.append("
      • ") + .append(message.getMessageText()); + } + } + + if (html.length() > 0) { + html.insert(0, "
          "); + html.append("
        "); + } + + return html.toString(); + } + + public static boolean hasMessages(String locationId) { + return hasServerMessages(locationId, null); + } + + public static boolean hasServerMessages(String locationId, String siteCd) { + List messages = getBroadcastMessages(locationId); + + boolean messagesExist = !((messages == null) || messages.size() == 0); + + if (siteCd == null) { + return messagesExist; + } + else { + for (int i=0; i < messages.size(); i++) { + BroadcastMessage message = (BroadcastMessage)messages.get(i); + + if ((message.getSiteCd() == null) || message.getSiteCd().equals(siteCd)) { + return true; + } + } + return false; + } + } + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + public void setDataAccessService(DataAccessService dataAccessService) { + dataAccessService = dataAccessService; + } + + public BroadcastMessage getBroadcastMessage(HttpServletRequest request) { + long messageId = ServletRequestUtils.getLongParameter(request, "message_id", 0); + + BroadcastMessage message = new BroadcastMessage(); + if(messageId!=0) + message = (BroadcastMessage)getDataAccessService().getDomainObject(BroadcastMessage.class, new Long(messageId), null); + + if (message.getLocationId() == null) { + try { + message.setLocationId(new Integer(ServletRequestUtils.getStringParameter(request, "message_location_id"))); + } catch (NumberFormatException e) { + e.printStackTrace(); + } catch (ServletRequestBindingException e) { + e.printStackTrace(); + } + message.setActive(Boolean.TRUE); + } + + return message; + } + + @Override + public void saveBroadcastMessage(BroadcastMessage broadcastMessage) { + dataAccessService.saveDomainObject(broadcastMessage, null); + } + + @Override + public void removeBroadcastMessage(BroadcastMessage broadcastMessage) { + dataAccessService.deleteDomainObject(broadcastMessage, null); + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/DataAccessService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/DataAccessService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/DataAccessService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/DataAccessService.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/DataAccessServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/DataAccessServiceImpl.java new file mode 100644 index 00000000..9c52b1b4 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/DataAccessServiceImpl.java @@ -0,0 +1,594 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.hibernate.Criteria; +import org.hibernate.FetchMode; +import org.hibernate.Query; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.ProjectionList; +import org.openecomp.portalsdk.core.domain.Lookup; +import org.openecomp.portalsdk.core.domain.support.DomainVo; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.service.support.FusionService; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +/** + * Provides implementations of methods in {@link DataAccessService}. + */ +@Transactional +public class DataAccessServiceImpl extends FusionService implements DataAccessService { + + @Autowired + private SessionFactory sessionFactory; + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(DataAccessServiceImpl.class); + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#getDomainObject(java.lang. + * Class, java.io.Serializable, java.util.HashMap) + */ + @Override + public DomainVo getDomainObject(Class domainClass, Serializable id, HashMap additionalParams) { + DomainVo vo = null; + Session session = sessionFactory.getCurrentSession(); + logger.info(EELFLoggerDelegate.debugLogger, "Getting " + domainClass.getName() + " record for id - " + id.toString()); + vo = (DomainVo) session.get(domainClass, id); + + if (vo == null) { + try { + vo = (DomainVo) domainClass.newInstance(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "An error occured while instantiating a class of " + domainClass.getName() + e.getMessage()); + } + } + return vo; + } + + /* + * (non-Javadoc) + * + */ + @Override + public void deleteDomainObject(DomainVo domainObject, HashMap additionalParams) { + Session session = sessionFactory.getCurrentSession(); + session.delete(domainObject); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#deleteDomainObjects(java. + * lang.Class, java.lang.String, java.util.HashMap) + */ + @Override + public void deleteDomainObjects(Class domainClass, String whereClause, HashMap additionalParams) { + int rowsAffected = 0; + Session session = sessionFactory.getCurrentSession(); + + StringBuffer sql = new StringBuffer("delete from "); + + sql.append(domainClass.getName()).append(" where ").append(whereClause); + + rowsAffected = session.createQuery(sql.toString()).executeUpdate(); + /* return rowsAffected; */ + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#saveDomainObject + */ + @Override + public void saveDomainObject(DomainVo vo, HashMap additionalParams) { + Integer userId = 1; + if (additionalParams != null) { + // look for a passed user id + // userId = (Integer)additionalParams.get(Parameters.PARAM_USERID); + Object uid = additionalParams.get(Parameters.PARAM_USERID); + if (uid instanceof Integer) { + userId = (Integer) uid; + } else if (uid instanceof Long) { + userId = ((Long) uid).intValue(); + } + // if (userId == null) { + // look for a passed request to get the user id from + // userId = new + // Integer(UserUtils.getUserId((HttpServletRequest)additionalParams.get(Parameters.PARAM_HTTP_REQUEST))); + // } + } + _update(vo, userId); + } + + /** + * Creates or updates the specified virtual object. Uses the specified user + * ID as the creator and modifier if a new object is created; uses ID only + * as modifier if an object already exists. + * + * @param vo + * @param userId + * Ignored if value is zero. + */ + protected final void _update(DomainVo vo, int userId) { + Date timestamp = new Date(); + + Session session = sessionFactory.getCurrentSession(); + + if (vo.getId() == null || vo.getId().intValue() == 0) { // add new + vo.setCreated(timestamp); + vo.setModified(timestamp); + + if (userId != 0 + && userId != Integer.parseInt(SystemProperties.getProperty(SystemProperties.APPLICATION_USER_ID))) { + vo.setCreatedId(new Long(userId)); + vo.setModifiedId(new Long(userId)); + } + } else { // update existing + vo.setModified(timestamp); + + if (userId != 0 + && userId != Integer.parseInt(SystemProperties.getProperty(SystemProperties.APPLICATION_USER_ID))) { + vo.setModifiedId(new Long(userId)); + } + } + + session.saveOrUpdate(vo); + } + + /** + * generic get list method + * + * @param domainClass + * @param filterClause + * @param fromIndex + * @param toIndex + * @param orderBy + * @return + */ + private List getListCommon(Class domainClass, String filterClause, Integer fromIndex, Integer toIndex, + String orderBy) { + List list = null; + String className = domainClass.getName(); + Session session = sessionFactory.getCurrentSession(); + + if (logger.isInfoEnabled()) { + logger.info(EELFLoggerDelegate.debugLogger, "Getting " + className.toLowerCase() + " records" + + ((fromIndex != null) ? " from rows " + fromIndex.toString() + " to " + toIndex.toString() : "") + + "..."); + if (filterClause != null && filterClause.length() > 0) + logger.info(EELFLoggerDelegate.debugLogger, "Filtering " + className + " by: " + filterClause); + } + + list = session.createQuery("from " + className + Utilities.nvl(filterClause, "") + + ((orderBy != null) ? " order by " + orderBy : "")).list(); + list = (fromIndex != null) ? list.subList(fromIndex.intValue() - 1, toIndex.intValue()) : list; + + if (orderBy == null && list != null) + Collections.sort(list); + + return list; + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, + * java.util.HashMap) + */ + @Override + public List getList(Class domainClass, HashMap additionalParams) { + return getListCommon(domainClass, null, null, null, null); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, + * java.lang.String, java.lang.String, java.util.HashMap) + */ + @Override + public List getList(Class domainClass, String filter, String orderBy, HashMap additionalParams) { + return getListCommon(domainClass, filter, null, null, orderBy); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, + * java.lang.String, int, int, java.lang.String, java.util.HashMap) + */ + @Override + public List getList(Class domainClass, String filter, int fromIndex, int toIndex, String orderBy, + HashMap additionalParams) { + return getListCommon(domainClass, filter, new Integer(fromIndex), new Integer(toIndex), orderBy); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, + * org.hibernate.criterion.ProjectionList, java.util.List, java.util.List) + */ + @Override + public List getList(Class domainClass, ProjectionList projectionsList, List restrictionsList, + List orderByList) { + + Session session = sessionFactory.getCurrentSession(); + + Criteria criteria = session.createCriteria(domainClass); + + if (projectionsList != null) { + criteria.setProjection(projectionsList); + } + + if (restrictionsList != null && !restrictionsList.isEmpty()) { + for (Criterion criterion : restrictionsList) + criteria.add(criterion); + } + + if (orderByList != null && !orderByList.isEmpty()) { + for (Order order : orderByList) + criteria.addOrder(order); + } + /* + * if(fetchModeMap!=null){ Iterator itr = + * fetchModeMap.keySet().iterator(); String key=null; + * while(itr.hasNext()){ key = itr.next(); + * criteria.setFetchMode(key,fetchModeMap.get(key)); } } + */ + return criteria.list(); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#getLookupList(java.lang. + * String, java.lang.String, java.lang.String, java.lang.String, + * java.lang.String, java.util.HashMap) + */ + @Override + public List getLookupList(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy, + HashMap additionalParams) { + if (logger.isInfoEnabled()) + logger.info(EELFLoggerDelegate.debugLogger, "Retrieving " + dbTable + " lookup list..."); + String dbOrderByCol = dbOrderBy; + + Session session = sessionFactory.getCurrentSession(); + + // default the orderBy if null; + if (Utilities.nvl(dbOrderBy).length() == 0) { + dbOrderByCol = dbLabelCol; + dbOrderBy = dbLabelCol; + } else { + if (dbOrderBy.lastIndexOf(" ") > -1) { + dbOrderByCol = dbOrderBy.substring(0, dbOrderBy.lastIndexOf(" ")); + } + } + + StringBuffer sql = new StringBuffer(); + + sql.append("select distinct ").append(dbLabelCol).append(" as lab, ").append(dbValueCol).append(" as val, ") + .append(dbOrderByCol).append(" as sortOrder ").append("from ").append(dbTable).append(" ") + .append((Utilities.nvl(dbFilter).length() == 0) ? "" : (" where " + dbFilter)).append(" order by ") + .append(dbOrderBy); + + List list = null; + try { + list = session.createSQLQuery(sql.toString()).addEntity(Lookup.class).list(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.debugLogger, "Failed to create SQL lookup query for [" + sql + "]" + e.getMessage()); + } + return list; + } + + /* + * methods accepting a Map of additional params to passed to the DAO (for + * extensibility, just in case) + */ + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeSQLQuery(java.lang. + * String, java.lang.Class, java.util.HashMap) + */ + @Override + public List executeSQLQuery(String sql, Class domainClass, HashMap additionalParams) { + return executeSQLQuery(sql, domainClass, null, null, additionalParams); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeSQLQuery(java.lang. + * String, java.lang.Class, java.lang.Integer, java.lang.Integer, + * java.util.HashMap) + */ + @Override + public List executeSQLQuery(String sql, Class domainClass, Integer fromIndex, Integer toIndex, + HashMap additionalParams) { + Session session = sessionFactory.getCurrentSession(); + + SQLQuery query = session.createSQLQuery(sql).addEntity(domainClass.getName().toLowerCase(), domainClass); + + if (fromIndex != null && toIndex != null) { + query.setFirstResult(fromIndex.intValue()); + int pageSize = (toIndex.intValue() - fromIndex.intValue()) + 1; + query.setMaxResults(pageSize); + } + + return query.list(); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeQuery(java.lang. + * String, java.util.HashMap) + */ + @Override + public List executeQuery(String sql, HashMap additionalParams) { + return executeQuery(sql, null, null, additionalParams); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeQuery(java.lang. + * String, java.lang.Integer, java.lang.Integer, java.util.HashMap) + */ + @Override + public List executeQuery(String sql, Integer fromIndex, Integer toIndex, HashMap additionalParams) { + Session session = sessionFactory.getCurrentSession(); + + Query query = session.createQuery(sql); + + if (fromIndex != null && toIndex != null) { + query.setFirstResult(fromIndex.intValue()); + int pageSize = (toIndex.intValue() - fromIndex.intValue()) + 1; + query.setMaxResults(pageSize); + } + + return query.list(); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedQuery(java.lang + * .String, java.lang.Integer, java.lang.Integer, java.util.HashMap) + */ + @Override + public List executeNamedQuery(String queryName, Integer fromIndex, Integer toIndex, HashMap additionalParams) { + return executeNamedQuery(queryName, null, fromIndex, toIndex, additionalParams); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedQuery(java.lang + * .String, java.util.Map, java.util.HashMap) + */ + @Override + public List executeNamedQuery(String queryName, Map params, HashMap additionalParams) { + return executeNamedQuery(queryName, params, null, null, additionalParams); + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedQuery(java.lang + * .String, java.util.Map, java.lang.Integer, java.lang.Integer, + * java.util.HashMap) + */ + @Override + public List executeNamedQuery(String queryName, Map params, Integer fromIndex, Integer toIndex, + HashMap additionalParams) { + Session session = sessionFactory.getCurrentSession(); + Query query = session.getNamedQuery(queryName); + bindQueryParameters(query, params); + if (fromIndex != null && toIndex != null) { + query.setFirstResult(fromIndex.intValue()); + int pageSize = (toIndex.intValue() - fromIndex.intValue()) + 1; + query.setMaxResults(pageSize); + } + return query.list(); + } + + /** + * Stores parameters into the query using String keys from the map. Gives + * special treatment to map values of Collection and array type. + * + * @param query + * Query with parameters + * @param params + * Map of String to Object. + */ + private void bindQueryParameters(Query query, Map params) { + if (params != null) { + for (Iterator i = params.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + + Object parameterValue = entry.getValue(); + + if (!(parameterValue instanceof Collection) && !(parameterValue instanceof Object[])) { + query.setParameter((String) entry.getKey(), parameterValue); + } else if (parameterValue instanceof Collection) { + query.setParameterList((String) entry.getKey(), (Collection) parameterValue); + } else if (parameterValue instanceof Object[]) { + query.setParameterList((String) entry.getKey(), (Object[]) parameterValue); + } + } + } + } + + // With Where Clause & RAPTOR's ZK + + /* + * (non-Javadoc) + * + * @see org.openecomp.portalsdk.core.service.DataAccessService# + * executeNamedQueryWithOrderBy(java.lang.Class, java.lang.String, + * java.util.Map, java.lang.String, boolean, java.lang.Integer, + * java.lang.Integer, java.util.HashMap) + */ + @Override + public List executeNamedQueryWithOrderBy(Class entity, String queryName, Map params, String _orderBy, boolean asc, + Integer fromIndex, Integer toIndex, HashMap additionalParams) { + // TODO Auto-generated method stub + logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedCountQuery(java + * .lang.Class, java.lang.String, java.lang.String, java.util.Map) + */ + @Override + public List executeNamedCountQuery(Class entity, String queryName, String whereClause, Map params) { + // TODO Auto-generated method stub + logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedQuery(java.lang + * .Class, java.lang.String, java.lang.String, java.util.Map, + * java.lang.Integer, java.lang.Integer, java.util.HashMap) + */ + @Override + public List executeNamedQuery(Class entity, String queryName, String whereClause, Map params, Integer fromIndex, + Integer toIndex, HashMap additionalParams) { + // TODO Auto-generated method stub + logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); + return null; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.portalsdk.core.service.DataAccessService# + * executeNamedQueryWithOrderBy(java.lang.Class, java.lang.String, + * java.lang.String, java.util.Map, java.lang.String, boolean, + * java.lang.Integer, java.lang.Integer, java.util.HashMap) + */ + @Override + public List executeNamedQueryWithOrderBy(Class entity, String queryName, String whereClause, Map params, + String _orderBy, boolean asc, Integer fromIndex, Integer toIndex, HashMap additionalParams) { + // TODO Auto-generated method stub + logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, + * org.hibernate.criterion.ProjectionList, java.util.List, java.util.List, + * java.util.HashMap) + */ + @Override + public List getList(Class domainClass, ProjectionList projectionsList, List restrictionsList, + List orderByList, HashMap fetchModeMap) { + // TODO Auto-generated method stub + logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeUpdateQuery(java. + * lang.String, java.util.HashMap) + */ + @Override + public int executeUpdateQuery(String sql, HashMap additionalParams) throws RuntimeException { + // TODO Auto-generated method stub + logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); + return 0; + } + + /* + * (non-Javadoc) + * + * @see + * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedUpdateQuery( + * java.lang.String, java.util.Map, java.util.HashMap) + */ + @Override + public int executeNamedUpdateQuery(String queryName, Map params, HashMap additionalParams) throws RuntimeException { + // TODO Auto-generated method stub + logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); + return 0; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.portalsdk.core.service.DataAccessService#synchronize(java.util. + * HashMap) + */ + @Override + public void synchronize(HashMap additionalParams) { + // TODO Auto-generated method stub + logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ElementLinkService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ElementLinkService.java new file mode 100644 index 00000000..0cd90dc7 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ElementLinkService.java @@ -0,0 +1,290 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.util.YamlUtils; + +public class ElementLinkService { + + /** + * Builds renderable model of element links in the network map. Parses YAML + * files with metadata and builds input for JoinJS to render in the browser + * as SVG. + * + * @param args + * arg 0 - realPath; arg 1 - callFlowName; arg 2 - callFlowStep. + * @return Renderable model of element links + * @throws Exception + */ + public String buildElementLinkYaml(String[] args) throws Exception { + String relFilePath; + if (args[1].startsWith("custom")) + relFilePath = SystemProperties.getProperty("customCallFlow_path"); + else + relFilePath = SystemProperties.getProperty("element_map_file_path"); + final String yamlDirPath = new File(args[0], relFilePath).getPath(); + + String callFlowBusinessYml = ""; + String callFlowStep = ""; + + if (args != null && args.length > 0) { + if (args[1] != null) + callFlowBusinessYml = args[1] + ".yml"; + if (args[2] != null) + callFlowStep = args[2]; + } + + ElementLinkService mapper = new ElementLinkService(); + String linkYaml = mapper.createLinkFile(yamlDirPath, callFlowBusinessYml, callFlowStep); + return linkYaml; + } + + /* + * public String main2(String[] args) throws Exception { + * + * String filePath = SystemProperties.getProperty("element_map_file_path") + + * File.separator; String callFlowBusinessYml = ""; String callFlowStep = + * ""; + * + * if (args != null && args.length > 0) { + * + * if (args[0] != null) { callFlowBusinessYml = args[0] + "-Override.yml"; } + * + * if (args[1] != null) { callFlowStep = args[1]; } } + * + * ElementLinkService mapper = new ElementLinkService(); + * + * return mapper.createLinkFileAdditional(filePath, callFlowBusinessYml, + * callFlowStep); } + */ + + public static void main(String[] args) throws Exception { + + String filePath = "\\D2Platform\\war\\WEB-INF\\resources\\trisim_files"; + String callFlowBusinessYml = "call_flow_hc-origination-termination-to-volteue-3.3.16-Override.yml"; + + ElementLinkService mapper = new ElementLinkService(); + + // System.out.print(mapper.createLinkFile(filePath, networkToscaYml, + // networkToscaUeYml, networkLayoutYml, callFlowBusinessYml,"Step_1")); + System.out.print(mapper.createLinkFileAdditional(filePath, callFlowBusinessYml, "Step_2")); + } + + @SuppressWarnings("unchecked") + protected String createLinkFile(String resourceFilePath, String callFLowBsFileName, String callFlowStep) + throws Exception { + + Map callFlowBs = YamlUtils.readYamlFile(resourceFilePath, callFLowBsFileName); + + List> callSteps = (List>) callFlowBs.get("callSequenceSteps"); + String callFlowName = (String) callFlowBs.get("shortName"); + return addLinks(resourceFilePath, callFlowName, callSteps, callFlowStep); + + } + + @SuppressWarnings("unchecked") + protected String createLinkFileAdditional(String resourceFilePath, String callFLowBsFileName, String callFlowStep) + throws Exception { + + // Map callFlowBs = + // YamlUtils.readYamlFile(resourceFilePath, callFLowBsFileName); + + // return YamlUtils.returnYaml(callFlowBs); + + Map callFlowBs; + + try { + callFlowBs = YamlUtils.readYamlFile(resourceFilePath, callFLowBsFileName); + + List> callSteps = (List>) callFlowBs.get("callSequenceSteps"); + String callFlowName = (String) callFlowBs.get("shortName"); + return addLinksAdditional(resourceFilePath, callFlowName, callSteps, callFlowStep); + + } catch (Exception e) { + + return ""; + } + + } + + @SuppressWarnings("unchecked") + protected String addLinks(String filePath, String callFlowName, List> callSteps, + String callFlowStep) throws IOException { + + Map> checkDuplicateMap = new HashMap>(); + + for (Map callStep : callSteps) { + + if (((String) callStep.get("name")).split(":")[0].trim().replace(" ", "_").equals(callFlowStep)) { + + // String callFlowStepName = callFlowName + "_" + + // ((String)callStep.get("name")).split("-")[0].trim().replace(" + // ", "_")+".yml"; + + List> links = new ArrayList>(); + + List> subSteps = (List>) callStep.get("subSteps"); + + for (Map subStep : subSteps) { + Map link = new HashMap(); + + String source = (String) subStep.get("source_tosca_id"); + String destination = (String) subStep.get("destination_tosca_id"); + + if ((checkDuplicateMap.get(source) == null || checkDuplicateMap.get(source).isEmpty() + || !checkDuplicateMap.get(source).contains(destination)) && !source.equals(destination)) { + if (checkDuplicateMap.get(destination) == null) { + List toscaList = new ArrayList(); + checkDuplicateMap.put(destination, toscaList); + } + + if (checkDuplicateMap.get(source) == null) { + List toscaList = new ArrayList(); + checkDuplicateMap.put(source, toscaList); + } + + List toscaSourceList = checkDuplicateMap.get(destination); + toscaSourceList.add(source); + + List toscaDestinationList = checkDuplicateMap.get(source); + toscaDestinationList.add(destination); + + link.put("s", source); + link.put("d", destination); + links.add(link); + + /* + * may be needed in future but nnot currently + * + * if((String) subStep.get("link_visibility")!=null){ + * if(((String) + * subStep.get("link_visibility")).equals("No")){ + * + * } }else{ + * + * links.add(link); } + */ + + } + + } + + Map callFlowUI = new HashMap(); + callFlowUI.put("linkList", links); + + return YamlUtils.returnYaml(callFlowUI); + + // YamlUtils.writeYamlFile(filePath, callFlowStepName, + // callFlowUI); + } + + } + return ""; + } + + protected String addLinksAdditional(String filePath, String callFlowName, List> callSteps, + String callFlowStep) throws IOException { + + for (Map callStep : callSteps) { + + if (((String) callStep.get("name")).split(":")[0].trim().replace(" ", "_").equals(callFlowStep)) { + + // String callFlowStepName = callFlowName + "_" + + // ((String)callStep.get("name")).split("-")[0].trim().replace(" + // ", "_")+".yml"; + + Map callFlowUI = new HashMap(); + try { + List> links = addLinkVertices(callStep); + callFlowUI.put("linkList", links); + } catch (Exception e) { + } + try { + List activeIds = addActiveNodes(callStep); + callFlowUI.put("activeIds", activeIds); + } catch (Exception e) { + } + try { + List> disconnectLinks = addDisconnectLinks(callStep); + callFlowUI.put("disconnectLinks", disconnectLinks); + } catch (Exception e) { + } + + return YamlUtils.returnYaml(callFlowUI); + } + } + + return ""; + } + + @SuppressWarnings("unchecked") + List addActiveNodes(Map callStep) { + List activeIds = (List) callStep.get("activeIds"); + return activeIds; + } + + @SuppressWarnings("unchecked") + List> addDisconnectLinks(Map callStep) { + List> disconnectLinks = (List>) callStep.get("disconnectLinks"); + return disconnectLinks; + } + + @SuppressWarnings("unchecked") + List> addLinkVertices(Map callStep) { + List> links = new ArrayList>(); + + List> vertices = (List>) callStep.get("vertices"); + + for (int i = 0; i < vertices.size() - 1; i++) { + Map vertex = (Map) vertices.get(i); + Map vertexNext = (Map) vertices.get(i + 1); + + Integer sourceX = (Integer) vertex.get("x"); + Integer sourceY = (Integer) vertex.get("y"); + String sourceD = (String) vertex.get("D"); + String sourceL = (vertex.get("L") != null) ? (String) vertex.get("L") : "-"; + + if (sourceX == -999) // there is a break in the linkage + continue; + + Integer destinationX = (Integer) vertexNext.get("x"); + Integer destinationY = (Integer) vertexNext.get("y"); + String destinationD = (String) vertexNext.get("D"); + + if (destinationX == -999) // there is a break in the linkage + continue; + + Map link = new HashMap(); + + link.put("s", sourceX + "," + sourceY + "," + sourceD + "," + sourceL); + link.put("d", destinationX + "," + destinationY + "," + destinationD); + links.add(link); + } + return links; + } +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ElementMapService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ElementMapService.java new file mode 100644 index 00000000..8213a5ba --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ElementMapService.java @@ -0,0 +1,1029 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.commons.lang.StringUtils; +import org.openecomp.portalsdk.core.domain.support.Container; +import org.openecomp.portalsdk.core.domain.support.Domain; +import org.openecomp.portalsdk.core.domain.support.Element; +import org.openecomp.portalsdk.core.domain.support.ElementDetails; +import org.openecomp.portalsdk.core.domain.support.Layout; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.util.YamlUtils; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.nodes.Tag; +import org.yaml.snakeyaml.representer.Representer; + +public class ElementMapService { + + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ElementMapService.class); + + /** + * + * @param contextRealPath + * @param layout + * @return + * @throws Exception + */ + private String convertToYAML(String contextRealPath, Layout layout) throws Exception { + + // Used to build image file relative URLs + final String iconRelPath = SystemProperties.getProperty("element_map_icon_path"); // "static/img/map/icons/"; + + Map resultAICDomain = layout.domainRowCol; + Map> domainMap = new HashMap>(); + List domainList = new ArrayList(); + for (Domain d : resultAICDomain.values()) { + d.setWidth(10 * d.computeSize().getWidth()); + d.setHeight(10 * d.computeSize().getHeight()); + d.setLeft(10 * d.getP().getX()); + d.setTop(10 * d.getP().getY()); + + List containerList = new ArrayList(); + for (Container c : d.getContainerRowCol().values()) { + c.setWidth(10 * c.computeSize().getWidth()); + c.setHeight(10 * c.computeSize().getHeight()); + c.setLeft(10 * c.getP().getX()); + c.setTop(10 * c.getP().getY()); + Element ue = (Element) c.getElementRowCol().values().toArray()[0]; + if (ue.getName().equals("ue1") || ue.getName().equals("ue2") || ue.getName().equals("ue3") + || ue.getName().equals("ue4") || ue.getName().equals("ue5") || ue.getName().equals("ue6")) { + c.setVisibilityType("invisible"); + } + + if (c.getContainerRowCol() != null) { + List innerContainerList = new ArrayList(); + for (Container innerC : c.getContainerRowCol().values()) { + innerC.setName(innerC.getName()); + innerC.setWidth(10 * innerC.computeSize().getWidth()); + innerC.setHeight(10 * innerC.computeSize().getHeight()); + innerC.setLeft(10 * innerC.getP().getX()); + innerC.setTop(10 * innerC.getP().getY()); + + if (innerC.getElementRowCol() != null) { + List innerContainerEList = new ArrayList(); + for (Element ele : innerC.getElementRowCol().values()) { + // ele.setName(ele.getName()); + ele.setWidth(10 * ele.computeSize().getWidth()); + ele.setHeight(10 * ele.computeSize().getHeight()); + ele.setLeft(10 * ele.getP().getX()); + ele.setTop(10 * ele.getP().getY() - 10); + ele.setImgFileName(iconRelPath + "/" + ele.getImgFileName()); + if (ele.getBorderType().equals("V")) + ele.setBorderType("dashed"); + else + ele.setBorderType("solid"); + innerContainerEList.add(ele); + } + innerC.setElementList(innerContainerEList); + } + innerContainerList.add(innerC); + } + c.setInnerCList(innerContainerList); + } + + if (c.getElementRowCol() != null) { + List elementList = new ArrayList(); + for (Element e : c.getElementRowCol().values()) { + // e.setName(e.getName()); + e.setWidth(10 * e.computeSize().getWidth()); + e.setHeight(10 * e.computeSize().getHeight()); + e.setLeft(10 * e.getP().getX()); + e.setTop(10 * e.getP().getY() - 10); + e.setImgFileName(iconRelPath + "/" + e.getImgFileName()); + + if (e.getBorderType().equals("V")) + e.setBorderType("dashed"); + else + e.setBorderType("solid"); + + if (e.getName().equals("ue1") || e.getName().equals("ue2") || e.getName().equals("ue3") + || e.getName().equals("ue4") || e.getName().equals("ue5") || e.getName().equals("ue6")) + e.setBgColor("white"); + elementList.add(e); + } + c.setElementList(elementList); + } + containerList.add(c); + } + d.setContainerList(containerList); + domainList.add(d); + + } + domainMap.put("domainList", domainList); + + List collapsedDomains = new ArrayList(); + + // nline + for (Domain collapsed : layout.getCollapsedDomainsNewList()) { + collapsed.setWidth(10 * collapsed.computeSize().getWidth()); + collapsed.setHeight(10 * collapsed.computeSize().getHeight()); + collapsed.setLeft(10 * collapsed.getP().getX()); + collapsed.setTop(10 * collapsed.getP().getY()); + // nline + collapsed.setNewXafterColl(10 * collapsed.getNewXafterColl()); + collapsed.setYafterColl(10 * collapsed.getYafterColl()); + collapsedDomains.add(collapsed); + } + + domainMap.put("collapsedDomainList", collapsedDomains); + + Representer representer = new Representer(); + representer.addClassTag(Domain.class, Tag.MAP); + + Yaml yaml = new Yaml(representer); + String output = yaml.dump(domainMap); + + return output; + + } + + private static HashMap toscaElementsMap = new HashMap(); + private static HashMap elementMap = new HashMap(); + private static HashMap miscElementMap = new HashMap(); + private static HashMap outercontainers = new HashMap(); + private static HashMap innercontainers = new HashMap(); + private static HashMap domainMap = new HashMap(); + + private static String filePath = SystemProperties.getProperty("element_map_file_path"); + private static String networkToscaYml = null;// "NetworkMap_topology_composition.yml"; + private static String networkLayoutYml = null;// "network_map_layout.yml"; + + /** + * Builds renderable model of elements in the network map. Parses YAML files + * with metadata and builds input for JoinJS to render in the browser as + * SVG. + * + * @param args + * arg 0 - collapsedDomains; arg 1 - expandedDomains; arg 2 - + * context real path; arg 3 - contentFileName; arg 4 - + * layoutFileName + * @return Renderable model of elements + * @throws Exception + */ + public String buildElementMapYaml(String args[]) throws Exception { + + final String yamlDirPath = new File(args[2], filePath).getPath(); + if (args != null && args.length > 4) { + if (args[3] != null) + networkToscaYml = args[3] + ".yml"; + if (args[4] != null) + networkLayoutYml = args[4] + ".yml"; + } + + Map toscaYaml = YamlUtils.readYamlFile(yamlDirPath, networkToscaYml); + Map networkMapLayoutYaml = YamlUtils.readYamlFile(yamlDirPath, networkLayoutYml); + + toscaElementsMap = new HashMap(); + elementMap = new HashMap(); + domainMap = new HashMap(); + outercontainers = new HashMap(); + innercontainers = new HashMap(); + miscElementMap = new HashMap(); + + if (toscaYaml != null) { + for (String key : toscaYaml.keySet()) { + if ("topology_template".equalsIgnoreCase(key) && toscaYaml.get(key) instanceof HashMap) { + HashMap toscaTopologyDetails = (HashMap) toscaYaml.get(key); + + for (String detailsKey : toscaTopologyDetails.keySet()) { + + if ("node_templates".equalsIgnoreCase(detailsKey) + && toscaTopologyDetails.get(detailsKey) instanceof HashMap) { + + toscaElementsMap = (HashMap) toscaTopologyDetails.get(detailsKey); + + // for (String toscaElementKey : + // toscaElementsMap.keySet()) { + //// System.out.println("Element - "+ "key :" + + //// toscaElementKey); + // } + + } + } + } + + } + } + + if (networkMapLayoutYaml != null) { + if (networkMapLayoutYaml.containsKey("toscaNetworkMapElementStyleList") + && networkMapLayoutYaml.get("toscaNetworkMapElementStyleList") instanceof ArrayList) { + + ArrayList elementlist = (ArrayList) networkMapLayoutYaml + .get("toscaNetworkMapElementStyleList"); + String elementName; + String elementID; + String imgPath; + String row; + String column; + String mapKey; + int i = 0; + + if (elementlist != null) { + for (Object eachElement : elementlist) { + // System.out.println("toscaNetworkMapElementStyleList + // Container : " +eachElement); + if (eachElement != null && eachElement instanceof HashMap) { + HashMap elementDetails = (HashMap) eachElement; + if (elementDetails != null) { + elementName = "NA" + i; + elementID = "NA" + i; + imgPath = "NA" + i; + row = "0"; + column = "0"; + for (String detailsKey : elementDetails.keySet()) { + if ("tosca_id".equalsIgnoreCase(detailsKey)) + elementName = elementDetails.get(detailsKey).toString(); + if ("id".equalsIgnoreCase(detailsKey)) { + elementID = String.valueOf(elementDetails.get(detailsKey)); + } + if ("row".equalsIgnoreCase(detailsKey)) { + row = String.valueOf(elementDetails.get(detailsKey)); + } + if ("column".equalsIgnoreCase(detailsKey)) { + column = String.valueOf(elementDetails.get(detailsKey)); + } + if ("icon".equalsIgnoreCase(detailsKey)) + imgPath = elementDetails.get(detailsKey).toString(); + } + + if (elementMap.containsKey(elementName.concat("/").concat(row).concat(column))) { + if (elementMap.containsKey(elementName.concat("/").concat(String.valueOf(i)) + .concat(String.valueOf(i)))) { + mapKey = elementName; + } else + mapKey = elementName.concat("/").concat(String.valueOf(i)) + .concat(String.valueOf(i)); + + } else + mapKey = elementName.concat("/").concat(row).concat(column); + + elementMap.put(mapKey, fetchElementObject(elementID, elementName, imgPath)); + } + } + i++; + } + } + + for (String elementkey : elementMap.keySet()) { + Element c = (Element) elementMap.get(elementkey); + // System.out.println("Element - "+ "key :" +elementkey +" - + // " + "value :" + c.getName()); + } + + if (!elementMap.isEmpty()) { + miscElementMap = new HashMap(elementMap); + } + } + + if (networkMapLayoutYaml.containsKey("containerStyleList") + && networkMapLayoutYaml.get("containerStyleList") instanceof ArrayList) { + + ArrayList containerstylelist = (ArrayList) networkMapLayoutYaml + .get("containerStyleList"); + String containerName; + String containerID; + String domain; + String row; + String column; + String mapKey; + int i = 0; + + if (containerstylelist != null) { + // Inner Containers + for (Object eachContainer : containerstylelist) { + if (eachContainer != null && eachContainer instanceof HashMap) { + HashMap containerDetails = (HashMap) eachContainer; + if (containerDetails != null) { + containerName = "NA" + i; + containerID = "NA" + i; + domain = "NA" + i; + row = "0"; + column = "0"; + + for (String detailsKey : containerDetails.keySet()) { + if ("logical_group_name".equalsIgnoreCase(detailsKey)) + containerName = containerDetails.get(detailsKey).toString(); + if ("id".equalsIgnoreCase(detailsKey)) { + containerID = String.valueOf(containerDetails.get(detailsKey)); + } + if ("domain".equalsIgnoreCase(detailsKey)) { + domain = containerDetails.get(detailsKey).toString(); + } + if ("row".equalsIgnoreCase(detailsKey)) { + row = String.valueOf(containerDetails.get(detailsKey)); + } + if ("column".equalsIgnoreCase(detailsKey)) { + column = String.valueOf(containerDetails.get(detailsKey)); + } + } + if (containerName.contains("/")) { + + if (innercontainers.containsKey( + (domain + ":" + containerName).concat("/").concat(row).concat(column))) { + if (elementMap.containsKey((domain + ":" + containerName).concat("/") + .concat(String.valueOf(i)).concat(String.valueOf(i)))) { + mapKey = (domain + ":" + containerName); + } else + mapKey = (domain + ":" + containerName).concat("/") + .concat(String.valueOf(i)).concat(String.valueOf(i)); + + } else + mapKey = (domain + ":" + containerName).concat("/").concat(row).concat(column); + + innercontainers.put(mapKey, + fetchContainerObject(containerID, + containerName.substring(containerName.indexOf("/") + 1), true, + containerName, domain)); + } + } + } + i++; + } + + // OuterContainers + i = 0; + for (Object eachContainer : containerstylelist) { + if (eachContainer != null && eachContainer instanceof HashMap) { + HashMap containerDetails = (HashMap) eachContainer; + if (containerDetails != null) { + containerName = "NA" + i; + containerID = "NA" + i; + domain = "NA" + i; + row = "0"; + column = "0"; + + for (String detailsKey : containerDetails.keySet()) { + if ("logical_group_name".equalsIgnoreCase(detailsKey)) + containerName = containerDetails.get(detailsKey).toString(); + if ("id".equalsIgnoreCase(detailsKey)) { + containerID = String.valueOf(containerDetails.get(detailsKey)); + } + if ("domain".equalsIgnoreCase(detailsKey)) { + domain = containerDetails.get(detailsKey).toString(); + } + if ("row".equalsIgnoreCase(detailsKey)) { + row = String.valueOf(containerDetails.get(detailsKey)); + } + if ("column".equalsIgnoreCase(detailsKey)) { + column = String.valueOf(containerDetails.get(detailsKey)); + } + } + if (!containerName.contains("/")) { + if (outercontainers.containsKey( + (domain + ":" + containerName).concat("/").concat(row).concat(column))) { + if (outercontainers.containsKey((domain + ":" + containerName).concat("/") + .concat(String.valueOf(i)).concat(String.valueOf(i)))) { + mapKey = (domain + ":" + containerName); + } else + mapKey = (domain + ":" + containerName).concat("/") + .concat(String.valueOf(i)).concat(String.valueOf(i)); + + } else + mapKey = (domain + ":" + containerName).concat("/").concat(row).concat(column); + outercontainers.put(mapKey, fetchContainerObject(containerID, containerName, false, + containerName, domain)); + } + // else innercontainers.put(domain +":"+ + // containerName, + // fetchContainerObject(containerID,containerName.substring(containerName.indexOf("/")+1),false,containerName,domain)); + + } + } + i++; + } + } + + for (String innerContainerkey : innercontainers.keySet()) { + Container c = (Container) innercontainers.get(innerContainerkey); + } + + for (String outerContainerkey : outercontainers.keySet()) { + Container c = (Container) outercontainers.get(outerContainerkey); + } + + } + + if (networkMapLayoutYaml.containsKey("domainList") + && networkMapLayoutYaml.get("domainList") instanceof ArrayList) { + + ArrayList domainlist = (ArrayList) networkMapLayoutYaml.get("domainList"); + String domainName; + String domainID; + String row; + String column; + String mapKey; + int i = 0; + + if (domainlist != null) { + + HashMap domainStagingMap = new HashMap(); + for (Object eachDomain : domainlist) { + // System.out.println("domainlist Container : " + // +eachDomain); + if (eachDomain != null && eachDomain instanceof HashMap) { + HashMap domainDetails = (HashMap) eachDomain; + if (domainDetails != null) { + domainName = "NA" + i; + domainID = "NA" + i; + row = "0"; + column = "0"; + for (String detailsKey : domainDetails.keySet()) { + if ("name".equalsIgnoreCase(detailsKey)) + domainName = domainDetails.get(detailsKey).toString(); + if ("id".equalsIgnoreCase(detailsKey)) { + domainID = String.valueOf(domainDetails.get(detailsKey)); + } + if ("row".equalsIgnoreCase(detailsKey)) { + row = String.valueOf(domainDetails.get(detailsKey)); + } + if ("column".equalsIgnoreCase(detailsKey)) { + column = String.valueOf(domainDetails.get(detailsKey)); + } + } + + if (domainStagingMap.containsKey(row.concat(column))) { + mapKey = domainName; + } else + mapKey = row.concat(column); + + domainStagingMap.put(mapKey, domainID + "%" + domainName); + } + } + i++; + } + + if (domainStagingMap != null && !domainStagingMap.isEmpty()) { + for (String domainsKey : new TreeSet(domainStagingMap.keySet())) { + String value = domainStagingMap.get(domainsKey); + if (value.contains("%")) { + domainMap.put(domainsKey, fetchDomainObject(value.substring(0, value.indexOf("%")), + value.substring(value.indexOf("%") + 1))); + } + } + } + } + + // for (String domainkey : domainMap.keySet()) { + // Domain c = (Domain) domainMap.get(domainkey); + // System.out.println("Domain - "+ "key :" +domainkey +" - " + // + "value :" + c.getName()); + // } + } + + } + + Layout dynamicLayout = new Layout(domainMap, 2, 10, 1, 5); + dynamicLayout.computeDomainPositionsModified(); + + /* + * Map resultAICDomain2 = dynamicLayout.domainRowCol; + * for (String key : resultAICDomain2.keySet()) { if + * (resultAICDomain2.get(key).getP() != null) { + * System.out.println(resultAICDomain2.get(key).name+" "+"x:"+ + * resultAICDomain2.get(key).getP().getX()+","+"y:"+ + * resultAICDomain2.get(key).getP().getY()+","+"width:"+ + * resultAICDomain2.get(key).computeSize().getWidth() + * +","+"height:"+resultAICDomain2.get(key).computeSize(). getHeight()); + * + * } } + */ + + ElementMapService cm2 = new ElementMapService(); + try { + + if (args != null && args.length > 0) { + + if (args[0] != null) { + String collapsedDomains[] = args[0].split(","); + for (String collapsedDomain : collapsedDomains) + // dynamicLayout.collapseDomainModified(collapsedDomain); + dynamicLayout.collapseDomainNew(collapsedDomain); + } + + if (args[1] != null) { + String expandedDomains[] = args[1].split(","); + for (String expandedDomain : expandedDomains) + // dynamicLayout.uncollapseDomainNew(expandedDomain); + dynamicLayout.uncollapseDomainNew1(expandedDomain); + } + + return cm2.convertToYAML(args[2], dynamicLayout); + } + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "buildElementMapYaml failed", e); + } + + return ""; + } + + private static int computeRows(Set keys) { + int i = 0; + if (keys != null && !keys.isEmpty()) { + for (String s : keys) { + String r = s.substring(0, 1); + if (StringUtils.isNumeric(r)) { + int j = Integer.parseInt(r); + if (i <= j) { + i = j; + } + + } + } + + return i + 1; + } + + return 1; + } + + private static int computeColumns(Set keys) { + int i = 0; + if (keys != null && !keys.isEmpty()) { + for (String s : keys) { + String r = s.substring(1, 2); + if (StringUtils.isNumeric(r)) { + int j = Integer.parseInt(r); + if (i <= j) { + i = j; + } + + } + } + + return i + 1; + } + + return 1; + } + + private static Container fetchContainerObject(String id, String name, boolean isInner, String logicalGroupName, + String domain) { + Map containerElementsMap = new HashMap(); + + containerElementsMap = fetchElementsMapForContainer(name, isInner, logicalGroupName, domain); + int rows = 1; + int columns = 1; + + if (isInner) { + + if (containerElementsMap != null && !containerElementsMap.isEmpty()) { + rows = computeRows(containerElementsMap.keySet()); + columns = computeColumns(containerElementsMap.keySet()); + } + + Container thisContainer = new Container(id, name, rows, columns, 1, 4, 8, 12, 1, 2); + thisContainer.setElements(containerElementsMap); + // thisContainer.setVisibilityType(""); + + return thisContainer; + } else { + Map innerContainersMap = fetchInnerContainersMapForOuter(name, isInner, logicalGroupName, + domain); + + if (innerContainersMap != null && !innerContainersMap.isEmpty()) { + if (containerElementsMap != null && !containerElementsMap.isEmpty()) { + Set keys = new HashSet(innerContainersMap.keySet()); + keys.addAll(containerElementsMap.keySet()); + rows = computeRows(keys); + columns = computeColumns(keys); + } else { + rows = computeRows(innerContainersMap.keySet()); + columns = computeColumns(innerContainersMap.keySet()); + } + } else if (containerElementsMap != null && !containerElementsMap.isEmpty()) { + rows = computeRows(containerElementsMap.keySet()); + columns = computeColumns(containerElementsMap.keySet()); + } + + Container thisContainer = new Container(id, name, rows, columns, 2, 6, 2, 5, 0, 0); + thisContainer.setElements(containerElementsMap); + thisContainer.setInnerContainer(innerContainersMap); + + if (containerElementsMap != null && !containerElementsMap.isEmpty()) { + for (Element thisElement : containerElementsMap.values()) { + if (thisElement.getId() != null + ) { + thisContainer.setVisibilityType("invisible"); + } + } + } + return thisContainer; + } + + } + + private static Domain fetchDomainObject(String id, String name) { + HashMap domainContainersMap = fetchContainersForDomain(name); + + int rows = 1; + int columns = 1; + if (domainContainersMap != null && !domainContainersMap.isEmpty()) { + rows = computeRows(domainContainersMap.keySet()); + columns = computeColumns(domainContainersMap.keySet()); + } + + double domainWidth = 11; + Domain thisDomain; + + if (domainMap != null && !domainMap.isEmpty()) { + int domainsCountSoFar = domainMap.size(); + switch (domainsCountSoFar) { + case 1: { + domainWidth = 12.1; + break; + } + case 2: { + domainWidth = 13.3; + break; + } + case 3: { + domainWidth = 14.5; + break; + } + case 4: { + domainWidth = 15.6; + break; + } + default: { + domainWidth = 11; + break; + } + } + + for (String domainsKey : new TreeSet(domainMap.keySet())) { + Domain eachDomain = domainMap.get(domainsKey); + domainWidth += eachDomain.computeSize().getWidth(); + } + thisDomain = new Domain(id, name, 2, 2, domainWidth, 10, 3, rows, columns); + } else { + + thisDomain = new Domain(id, name, 2, 1, 11, 10, 3, rows, columns); + } + + // Domain thisDomain = new Domain(id, name, 2, 1, leftPosition, 10, 3, + // rows, columns); + thisDomain.setContainers(domainContainersMap); + + thisDomain.computeConatinerPositions(); + if (domainContainersMap != null && !domainContainersMap.isEmpty()) { + for (Container thisContainer : domainContainersMap.values()) { + thisContainer.computeSize(); + thisContainer.computeElementPositions(); + Map resultElementMap = thisContainer.elementRowCol; + for (String key : resultElementMap.keySet()) { + if (resultElementMap.get(key) == null || resultElementMap.get(key).getP() == null) { + // System.out.println("culprit " +key); + } + /* + * System.out.println(resultElementMap.get(key).name+" " + * +"x:"+resultElementMap.get(key).getP().getX()+","+"y:"+ + * resultElementMap.get(key).getP().getY()+","+"width:"+ + * resultElementMap.get(key).computeSize().getWidth() + * +","+"height:"+resultElementMap.get(key).computeSize(). + * getHeight()); + */ + + } + + HashMap innerContainersMap = (HashMap) thisContainer + .getContainerRowCol(); + if (innerContainersMap != null && !innerContainersMap.isEmpty()) { + for (Container thisInnerContainer : innerContainersMap.values()) { + // thisInnerContainer.computeSize(); + thisInnerContainer.computeElementPositions(); + /* + * Map resultInnerElementMap = + * thisContainer.elementRowCol; for (String key : + * resultElementMap.keySet()) { // + * System.out.println(resultElementMap.get(key).name+" " + * +"x:"+resultElementMap.get(key).getP().getX()+","+ + * "y:"+ + * resultElementMap.get(key).getP().getY()+","+"width:"+ + * resultElementMap.get(key).computeSize().getWidth() + * +","+"height:"+resultElementMap.get(key).computeSize( + * ).getHeight()); + * + * } + */ + } + } + } + } + + return thisDomain; + } + + private static HashMap fetchContainersForDomain(String domain) { + HashMap domainContainersMap = new HashMap(); + + domainContainersMap = fetchFromOuterContainers(domain); + + return domainContainersMap; + + } + + private static Element fetchElementObject(String id, String name, String imgPath) { + String bgColor = "bgColor"; + String logical_group; + String display_longname; + String display_shortname; + String description; + String primary_function; + String key_interfaces; + String location; + String vendor; + String vendor_shortname; + String enclosingContainer; + String borderType; + String network_function; + + if (toscaElementsMap.containsKey(name)) { + + if (toscaElementsMap.get(name) != null && toscaElementsMap.get(name) instanceof HashMap) { + HashMap toscaElementDetails = (HashMap) toscaElementsMap.get(name); + + for (String detailsKey : toscaElementDetails.keySet()) { + if ("properties".equalsIgnoreCase(detailsKey) + && toscaElementDetails.get(detailsKey) instanceof HashMap) { + HashMap elementDetails = (HashMap) toscaElementDetails + .get(detailsKey); + + if (elementDetails != null) { + logical_group = elementDetails.get("logical_group") == null ? "" + : elementDetails.get("logical_group").toString(); + display_longname = elementDetails.get("display_longname") == null ? "" + : elementDetails.get("display_longname").toString(); + display_shortname = elementDetails.get("display_shortname") == null ? "" + : elementDetails.get("display_shortname").toString(); + description = elementDetails.get("description") == null ? "" + : elementDetails.get("description").toString(); + primary_function = elementDetails.get("primary_function") == null ? "" + : elementDetails.get("primary_function").toString(); + key_interfaces = elementDetails.get("key_interfaces") == null ? "" + : elementDetails.get("key_interfaces").toString(); + location = elementDetails.get("location") == null ? "" + : elementDetails.get("location").toString(); + vendor = elementDetails.get("vendor") == null ? "" + : elementDetails.get("vendor").toString(); + vendor_shortname = elementDetails.get("vendor_shortname") == null ? "" + : elementDetails.get("vendor_shortname").toString(); + enclosingContainer = logical_group.replace("/", "-"); + network_function = elementDetails.get("network_function"); + borderType = elementDetails.get("network_function") == null ? "P" + : elementDetails.get("network_function").toString().toUpperCase(); + bgColor = elementDetails.get("background_color") == null ? "bgColor" + : elementDetails.get("background_color").toString(); + + ElementDetails details = new ElementDetails(logical_group, display_longname, description, + primary_function, network_function, key_interfaces, location, vendor, + vendor_shortname, enclosingContainer); + + return new Element(name, display_shortname, imgPath, bgColor, borderType, details); + } + + } + } + + } + + // Element(id, name, imgPath, bgColor, logical_group, + // display_longname, + // description, primary_function, key_interfaces, location, vendor, + // vendor_shortname); + } else { + return new Element(id, name); + } + + return new Element(id, name); + } + + private static String fetchDomainNameOfElement(String name) { + if (toscaElementsMap.containsKey(name)) { + + if (toscaElementsMap.get(name) != null && toscaElementsMap.get(name) instanceof HashMap) { + HashMap toscaElementDetails = (HashMap) toscaElementsMap.get(name); + + for (String detailsKey : toscaElementDetails.keySet()) { + if ("properties".equalsIgnoreCase(detailsKey) + && toscaElementDetails.get(detailsKey) instanceof HashMap) { + HashMap elementDetails = (HashMap) toscaElementDetails + .get(detailsKey); + + if (elementDetails != null) { + return elementDetails.get("domain") == null ? "" : elementDetails.get("domain").toString(); + } + + } + } + + } + + } else { + return ""; + } + + return ""; + } + + private static HashMap fetchInnerContainersMapForOuter(String name, boolean isInner, + String logicalGroupName, String domain) { + return fetchInnerContainersMap(name, logicalGroupName, domain); + } + + private static HashMap fetchElementsMapForContainer(String name, boolean isInner, + String logicalGroupName, String domain) { + return fetchElementsMap(logicalGroupName, domain); + } + + private static HashMap fetchInnerContainersMap(String name, String logicalGroupName, + String domain) { + HashMap containersMap = new HashMap(); + String rowColumnKey = ""; + int count = 0; + + if (innercontainers != null && !innercontainers.isEmpty()) { + for (String key : innercontainers.keySet()) { + + Container eachContainer = innercontainers.get(key); + + if (key.toUpperCase().contains((domain + ":" + name).toUpperCase())) { + if (key.contains("/")) { + rowColumnKey = key.substring(key.lastIndexOf("/") + 1); + } + + if (rowColumnKey.isEmpty() || containersMap.containsKey(rowColumnKey)) { + count = 0; + while (count <= 9) { + if (containersMap.containsKey(String.valueOf(count).concat(String.valueOf(count)))) { + count++; + } else { + rowColumnKey = String.valueOf(count).concat(String.valueOf(count)); + break; + } + } + + } + + containersMap.put(rowColumnKey, eachContainer); + } + + } + } + return containersMap.isEmpty() ? null : containersMap; + + } + + private static HashMap fetchFromOuterContainers(String domain) { + HashMap thisContainersMap = new HashMap(); + String rowColumnKey = ""; + int count = 0; + + if (outercontainers != null && !outercontainers.isEmpty()) { + for (String key : outercontainers.keySet()) { + Container eachContainer = outercontainers.get(key); + + if (key.toUpperCase().contains((domain + ":").toUpperCase())) { + if (key.contains("/")) { + rowColumnKey = key.substring(key.lastIndexOf("/") + 1); + } + + if (rowColumnKey.isEmpty() || thisContainersMap.containsKey(rowColumnKey)) { + count = 0; + while (count <= 9) { + if (thisContainersMap.containsKey(String.valueOf(count).concat(String.valueOf(count)))) { + count++; + } else { + rowColumnKey = String.valueOf(count).concat(String.valueOf(count)); + break; + } + } + + } + + thisContainersMap.put(rowColumnKey, eachContainer); + } + } + + } + + // Misc Elements Containers + + if (miscElementMap != null && !miscElementMap.isEmpty()) { + for (String key : miscElementMap.keySet()) { + Element eachElement = miscElementMap.get(key); + String elementName = eachElement.getName(); + String domainName = fetchDomainNameOfElement(elementName); + + if (domain.equalsIgnoreCase(domainName)) { + Container eachContainer = new Container(domainName + ":" + elementName, elementName, 1, 1, 3, 6, 2, + 5, 0, 0); + count = 0; + while (count <= 9) { + if (thisContainersMap.containsKey(String.valueOf(count).concat(String.valueOf(count)))) { + count++; + } else { + rowColumnKey = String.valueOf(count).concat(String.valueOf(count)); + break; + } + } + + thisContainersMap.put(rowColumnKey, eachContainer); + } + + } + + } + + return thisContainersMap.isEmpty() ? null : thisContainersMap; + } + + private static HashMap addOuterContainersForMiscElements(String domain) { + HashMap containerElementsMap = new HashMap(); + if (miscElementMap != null && !miscElementMap.isEmpty()) { + for (String key : miscElementMap.keySet()) { + Element eachElement = miscElementMap.get(key); + String elementName = eachElement.getName(); + String domainName = fetchDomainNameOfElement(elementName); + + if (domain.equalsIgnoreCase(domainName)) { + Container newContainer = new Container(domainName + ":" + elementName, elementName, 1, 1, 3, 6, 2, + 5, 0, 0); + containerElementsMap.put(domainName + ":" + elementName, newContainer); + } + + } + + } + return containerElementsMap.isEmpty() ? null : containerElementsMap; + } + + private static HashMap fetchElementsMap(String logicalGroupName, String domain) { + HashMap innerElementMap = new HashMap(); + String rowColumnKey = ""; + int count = 0; + + if (elementMap != null && !elementMap.isEmpty()) { + for (String key : elementMap.keySet()) { + Element eachElement = elementMap.get(key); + + String elementName = eachElement.getId(); + String elementLogicalGroup = eachElement.details == null ? "" : eachElement.details.logical_group; + if (elementLogicalGroup.equalsIgnoreCase(logicalGroupName) + && domain.equalsIgnoreCase(fetchDomainNameOfElement(elementName))) { + if (key.contains("/")) { + rowColumnKey = key.substring(key.indexOf("/") + 1); + } + + if (rowColumnKey.isEmpty() || innerElementMap.containsKey(rowColumnKey)) { + count = 0; + while (count <= 9) { + if (innerElementMap.containsKey(String.valueOf(count).concat(String.valueOf(count)))) { + count++; + } else { + rowColumnKey = String.valueOf(count).concat(String.valueOf(count)); + break; + } + } + + } + + innerElementMap.put(rowColumnKey, eachElement); + miscElementMap.remove(key); + } + + } + } + + return innerElementMap.isEmpty() ? null : innerElementMap; + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/FnMenuService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/FnMenuService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/FnMenuService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/FnMenuService.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/FnMenuServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/FnMenuServiceImpl.java new file mode 100644 index 00000000..ca73339d --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/FnMenuServiceImpl.java @@ -0,0 +1,161 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.openecomp.portalsdk.core.domain.FnMenu; +import org.openecomp.portalsdk.core.domain.Menu; +import org.openecomp.portalsdk.core.domain.MenuData; +import org.openecomp.portalsdk.core.domain.Role; +import org.openecomp.portalsdk.core.domain.RoleFunction; +import org.openecomp.portalsdk.core.service.DataAccessService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +/** + * Description: this java class is an implementation of services for Admin to add/edit/delete menu items from FN_MENU + */ + +@Service("fnMenuService") +@Transactional +public class FnMenuServiceImpl implements FnMenuService{ + + @Autowired + private DataAccessService dataAccessService; + + @SuppressWarnings("unchecked") + public List getFnMenuItems() { + //List msgDB = getDataAccessService().getList(Profile.class, null); + return getDataAccessService().getList(MenuData.class, null, "1", null); + + } + + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + + @Override + public void saveFnMenuData(MenuData domainFnMenu) { + // TODO Auto-generated method stub + getDataAccessService().saveDomainObject(domainFnMenu, null); + + } + + @SuppressWarnings("unchecked") + @Override + public List getParentId(String label) { + // TODO Auto-generated method stub + //List functioCDlist = new ArrayList(); + //functioCDlist.add("Mahdy1"); + //functioCDlist.add("Mahdy2"); + Map params = new HashMap(); + params.put("paramLabel", label); + return getDataAccessService().executeNamedQuery("IdForLabelList", params, null); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public List getParentList() { + // TODO Auto-generated method stub + //List functioCDlist = new ArrayList(); + //functioCDlist.add("Mahdy1"); + //functioCDlist.add("Mahdy2"); + return getDataAccessService().executeNamedQuery("parentList", null, null); + + //return null; + } + + @SuppressWarnings("unchecked") + @Override + public List getFunctionCDList() { + // TODO Auto-generated method stub + //List functioCDlist = new ArrayList(); + //functioCDlist.add("Mahdy1"); + //functioCDlist.add("Mahdy2"); + return getDataAccessService().executeNamedQuery("functionCDlist", null, null); + + //return null; + } + + @Override + public void removeMenuItem(MenuData domainFnMenu) { + getDataAccessService().deleteDomainObject(domainFnMenu, null); + } + + @Override + public void removeMenuItem(Menu domainFnMenu) { + getDataAccessService().deleteDomainObject(domainFnMenu, null); + } + + public MenuData getMenuItemRow(Long id) { + return (MenuData)getDataAccessService().getDomainObject(MenuData.class, id, null); + } + + @Override + public Menu getMenuItem(Long id) { + return (Menu)getDataAccessService().getDomainObject(Menu.class, id, null); + } + + @Override + public void saveFnMenu(Menu domainFnMenu) { + // TODO Auto-generated method stub + getDataAccessService().saveDomainObject(domainFnMenu, null); + + } + @Override + public Map> setMenuDataStructure(List> childItemList, List parentList, Set menuResult) throws Exception{ + for(MenuData menu: menuResult){ + MenuData parentData = new MenuData(); + parentData.setLabel(menu.getLabel()); + parentData.setAction(menu.getAction()); + parentData.setImageSrc(menu.getImageSrc()); + parentList.add(parentData); + List tempList = new ArrayList(); + for(Object o:menu.getChildMenus()){ + MenuData m = (MenuData)o; + MenuData data = new MenuData(); + data.setLabel(m.getLabel()); + data.setAction(m.getAction()); + data.setImageSrc(m.getImageSrc()); + tempList.add(data); + } + childItemList.add(tempList); + } + return null; + } + + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LdapService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LdapService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LdapService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LdapService.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LdapServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LdapServiceImpl.java new file mode 100644 index 00000000..ba43e45f --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LdapServiceImpl.java @@ -0,0 +1,267 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.SearchControls; + +import org.openecomp.portalsdk.core.command.support.SearchResult; +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.domain.support.DomainVo; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.service.support.FusionService; +import org.openecomp.portalsdk.core.service.support.ServiceLocator; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("ldapService") +@Transactional +public class LdapServiceImpl extends FusionService implements LdapService { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(LdapServiceImpl.class); + @Autowired + private ServiceLocator serviceLocator; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public SearchResult searchPost(DomainVo searchCriteria, String sortBy1, String sortBy2, String sortBy3, + int pageNo, int dataSize, int userId) throws Exception { + + // initialize the directory context to access POST + DirContext dirContext = serviceLocator.getDirContext(SystemProperties.getProperty(SystemProperties.POST_INITIAL_CONTEXT_FACTORY), + SystemProperties.getProperty(SystemProperties.POST_PROVIDER_URL), + SystemProperties.getProperty(SystemProperties.POST_SECURITY_PRINCIPAL)); + + SearchResult searchResult = new SearchResult(); + + try { + + String[] postAttributes = {"nickname","givenName","initials","sn","employeeNumber","mail","telephoneNumber", + "departmentNumber","a1","street","roomNumber","l","st","postalCode","zip4","physicalDeliveryOfficeName","bc", + "friendlyCountryName","bd","bdname","bu","buname","jtname","mgrid","a2","compcode","compdesc", + "costcenter","silo","b2"}; + + SearchControls searchControls = new SearchControls(); + searchControls.setTimeLimit(5000); + searchControls.setReturningAttributes(postAttributes); + + StringBuffer filterClause = new StringBuffer("(&(objectClass=*)"); + + User user = (User)searchCriteria; + + if(Utilities.nvl(user.getFirstName()).length() > 0) { + filterClause.append("(givenName=").append(user.getFirstName()).append("*)"); + } + if(Utilities.nvl(user.getLastName()).length() > 0) { + filterClause.append("(sn=").append(user.getLastName()).append("*)"); + } + if(Utilities.nvl(user.getHrid()).length() > 0) { + filterClause.append("(employeeNumber=").append(user.getHrid()).append("*)"); + } + if(Utilities.nvl(user.getOrgManagerUserId()).length() > 0) { + filterClause.append("(mgrid=").append(user.getOrgManagerUserId()).append("*)"); + } + if(Utilities.nvl(user.getOrgCode()).length() > 0) { + filterClause.append("(departmentNumber=").append(user.getOrgCode()).append("*)"); + } + if(Utilities.nvl(user.getEmail()).length() > 0) { + filterClause.append("(mail=").append(user.getEmail()).append("*)"); + } + if(Utilities.nvl(user.getOrgUserId()).length() > 0) { + filterClause.append("(a1=").append(user.getOrgUserId()).append("*)"); + } + filterClause.append("(c3=N)"); // this has been added to filter CP09 entries on the LDAP server that are duplicates of existing individuals + filterClause.append(")"); + + List list = new ArrayList(); + if (!filterClause.toString().equals("(&(objectClass=*))")) { + NamingEnumeration e = dirContext.search(SystemProperties.getProperty(SystemProperties.POST_PROVIDER_URL) + "/" + + SystemProperties.getProperty(SystemProperties.POST_SECURITY_PRINCIPAL), + filterClause.toString(), + searchControls); + + list = processResults(e); + } + + Collections.sort(list); + + searchResult = new SearchResult(list); + searchResult.setPageNo(pageNo); + if(dataSize >= 0) { + searchResult.setDataSize(dataSize); + } + else { + searchResult.setDataSize(list.size()); + } // else + + } + catch(NamingException ne) { + logger.error(EELFLoggerDelegate.errorLogger,ne.getMessage()); + } + finally { + dirContext.close(); + } + + return searchResult; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private ArrayList processResults(NamingEnumeration e) throws NamingException { + ArrayList results = new ArrayList(); + int count = 0; + + while (e.hasMore()) { + javax.naming.directory.SearchResult searchResult = (javax.naming.directory.SearchResult)e.next(); + results.add(processAttributes(searchResult.getAttributes())); + count++; + + if(count > Integer.parseInt(SystemProperties.getProperty(SystemProperties.POST_MAX_RESULT_SIZE))) { + break; + } + + } + + return results; + } + + @SuppressWarnings("rawtypes") + private DomainVo processAttributes(Attributes resultAttributes) throws NamingException { + User user = new User(); + + try { + if (resultAttributes == null) { + // System.out.println("This result has no attributes"); + } else { + for (NamingEnumeration e = resultAttributes.getAll(); e.hasMore();) { //why the nested loop? + Attribute attribute = (Attribute)e.next(); + for (NamingEnumeration ie = attribute.getAll(); ie.hasMore();) { + if (attribute.getID().equalsIgnoreCase("nickname")) { + user.setFirstName((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("initials")) { + user.setMiddleInitial((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("sn")) { + user.setLastName((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("employeeNumber")) { + user.setHrid((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("mail")) { + user.setEmail((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("telephoneNumber")) { + user.setPhone((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("departmentNumber")) { + user.setOrgCode((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("a1")) { + user.setOrgUserId((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("street")) { + user.setAddress1((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("roomNumber")) { + user.setAddress2((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("l")) { + user.setCity((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("st")) { + user.setState((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("postalCode")) { + user.setZipCode((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("zip4")) { + user.setZipCodeSuffix((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("physicalDeliveryOfficeName")) { + user.setLocationClli((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("bc")) { + user.setBusinessCountryCode((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("friendlyCountryName")) { + user.setBusinessCountryName((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("bd")) { + user.setDepartment((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("bdname")) { + user.setDepartmentName((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("jtname")) { + user.setJobTitle((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("mgrid")) { + user.setOrgManagerUserId((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("a2")) { + user.setCommandChain((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("compcode")) { + user.setCompanyCode((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("compdesc")) { + user.setCompany((String) ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("bu")) { + user.setBusinessUnit((String)ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("buname")) { + user.setBusinessUnitName((String)ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("silo")) { + user.setSiloStatus((String)ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("costcenter")) { + user.setCostCenter((String)ie.next()); + } + else if (attribute.getID().equalsIgnoreCase("b2")) { + user.setFinancialLocCode((String)ie.next()); + } + else { //we don't care about returned attribute, let's move on + ie.next(); + } + + } + } + } + } catch (NamingException e) { + logger.error(EELFLoggerDelegate.errorLogger, "An error occurred while processing the following user from POST with an ORGUSERID of " + user.getOrgUserId() + e.getMessage()); + } finally { + return user; + } + + } + + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LoginService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LoginService.java new file mode 100644 index 00000000..4f004108 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LoginService.java @@ -0,0 +1,36 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + + +import java.util.*; + +import org.openecomp.portalsdk.core.command.*; + + +public interface LoginService { + + // validate user exists in the system + @SuppressWarnings("rawtypes") + LoginBean findUser(LoginBean bean, String menuPropertiesFilename, HashMap additionalParams) throws Exception; + + @SuppressWarnings("rawtypes") + LoginBean findUser(LoginBean bean, String menuPropertiesFilename, HashMap additionalParams, boolean matchPassword) throws Exception; +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LoginServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LoginServiceImpl.java new file mode 100644 index 00000000..e0a4b7c6 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/LoginServiceImpl.java @@ -0,0 +1,205 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.openecomp.portalsdk.core.command.LoginBean; +import org.openecomp.portalsdk.core.domain.Role; +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.domain.UserApp; +import org.openecomp.portalsdk.core.menu.MenuBuilder; +import org.openecomp.portalsdk.core.service.support.FusionService; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.web.support.AppUtils; +import org.openecomp.portalsdk.core.web.support.UserUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("loginService") +@Transactional +public class LoginServiceImpl extends FusionService implements LoginService { + + @SuppressWarnings("unused") + private MenuBuilder menuBuilder; + + @Autowired + private DataAccessService dataAccessService; + + @SuppressWarnings("rawtypes") + public LoginBean findUser(LoginBean bean, String menuPropertiesFilename, HashMap additionalParams ) throws Exception { + return findUser(bean, menuPropertiesFilename, additionalParams, true); + } + + @SuppressWarnings("rawtypes") + public LoginBean findUser(LoginBean bean, String menuPropertiesFilename, HashMap additionalParams, boolean matchPassword) throws Exception { + User user = null; + User userCopy = null; + + if (bean.getUserid() != null && bean.getUserid() != null) { + user = (User)findUser(bean); + } + else { + if (matchPassword) + user = (User)findUser(bean.getLoginId(), bean.getLoginPwd()); + else + user = (User)findUserWithoutPwd(bean.getLoginId()); + } + + if (user != null) { + + // raise an error if the application is locked and the user does not have system administrator privileges + if (AppUtils.isApplicationLocked() && !UserUtils.hasRole(user, SystemProperties.getProperty(SystemProperties.SYS_ADMIN_ROLE_ID))) { + bean.setLoginErrorMessage(SystemProperties.MESSAGE_KEY_LOGIN_ERROR_APPLICATION_LOCKED); + } + + // raise an error if the user is inactive + if (!user.getActive()) { + bean.setLoginErrorMessage(SystemProperties.MESSAGE_KEY_LOGIN_ERROR_USER_INACTIVE); + } + + // raise an error if no active roles exist for the user +// boolean hasActiveRole = false; +// Iterator roles = user.getRoles().iterator(); +// while (roles.hasNext()) { +// Role role = (Role)roles.next(); +// if (role.getActive()) { +// hasActiveRole = true; +// break; +// } +// } + +// if (!hasActiveRole) { +// bean.setLoginErrorMessage(SystemProperties.MESSAGE_KEY_LOGIN_ERROR_USER_INACTIVE); +// } + if (!userHasActiveRoles(user)) { + bean.setLoginErrorMessage(SystemProperties.MESSAGE_KEY_LOGIN_ERROR_USER_INACTIVE); + } + // only login the user if no errors have occurred + if (bean.getLoginErrorMessage() == null) { + + // this will be a snapshot of the user's information as retrieved from the database + userCopy = (User)user.clone(); + + // update the last logged in date for the user + user.setLastLoginDate(new Date()); + getDataAccessService().saveDomainObject(user, additionalParams); + + // update the audit log of the user + //Check for the client device type and set log attributes appropriately + + + // save the above changes to the User and their audit trail + + + + + // create the application menu based on the user's privileges + Set appMenu = getMenuBuilder().getMenu(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_SET_NAME),dataAccessService); + bean.setMenu(appMenu != null?appMenu:new HashSet()); + Set businessDirectMenu = getMenuBuilder().getMenu(SystemProperties.getProperty(SystemProperties.BUSINESS_DIRECT_MENU_SET_NAME),dataAccessService); + bean.setBusinessDirectMenu(businessDirectMenu != null?businessDirectMenu:new HashSet()); + + bean.setUser(userCopy); + } + + } + + return bean; + } + + private boolean userHasActiveRoles(User user) { + boolean hasActiveRole = false; + Iterator roles = user.getRoles().iterator(); + while (roles.hasNext()) { + Role role = (Role)roles.next(); + if (role.getActive()) { + hasActiveRole = true; + break; + } + } + return hasActiveRole; + } + + @SuppressWarnings("rawtypes") + public User findUser(String loginId, String password) { + List list = null; + + StringBuffer criteria = new StringBuffer(); + criteria.append(" where login_id = '").append(loginId).append("'") + .append(" and login_pwd = '").append(password).append("'"); + + list = getDataAccessService().getList(User.class, criteria.toString(), null, null); + + return (list == null || list.size() == 0) ? null : (User)list.get(0); + } + + @SuppressWarnings("rawtypes") + private User findUserWithoutPwd(String loginId) { + List list = null; + + StringBuffer criteria = new StringBuffer(); + criteria.append(" where login_id = '").append(loginId).append("'"); + + list = getDataAccessService().getList(User.class, criteria.toString(), null, null); + + return (list == null || list.size() == 0) ? null : (User)list.get(0); + } + + @SuppressWarnings("rawtypes") + public User findUser(LoginBean bean) { + List list = null; + + StringBuffer criteria = new StringBuffer(); + criteria.append(" where org_user_id = '").append(bean.getUserid()).append("'"); + + list = getDataAccessService().getList(User.class, criteria.toString(), null, null); + + return (list == null || list.size() == 0) ? null : (User)list.get(0); + } + + + public MenuBuilder getMenuBuilder() { + return new MenuBuilder(); + } + + + public void setMenuBuilder(MenuBuilder menuBuilder) { + this.menuBuilder = menuBuilder; + } + + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsService.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsServiceImpl.java new file mode 100644 index 00000000..658de264 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsServiceImpl.java @@ -0,0 +1,186 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.io.File; +import java.io.IOException; +import java.nio.file.DirectoryIteratorException; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.kie.api.io.ResourceType; +import org.kie.internal.KnowledgeBase; +import org.kie.internal.KnowledgeBaseFactory; +import org.kie.internal.builder.KnowledgeBuilder; +import org.kie.internal.builder.KnowledgeBuilderFactory; +import org.kie.internal.definition.KnowledgePackage; +import org.kie.internal.io.ResourceFactory; +import org.kie.internal.runtime.StatefulKnowledgeSession; +import org.openecomp.portalsdk.core.command.PostDroolsBean; +import org.openecomp.portalsdk.core.drools.DroolsRuleService; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * TODO REFACTOR + * + */ +@Service("postDroolsService") +@Transactional +public class PostDroolsServiceImpl implements PostDroolsService{ + + static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PostDroolsServiceImpl.class); + + @Override + public String execute(String droolsFile, String className, String selectedRules) { + logger.info(EELFLoggerDelegate.applicationLogger, "Executing Drools..."); + String resultsString = executeDemoRules(droolsFile, className, selectedRules); + return resultsString; + } + + + public List fetchDroolBeans() { + + List beanList = new ArrayList(); + Path path = FileSystems.getDefault().getPath(SystemProperties.getProperty(SystemProperties.FILES_PATH)); + try (DirectoryStream stream = Files.newDirectoryStream(path,"*.{drl}")) { + for (Path entry: stream) { + + PostDroolsBean postDroolsBean = new PostDroolsBean(); + String fileName = entry.getName(entry.getNameCount()-1).toString(); + postDroolsBean.setDroolsFile(fileName);//sample populated + postDroolsBean.setClassName(retrieveClass(fileName)); + //postDroolsBean.setSelectedRules("[\"NJ\",\"NY\",\"KY\"]"); + beanList.add(postDroolsBean); + } + } catch (DirectoryIteratorException ex) { + logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage()); + } catch (IOException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage()); + } + return beanList; + } + + @Override + public String retrieveClass(String fileName) { + String resultsString = ""; + try { + // load up the knowledge base + final KnowledgeBuilder kbuilder = loadKBuilder(fileName); + final Collection pkgs = kbuilder.getKnowledgePackages(); + return pkgs.iterator().next().getFactTypes().iterator().next().getFactClass().getName(); + + } catch (Throwable t) { + logger.error(EELFLoggerDelegate.errorLogger, t.getMessage()); + } + + return resultsString; + } + + protected static KnowledgeBuilder loadKBuilder(String fileName) { + final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); + + // this will parse and compile in one step + kbuilder.add(ResourceFactory.newFileResource(SystemProperties.getProperty(SystemProperties.FILES_PATH) + File.separator + fileName), + //kbuilder.add(ResourceFactory.newClassPathResource(SystemProperties.getProperty(SystemProperties.FILES_PATH) + File.separator + drl_file_path, DroolsRuleService.class), + ResourceType.DRL); + // kbuilder.add(ResourceFactory.newClassPathResource("rules.drl",DroolsRuleService.class), + // ResourceType.DRL); + + // Check the builder for errors + if (kbuilder.hasErrors()) { + + logger.error(EELFLoggerDelegate.errorLogger, kbuilder.getErrors().toString()); + + throw new RuntimeException("Unable to compile \".drl\"."); + + } + return kbuilder; + } + + + @SuppressWarnings({ "deprecation", "unchecked" }) + public static String executeDemoRules(String fileName, String className, String ruleValue) { + String resultsString = ""; + try { + // load up the knowledge base + // KieServices ks = KieServices.Factory.get(); + // KieContainer kContainer = ks.getKieClasspathContainer(); + // KieSession kSession = kContainer.newKieSession("ksession-rules"); + + final KnowledgeBuilder kbuilder = loadKBuilder(fileName); + + // get the compiled packages (which are serializable) + + final Collection pkgs = kbuilder.getKnowledgePackages(); + + // add the packages to a knowledgebase (deploy the knowledge + // packages). + + final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); + + kbase.addKnowledgePackages(pkgs); + + final StatefulKnowledgeSession kSession = kbase.newStatefulKnowledgeSession(); + + ObjectMapper mapper = new ObjectMapper(); + if(ruleValue == null || ruleValue.equals("")) { + resultsString = "Please enter valid rule"; + return resultsString; + } + List selectedRules = mapper.readValue(ruleValue, List.class); + List ruleResponse = new ArrayList(); + + for(String rule : selectedRules){ + Class clazz = (Class) Class.forName(className); + DroolsRuleService droolsIntroduction =clazz.newInstance(); + droolsIntroduction.init(rule); + kSession.insert(droolsIntroduction); + kSession.fireAllRules(); + ruleResponse.add(droolsIntroduction.getResultsString()); + } + + resultsString = mapper.writeValueAsString(ruleResponse); + +// kSession.insert(new DroolsRuleService("KY")); +// kSession.fireAllRules(); +// +// kSession.setGlobal("age", "25"); +// kSession.insert(new DroolsRuleService("NY")); +// kSession.fireAllRules(); + } catch (Throwable t) { + logger.error(EELFLoggerDelegate.errorLogger, t.getMessage()); + } + + return resultsString; + } + + + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostSearchService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostSearchService.java new file mode 100644 index 00000000..cde9a370 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostSearchService.java @@ -0,0 +1,37 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.command.PostSearchBean; + +public interface PostSearchService { + + /** + * Imports the selected users in the search results as new users. + * + * @param request + * @param postSearch + * @return the number of users successfully imported + */ + int process(HttpServletRequest request, PostSearchBean postSearch); + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostSearchServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostSearchServiceImpl.java new file mode 100644 index 00000000..f2877d4d --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/PostSearchServiceImpl.java @@ -0,0 +1,207 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.FusionObject.Parameters; +import org.openecomp.portalsdk.core.command.PostSearchBean; +import org.openecomp.portalsdk.core.domain.Lookup; +import org.openecomp.portalsdk.core.domain.Role; +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("postSearchService") +@Transactional +public class PostSearchServiceImpl implements PostSearchService { + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PostSearchServiceImpl.class); + + @Autowired + private DataAccessService dataAccessService; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public int process(HttpServletRequest request, PostSearchBean postSearch) { + HashMap additionalParams = new HashMap(); + additionalParams.put(Parameters.PARAM_HTTP_REQUEST, request); + int numUsersImported = 0; + + if (postSearch.getSelected() != null) { + // sort the selected users for quick validation + + Arrays.sort(postSearch.getSelected()); + // import the users that have been selected + for (int i = 0; i < postSearch.getPostOrgUserId().length; i++) { + if (Arrays.binarySearch(postSearch.getSelected(), postSearch.getPostOrgUserId()[i]) >= 0) { + logger.debug(EELFLoggerDelegate.debugLogger, + "Adding ORGUSERID - " + postSearch.getPostOrgUserId()[i]); + logger.debug(EELFLoggerDelegate.auditLogger, + "Import new user from webphone " + postSearch.getPostOrgUserId()[i]); + + User user = new User(); + user.setLastName(postSearch.getPostLastName()[i]); + user.setFirstName(postSearch.getPostFirstName()[i]); + + if (postSearch.getPostHrid() != null && postSearch.getPostHrid().length > 0) { + user.setHrid(postSearch.getPostHrid()[i]); + } + + if (postSearch.getPostPhone() != null && postSearch.getPostPhone().length > 0) { + user.setPhone(postSearch.getPostPhone()[i]); + } + + if (postSearch.getPostEmail() != null && postSearch.getPostEmail().length > 0) { + user.setEmail(postSearch.getPostEmail()[i]); + } + + if (postSearch.getPostOrgUserId() != null && postSearch.getPostOrgUserId().length > 0) { + user.setOrgUserId(postSearch.getPostOrgUserId()[i]); + user.setLoginId(postSearch.getPostOrgUserId()[i]); + } + + if (postSearch.getPostAddress1() != null && postSearch.getPostAddress1().length > 0) { + user.setAddress1(postSearch.getPostAddress1()[i]); + } + + if (postSearch.getPostAddress2() != null && postSearch.getPostAddress2().length > 0) { + user.setAddress2(postSearch.getPostAddress2()[i]); + } + + if (postSearch.getPostCity() != null && postSearch.getPostCity().length > 0) { + user.setCity(postSearch.getPostCity()[i]); + } + + if (postSearch.getPostState() != null && postSearch.getPostState().length > 0) { + user.setState(postSearch.getPostState()[i]); + } + + if (postSearch.getPostZipCode() != null && postSearch.getPostZipCode().length > 0) { + user.setZipCode(postSearch.getPostZipCode()[i]); + } + + if (postSearch.getPostLocationClli() != null && postSearch.getPostLocationClli().length > 0) { + user.setLocationClli(postSearch.getPostLocationClli()[i]); + } + + if (postSearch.getPostBusinessCountryCode() != null + && postSearch.getPostBusinessCountryCode().length > 0) { + user.setBusinessCountryCode(postSearch.getPostBusinessCountryCode()[i]); + } + + if (postSearch.getPostBusinessCountryName() != null + && postSearch.getPostBusinessCountryName().length > 0) { + + // find the country cd for the indicated country + List countries = dataAccessService.getLookupList("fn_lu_country", "country_cd", "country", + "country = '" + postSearch.getPostBusinessCountryName()[i] + "'", null, null); + + if (countries != null && countries.size() == 1) { + Lookup country = (Lookup) countries.get(0); + user.setCountry(country.getValue()); + } else { + logger.info(EELFLoggerDelegate.debugLogger, + "No countries or more than one country was found matching the country returned from WEBPHONE. " + + "Therefore, no country was set for this user."); + } + + } + + if (postSearch.getPostDepartment() != null && postSearch.getPostDepartment().length > 0) { + user.setDepartment(postSearch.getPostDepartment()[i]); + } + + if (postSearch.getPostDepartmentName() != null && postSearch.getPostDepartmentName().length > 0) { + user.setDepartmentName(postSearch.getPostDepartmentName()[i]); + } + + if (postSearch.getPostBusinessUnit() != null && postSearch.getPostBusinessUnit().length > 0) { + user.setBusinessUnit(postSearch.getPostBusinessUnit()[i]); + } + + if (postSearch.getPostBusinessUnitName() != null + && postSearch.getPostBusinessUnitName().length > 0) { + user.setBusinessUnitName(postSearch.getPostBusinessUnitName()[i]); + } + + if (postSearch.getPostJobTitle() != null && postSearch.getPostJobTitle().length > 0) { + user.setJobTitle(postSearch.getPostJobTitle()[i]); + } + + if (postSearch.getPostOrgManagerUserId() != null + && postSearch.getPostOrgManagerUserId().length > 0) { + user.setOrgManagerUserId(postSearch.getPostOrgManagerUserId()[i]); + } + + if (postSearch.getPostCommandChain() != null && postSearch.getPostCommandChain().length > 0) { + user.setCommandChain(postSearch.getPostCommandChain()[i]); + } + + if (postSearch.getPostCompanyCode() != null && postSearch.getPostCompanyCode().length > 0) { + user.setCompanyCode(postSearch.getPostCompanyCode()[i]); + } + + if (postSearch.getPostCompany() != null && postSearch.getPostCompany().length > 0) { + user.setCompany(postSearch.getPostCompany()[i]); + } + + if (postSearch.getPostCostCenter() != null && postSearch.getPostCostCenter().length > 0) { + user.setCostCenter(postSearch.getPostCostCenter()[i]); + } + + if (postSearch.getPostSiloStatus() != null && postSearch.getPostSiloStatus().length > 0) { + user.setSiloStatus(postSearch.getPostSiloStatus()[i]); + } + + if (postSearch.getPostFinancialLocCode() != null + && postSearch.getPostFinancialLocCode().length > 0) { + user.setFinancialLocCode(postSearch.getPostFinancialLocCode()[i]); + } + + user.setActive(true); + + try { + dataAccessService.saveDomainObject(user, additionalParams); + Role role = (Role) dataAccessService.getDomainObject(Role.class, + Long.valueOf(SystemProperties.getProperty(SystemProperties.POST_DEFAULT_ROLE_ID)), + null); + user.addRole(role); + numUsersImported++; + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, + "process: saveDomainObject failed on user " + user.getLoginId(), e); + } + } + } + + } + + return numUsersImported; + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ProfileService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ProfileService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ProfileService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ProfileService.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ProfileServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ProfileServiceImpl.java new file mode 100644 index 00000000..2d6fcfee --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/ProfileServiceImpl.java @@ -0,0 +1,74 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.List; + +import org.openecomp.portalsdk.core.dao.ProfileDao; +import org.openecomp.portalsdk.core.domain.Profile; +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.service.DataAccessService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("profileService") +@Transactional +public class ProfileServiceImpl implements ProfileService{ + + @Autowired + private ProfileDao profileDao; + + @Autowired + private DataAccessService dataAccessService; + + @SuppressWarnings("unchecked") + public List findAll() { + //List msgDB = getDataAccessService().getList(Profile.class, null); + return getDataAccessService().getList(Profile.class, null); + } + + public User getUser(String userId){ + return (User) getDataAccessService().getDomainObject(User.class, Long.parseLong(userId), null); + } + + public void saveUser(User user){ + + getDataAccessService().saveDomainObject(user, null); + } + + + public Profile getProfile(int id) { + return profileDao.getProfile(id); + } + + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleService.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceImpl.java new file mode 100644 index 00000000..2e780998 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceImpl.java @@ -0,0 +1,171 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import javax.sql.DataSource; + +import org.openecomp.portalsdk.core.domain.Role; +import org.openecomp.portalsdk.core.domain.RoleFunction; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("roleService") +@Transactional +public class RoleServiceImpl implements RoleService { + + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RoleServiceImpl.class); + + @Autowired + private DataAccessService dataAccessService; + + DataSource dataSource; + + public DataSource getDataSource() { + return dataSource; + } + + @Autowired + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } + + @SuppressWarnings("unchecked") + public List getRoleFunctions() { + // List msgDB = getDataAccessService().getList(Profile.class, null); + return getDataAccessService().getList(RoleFunction.class, null); + } + + @SuppressWarnings("unchecked") + public List getAvailableChildRoles(Long roleId) { + List availableChildRoles = (List) getDataAccessService().getList(Role.class, null); + if (roleId == null || roleId == 0) { + return availableChildRoles; + } + + Role currentRole = (Role) getDataAccessService().getDomainObject(Role.class, roleId, null); + Set allParentRoles = new TreeSet(); + allParentRoles = getAllParentRolesAsList(currentRole, allParentRoles); + + Iterator availableChildRolesIterator = availableChildRoles.iterator(); + while (availableChildRolesIterator.hasNext()) { + Role role = availableChildRolesIterator.next(); + if (!role.getActive() || allParentRoles.contains(role) || role.getId().equals(roleId)) { + availableChildRolesIterator.remove(); + } + } + return availableChildRoles; + } + + @SuppressWarnings("unchecked") + private Set getAllParentRolesAsList(Role role, Set allParentRoles) { + Set parentRoles = role.getParentRoles(); + allParentRoles.addAll(parentRoles); + Iterator parentRolesIterator = parentRoles.iterator(); + while (parentRolesIterator.hasNext()) { + getAllParentRolesAsList(parentRolesIterator.next(), allParentRoles); + } + return allParentRoles; + } + + public RoleFunction getRoleFunction(String code) { + return (RoleFunction) getDataAccessService().getDomainObject(RoleFunction.class, code, null); + } + + public void saveRoleFunction(RoleFunction domainRoleFunction) { + getDataAccessService().saveDomainObject(domainRoleFunction, null); + } + + public void deleteRoleFunction(RoleFunction domainRoleFunction) { + getDataAccessService().deleteDomainObject(domainRoleFunction, null); + } + + public Role getRole(Long id) { + return (Role) getDataAccessService().getDomainObject(Role.class, id, null); + } + + public void saveRole(Role domainRole) { + getDataAccessService().saveDomainObject(domainRole, null); + } + + public void deleteRole(Role domainRole) { + getDataAccessService().deleteDomainObject(domainRole, null); + } + + @SuppressWarnings("unchecked") + public List getAvailableRoles() { + return getDataAccessService().getList(Role.class, null); + } + + @SuppressWarnings("unchecked") + @Override + public List getActiveRoles() { + String filter = " where active_yn = 'Y' "; + return getDataAccessService().getList(Role.class, filter, null, null); + } + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + @Override + public void deleteDependcyRoleRecord(Long id) { + Connection conn = null; + Statement stmt = null; + try { + conn = getDataSource().getConnection(); + stmt = conn.createStatement(); + String sql = "delete from fn_user_role where role_id = '" + id + "'"; + stmt.executeUpdate(sql); + stmt.close(); + conn.close(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "deleteDependcyRoleRecord failed", e); + } finally { + try { + if (stmt != null) + stmt.close(); + } catch (SQLException se2) { + logger.error(EELFLoggerDelegate.errorLogger, "deleteDependcyRoleRecord failed", se2); + } + try { + if (conn != null) + conn.close(); + } catch (SQLException se) { + logger.error(EELFLoggerDelegate.errorLogger, "deleteDependcyRoleRecord failed", se); + } + } + + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceNonSpringImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceNonSpringImpl.java new file mode 100644 index 00000000..a7374d0c --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceNonSpringImpl.java @@ -0,0 +1,122 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; +/*package org.openecomp.portalsdk.core.service; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import org.openecomp.portalsdk.core.domain.Role; +import org.openecomp.portalsdk.core.domain.RoleFunction; + +@Service("roleService") +@Transactional +public class RoleServiceNonSpringImpl implements RoleService{ + + @Autowired + private DataAccessService dataAccessService; + + @SuppressWarnings("unchecked") + public List getRoleFunctions() { + //List msgDB = getDataAccessService().getList(Profile.class, null); + return getDataAccessService().getList(RoleFunction.class, null); + } + + @SuppressWarnings("unchecked") + public List getAvailableChildRoles(Long roleId) { + List availableChildRoles = (List)getDataAccessService().getList(Role.class,null); + if(roleId==null || roleId==0){ + return availableChildRoles; + } + + Role currentRole = (Role)getDataAccessService().getDomainObject(Role.class,roleId,null); + Set allParentRoles = new TreeSet(); + allParentRoles = getAllParentRolesAsList(currentRole, allParentRoles); + + + Iterator availableChildRolesIterator = availableChildRoles.iterator(); + while (availableChildRolesIterator.hasNext()) { + Role role = availableChildRolesIterator.next(); + if(!role.getActive() || allParentRoles.contains(role) || role.getId().equals(roleId)){ + availableChildRolesIterator.remove(); + } + } + return availableChildRoles; + } + + @SuppressWarnings("unchecked") + private Set getAllParentRolesAsList(Role role, Set allParentRoles) { + Set parentRoles = role.getParentRoles(); + allParentRoles.addAll(parentRoles); + Iterator parentRolesIterator = parentRoles.iterator(); + while (parentRolesIterator.hasNext()) { + getAllParentRolesAsList(parentRolesIterator.next(),allParentRoles); + } + return allParentRoles; + } + + public RoleFunction getRoleFunction(String code) { + return (RoleFunction)getDataAccessService().getDomainObject(RoleFunction.class, code, null); + } + + public void saveRoleFunction(RoleFunction domainRoleFunction) { + getDataAccessService().saveDomainObject(domainRoleFunction, null); + } + + public void deleteRoleFunction(RoleFunction domainRoleFunction) { + getDataAccessService().deleteDomainObject(domainRoleFunction, null); + } + + public Role getRole(Long id) { + return (Role)getDataAccessService().getDomainObject(Role.class, id, null); + } + + public void saveRole(Role domainRole) { + getDataAccessService().saveDomainObject(domainRole, null); + } + + public void deleteRole(Role domainRole) { + getDataAccessService().deleteDomainObject(domainRole, null); + } + + @SuppressWarnings("unchecked") + public List getAvailableRoles() { + return getDataAccessService().getList(Role.class, null); + } + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + + +} +*/ \ No newline at end of file diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/UserProfileService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/UserProfileService.java new file mode 100644 index 00000000..b844fb0c --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/UserProfileService.java @@ -0,0 +1,34 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.List; + +import org.openecomp.portalsdk.core.domain.User; + + +public interface UserProfileService { + List findAll(); + User getUser(String id); + User getUserByLoginId(String loginId); + void saveUser(User user); + public List findAllUserWithOnOffline(String originOrgUserId); + List findAllActive(); +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/UserProfileServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/UserProfileServiceImpl.java new file mode 100644 index 00000000..2d134725 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/UserProfileServiceImpl.java @@ -0,0 +1,116 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; + +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Restrictions; +import org.openecomp.portalsdk.core.domain.Role; +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.domain.support.CollaborateList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("userProfileService") +@Transactional +public class UserProfileServiceImpl implements UserProfileService{ + + + @Autowired + private DataAccessService dataAccessService; + + public List findAll() { + return getDataAccessService().getList(User.class, null); + } + + public User getUser(String userId){ + return (User) getDataAccessService().getDomainObject(User.class, Long.parseLong(userId), null); + } + + @SuppressWarnings("unchecked") + public User getUserByLoginId(String loginId){ + User user=null; + List restrictionsList = new ArrayList(); + Criterion criterion1= Restrictions.eq("loginId",loginId); + restrictionsList.add(criterion1); + List users = (List) getDataAccessService().getList(User.class,null, restrictionsList, null); + if(users!=null && users.size()==1) + user = users.get(0); + return user; + } + + public void saveUser(User user){ + + getDataAccessService().saveDomainObject(user, null); + } + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + @SuppressWarnings("unchecked") + public List findAllUserWithOnOffline(String originOrgUserId) { + HashSet onlineUser = CollaborateList.getInstance().getAllUserName(); + List users = getDataAccessService().getList(User.class, null); + for(User u:users){ + if(onlineUser.contains(u.getOrgUserId())) + u.setOnline(true); + if(u.getOrgUserId()!=null){ + if(originOrgUserId.compareTo(u.getOrgUserId()) > 0) { + u.setChatId(originOrgUserId + "-" + u.getOrgUserId()); + } else u.setChatId(u.getOrgUserId() + "-" + originOrgUserId ); + } + } + return users; + + } + + public List findAllActive() { + List users = getDataAccessService().getList(User.class, null); + Iterator itr = users.iterator(); + while(itr.hasNext()){ + User u = (User) itr.next(); + if(!u.getActive()) + itr.remove();//if not active remove user from list + else { + SortedSet roles = u.getRoles(); + Iterator itrRoles = roles.iterator(); + while(itrRoles.hasNext()){ + Role role = (Role) itrRoles.next(); + if(!role.getActive()) + u.removeRole(role.getId());//if not active remove role from list + } + } + } + return users; + } + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallService.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallServiceImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallServiceImpl.java new file mode 100644 index 00000000..557af2dd --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallServiceImpl.java @@ -0,0 +1,189 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service; + +import java.util.List; + +import org.openecomp.portalsdk.core.domain.App; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.onboarding.util.CipherUtil; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("webServiceCallService") +@Transactional +public class WebServiceCallServiceImpl implements WebServiceCallService{ + + @Autowired + private DataAccessService dataAccessService; + + @Autowired + AppService appService; + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(WebServiceCallServiceImpl.class); + + /** + * Verify REST Credential + * @return true if the credential is accepted; else false. + */ + @Override + public boolean verifyRESTCredential(String secretKey, String requestAppName, String requestPassword)throws Exception { + App app = appService.getDefaultApp(); + if (app!=null) { + String encriptedPwdDB = app.getAppPassword(); + String appUserName = app.getUsername(); + String decreptedPwd = CipherUtil.decrypt(encriptedPwdDB, secretKey==null?SystemProperties.getProperty(SystemProperties.Decryption_Key):secretKey); + if(decreptedPwd.equals(requestPassword) && appUserName.equals(requestAppName)) { + return true; + } + } + return false; + } + + /** + * Getting App information from FN_APP table + * @return App domain object, or null if not found. + */ + public App findApp(){ + List list = null; + StringBuffer criteria = new StringBuffer(); + criteria.append(" where id = 1"); + list = getDataAccessService().getList(App.class, criteria.toString(), null, null); + return (list == null || list.size() == 0) ? null : (App) list.get(0); + } + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + /*/ + @Override + public String get(String restURL, String restPath) { + String appUserName = ""; + String appUebKey = ""; + String decreptedPwd = ""; + String appName = ""; + String inputLine = ""; + String serviceName = ""; + String loginId = ""; + StringBuffer jsonResponse = new StringBuffer(); + + StopWatch stopWatch = new StopWatch("WebServiceCallServiceImpl.get"); + stopWatch.start(); + try { + logger.info(EELFLoggerDelegate.metricsLogger, "WebServiceCallServiceImpl.get (" + restPath + ") operation is started."); + logger.debug(EELFLoggerDelegate.debugLogger, "WebServiceCallServiceImpl.get (" + restPath + ") operation is started."); + loginId = MDC.get("LoginId"); + appUebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + App app = appService.getDefaultApp(); + if (app!=null) { + appName = app.getName(); + appUserName = app.getUsername(); + try{ + decreptedPwd = CipherUtil.decrypt(app.getAppPassword(), SystemProperties.getProperty(SystemProperties.Decryption_Key)); + } catch(Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred in WebServiceCallServiceImpl.get while decrypting the password. Details: " + e.getMessage()); + } + } else { + logger.warn(EELFLoggerDelegate.errorLogger, "Unable to locate the app information from the database."); + appName = SystemProperties.SERVICE_NAME; + } + + //Create the connection object + URL obj = new URL(restURL + restPath); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("GET"); + con.setConnectTimeout(3000); + con.setReadTimeout(8000); + + //add request header + con.setRequestProperty("username", appUserName); + con.setRequestProperty("password", decreptedPwd); + con.setRequestProperty("uebkey", appUebKey); + con.setRequestProperty(SystemProperties.LOGIN_ID, loginId); + con.setRequestProperty(SystemProperties.USERAGENT_NAME, appName); + con.setRequestProperty(SystemProperties.ECOMP_REQUEST_ID, MDC.get(MDC_KEY_REQUEST_ID)); + + //set MDC context for outgoing audit logging + serviceName = String.format("%s:%s.%s", appName, SystemProperties.ECOMP_PORTAL_BE, restPath); + MDC.put(Configuration.MDC_SERVICE_NAME, serviceName); + MDC.put(Configuration.MDC_REMOTE_HOST, restURL); + MDC.put(SystemProperties.MDC_APPNAME, appName); + MDC.put(SystemProperties.MDC_REST_PATH, restPath); + MDC.put(SystemProperties.MDC_REST_METHOD, "GET"); + + int responseCode = con.getResponseCode(); + logger.info(EELFLoggerDelegate.errorLogger, "Received the response code '" + responseCode + "' while getting the '" + restPath + "' for user: " + loginId); + + BufferedReader in = new BufferedReader( + new InputStreamReader(con.getInputStream())); + + while ((inputLine = in.readLine()) != null) { + jsonResponse.append(inputLine); + } + in.close(); + + logSecurityMessage(RESULT_ENUM.SUCCESS); + logger.debug(EELFLoggerDelegate.debugLogger, restPath + " response: " + jsonResponse.toString()); + logger.debug(EELFLoggerDelegate.debugLogger, "WebServiceCallServiceImpl.get (" + restPath + ") operation is started."); + } catch(UrlAccessRestrictedException e) { + logger.error(EELFLoggerDelegate.errorLogger, "Authentication exception occurred in WebServiceCallServiceImpl.get (" + restPath + "). Details: " + e.getMessage()); + logSecurityMessage(RESULT_ENUM.FAILURE); + } catch(Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred in WebServiceCallServiceImpl.get (" + restPath + "). Details: " + e.getMessage()); + logSecurityMessage(RESULT_ENUM.FAILURE); + } finally { + if (stopWatch.isRunning()) stopWatch.stop(); + MDC.put(SystemProperties.MDC_TIMER, stopWatch.getTotalTimeMillis() + "ms"); + logger.info(EELFLoggerDelegate.metricsLogger, "WebServiceCallServiceImpl.get (" + restPath + ") operation is completed."); + + //clear the temporary MDC context values + MDC.remove(SystemProperties.MDC_TIMER); + MDC.remove(SystemProperties.MDC_REST_METHOD); + MDC.remove(SystemProperties.MDC_REST_PATH); + MDC.remove(SystemProperties.MDC_APPNAME); + MDC.remove(Configuration.MDC_REMOTE_HOST); + MDC.remove(Configuration.MDC_SERVICE_NAME); + } + + return jsonResponse.toString(); + } + + //Handles all the outgoing rest/ueb messages. + public void logSecurityMessage(RESULT_ENUM isSuccess) { + String additionalInfo = ""; + String protocol = "HTTP"; + String loginId = MDC.get("LoginId"); + additionalInfo = String.format("Rest API=%s, Rest Method=%s, App-Name=%s, Request-URL=%s", + MDC.get(SystemProperties.MDC_REST_PATH), MDC.get(SystemProperties.MDC_REST_METHOD), + MDC.get(SystemProperties.MDC_APPNAME), MDC.get(Configuration.MDC_REMOTE_HOST)); + + logger.info(EELFLoggerDelegate.auditLogger, AuditLogFormatter.getInstance().createMessage( + protocol, SecurityEventTypeEnum.OUTGOING_REST_MESSAGE.name(), loginId, SystemProperties.SERVICE_NAME, + isSuccess.name(), additionalInfo)); + } + /**/ +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/support/FusionService.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/support/FusionService.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/support/FusionService.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/support/FusionService.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocator.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocator.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocator.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocator.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocatorImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocatorImpl.java new file mode 100644 index 00000000..97f4875d --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocatorImpl.java @@ -0,0 +1,105 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.service.support; + +import java.util.*; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.springframework.stereotype.Service; + +/** + * This class implements the J2EE service locator pattern. It provides lookup + * facilities for various services. Currenttly LDAP (pre-v3) is supported + */ +@Service("serviceLocator") +public class ServiceLocatorImpl implements ServiceLocator { + + //private static ServiceLocator locator; // The singleton instance + + private Context context; // JNDI context (not currently in use) + private Context rootContext; // Java env root context (not currently in use) + private DirContext dirContext; // LDAP DIR context + private InitialLdapContext ldapContext; // LDAP context LDAPv3-style (not currently in use) + + + // cannot directly instantiate + public ServiceLocatorImpl() {} + + /*public static ServiceLocator getLocator() { + if (locator == null) + locator = new ServiceLocator(); + return locator; + } + + public Object clone() throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + }*/ + + + // Get an LDAP directory context + public DirContext getDirContext(String initialContextFactory, String providerUrl, String securityPrincipal) { + + if (dirContext == null) { + + Properties properties = new Properties(); + properties.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory); + properties.put(Context.PROVIDER_URL, providerUrl); + properties.put(Context.SECURITY_PRINCIPAL, securityPrincipal); + + try { + dirContext = new InitialDirContext(properties); + } + catch (NamingException ne) { + logger.error(EELFLoggerDelegate.errorLogger, "An error has occurred while creating an Initial Directory Context: " + ne.getMessage()); + logger.error(EELFLoggerDelegate.errorLogger, "Explanation: " + ne.getExplanation()); + } + } + + return dirContext; + } + + // Get an LDAP directory context - LDAPv3-style + /*public InitialLdapContext getLdapContext() { //throws NamingException { + if (ldapContext == null) { + Properties properties = new Properties(); + // @todo - need to parameterize context factoy class and url + properties.put(Context.INITIAL_CONTEXT_FACTORY, AttLdap.DIR_INITIAL_CONTEXT_FACTORY); + properties.put(Context.PROVIDER_URL, AttLdap.DIR_PROVIDER_URL); + properties.put(Context.SECURITY_PRINCIPAL, AttLdap.DIR_SECURITY_PRINCIPAL); + Control[] ctrl = null; + try { + ldapContext = new InitialLdapContext(properties, ctrl); + } + catch (NamingException ne) { + // MJ FIX log exception? + } + } + return ldapContext; + }*/ + + + /** Logger for this class and subclasses */ + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ServiceLocatorImpl.class); + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/CacheManager.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/CacheManager.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/CacheManager.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/CacheManager.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/EncDecUtilTest.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/EncDecUtilTest.java new file mode 100644 index 00000000..23d90cc9 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/EncDecUtilTest.java @@ -0,0 +1,112 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.util; +import java.security.AlgorithmParameters; +import java.security.SecureRandom; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Base64; + +public class EncDecUtilTest { + + private static final String password = "test"; + private static final String salt = "r n�HN~��|f��X�" ; + private static int pswdIterations = 65536 ; + private static int keySize = 256; + private byte[] ivBytes; + + public String encrypt(String plainText) throws Exception { + + //get salt + //salt = generateSalt(); + byte[] saltBytes = salt.getBytes("UTF-8"); + + // Derive the key + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + PBEKeySpec spec = new PBEKeySpec( + password.toCharArray(), + saltBytes, + pswdIterations, + keySize + ); + + SecretKey secretKey = factory.generateSecret(spec); + SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); + + //encrypt the message + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, secret); + AlgorithmParameters params = cipher.getParameters(); + ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV(); + byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8")); + return new Base64().encodeAsString(encryptedTextBytes); + } + + @SuppressWarnings("static-access") + public String decrypt(String encryptedText) throws Exception { + + byte[] saltBytes = salt.getBytes("UTF-8"); + byte[] encryptedTextBytes = new Base64().decodeBase64(encryptedText); + + // Derive the key + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + PBEKeySpec spec = new PBEKeySpec( + password.toCharArray(), + saltBytes, + pswdIterations, + keySize + ); + + SecretKey secretKey = factory.generateSecret(spec); + SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); + + // Decrypt the message + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes)); + + + byte[] decryptedTextBytes = null; + try { + decryptedTextBytes = cipher.doFinal(encryptedTextBytes); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } + + return new String(decryptedTextBytes); + } + + public String generateSalt() { + SecureRandom random = new SecureRandom(); + byte bytes[] = new byte[20]; + random.nextBytes(bytes); + String s = new String(bytes); + return s; + } +} \ No newline at end of file diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/JSONUtil.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/JSONUtil.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/JSONUtil.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/JSONUtil.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/SystemProperties.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/SystemProperties.java new file mode 100644 index 00000000..6a705aed --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/SystemProperties.java @@ -0,0 +1,327 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.util; + +import javax.servlet.ServletContext; + +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; + +/** + * SystemProperties contains a list of constants used throughout portions of the + * application. Populated by Spring from multiple configuration files. + * + * Should be used like this: + * + *
        + * 
        + * @Autowired
        + * SystemProperties systemProperties;
        + * 
        + */ +@Configuration +@PropertySource(value = { "${container.classpath:}/WEB-INF/conf/system.properties", + "${container.classpath:}/WEB-INF/fusion/conf/fusion.properties", + "${container.classpath:}/WEB-INF/conf/sql.properties" }) +public class SystemProperties { + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SystemProperties.class); + + private static Environment environment; + + private ServletContext servletContext; + + public SystemProperties() { + } + + protected Environment getEnvironment() { + return environment; + } + + @Autowired + public void setEnvironment(Environment environment) { + SystemProperties.environment = environment; + } + + public ServletContext getServletContext() { + return servletContext; + } + + public void setServletContext(ServletContext servletContext) { + this.servletContext = servletContext; + } + + /** + * Tests whether a property value is available for the specified key. + * + * @param key + * @return True if the key is known, otherwise false. + */ + public static boolean containsProperty(String key) { + return environment.containsProperty(key); + } + + /** + * Returns the property value associated with the given key (never + * {@code null}), after trimming any trailing space. + * + * @throws IllegalStateException + * if the key cannot be resolved + * @param key + * Property key + * @return Property value; the empty string if the environment was not + * autowired, which should never happen. + */ + public static String getProperty(String key) { + String value = ""; + if (environment == null) { + logger.error(EELFLoggerDelegate.errorLogger, "getProperty: environment is null, should never happen!"); + } + else { + value = environment.getRequiredProperty(key); + // java.util.Properties preserves trailing space + if (value != null) + value = value.trim(); + } + return value; + } + + /** + * Gets the property value for the key {@link #APPLICATION_NAME}. + * + * method created to get around JSTL 1.0 limitation of not being able to + * access a static method of a bean + * + * @return Application name + */ + public String getApplicationName() { + return getProperty(APPLICATION_NAME); + } + + /** + * Gets the property value for the key {@link #APP_DISPLAY_NAME}. + * + * @return Application display name + */ + public String getAppDisplayName() { + return getProperty(APP_DISPLAY_NAME); + } + + // keys used to reference values in the system properties file + public static final String DOMAIN_CLASS_LOCATION = "domain_class_location"; + public static final String DEFAULT_ERROR_MESSAGE = "default_error_message"; + + public static final String CSP_COOKIE_NAME = "csp_cookie_name"; + public static final String CSP_GATE_KEEPER_DATA_KEY = "csp_gate_keeper_data_key"; + public static final String CSP_GATE_KEEPER_PROD_KEY = "csp_gate_keeper_prod_key"; + public static final String CSP_LOGIN_URL = "csp_login_url"; + public static final String CSP_LOGOUT_URL = "csp_logout_url"; + + public static final String WEB_JUNCTION_USER_ID_HEADER_NAME = "web_junction_user_id_header_name"; + + public static final String AUTHENTICATION_MECHANISM = "authentication_mechanism"; + + public static final String APPLICATION_NAME = "application_name"; + public static final String HIBERNATE_CONFIG_FILE_PATH = "hibernate_config_file_path"; + public static final String APPLICATION_USER_ID = "application_user_id"; + + public static final String POST_INITIAL_CONTEXT_FACTORY = "post_initial_context_factory"; + public static final String POST_PROVIDER_URL = "post_provider_url"; + public static final String POST_SECURITY_PRINCIPAL = "post_security_principal"; + public static final String POST_MAX_RESULT_SIZE = "post_max_result_size"; + public static final String POST_DEFAULT_ROLE_ID = "post_default_role_id"; + + public static final String FILES_PATH = "files_path"; + public static final String TEMP_PATH = "temp_path"; + + public static final String NUM_UPLOAD_FILES = "num_upload_files"; + + public static final String SYS_ADMIN_ROLE_ID = "sys_admin_role_id"; + + public static final String SYS_ADMIN_ROLE_FUNCTION_DELETE_FROM_UI = "sys_admin_role_function_delete_from_ui"; + public static final String USER_NAME = "user_name"; + public static final String FIRST_NAME = "first_name"; + public static final String LAST_NAME = "last_name"; + public static final String APP_DISPLAY_NAME = "app_display_name"; + // Application base URL is a proper prefix of the on-boarding URL + public static final String APP_BASE_URL = "app_base_url"; + + public static final String MENU_PROPERTIES_FILE_LOCATION = "menu_properties_file_location"; + public static final String MENU_QUERY_NAME = "menu_query_name"; + public static final String APPLICATION_MENU_SET_NAME = "application_menu_set_name"; + public static final String APPLICATION_MENU_ATTRIBUTE_NAME = "application_menu_attribute_name"; + public static final String APPLICATION_MENU_PROPERTIES_NAME = "application_menu_properties_name"; + public static final String BUSINESS_DIRECT_MENU_SET_NAME = "business_direct_menu_set_name"; + public static final String BUSINESS_DIRECT_MENU_ATTRIBUTE_NAME = "business_direct_menu_attribute_name"; + public static final String BUSINESS_DIRECT_MENU_PROPERTIES_NAME = "business_direct_menu_properties_name"; + public static final String RAPTOR_CONFIG_FILE_PATH = "raptor_config_file_path"; + public static final String HOMEPAGE_DATA_CALLBACK_CLASS = "homepage_data_callback_class"; + public static final String ERROR_EMAIL_DISTRIBUTION = "error_email_distribution"; + public static final String ERROR_EMAIL_SOURCE_ADDRESS = "error_email_source_address"; + public static final String ERROR_EMAIL_SUBJECT_LINE = "error_email_subject_line"; + public static final String PROFILE_SEARCH_REPORT_ID = "profile_search_report_id"; + public static final String CALLABLE_PROFILE_SEARCH_REPORT_ID = "callable_profile_search_report_id"; + public static final String CLUSTERED = "clustered"; + + public static final String USER_ATTRIBUTE_NAME = "user_attribute_name"; + public static final String ROLES_ATTRIBUTE_NAME = "roles_attribute_name"; + public static final String ROLE_FUNCTIONS_ATTRIBUTE_NAME = "role_functions_attribute_name"; + public static final String CLIENT_DEVICE_ATTRIBUTE_NAME = "client_device_attribute_name"; + public static final String CLIENT_DEVICE_EMULATION = "client_device_emulation"; + public static final String CLIENT_DEVICE_TYPE_TO_EMULATE = "client_device_type_to_emulate"; + // File generation - Document + public static final String TEMPLATES_PATH = "templates_path"; + public static final String DOCUMENT_XML_ENCODING = "document_xml_encoding"; + + // Transaction + public static final String ROUTING_DATASOURCE_KEY = "routing_datasource_key"; + + // Document Library keys + public static final String DOCLIB_ADMIN_ROLE_ID = "doclib_admin_role_id"; + public static final String DOCLIB_USER_ROLE_ID = "doclib_user_role_id"; + + public static final String SYSTEM_PROPERTIES_FILENAME = "system.properties"; + public static final String FUSION_PROPERTIES_FILENAME = "fusion.properties"; + public static final String SUCCESS_TASKS_PROPERTIES_FILENAME = "success_tasks.properties"; + + // login methods + public static final String LOGIN_METHOD_CSP = "login_method_csp"; + public static final String LOGIN_METHOD_WEB_JUNCTION = "login_method_web_junction"; + public static final String LOGIN_METHOD_BACKDOOR = "login_method_backdoor"; + public static final String LOGIN_METHOD_ATTRIBUTE_NAME = "login_method_attribute_name"; + + // login error message keys + public static final String MESSAGE_KEY_LOGIN_ERROR_COOKIE_EMPTY = "login.error.hrid.empty"; + public static final String MESSAGE_KEY_LOGIN_ERROR_HEADER_EMPTY = "login.error.header.empty"; + public static final String MESSAGE_KEY_LOGIN_ERROR_USER_INACTIVE = "login.error.user.inactive"; + public static final String MESSAGE_KEY_LOGIN_ERROR_USER_NOT_FOUND = "login.error.hrid.not-found"; + public static final String MESSAGE_KEY_LOGIN_ERROR_APPLICATION_LOCKED = "login.error.application.locked"; + public static final String MESSAGE_KEY_AUTOLOGIN_NONE = "webphone.autoimport.nouser"; + public static final String MESSAGE_KEY_AUTOLOGIN_MULTIPLE = "webphone.autoimport.multiple"; + + // Application Mobile capability + public static final String MOBILE_ENABLE = "mobile_enable"; + + public static final String DATABASE_TIME_ZONE = "db.time_zone"; + + public static final String AUTO_USER_IMPORT_ENABLE = "auto_user_import_enable"; + public static final String AUTO_USER_IMPORT_ROLE = "auto_user_import_role"; + + public static final String ITRACKER_EMAIL_SOURCE_ADDRESS = "itracker_email_source_address"; + public static final String ITRACKER_EMAIL_DISTRIBUTION = "itracker_email_distribution"; + public static final String ITRACKER_SYSTEM_USER = "itracker_system_user_id"; + + public static final String MAIL_SERVER_HOST = "mail_server_host"; + public static final String MAIL_SERVER_PORT = "mail_server_port"; + + // Routing Data Source keys + public static final String ROUTING_DATASOURCE_KEY_NON_XA = "NON-XA"; + public static final String ROUTING_DATASOURCE_KEY_XA = "XA"; + public static final String QUARTZ_JOB_ENABLED = "quartz_job_enable"; + public static final String WORKFLOW_EMAIL_SENDER = "workflow_email_sender"; + public static final String DROOLS_GUVNOR_HOME = "drools.guvnor.home"; + + // Hibernate Config + public static final String HB_DIALECT = "hb.dialect"; + public static final String HB_SHOW_SQL = "hb.show_sql"; + + // DataSource + public static final String DB_DRIVER = "db.driver"; + public static final String DB_CONNECTIONURL = "db.connectionURL"; + public static final String DB_USERNAME = "db.userName"; + public static final String DB_PASSWOR = "db.password"; + public static final String DB_MIN_POOL_SIZE = "db.min_pool_size"; + public static final String DB_MAX_POOL_SIZE = "db.max_pool_size"; + public static final String IDLE_CONNECTION_TEST_PERIOD = "hb.idle_connection_test_period"; + + public static final String MYLOGINS_FEED_CRON = "mylogins_feed_cron"; + public static final String SESSIONTIMEOUT_FEED_CRON = "sessiontimeout_feed_cron"; + public static final String LOG_CRON = "log_cron"; + + public static final String DB_ENCRYPT_FLAG = "db.encrypt_flag"; + + // Decryption Key + public static final String Decryption_Key = "decryption_key"; + + // Logging/Audit Fields + public static final String MDC_APPNAME = "AppName"; + public static final String MDC_REST_PATH = "RestPath"; + public static final String MDC_REST_METHOD = "RestMethod"; + public static final String INSTANCE_UUID = "instance_uuid"; + public static final String MDC_CLASS_NAME = "ClassName"; + public static final String MDC_LOGIN_ID = "LoginId"; + public static final String MDC_TIMER = "Timer"; + public static final String SDK_NAME = "ECOMP_SDK"; + public static final String ECOMP_REQUEST_ID = "X-ECOMP-RequestID"; + public static final String PARTNER_NAME = "PartnerName"; + public static final String FULL_URL = "Full-URL"; + public static final String AUDITLOG_BEGIN_TIMESTAMP = "AuditLogBeginTimestamp"; + public static final String AUDITLOG_END_TIMESTAMP = "AuditLogEndTimestamp"; + public static final String METRICSLOG_BEGIN_TIMESTAMP = "MetricsLogBeginTimestamp"; + public static final String METRICSLOG_END_TIMESTAMP = "MetricsLogEndTimestamp"; + public static final String CLIENT_IP_ADDRESS = "ClientIPAddress"; + public static final String STATUS_CODE = "StatusCode"; + public static final String RESPONSE_CODE = "ResponseCode"; + // Component or sub component name + public static final String TARGET_ENTITY = "TargetEntity"; + // API or operation name + public static final String TARGET_SERVICE_NAME = "TargetServiceName"; + + // Logging Compliance + public static final String DOUBLE_WHITESPACE_SEPARATOR = " "; + public static final String SINGLE_WHITESPACE_SEPARATOR = " "; + public static final String SINGLE_QUOTE = "'"; + public static final String NA = "N/A"; + public static final String UNKNOWN = "Unknown"; + public static final String SECURITY_LOG_TEMPLATE = "Protocol:{0} Security-Event-Type:{1} Login-ID:{2} {3}"; + public static final String ECOMP_PORTAL_BE = "ECOMP_PORTAL_BE"; + public static final String PROTOCOL = "PROTOCOL"; + public static final String SECURIRY_EVENT_TYPE = "SECURIRY_EVENT_TYPE"; + public static final String LOGIN_ID = "LOGIN_ID"; + public static final String ACCESSING_CLIENT = "ACCESSING_CLIENT"; + public static final String RESULT_STR = "RESULT"; + public static final String ECOMP_PORTAL_FE = "ECOMP_PORTAL_FE"; + public static final String ADDITIONAL_INFO = "ADDITIONAL_INFO"; + public static final String INTERFACE_NAME = "INTERFACE_NAME"; + public static final String USERAGENT_NAME = "user-agent"; + + // Protocols + public static final String HTTP = "HTTP"; + public static final String HTTPS = "HTTPS"; + public static final String SSO_VALUE = "sso"; + + public enum RESULT_ENUM { + SUCCESS, FAILURE + } + + public enum SecurityEventTypeEnum { + FE_LOGIN_ATTEMPT, FE_LOGOUT, SSO_LOGIN_ATTEMPT_PHASE_1, SSO_LOGIN_ATTEMPT_PHASE_2, SSO_LOGOUT, LDAP_PHONEBOOK_USER_SEARCH, INCOMING_REST_MESSAGE, OUTGOING_REST_MESSAGE, REST_AUTHORIZATION_CREDENTIALS_MODIFIED, ECOMP_PORTAL_USER_MODIFIED, ECOMP_PORTAL_USER_ADDED, ECOMP_PORTAL_USER_REMOVED, ECOMP_PORTAL_WIDGET, INCOMING_UEB_MESSAGE, ECOMP_PORTAL_HEALTHCHECK + } + + // Menu + public static final String CONTACT_US_LINK = "contact_us_link"; + + // Left Menu + public static final String LEFT_MENU_PARENT = "parentList"; + public static final String LEFT_MENU_CHILDREND = "childItemList"; +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/UsageUtils.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/UsageUtils.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/UsageUtils.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/UsageUtils.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/YamlUtils.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/YamlUtils.java new file mode 100644 index 00000000..da69b729 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/util/YamlUtils.java @@ -0,0 +1,72 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.util; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Map; + +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.representer.Representer; + +public class YamlUtils { + + static Yaml yaml; + + static { + + Representer representer = new Representer(); + //representer.addClassTag(Domain.class, Tag.MAP); + + + yaml = new Yaml(representer); + + } + + public static void writeYamlFile(String filePath, String fileName, + Map model) throws IOException { + FileWriter writer = new FileWriter(filePath + File.separator + fileName); + yaml.dump(model, writer); + writer.close(); + } + + public static String returnYaml( + Map model) throws IOException { + + return yaml.dump(model); + + } + + @SuppressWarnings("unchecked") + public static Map readYamlFile( + String filePath, String fileName) throws FileNotFoundException, + IOException { + FileReader reader = new FileReader(filePath + File.separator + fileName); + + Map callFlowBs = (Map)yaml.load(reader); + reader.close(); + return callFlowBs; + } + + +} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/socket/PeerBroadcastSocket.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/socket/PeerBroadcastSocket.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/socket/PeerBroadcastSocket.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/socket/PeerBroadcastSocket.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/socket/WebRTCSocket.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/socket/WebRTCSocket.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/socket/WebRTCSocket.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/socket/WebRTCSocket.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/AppUtils.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/AppUtils.java new file mode 100644 index 00000000..295cff42 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/AppUtils.java @@ -0,0 +1,213 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.web.support; + +import java.io.File; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Date; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.sql.DataSource; + +import org.hibernate.Session; +import org.openecomp.portalsdk.core.exception.SessionExpiredException; +import org.openecomp.portalsdk.core.objectcache.AbstractCacheManager; +import org.openecomp.portalsdk.core.service.DataAccessService; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.FileSystemResource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + + +public class AppUtils { + + + + private static DataAccessService dataAccessService; + + private static AbstractCacheManager cacheManager; + + private static boolean applicationLocked; + + private static Hashtable feedback = new Hashtable(); + + private static DataSource datasource; + + public static DataSource getDatasource() { + return datasource; + } + + @Autowired + public void setDatasource(DataSource datasource) { + AppUtils.datasource = datasource; + } + + public AppUtils() { + } + + public static HttpSession getSession(HttpServletRequest request) { + HttpSession session = null; + if (request != null) { + session = request.getSession(false); + if (session == null) { + throw new SessionExpiredException(); + } + } else { + throw new SessionExpiredException(); + } + return session; + } + + public static List getLookupList(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy) { + return getLookupList(dbTable, dbValueCol, dbLabelCol, dbFilter, dbOrderBy, null); + } // getLookupList + + public static List getLookupList(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy, Session session) { + String cacheKey = dbTable + "|" + dbValueCol + "|" + dbLabelCol + "|" + dbFilter + "|" + dbOrderBy; + List list = getLookupListFromCache(cacheKey); + if (list == null) { + list = getDataAccessService().getLookupList(dbTable, dbValueCol, dbLabelCol, dbFilter, dbOrderBy, null); + if (list != null) { + addLookupListToCache(cacheKey, list); + } + } // if + return list; + } // getLookupList + + private static List getLookupListFromCache(String key) { + return (List)getObjectFromCache(key); + } // getLookupListFromCache + + public static Object getObjectFromCache(String key) { + if (isCacheManagerAvailable()) { + return getCacheManager().getObject(key); + } else { + return null; + } + } // getObjectFromCache + + private static void addLookupListToCache(String key, List list) { + addObjectToCache(key, list); + } // addLookupListToCache + + public static void addObjectToCache(String key, Object o) { + if (isCacheManagerAvailable()) { + getCacheManager().putObject(key, o); + } + } // addObjectToCache + + @Autowired + public void setCacheManager(AbstractCacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + public static AbstractCacheManager getCacheManager() { + return cacheManager; + } + + public static boolean isCacheManagerAvailable() { + return (getCacheManager() != null); + } + + public void setFeedback(Hashtable feedback) { + this.feedback = feedback; + } + + public static boolean isApplicationLocked() { + return applicationLocked; + } + + public static DataAccessService getDataAccessService() { + return dataAccessService; + } + + @Autowired + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + public static void setApplicationLocked(boolean locked) { + applicationLocked = locked; + } + + public static String getLookupValueByLabel(String label, String dbTable, String dbValueCol, String dbLabelCol) { + if (label == null || label.equals("")) { + return ""; + } + + List lstResult = getLookupListNoCache(dbTable, dbValueCol, dbLabelCol, dbLabelCol + "='" + label.replaceAll("'", "''") + "'", ""); + if (lstResult == null) { + return ""; + } + if (lstResult.size() > 0) { + return ((org.openecomp.portalsdk.core.domain.Lookup)lstResult.toArray()[0]).getValue(); + } else { + return ""; + } + } + + public static String getLookupValueByLabel(String label, List lookupList) { + Iterator i = null; + + if (label == null || label.equalsIgnoreCase("")) { + return ""; + } + + if (lookupList == null || lookupList.size() == 0) { + return ""; + } + + i = lookupList.iterator(); + while (i.hasNext()) { + org.openecomp.portalsdk.core.domain.Lookup lookup = (org.openecomp.portalsdk.core.domain.Lookup)i.next(); + + if (lookup.getLabel().equals(label)) { + return lookup.getValue(); + } + } + + return ""; +} + public static List getLookupListNoCache(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy) { + return getLookupListNoCache(dbTable, dbValueCol, dbLabelCol, dbFilter, dbOrderBy, null); + } // getLookupListNoCache + + + public static List getLookupListNoCache(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy, Session session) { + return getDataAccessService().getLookupList(dbTable, dbValueCol, dbLabelCol, dbFilter, dbOrderBy, null); + } // getLookupListNoCache + + + +} // AppUtils diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/ControllerProperties.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/ControllerProperties.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/ControllerProperties.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/ControllerProperties.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/FeedbackMessage.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/FeedbackMessage.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/FeedbackMessage.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/FeedbackMessage.java diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/JsonMessage.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/JsonMessage.java similarity index 100% rename from ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/JsonMessage.java rename to ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/JsonMessage.java diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/MessagesList.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/MessagesList.java new file mode 100644 index 00000000..0cf628aa --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/MessagesList.java @@ -0,0 +1,92 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.web.support; + +import java.util.*; + +public class MessagesList { + + private boolean successMessageDisplayed = true; + private boolean includeCauseInCustomExceptions = false; + + private List successMessages; + private List exceptionMessages; + + public MessagesList() { + setExceptionMessages(new ArrayList()); + setSuccessMessages(new ArrayList()); + } + + public MessagesList(boolean displaySuccess) { + this(); + setSuccessMessageDisplayed(displaySuccess); + } + + public List getExceptionMessages() { + return exceptionMessages; + } + + public List getSuccessMessages() { + return successMessages; + } + + public boolean isSuccessMessageDisplayed() { + return successMessageDisplayed; + } + + public boolean isIncludeCauseInCustomExceptions() { + return includeCauseInCustomExceptions; + } + + + public void setExceptionMessages(List exceptionMessages) { + this.exceptionMessages = exceptionMessages; + } + + public void setSuccessMessages(List successMessages) { + this.successMessages = successMessages; + } + + public void setSuccessMessageDisplayed(boolean successMessageDisplayed) { + this.successMessageDisplayed = successMessageDisplayed; + } + + public void setIncludeCauseInCustomExceptions(boolean includeCauseInCustomExceptions) { + this.includeCauseInCustomExceptions = includeCauseInCustomExceptions; + } + + + public void addSuccessMessage(FeedbackMessage message) { + getSuccessMessages().add(message); + } + + public void addExceptionMessage(FeedbackMessage message) { + getExceptionMessages().add(message); + } + + public boolean hasExceptionMessages() { + return!getExceptionMessages().isEmpty(); + } + + public boolean hasSuccessMessages() { + return!getSuccessMessages().isEmpty(); + } + +} diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/UserUtils.java b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/UserUtils.java new file mode 100644 index 00000000..37eaccad --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/main/java/org/openecomp/portalsdk/core/web/support/UserUtils.java @@ -0,0 +1,423 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.web.support; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.openecomp.portalsdk.core.domain.Role; +import org.openecomp.portalsdk.core.domain.RoleFunction; +import org.openecomp.portalsdk.core.domain.UrlsAccessible; +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.exception.SessionExpiredException; +import org.openecomp.portalsdk.core.lm.FusionLicenseManager; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.menu.MenuBuilder; +import org.openecomp.portalsdk.core.restful.domain.EcompRole; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; +import org.openecomp.portalsdk.core.service.DataAccessService; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; + +@SuppressWarnings("rawtypes") +public class UserUtils { + + static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(UserUtils.class); + + public static final String KEY_USER_ROLES_CACHE = "userRoles"; + + private static DataAccessService dataAccessService; + + public static void setUserSession(HttpServletRequest request, User user, Set applicationMenuData, + Set businessDirectMenuData, String loginMethod) { + HttpSession session = request.getSession(true); + + UserUtils.clearUserSession(request); // let's clear the current user + // session to avoid any + // conflicts during the set + + session.setAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME), user); + session.setAttribute(SystemProperties.getProperty(SystemProperties.LOGIN_METHOD_ATTRIBUTE_NAME), loginMethod); + + getRoleFunctions(request); + + // truncate the role (and therefore the role function) data to save + // memory in the session + user.setRoles(null); + session.setAttribute(SystemProperties.getProperty(SystemProperties.USER_NAME), user.getFullName()); + session.setAttribute(SystemProperties.FIRST_NAME, user.getFirstName()); + session.setAttribute(SystemProperties.LAST_NAME, user.getLastName()); + ServletContext context = session.getServletContext(); + int licenseVarificationFlag = 3; + try { + licenseVarificationFlag = (Integer) context.getAttribute("licenseVerification"); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.debugLogger, "Error while get license varification " + e.getMessage()); + } + String displayName = ""; + if (SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME) != null) + displayName = SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME); + switch (licenseVarificationFlag) { + case FusionLicenseManager.DEVELOPER_LICENSE: + session.setAttribute(SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME), + displayName + " [Development Version]"); + break; + case FusionLicenseManager.EXPIRED_LICENSE: + session.setAttribute(SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME), + displayName + " [LICENSE EXPIRED]"); + break; + case FusionLicenseManager.VALID_LICENSE: + session.setAttribute(SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME), displayName); + break; + default: + session.setAttribute(SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME), + displayName + " [INVALID LICENSE]"); + break; + } + + session.setAttribute(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_ATTRIBUTE_NAME), + MenuBuilder.filterMenu(applicationMenuData, request)); + session.setAttribute(SystemProperties.getProperty(SystemProperties.BUSINESS_DIRECT_MENU_ATTRIBUTE_NAME), + MenuBuilder.filterMenu(businessDirectMenuData, request)); + } + + public static void clearUserSession(HttpServletRequest request) { + HttpSession session = AppUtils.getSession(request); + + if (session == null) { + throw new SessionExpiredException(); + } + + // removes all stored attributes from the current user's session + session.removeAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME)); + session.removeAttribute(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_ATTRIBUTE_NAME)); + session.removeAttribute(SystemProperties.getProperty(SystemProperties.BUSINESS_DIRECT_MENU_ATTRIBUTE_NAME)); + session.removeAttribute(SystemProperties.getProperty(SystemProperties.ROLES_ATTRIBUTE_NAME)); + session.removeAttribute(SystemProperties.getProperty(SystemProperties.ROLE_FUNCTIONS_ATTRIBUTE_NAME)); + session.removeAttribute(SystemProperties.getProperty(SystemProperties.LOGIN_METHOD_ATTRIBUTE_NAME)); + } + + @SuppressWarnings("unchecked") + public static Set getRoleFunctions(HttpServletRequest request) { + HashSet roleFunctions = null; + + HttpSession session = request.getSession(); + roleFunctions = (HashSet) session + .getAttribute(SystemProperties.getProperty(SystemProperties.ROLE_FUNCTIONS_ATTRIBUTE_NAME)); + + if (roleFunctions == null) { + HashMap roles = getRoles(request); + roleFunctions = new HashSet(); + + Iterator i = roles.keySet().iterator(); + + while (i.hasNext()) { + Long roleKey = (Long) i.next(); + Role role = (Role) roles.get(roleKey); + + Iterator j = role.getRoleFunctions().iterator(); + + while (j.hasNext()) { + RoleFunction function = (RoleFunction) j.next(); + roleFunctions.add(function.getCode()); + } + } + + session.setAttribute(SystemProperties.getProperty(SystemProperties.ROLE_FUNCTIONS_ATTRIBUTE_NAME), + roleFunctions); + } + + return roleFunctions; + } + + public static HashMap getRoles(HttpServletRequest request) { + HashMap roles = null; + + // HttpSession session = request.getSession(); + HttpSession session = AppUtils.getSession(request); + roles = (HashMap) session.getAttribute(SystemProperties.getProperty(SystemProperties.ROLES_ATTRIBUTE_NAME)); + + // if roles are not already cached, let's grab them from the user + // session + if (roles == null) { + User user = getUserSession(request); + + // get all user roles (including the tree of child roles) + roles = getAllUserRoles(user); + + session.setAttribute(SystemProperties.getProperty(SystemProperties.ROLES_ATTRIBUTE_NAME), + getAllUserRoles(user)); + } + + return roles; + } + + public static User getUserSession(HttpServletRequest request) { + HttpSession session = AppUtils.getSession(request); + + if (session == null) { + throw new SessionExpiredException(); + } + + return (User) session.getAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME)); + } + + @SuppressWarnings("unchecked") + public static HashMap getAllUserRoles(User user) { + HashMap roles = new HashMap(); + Iterator i = user.getRoles().iterator(); + + while (i.hasNext()) { + Role role = (Role) i.next(); + + if (role.getActive()) { + roles.put(role.getId(), role); + + // let's take a recursive trip down the tree to add all child + // roles + addChildRoles(role, roles); + } + } + + return roles; + } + + @SuppressWarnings("unchecked") + private static void addChildRoles(Role role, HashMap roles) { + Set childRoles = role.getChildRoles(); + if (childRoles != null && childRoles.size() > 0) { + Iterator j = childRoles.iterator(); + while (j.hasNext()) { + Role childRole = (Role) j.next(); + if (childRole.getActive()) { + roles.put(childRole.getId(), childRole); + addChildRoles(childRole, roles); + } + } + } + + } + + /** + * Answers whether the specified URL is accessible. + * + * @param request + * @param currentUrl + * @return true if yes, false if no. + */ + public static boolean isUrlAccessible(HttpServletRequest request, String currentUrl) { + boolean isAccessible = false; + Map params = new HashMap<>(); + params.put("current_url", currentUrl); + List list = getDataAccessService().executeNamedQuery("restrictedUrls", params, null); + // loop through the list of restricted URL's + if (list != null && list.size() > 0) { + for (int i = 0; i < list.size(); i++) { + /* + * Object[] restrictedUrl = (Object[])list.get(i); + * + * String url = (String)restrictedUrl[0]; String functionCd = + * (String)restrictedUrl[1]; + */ + UrlsAccessible urlFunctions = (UrlsAccessible) list.get(i); + // String url = (String) urlFunctions.getUrl(); + String functionCd = (String) urlFunctions.getFunctionCd(); + if (UserUtils.isAccessible(request, functionCd)) { + isAccessible = true; + } + } + return isAccessible; + } + return true; + } + + public static boolean hasRole(HttpServletRequest request, String roleKey) { + return getRoles(request).keySet().contains(new Long(roleKey)); + } + + public static boolean hasRole(User user, String roleKey) { + return getAllUserRoles(user).keySet().contains(new Long(roleKey)); + } + + public static boolean isAccessible(HttpServletRequest request, String functionKey) { + return getRoleFunctions(request).contains(functionKey); + } + + public static String getLoginMethod(HttpServletRequest request) { + HttpSession session = AppUtils.getSession(request); + + if (session == null) { + throw new SessionExpiredException(); + } + + return (String) session + .getAttribute(SystemProperties.getProperty(SystemProperties.LOGIN_METHOD_ATTRIBUTE_NAME)); + } + + public static DataAccessService getDataAccessService() { + return dataAccessService; + } + + @Autowired + public void setDataAccessService(DataAccessService dataAccessService) { + UserUtils.dataAccessService = dataAccessService; + } + + public static int getUserId(HttpServletRequest request) { + return getUserIdAsLong(request).intValue(); + } + + public static Long getUserIdAsLong(HttpServletRequest request) { + Long userId = new Long(SystemProperties.getProperty(SystemProperties.APPLICATION_USER_ID)); + + if (request != null) { + if (getUserSession(request) != null) { + userId = getUserSession(request).getId(); + } + } + return userId; + } + + + private static final Object stackTraceLock = new Object(); + /** + * Serializes a stack trace of the specified throwable and returns it as a string. + * + * TODO: why is synchronization required? + * + * @param t + * @return String version of stack trace + */ + public static String getStackTrace(Throwable t) { + synchronized (stackTraceLock) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + t.printStackTrace(pw); + return sw.toString(); + } + } + + /** + * Gets the full URL of the request by joining the request and any query string. + * + * @param request + * @return Full URL of the request including query parameters + */ + public static String getFullURL(HttpServletRequest request) { + if (request != null) { + StringBuffer requestURL = request.getRequestURL(); + String queryString = request.getQueryString(); + + if (queryString == null) { + return requestURL.toString(); + } else { + return requestURL.append('?').append(queryString).toString(); + } + } + return ""; + } + + /** + * Gets or generates a request ID by searching for header X-ECOMP-RequestID. + * If not found, generates a new random UUID. + * + * @param request + * @return Request ID for the specified request + */ + public static String getRequestId(HttpServletRequest request) { + Enumeration headerNames = request.getHeaderNames(); + + String requestId = ""; + try { + while (headerNames.hasMoreElements()) { + String headerName = (String) headerNames.nextElement(); + if (logger.isTraceEnabled()) + logger.trace(EELFLoggerDelegate.debugLogger, + "getRequestId: header {} = {}", headerName, request.getHeader(headerName)); + if (headerName.equalsIgnoreCase(SystemProperties.ECOMP_REQUEST_ID)) { + requestId = request.getHeader(headerName); + break; + } + } + } catch (Exception e) { + logger.error(EELFLoggerDelegate.debugLogger, "getRequestId: failed to get headder", e); + } + + if (requestId.isEmpty()) + requestId = UUID.randomUUID().toString(); + logger.debug(EELFLoggerDelegate.debugLogger, "getRequestId: result is {}", requestId); + return requestId; + } + + /** + * Converts a Hibernate-mapped User object to a JSON-serializable EcompUser object. + * + * @param user + * @return EcompUser with a subset of fields. + */ + public static EcompUser convertToEcompUser(User user) { + EcompUser userJson = new EcompUser(); + userJson.setEmail(user.getEmail()); + userJson.setFirstName(user.getFirstName()); + userJson.setHrid(user.getHrid()); + userJson.setJobTitle(user.getJobTitle()); + userJson.setLastName(user.getLastName()); + userJson.setLoginId(user.getLoginId()); + userJson.setOrgManagerUserId(user.getOrgManagerUserId()); + userJson.setMiddleInitial(user.getMiddleInitial()); + userJson.setOrgCode(user.getOrgCode()); + userJson.setOrgId(user.getOrgId()); + userJson.setPhone(user.getPhone()); + userJson.setOrgUserId(user.getOrgUserId()); + Set ecompRoles = new TreeSet(); + for (Role role : user.getRoles()) { + ecompRoles.add(convertToEcompRole(role)); + } + userJson.setRoles(ecompRoles); + return userJson; + } + + /** + * Converts a Hibernate-mapped Role object to a JSON-serializable EcompRole object. + * + * @param role + * @return EcompRole with a subset of fields: ID and name + */ + public static EcompRole convertToEcompRole(Role role) { + EcompRole ecompRole = new EcompRole(); + ecompRole.setId(role.getId()); + ecompRole.setName(role.getName()); + return ecompRole; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/fusion/core/MockApplicationContextTestSuite.java b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/fusion/core/MockApplicationContextTestSuite.java new file mode 100644 index 00000000..0867f2a7 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/fusion/core/MockApplicationContextTestSuite.java @@ -0,0 +1,114 @@ +package org.openecomp.fusion.core; + +import java.io.IOException; + +import org.junit.Before; +import org.junit.runner.RunWith; +import org.openecomp.portalsdk.core.conf.AppConfig; +import org.openecomp.portalsdk.core.objectcache.AbstractCacheManager; +import org.openecomp.portalsdk.core.util.CacheManager; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.AnnotationConfigWebContextLoader; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; + +/** + * In order to write a unit test, 1. inherit this class - See SanityTest.java 2. + * place the "war" folder on your test class's classpath 3. run the test with + * the following VM argument; This is important because when starting the + * application from Container, the System Properties file + * (SystemProperties.java) can have the direct path but, when running from the + * Mock Junit container, the path should be prefixed with "classpath" to enable + * the mock container to search for the file in the classpath + * -Dcontainer.classpath="classpath:" + * + */ + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, classes = { MockAppConfig.class }) +@ActiveProfiles(value = "test") +public class MockApplicationContextTestSuite { + + @Autowired + public WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() { + if (mockMvc == null) { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + + } + } + + public Object getBean(String name) { + return this.wac.getBean(name); + } + + public MockMvc getMockMvc() { + return mockMvc; + } + + public void setMockMvc(MockMvc mockMvc) { + this.mockMvc = mockMvc; + } + + public WebApplicationContext getWebApplicationContext() { + return wac; + } + +} + +@Configuration +@ComponentScan(basePackages = "org.openecomp", excludeFilters = {}) +@Profile("test") +class MockAppConfig extends AppConfig { + + @Bean + public SystemProperties systemProperties() { + return new MockSystemProperties(); + } + + @Bean + public AbstractCacheManager cacheManager() { + return new CacheManager() { + + public void configure() throws IOException { + + } + }; + } + + protected String[] tileDefinitions() { + return new String[] { "classpath:/WEB-INF/fusion/defs/definitions.xml", + "classpath:/WEB-INF/defs/definitions.xml" }; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + // registry.addInterceptor(new + // SessionTimeoutInterceptor()).excludePathPatterns(getExcludeUrlPathsForSessionTimeout()); + // registry.addInterceptor(resourceInterceptor()); + } + + public static class MockSystemProperties extends SystemProperties { + + public MockSystemProperties() { + } + + } + +} diff --git a/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/fusion/core/MockHibernateMappingLocations.java b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/fusion/core/MockHibernateMappingLocations.java new file mode 100644 index 00000000..fea7cdda --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/fusion/core/MockHibernateMappingLocations.java @@ -0,0 +1,23 @@ +package org.openecomp.fusion.core; + +import org.openecomp.portalsdk.core.conf.HibernateMappingLocatable; +import org.springframework.context.annotation.Profile; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; + +@Component +@Profile("test") +public class MockHibernateMappingLocations implements HibernateMappingLocatable{ + + @Override + public Resource[] getMappingLocations() { + return new Resource[]{new ClassPathResource("WEB-INF/fusion/orm/Fusion.hbm.xml"), new ClassPathResource("WEB-INF/fusion/orm/Workflow.hbm.xml")}; + } + + @Override + public String[] getPackagesToScan() { + return new String[] { "org.openecomp" }; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/MockApplicationContextTestSuite.java b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/MockApplicationContextTestSuite.java new file mode 100644 index 00000000..812d438a --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/MockApplicationContextTestSuite.java @@ -0,0 +1,143 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk; + +import java.io.IOException; + +import org.junit.Before; +import org.junit.runner.RunWith; +import org.openecomp.portalsdk.core.conf.AppConfig; +import org.openecomp.portalsdk.core.objectcache.AbstractCacheManager; +import org.openecomp.portalsdk.core.util.CacheManager; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.AnnotationConfigWebContextLoader; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; + +/** + * + * + * + * In order to write a unit test, + * 1. inherit this class - See SanityTest.java + * 2. place the "war" folder on your test class's classpath + * 3. run the test with the following VM argument; This is important because when starting the application from Container, the System Properties file (SystemProperties.java) can have the direct path + * but, when running from the Mock Junit container, the path should be prefixed with "classpath" to enable the mock container to search for the file in the classpath + * -Dcontainer.classpath="classpath:" + * + */ + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, classes = {MockAppConfig.class}) +@ActiveProfiles(value="test") +public class MockApplicationContextTestSuite { + + @Autowired + public WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() { + if(mockMvc == null) { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + + } + } + + public Object getBean(String name) { + return this.wac.getBean(name); + } + + + public MockMvc getMockMvc() { + return mockMvc; + } + + public void setMockMvc(MockMvc mockMvc) { + this.mockMvc = mockMvc; + } + + public WebApplicationContext getWebApplicationContext() { + return wac; + } + + + + +} + + + @Configuration + @ComponentScan(basePackages = "org.openecomp", + excludeFilters = { } + ) + @Profile("test") + class MockAppConfig extends AppConfig { + + @Bean + public SystemProperties systemProperties(){ + return new MockSystemProperties(); + } + + @Bean + public AbstractCacheManager cacheManager() { + return new CacheManager() { + + public void configure() throws IOException { + + } + }; + } + + protected String[] tileDefinitions() { + return new String[] {"classpath:/WEB-INF/fusion/defs/definitions.xml", "classpath:/WEB-INF/defs/definitions.xml"}; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + //registry.addInterceptor(new SessionTimeoutInterceptor()).excludePathPatterns(getExcludeUrlPathsForSessionTimeout()); + //registry.addInterceptor(resourceInterceptor()); + } + + public static class MockSystemProperties extends SystemProperties { + + public MockSystemProperties() { + } + + } + + } + + + + diff --git a/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/MockHibernateMappingLocations.java b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/MockHibernateMappingLocations.java new file mode 100644 index 00000000..a9fdebb4 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/MockHibernateMappingLocations.java @@ -0,0 +1,42 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk; + +import org.openecomp.portalsdk.core.conf.HibernateMappingLocatable; +import org.springframework.context.annotation.Profile; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; + +@Component +@Profile("test") +public class MockHibernateMappingLocations implements HibernateMappingLocatable { + + public Resource[] getMappingLocations() { + return new Resource[] { new ClassPathResource("WEB-INF/fusion/orm/Fusion.hbm.xml"), + new ClassPathResource("WEB-INF/fusion/orm/Workflow.hbm.xml") }; + } + + @Override + public String[] getPackagesToScan() { + return new String[] { "org.openecomp" }; + } + +} diff --git a/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/controller/sessionmgt/PortalCommunicationTest.java b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/controller/sessionmgt/PortalCommunicationTest.java new file mode 100644 index 00000000..6b87dbe4 --- /dev/null +++ b/ecomp-sdk/epsdk-core/src/test/java/org/openecomp/portalsdk/controller/sessionmgt/PortalCommunicationTest.java @@ -0,0 +1,75 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.controller.sessionmgt; +/*package org.openecomp.portalsdk.controller.sessionmgt; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import org.openecomp.portalsdk.MockApplicationContextTestSuite; +import org.openecomp.portalsdk.service.sessionmgt.CoreTimeoutHandler; + +public class PortalCommunicationTest extends MockApplicationContextTestSuite{ + + + @Test + public void testGetTimeoutSessions() throws Exception { + + MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/api/sessionTimeOuts"); + MockHttpSession httpSession = new MockHttpSession(this.wac.getServletContext(),"1234"); + CoreTimeoutHandler.sessionCreated("12", "1234", httpSession); + + ResultActions ra = this.getMockMvc().perform(requestBuilder); + + System.out.println(" %%%%%%%%%%%%%%%%%%%%%%%%% " + ra.andReturn().getResponse().getContentAsString()); + System.out.println(" %%%%%%%%%%%%%%%%%%%%%%%%% " + "{\"12\":{\"jSessionId\":\"1234\",\"sessionTimOutMilliSec\":"); + + Assert.assertTrue(ra.andReturn().getResponse().getContentAsString().startsWith("{\"12\":{\"jSessionId\":\"1234\",\"sessionTimOutMilliSec\":")); + + } + + @Test + public void testUpdateTimeoutSessions() throws Exception { + + // pre condition + MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/api/sessionTimeOuts"); + MockHttpSession httpSession = new MockHttpSession(this.wac.getServletContext(),"1234"); + CoreTimeoutHandler.sessionCreated("12", "1234", httpSession); + ResultActions ra = this.getMockMvc().perform(requestBuilder); + + String responseSessMapStr = ra.andReturn().getResponse().getContentAsString(); + + + // test + requestBuilder = MockMvcRequestBuilders.post("/api/updateSessionTimeOuts"); + requestBuilder.param("sessionMap", responseSessMapStr); + ra = this.getMockMvc().perform(requestBuilder); + + + } + + + +} +*/ diff --git a/ecomp-sdk/epsdk-fw/.gitignore b/ecomp-sdk/epsdk-fw/.gitignore new file mode 100644 index 00000000..aa0c881b --- /dev/null +++ b/ecomp-sdk/epsdk-fw/.gitignore @@ -0,0 +1,5 @@ +/target +/bin/ +/.settings/ +.project +.classpath diff --git a/ecomp-sdk/epsdk-fw/README.md b/ecomp-sdk/epsdk-fw/README.md new file mode 100644 index 00000000..af36ddc2 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/README.md @@ -0,0 +1,111 @@ +# ECOMP Portal SDK Framework + +## Overview + +This is the Maven project for the ECOMP Portal SDK Framework library, +which is distributed as epsdk-fw-N.N.N.jar. This library +(once called third-party onboarding) provides features to +partner applications that use a J2EE Servlet 3.0 container +as Apache Tomcat. These features include: +- REST endpoint for use by the ECOMP Portal aplication. This endpoint + answers queries about roles, users and user-role assignments. + The endpoint methods are defined by the Java interface class + IPortalRestAPIService. Application developers must provide a + class that implements this interface, and publish the name of + that class in the properties file as discussed below. +- A session listener that updates a collection with current user sessions + as sessions are created and destroyed. This information is used to maintain + and extend user session timeouts across applications that are on-boarded to + the ECOMP portal. +- Single sign-on to the application via either the AT&T Central Security Platform (SCP) + or WebSEAL Junction. +- Communication with the ECOMP Portal to fetch a user-specific functional menu, either + via REST or UEB. + +Unlike the other ECOMP SDK libraries, this library does NOT require Hibernate, +nor does it require Spring. + +## Release Notes + +### OpenECOMP Distributions + +Build 1.2.8, ?? ??? 2017 +* put new entries here * + +Build 1.2.7, 10 Apr 2017 +- No changes + +Build 1.2.6, 23 Mar 2017 +- No changes + +Build 1.2.5, 16 Mar 2017 +- Extended PortalTimeoutHandler to show method names in all exception output +- US869765 Post OpenSource SDKs and ecompFW apps should listen to endpoint /api/v2 instead of just /api + +Build 1.2.4, 10 Mar 2017 +- No changes + +Build 1.2.3, 8 Mar 2017 +- No changes + +Build 1.2.2, 6 Mar 2017 +- No changes + +Build 1.2.1, 2 Mar 2017 +- Refactor to remove dependency on AT&T Global Log On single sign on (SSO) library. +- Move UEB/Cambria library and demonstration use classes out of FW + +Build 1.2.0, 9 Feb 2017 +- Change group to org.openecomp.ecompsdkos; restart version numbering for open-source distribution + +### Closed-Source Distributions + +The following history is preserved for the benefit of partner application teams. + +Version 4.3.5, 2 Feb 2017 +- No changes + +Version 4.3.4 13 Jan 2017 +- No changes + +Version 4.3.3, 11 Jan 2017 +- US779882 Extend analytics servlet to use content type text/javascript for analytics script; + check for empty user ID when validating analytics GET/POST requests + +Version 4.3.2, 9 Jan 2017 +- US779882 Extend servlet to provide GET/POST endpoints for Web Analytics + +Version 4.3.1, 3 Jan 2017 +- No changes + +Version 4.2.1, 15 Dec 2016 +- DE255409 trim trailing space on values fetched from Portal, System properties + +Version 4.1.4, 22 Nov 2016 + - No changes + +Version 4.1.3, 14 Nov 2016 + - No changes + +Version 4.1.2, 14 Nov 2016 + - No changes + +Version 4.1.1, 3 Nov 2016 + - No changes + +Version 3.3.3, 13 Oct 2016 + - No changes + +Version 3.3.2, 26 Sep 2016 + - DE237818, fix bug that blocked return of session timeout information + +Version 3.3.1, 22 Sep 2016 + - No changes + +Version 3.2.2, 4 Aug 2016 + +Version 3.2.1, 12 July 2016 + +Version 2.0.3, 13 June 2016 + +Version 2.0.2, 27 May 2016 diff --git a/ecomp-sdk/epsdk-fw/pom.xml b/ecomp-sdk/epsdk-fw/pom.xml new file mode 100644 index 00000000..504d768a --- /dev/null +++ b/ecomp-sdk/epsdk-fw/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + + org.openecomp.ecompsdkos + epsdk-project + 1.1.0-SNAPSHOT + + + + epsdk-fw + + jar + ECOMP Portal SDK Framework + + + + + + + + + + + + src/main/java + + **/portal*.properties + + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + + ${project.version} + ${sdk-internal.version} + + + + + + + + + + + + + + javax.servlet + javax.servlet-api + 3.0.1 + + + commons-codec + commons-codec + 1.10 + + + commons-logging + commons-logging + 1.2 + + + com.fasterxml.jackson.core + jackson-annotations + 2.6.3 + + + com.fasterxml.jackson.core + jackson-databind + 2.6.3 + + + + + diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java new file mode 100644 index 00000000..0efd1ce4 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java @@ -0,0 +1,175 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.onboarding.exception.PortalAPIException; +import org.openecomp.portalsdk.core.restful.domain.EcompRole; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; + +/** + * Defines the REST API Interface that an on-boarding application must implement + * to answer queries and accept updates from the ECOMP Portal about the + * application's users, roles and user-role assignments. + */ +public interface IPortalRestAPIService { + + // EcompUser Interface + + /** + * Creates a user with the specified details. If any error occurs, for + * example the user exists, the method should throw PortalApiException with + * an appropriate message. The FW library will catch the exception and send + * an appropriate response to Portal. + * + * @param user + * Model object with attributes of user to be created. + * @throws PortalAPIException + * If any error occurs while processing the request; for + * example, user exists. + */ + public void pushUser(EcompUser user) throws PortalAPIException; + + /** + * Updates details about the user with the specified loginId. For example, + * mark user as inactive. If any error occurs, the method should throw + * PortalApiException with an appropriate message. The FW library will catch + * the exception and send an appropriate response to Portal. + * + * @param loginId + * EcompUser ID to be updated. + * @param user + * Model object with attributes of user to be updated. + * @throws PortalAPIException + * If any error occurs while processing the request; for + * example, unknown user. + */ + public void editUser(String loginId, EcompUser user) throws PortalAPIException; + + /** + * Gets and returns the user object with the specified loginId. If any error + * occurs, the method should throw PortalApiException with an appropriate + * message. The FW library will catch the exception and send an appropriate + * response to Portal + * + * @param loginId + * EcompUser ID to be fetched + * @return Model object with user attributes. + * @throws PortalAPIException + * If any error occurs while processing the request; for + * example, unknown user. + */ + public EcompUser getUser(String loginId) throws PortalAPIException; + + /** + * Gets and returns a list of active users. If any error occurs, the method + * should throw PortalApiException with an appropriate message. The FW + * library will catch the exception and send an appropriate response to + * Portal. + * + * @return List of user attribute model objects; empty list if none are + * found. + * @throws PortalAPIException + * If any error occurs while processing the request. + */ + public List getUsers() throws PortalAPIException; + + // Roles Interface + + /** + * Gets and returns a list of active roles. If any error occurs, the method + * should throw PortalApiException with an appropriate message. The FW + * library will catch the exception and send an appropriate response to + * Portal. + * + * @return List of role attribute objects; empty list if none are found. + * @throws PortalAPIException + * If an unexpected error occurs while processing the request. + */ + public List getAvailableRoles() throws PortalAPIException; + + /** + * Updates roles for the user with the specified loginId to the list of + * roles provided as the second argument. After this operation, the should + * have ONLY the roles provided in the list above. For example, if user had + * roles r1, r2 and r3; and a call was made to pushUserRole with a list + * containing only roles r3 and r4, this method should leave the user with + * roles r3 and r4 since those were the ONLY roles provided in second + * argument. If any error occurs, the method should throw PortalApiException + * with an appropriate message. The FW library will catch the exception and + * send an appropriate response to Portal. + * + * @param loginId + * EcompUser ID to be updated. + * @param roles + * List of role attribute objects + * @throws PortalAPIException + * If any error occurs while processing the request. + */ + public void pushUserRole(String loginId, List roles) throws PortalAPIException; + + /** + * Gets and returns a list of roles for the user with the specified loginId. + * If any error occurs, the method should throw PortalApiException with an + * appropriate message. The FW library will catch the exception and send an + * appropriate response to Portal. + * + * @param loginId + * @return List of model objects; empty if no roles are found. + * @throws PortalAPIException + * If any error occurs while processing the request; e.g., user + * not found. + */ + public List getUserRoles(String loginId) throws PortalAPIException; + + // Security Interface + + /** + * Should return true if the call should be allowed and false if not. + * Currently Portal sends two headers of username and password in each + * request which the app should check. If match, return true; else return + * false. If any error occurs, the method should throw PortalApiException + * with an appropriate message. The FW library will catch the exception and + * send an appropriate response to Portal. + * + * @param request + * @return true if the request contains appropriate credentials, else false. + * @throws PortalAPIException + * If an unexpected error occurs while processing the request. + */ + public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException; + + /** + * Gets and returns the userId for the logged-in user based on the request. + * If any error occurs, the method should throw PortalApiException with an + * appropriate message. The FW library will catch the exception and send an + * appropriate response to Portal. + * + * @param request + * @return true if the request contains appropriate credentials, else false. + * @throws PortalAPIException + * If an unexpected error occurs while processing the request. + */ + public String getUserId(HttpServletRequest request) throws PortalAPIException; + +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java new file mode 100644 index 00000000..b6e0150e --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java @@ -0,0 +1,47 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; + +import org.openecomp.portalsdk.core.onboarding.exception.PortalAPIException; + +/** + * + * @author Ikram Ikramullah + * + * UEB API Interface for all the onboarding third party applications. + * + */ + +public interface IPortalUebAPIService { + //User Interface + public String pushUser(String userJson) throws PortalAPIException; + public String editUser(String loginId, String userJson) throws PortalAPIException; + public String getUser(String loginId) throws PortalAPIException; + public String getUsers() throws PortalAPIException; + + //Roles Interface + public String getAvailableRoles() throws PortalAPIException; + public String getAvailableFullRoles() throws PortalAPIException; + public String pushUserRole(String loginId, String rolesJson) throws PortalAPIException; + public String getUserRoles(String loginId) throws PortalAPIException; + + //Security Interface + public boolean isAppAuthenticated(String appUserName, String appPassword) throws PortalAPIException; +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java new file mode 100644 index 00000000..ad1eae8d --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java @@ -0,0 +1,58 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; + +/** + * This bean holds a response that is returned by the role and user-management + * REST API. + */ +public class PortalAPIResponse { + + /** + * Either "ok" or "error" + */ + private String status; + /** + * Optional if status is ok + */ + private String message; + + public PortalAPIResponse(boolean isOk, String msg) { + status = (isOk? "ok" : "error"); + message = msg; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java new file mode 100644 index 00000000..02d35ae9 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java @@ -0,0 +1,618 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.exception.PortalAPIException; +import org.openecomp.portalsdk.core.onboarding.listener.PortalTimeoutHandler; +import org.openecomp.portalsdk.core.onboarding.rest.RestWebServiceClient; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; +import org.openecomp.portalsdk.core.restful.domain.EcompRole; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * This servlet performs the functions described below. It listens on a path + * like "/api" (see {@link PortalApiConstants#API_PREFIX}). The servlet checks + * for authorized access and rejects unauthorized requests. + *
          + *
        1. Proxies user (i.e., browser) requests for web analytics. The GET method + * fetches javascript from the Portal and returns it. The POST method forwards + * data sent by the browser on to Portal. These requests are checked for a valid + * User UID in a header; these requests do NOT use the application + * username-password header.
        2. + *
        3. Responds to ECOMP Portal API requests to query and update user, role and + * user-role information. The servlet proxies all requests on to a local Java + * class that implements {@link IPortalRestAPIService}. These requests must have + * the application username-password header.
        4. + *
        + * This servlet will not start if the required portal.properties file is not + * found on the classpath. + */ + +@WebServlet(urlPatterns = { PortalApiConstants.API_PREFIX + "/*" }) +public class PortalRestAPIProxy extends HttpServlet implements IPortalRestAPIService { + private static final long serialVersionUID = 1L; + + private static final String contentTypeAppJson = "application/json"; + + private final Log logger = LogFactory.getLog(getClass()); + + /** + * Mapper for JSON to object etc. + */ + private final ObjectMapper mapper = new ObjectMapper(); + + /** + * Client-supplied class that implements our interface. + */ + private static IPortalRestAPIService portalRestApiServiceImpl; + + public PortalRestAPIProxy() { + // Ensure that any additional fields sent by the Portal + // will be ignored when creating objects. + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + @Override + public void init() throws ServletException { + String className = PortalApiProperties.getProperty(PortalApiConstants.PORTAL_API_IMPL_CLASS); + if (className == null) + throw new ServletException( + "init: Failed to find class name property " + PortalApiConstants.PORTAL_API_IMPL_CLASS); + try { + logger.debug("init: creating instance of class " + className); + Class implClass = Class.forName(className); + portalRestApiServiceImpl = (IPortalRestAPIService) (implClass.getConstructor().newInstance()); + } catch (Exception ex) { + throw new ServletException("init: Failed to find or instantiate class " + className, ex); + } + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + + if (portalRestApiServiceImpl == null) { + // Should never happen due to checks in init() + logger.error("doPost: no service class instance"); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + response.getWriter().write(buildJsonResponse(false, "Misconfigured - no instance of service class")); + return; + } + String requestUri = request.getRequestURI(); + String responseJson = ""; + String storeAnalyticsContextPath = "/storeAnalytics"; + if (requestUri.endsWith(PortalApiConstants.API_PREFIX + storeAnalyticsContextPath)) { + String userId; + try { + userId = getUserId(request); + } catch (PortalAPIException e) { + logger.error("Issue with invoking getUserId implemenation !!! ", e); + throw new ServletException(e); + } + if (userId == null || userId.length() == 0) { + logger.debug("doPost: userId is null or empty"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + responseJson = buildJsonResponse(false, "Not authorized for " + storeAnalyticsContextPath); + } else { + // User ID obtained from request + try { + String credential = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + // for now lets also pass uebkey as user name and password + String requestBody = readRequestBody(request); + @SuppressWarnings("unchecked") + Map bodyMap = mapper.readValue(requestBody, Map.class); + // add user ID + bodyMap.put("userid", userId); + requestBody = mapper.writeValueAsString(bodyMap); + responseJson = RestWebServiceClient.getInstance().postPortalContent(storeAnalyticsContextPath, + userId, credential, null, credential, credential, "application/json", requestBody); + if (logger.isDebugEnabled()) + logger.debug("doPost: postPortalContent returns " + responseJson); + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception ex) { + logger.error("doPost: " + storeAnalyticsContextPath + " caught exception", ex); + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + writeAndFlush(response, contentTypeAppJson, responseJson); + return; + } // post analytics + + boolean secure = false; + try { + secure = isAppAuthenticated(request); + } catch (PortalAPIException ex) { + logger.error("doPost: isAppAuthenticated threw exception", ex); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + response.getWriter().write(buildJsonResponse(false, "Failed to authenticate request")); + return; + } + if (!secure) { + if (logger.isDebugEnabled()) + logger.debug("doPost: isAppAuthenticated answered false"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + writeAndFlush(response, contentTypeAppJson, buildJsonResponse(false, "Not authorized")); + return; + } + + try { + String requestBody = readRequestBody(request); + if (logger.isDebugEnabled()) + logger.debug("doPost: URI = " + requestUri + ", payload = " + requestBody); + + /* + * All APIs: + * + * 1. /user <-- save user + * + * 2. /user/{loginId} <-- edit user + * + * 3. /user/{loginId}/roles <-- save roles for user + */ + + // On success return the empty string. + + if (requestUri.endsWith("/updateSessionTimeOuts")) { + if (updateSessionTimeOuts(requestBody)) { + if (logger.isDebugEnabled()) + logger.debug("doPost: updated session timeouts"); + response.setStatus(HttpServletResponse.SC_OK); + } else { + String msg = "Failed to update session time outs"; + logger.error("doPost: " + msg); + responseJson = buildJsonResponse(false, msg); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } else if (requestUri.endsWith("/timeoutSession")) { + String portalJSessionId = request.getParameter("portalJSessionId"); + if (portalJSessionId == null) { + portalJSessionId = ""; + } + if (timeoutSession(portalJSessionId)) { + if (logger.isDebugEnabled()) + logger.debug("doPost: timed out session"); + response.setStatus(HttpServletResponse.SC_OK); + } else { + String msg = "Failed to timeout session"; + logger.error("doPost: " + msg); + responseJson = buildJsonResponse(false, msg); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } else + // Example: /user <-- create user + if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/user")) { + try { + EcompUser user = mapper.readValue(requestBody, EcompUser.class); + pushUser(user); + if (logger.isDebugEnabled()) + logger.debug("doPost: pushUser: success"); + responseJson = buildJsonResponse(true, null); + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doPost: pushUser: caught exception", ex); + } + } else + // Example: /user/fi241c <-- edit user fi241c + if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !(requestUri.endsWith("/roles"))) { + String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1); + try { + EcompUser user = mapper.readValue(requestBody, EcompUser.class); + editUser(loginId, user); + if (logger.isDebugEnabled()) + logger.debug("doPost: editUser: success"); + responseJson = buildJsonResponse(true, null); + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doPost: editUser: caught exception", ex); + } + } else + // Example: /user/{loginId}/roles <-- save roles for user + if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) { + String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1, + requestUri.lastIndexOf('/')); + try { + TypeReference> typeRef = new TypeReference>() { + }; + List roles = mapper.readValue(requestBody, typeRef); + pushUserRole(loginId, roles); + if (logger.isDebugEnabled()) + logger.debug("doPost: pushUserRole: success"); + responseJson = buildJsonResponse(true, null); + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doPost: pushUserRole: caught exception", ex); + } + } else { + String msg = "doPost: no match for request " + requestUri; + logger.warn(msg); + responseJson = buildJsonResponse(false, msg); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + } catch (Exception ex) { + logger.error("doPost: Failed to process request " + requestUri, ex); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + responseJson = buildJsonResponse(ex); + } + + writeAndFlush(response, contentTypeAppJson, responseJson); + + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + + if (portalRestApiServiceImpl == null) { + // Should never happen due to checks in init() + logger.error("doGet: no service class instance"); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + writeAndFlush(response, contentTypeAppJson, + buildJsonResponse(false, "Misconfigured - no instance of service class")); + return; + } + + String requestUri = request.getRequestURI(); + String responseString = ""; + String contentType = contentTypeAppJson; + + String webAnalyticsContextPath = "/analytics"; + if (requestUri.endsWith(PortalApiConstants.API_PREFIX + webAnalyticsContextPath)) { + String userId; + try { + userId = getUserId(request); + } catch (PortalAPIException e) { + logger.error("Issue with invoking getUserId implemenation !!! ", e); + throw new ServletException(e); + } + if (userId == null || userId.length() == 0) { + logger.debug("doGet: userId is null or empty"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + responseString = buildJsonResponse(false, "Not authorized for " + webAnalyticsContextPath); + } else { + // User ID obtained from request + try { + String credential = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + // for now lets also pass uebkey as user name and password + contentType = "text/javascript"; + responseString = RestWebServiceClient.getInstance().getPortalContent(webAnalyticsContextPath, + userId, credential, null, credential, credential); + if (logger.isDebugEnabled()) + logger.debug("doGet: " + webAnalyticsContextPath + ": " + responseString); + response.setStatus(HttpServletResponse.SC_OK); + } catch (Exception ex) { + responseString = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doGet: " + webAnalyticsContextPath + " caught exception", ex); + } + } + writeAndFlush(response, contentType, responseString); + return; + } + + boolean secure = false; + try { + secure = isAppAuthenticated(request); + } catch (PortalAPIException ex) { + logger.error("doGet: isAppAuthenticated threw exception", ex); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + writeAndFlush(response, contentTypeAppJson, buildJsonResponse(false, "Failed to authenticate request")); + return; + } + + if (!secure) { + if (logger.isDebugEnabled()) + logger.debug("doGet: isAppAuthenticated answered false"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + writeAndFlush(response, contentTypeAppJson, buildJsonResponse(false, "Not authorized")); + return; + } + + String responseJson = null; + try { + // Ignore any request body in a GET. + // String requestBody = readRequestBody(request); + if (logger.isDebugEnabled()) + logger.debug("doGet: URI = " + requestUri); + + /* + * 1. /roles <-- get roles + * + * 2. /user/{loginId} <-- get user + * + * 3. /users <-- get all users + * + * 4. /user/{loginId}/roles <-- get roles for user + */ + + if (requestUri.endsWith("/sessionTimeOuts")) { + responseJson = getSessionTimeOuts(); + if (responseJson != null && responseJson.length() > 0) { + if (logger.isDebugEnabled()) + logger.debug("doGet: got session timeouts"); + response.setStatus(HttpServletResponse.SC_OK); + } else { + String msg = "Failed to get session time outs"; + logger.error("doGet: " + msg); + responseJson = buildJsonResponse(false, msg); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } else + // Example: /users <-- get all users + if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/users")) { + try { + List users = getUsers(); + responseJson = mapper.writeValueAsString(users); + if (logger.isDebugEnabled()) + logger.debug("doGet: getUsers: " + responseJson); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doGet: getUsers: caught exception", ex); + } + } else + // Example: /roles <-- get all roles + if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/roles")) { + try { + List roles = getAvailableRoles(); + responseJson = mapper.writeValueAsString(roles); + if (logger.isDebugEnabled()) + logger.debug("doGet: getAvailableRoles: " + responseJson); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doGet: getAvailableRoles: caught exception", ex); + } + } else + // Example: /user/fi241c <-- get user fi241c + if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !requestUri.endsWith("/roles")) { + String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1); + try { + EcompUser user = getUser(loginId); + responseJson = mapper.writeValueAsString(user); + if (logger.isDebugEnabled()) + logger.debug("doGet: getUser: " + responseJson); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doGet: getUser: caught exception", ex); + } + } + // Example: /user/fi241c/roles <-- get roles for user fi241c + else if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) { + String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1, + requestUri.lastIndexOf('/')); + try { + List roles = getUserRoles(loginId); + responseJson = mapper.writeValueAsString(roles); + if (logger.isDebugEnabled()) + logger.debug("doGet: getUserRoles: " + responseJson); + } catch (Exception ex) { + responseJson = buildJsonResponse(ex); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.error("doGet: getUserRoles: caught exception", ex); + } + } else { + logger.warn("doGet: no match found for request"); + responseJson = buildJsonResponse(false, "No match for request"); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + } catch (Exception ex) { + logger.error("doGet: Failed to process request", ex); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + responseJson = buildJsonResponse(ex); + } + writeAndFlush(response, contentTypeAppJson, responseJson); + } + + public String getSessionTimeOuts() throws Exception { + return PortalTimeoutHandler.gatherSessionExtensions(); + } + + public boolean timeoutSession(String portalJSessionId) throws Exception { + return PortalTimeoutHandler.invalidateSession(portalJSessionId); + } + + public boolean updateSessionTimeOuts(String sessionMap) throws Exception { + return PortalTimeoutHandler.updateSessionExtensions(sessionMap); + } + + @Override + public void pushUser(EcompUser user) throws PortalAPIException { + portalRestApiServiceImpl.pushUser(user); + } + + @Override + public void editUser(String loginId, EcompUser user) throws PortalAPIException { + portalRestApiServiceImpl.editUser(loginId, user); + } + + @Override + public EcompUser getUser(String loginId) throws PortalAPIException { + return portalRestApiServiceImpl.getUser(loginId); + } + + @Override + public List getUsers() throws PortalAPIException { + return portalRestApiServiceImpl.getUsers(); + } + + @Override + public List getAvailableRoles() throws PortalAPIException { + return portalRestApiServiceImpl.getAvailableRoles(); + } + + @Override + public void pushUserRole(String loginId, List roles) throws PortalAPIException { + portalRestApiServiceImpl.pushUserRole(loginId, roles); + } + + @Override + public List getUserRoles(String loginId) throws PortalAPIException { + return portalRestApiServiceImpl.getUserRoles(loginId); + } + + @Override + public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException { + return portalRestApiServiceImpl.isAppAuthenticated(request); + } + + /** + * Sets the content type and writes the response. + * + * @param response + * @param contentType + * @param responseBody + * @throws IOException + */ + private void writeAndFlush(HttpServletResponse response, String contentType, String responseBody) + throws IOException { + response.setContentType(contentType); + PrintWriter out = response.getWriter(); + out.print(responseBody); + out.flush(); + } + + /** + * Reads the request body and closes the input stream. + * + * @param request + * @return String read from the request, the empty string if nothing is + * read. + * @throws IOException + */ + private static String readRequestBody(HttpServletRequest request) throws IOException { + + String body = null; + StringBuilder stringBuilder = new StringBuilder(); + BufferedReader bufferedReader = null; + try { + InputStream inputStream = request.getInputStream(); + if (inputStream != null) { + bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + char[] charBuffer = new char[1024]; + int bytesRead = -1; + while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { + stringBuilder.append(charBuffer, 0, bytesRead); + } + } else { + stringBuilder.append(""); + } + } finally { + if (bufferedReader != null) { + try { + bufferedReader.close(); + } catch (IOException ex) { + throw ex; + } + } + } + body = stringBuilder.toString(); + return body; + } + + /** + * Builds JSON object with status + message response body. + * + * @param success + * True to indicate success, false to signal failure. + * @param msg + * Message to include in the response object; ignored if null. + * @return + * + *
        +	 * { "status" : "ok" (or "error"), "message": "some explanation" }
        +	 *         
        + */ + private String buildJsonResponse(boolean success, String msg) { + PortalAPIResponse response = new PortalAPIResponse(success, msg); + String json = null; + try { + json = mapper.writeValueAsString(response); + } catch (JsonProcessingException ex) { + // Truly should never, ever happen + json = "{ \"status\": \"error\",\"message\":\"" + ex.toString() + "\" }"; + } + return json; + } + + /** + * Builds JSON object with status of error and message containing stack + * trace for the specified throwable. + * + * @param t + * Throwable with stack trace to use as message + * + * @return + * + *
        +	 * { "status" : "error", "message": "some-big-stacktrace" }
        +	 *         
        + */ + private String buildJsonResponse(Throwable t) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + t.printStackTrace(pw); + return buildJsonResponse(false, sw.toString()); + } + + @Override + public String getUserId(HttpServletRequest request) throws PortalAPIException { + return portalRestApiServiceImpl.getUserId(request); + } + + public static IPortalRestAPIService getPortalRestApiServiceImpl() { + return portalRestApiServiceImpl; + } + + public static void setPortalRestApiServiceImpl(IPortalRestAPIService portalRestApiServiceImpl) { + PortalRestAPIProxy.portalRestApiServiceImpl = portalRestApiServiceImpl; + } + +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunicationService.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunicationService.java new file mode 100644 index 00000000..be3a7d54 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunicationService.java @@ -0,0 +1,161 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class SessionCommunicationService { + + protected static final Log logger = LogFactory.getLog(SessionCommunicationService.class); + + /** + * Calls the ECOMP Portal to retrieve the session slot check interval. + * + * @param ecompRestURL + * @param userName + * application user name used for authentication at Portal + * @param password + * application password used for authentication at Portal + * @param uebKey + * application UEB key (basically application ID) used for + * authentication at Portal + * @return Content read from the remote REST endpoint + */ + public static String getSessionSlotCheckInterval(String ecompRestURL, String userName, String password, + String uebKey) { + try { + String url = ecompRestURL + "/getSessionSlotCheckInterval"; + + URL obj = new URL(url); + + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // optional default is GET + con.setRequestMethod("GET"); + con.setConnectTimeout(3000); + con.setReadTimeout(8000); + // add request header + con.setRequestProperty("username", userName); + con.setRequestProperty("password", password); + con.setRequestProperty("uebkey", uebKey); + + int responseCode = con.getResponseCode(); + if (logger.isDebugEnabled()) { + logger.debug("getSessionSlotCheckInterval: Sending 'GET' request to URL : " + url); + logger.debug("getSessionSlotCheckInterval: Response Code : " + responseCode); + } + + StringBuffer response = new StringBuffer(); + + BufferedReader in = null; + try { + in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); + String inputLine; + while ((inputLine = in.readLine()) != null) + response.append(inputLine); + } finally { + in.close(); + } + return response.toString(); + } catch (Exception e) { + logger.error("getSessionSlotCheckInterval: failed to fetch the session slot check", e); + return null; + } + + } + + /** + * Calls the ECOMP Portal to request an extension of the current session. + * + * @param ecompRestURL + * @param userName + * application user name used for authentication at Portal + * @param password + * application password used for authentication at Portal + * @param uebKey + * application UEB key (basically application ID) used for + * authentication at Portal + * @param sessionTimeoutMap + * @return Content read from the remote REST endpoint + * @throws Exception + */ + public static String requestPortalSessionTimeoutExtension(String ecompRestURL, String userName, String password, + String uebKey, String sessionTimeoutMap) throws Exception { + + try { + + String url = ecompRestURL + "/extendSessionTimeOuts"; + // String decreptedPwd = + // app.appPassword;//CipherUtil.decrypt(encriptedPwdDB, + // SystemProperties.getProperty(SystemProperties.SECRET_KEY)); + + URL obj = new URL(url); + + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + con.setRequestMethod("POST"); + con.setConnectTimeout(3000); + con.setReadTimeout(15000); + + // add request header + con.setRequestProperty("username", userName); + con.setRequestProperty("password", password); + con.setRequestProperty("uebkey", uebKey); + con.setRequestProperty("sessionMap", sessionTimeoutMap); + con.setDoInput(true); + con.setDoOutput(true); + con.getOutputStream().write(sessionTimeoutMap.getBytes()); + con.getOutputStream().flush(); + con.getOutputStream().close(); + + // con.set + + int responseCode = con.getResponseCode(); + if (logger.isDebugEnabled()) { + logger.debug("requestPortalSessionTimeoutExtension: Sending 'GET' request to URL : " + url); + logger.debug("requestPortalSessionTimeoutExtension: Response Code : " + responseCode); + } + + StringBuffer response = new StringBuffer(); + BufferedReader in = null; + try { + in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + } finally { + in.close(); + } + return response.toString(); + } catch (Exception e) { + logger.error("requestPortalSessionTimeoutExtension: failed to request Portal to extend time out ", e); + return null; + } + + } + +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/exception/PortalAPIException.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/exception/PortalAPIException.java new file mode 100644 index 00000000..ea9b1c66 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/exception/PortalAPIException.java @@ -0,0 +1,46 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.exception; + +public class PortalAPIException extends Exception{ + + private static final long serialVersionUID = 4854048794984375707L; + + public PortalAPIException() { + super(); + } + + public PortalAPIException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public PortalAPIException(String message, Throwable cause) { + super(message, cause); + } + + public PortalAPIException(String message) { + super(message); + } + + public PortalAPIException(Throwable cause) { + super(cause); + } + +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/PortalTimeoutBindingListener.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/PortalTimeoutBindingListener.java new file mode 100644 index 00000000..4a6b43bc --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/PortalTimeoutBindingListener.java @@ -0,0 +1,53 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.listener; + +import java.io.Serializable; + +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; + +public class PortalTimeoutBindingListener implements HttpSessionBindingListener, Serializable { + + private final Log logger = LogFactory.getLog(getClass()); + + private static final long serialVersionUID = 1L; + + @Override + public void valueBound(HttpSessionBindingEvent event) { + final HttpSession session = event.getSession(); + PortalTimeoutHandler.sessionMap.put((String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID), + session); + } + + @Override + public void valueUnbound(HttpSessionBindingEvent event) { + final HttpSession session = event.getSession(); + String portalJSessionId = (String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); + logger.debug(portalJSessionId + " getting removed"); + PortalTimeoutHandler.sessionMap.remove(portalJSessionId); + } + +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/PortalTimeoutHandler.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/PortalTimeoutHandler.java new file mode 100644 index 00000000..90a9121c --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/PortalTimeoutHandler.java @@ -0,0 +1,420 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.listener; + +import java.util.Calendar; +import java.util.Hashtable; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.crossapi.SessionCommunicationService; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.restful.domain.PortalTimeoutVO; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Invoked by listeners (UserContextListener and UserSessionListener) to track + * user sessions. + */ +public class PortalTimeoutHandler { + + protected static final SessionCommInf sessionComm = new SessionComm(); + + public interface SessionCommInf { + public Integer fetchSessionSlotCheckInterval(String... params) throws Exception; + + public void extendSessionTimeOuts(String... sessionMap) throws Exception; + } + + public static class SessionComm implements SessionCommInf { + public Integer fetchSessionSlotCheckInterval(String... params) throws Exception { + + String ecompRestURL = params[0]; + String userName = params[1]; + String pwd = params[2]; + String uebKey = params[3]; + + String sessionSlot = SessionCommunicationService.getSessionSlotCheckInterval(ecompRestURL, userName, pwd, + uebKey); + if (sessionSlot == null) + return null; + return Integer.parseInt(sessionSlot); + } + + public void extendSessionTimeOuts(String... params) throws Exception { + + String ecompRestURL = params[0]; + String userName = params[1]; + String pwd = params[2]; + String uebKey = params[3]; + String sessionTimeoutMap = params[4]; + + SessionCommunicationService.requestPortalSessionTimeoutExtension(ecompRestURL, userName, pwd, uebKey, + sessionTimeoutMap); + } + } + + public static final Map sessionMap = new Hashtable(); + public static final Integer repeatInterval = 15 * 60; // 15 minutes + protected static final Log logger = LogFactory.getLog(PortalTimeoutHandler.class); + static ObjectMapper mapper = new ObjectMapper(); + private static PortalTimeoutHandler timeoutHandler; + + public static PortalTimeoutHandler getInstance() { + if (timeoutHandler == null) + timeoutHandler = new PortalTimeoutHandler(); + + return timeoutHandler; + } + + /** + * TODO: remove static + * + * @param portalJSessionId + * @param jSessionId + * @param session + */ + public static void sessionCreated(String portalJSessionId, String jSessionId, HttpSession session) { + + storeMaxInactiveTime(session); + + // this key is a combination of portal jsession id and app session id + String jSessionKey = jSessionKey(jSessionId, portalJSessionId); + Object jSessionKeySessionVal = session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); + + // do not reset the attributes if the same values have already been set + // because that will cause PortalTimeoutBindingListener to unbound the + // value from map + if (jSessionKeySessionVal != null && jSessionKeySessionVal.equals(jSessionKey)) { + logger.debug(" Session Values already exist in te map for sessionKey " + jSessionKey); + return; + } + + session.setAttribute(PortalApiConstants.PORTAL_JSESSION_ID, jSessionKey); + + // session binding listener will add this value to the static map + // and with session replication the listener will fire in all tomcat + // instances + session.setAttribute(PortalApiConstants.PORTAL_JSESSION_BIND, new PortalTimeoutBindingListener()); + // sessionMap.put((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID), + // session); + + } + + /** + * TODO: remove static + * + * @param session + */ + protected static void storeMaxInactiveTime(HttpSession session) { + if (session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME) == null) + session.setAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME, session.getMaxInactiveInterval()); + } + + /** + * TODO: remove static + * + * @param session + */ + public static void sessionDestroyed(HttpSession session) { + try { + logger.info(" Session getting destroyed - id: " + session.getId()); + session.removeAttribute(PortalApiConstants.PORTAL_JSESSION_BIND); + // sessionMap.remove((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID)); + } catch (Exception e) { + logger.error("sessionDestroyed failed", e); + } + } + + /*** + * TODO: remove static + * + * @param portalJSessionId + * @return true on success, false if the session cannot be found, etc. + */ + public static boolean invalidateSession(String portalJSessionId) { + boolean result = false; + logger.debug("Session Management: request from Portal to invalidate the session: " + portalJSessionId); + for (String jSessionKey : sessionMap.keySet()) { + try { + HttpSession session = sessionMap.get(jSessionKey); + if (portalJSessionId(jSessionKey).equals(portalJSessionId)) { + session.invalidate(); + result = true; + } + } catch (Exception e) { + logger.error("invalidateSession failed", e); + } + } + return result; + } + + /** + * TODO: remove static + * + * @return json version of the timeout map: session ID -> timeout object + */ + public static String gatherSessionExtensions() { + logger.debug("Session Management: gatherSessionExtensions"); + + Map sessionTimeoutMap = new Hashtable(); + String jsonMap = ""; + + for (String jSessionKey : sessionMap.keySet()) { + + try { + // get the expirytime in seconds + HttpSession session = sessionMap.get(jSessionKey); + + Long lastAccessedTimeMilliSec = session.getLastAccessedTime(); + Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L; + // Long currentTimeMilliSec = + // Calendar.getInstance().getTimeInMillis() ; + // (maxIntervalMilliSec - (currentTimeMilliSec - + // lastAccessedTimeMilliSec) + ; + Calendar instance = Calendar.getInstance(); + instance.setTimeInMillis(session.getLastAccessedTime()); + logger.debug("Session Management: Last Accessed time for " + jSessionKey + ": " + instance.getTime()); + + Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; + + sessionTimeoutMap.put(portalJSessionId(jSessionKey), + getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec)); + logger.debug("Session Management: putting session in map " + jSessionKey + " sessionTimoutSec" + + (int) (sessionTimOutMilliSec / 1000)); + + jsonMap = mapper.writeValueAsString(sessionTimeoutMap); + + } catch (Exception e) { + logger.error("gatherSessionExtensions failed", e); + } + + } + + return jsonMap; + + } + + /** + * TODO: remove static + * + * @param sessionTimeoutMapStr + * @return true on success, false otherwise + * @throws Exception + */ + public static boolean updateSessionExtensions(String sessionTimeoutMapStr) throws Exception { + logger.debug("Session Management: updateSessionExtensions"); + // Map sessionTimeoutMap = + // mapper.readValue(sessionTimeoutMapStr, Map.class); + Map sessionTimeoutMap = null; + + try { + TypeReference> typeRef = new TypeReference>() { + }; + sessionTimeoutMap = mapper.readValue(sessionTimeoutMapStr, typeRef); + } catch (Exception e) { + logger.error("updateSessionExtensions failed to parse the sessionTimeoutMap from portal", e); + return false; + } + + boolean result = true; + for (String jPortalSessionId : sessionTimeoutMap.keySet()) { + try { + PortalTimeoutVO extendedTimeoutVO = mapper.readValue( + mapper.writeValueAsString(sessionTimeoutMap.get(jPortalSessionId)), PortalTimeoutVO.class); + HttpSession session = sessionMap.get(jSessionKey(extendedTimeoutVO.getjSessionId(), jPortalSessionId)); + + if (session == null) { + continue; + } + + Long lastAccessedTimeMilliSec = session.getLastAccessedTime(); + Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L; + Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; + + Long maxTimeoutTimeMilliSec = extendedTimeoutVO.getSessionTimOutMilliSec(); + if (maxTimeoutTimeMilliSec > sessionTimOutMilliSec) { + session.setMaxInactiveInterval((int) (maxTimeoutTimeMilliSec - lastAccessedTimeMilliSec) / 1000); + logger.debug("Session Management: extended session for :" + session.getId() + " to :" + + (int) (maxTimeoutTimeMilliSec / 1000)); + // System.out.println("!!!!!!!!!extended session for :" + + // session.getId() + " to :" + + // (int)(maxTimeoutTimeMilliSec/1000)); + } + } catch (Exception e) { + logger.error("updateSessionExtensions failed to update session timeouts", e); + // Signal a problem if any one of them fails + result = false; + } + + } + return result; + } + + /** + * TODO: Remove static + * + * @param request + * @param userName + * @param pwd + * @param ecompRestURL + * @param _sessionComm + */ + public static void handleSessionUpdatesNative(HttpServletRequest request, String userName, String pwd, + String uebKey, String ecompRestURL, SessionCommInf _sessionComm) { + + if (_sessionComm == null) { + _sessionComm = sessionComm; + } + try { + synchronizeSessionForLastMinuteRequests(request, ecompRestURL, userName, pwd, uebKey, _sessionComm); + } catch (Exception e) { + logger.error("handleSesionUpdatesNative failed", e); + } + resetSessionMaxIdleTimeOut(request); + } + + /** + * TODO: remove Static + * + * @param request + * @param ecompRestURL + * @param userName + * @param pwd + * @param _sessionComm + * @throws JsonProcessingException + * @throws Exception + */ + public static void synchronizeSessionForLastMinuteRequests(HttpServletRequest request, String ecompRestURL, + String userName, String pwd, String uebKey, SessionCommInf _sessionComm) + throws JsonProcessingException, Exception { + + HttpSession session = request.getSession(false); + if (session == null) + return; + + Object portalSessionSlotCheckObj = session.getServletContext() + .getAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK); + Integer portalSessionSlotCheckinMilliSec = 5 * 60 * 1000; // (5 minutes) + if (portalSessionSlotCheckObj != null) { + portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString()); + } else { + portalSessionSlotCheckObj = _sessionComm + .fetchSessionSlotCheckInterval(new String[] { ecompRestURL, userName, pwd, uebKey }); + logger.debug("Fetching Portal Session Slot Object: " + portalSessionSlotCheckObj); + if (portalSessionSlotCheckObj != null) { + portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString()); + session.getServletContext().setAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK, + portalSessionSlotCheckinMilliSec); + } + } + + Object previousToLastAccessTimeObj = session.getAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME); + final long lastAccessedTimeMilliSec = session.getLastAccessedTime(); + if (previousToLastAccessTimeObj == null) { + previousToLastAccessTimeObj = lastAccessedTimeMilliSec; + session.setAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME, previousToLastAccessTimeObj); + } else { + Long previousToLastAccessTime = (Long) previousToLastAccessTimeObj; + final int maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000; + if (maxIntervalMilliSec + - (lastAccessedTimeMilliSec - previousToLastAccessTime) <= portalSessionSlotCheckinMilliSec) { + + String jSessionKey = (String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); + Map sessionTimeoutMap = new Hashtable(); + Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; + + sessionTimeoutMap.put(PortalTimeoutHandler.portalJSessionId(jSessionKey), + PortalTimeoutHandler.getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec)); + String jsonMap = mapper.writeValueAsString(sessionTimeoutMap); + logger.debug("Extension requested for all the Apps and Portal; JessionKey: " + jSessionKey + + "; SessionMap: " + sessionTimeoutMap); + _sessionComm.extendSessionTimeOuts(new String[] { ecompRestURL, userName, pwd, uebKey, jsonMap }); + } + + } + } + + /** + * TODO: remove static + * + * @param request + */ + public static void resetSessionMaxIdleTimeOut(HttpServletRequest request) { + try { + HttpSession session = request.getSession(false); + if (session == null) + return; + final Object maxIdleAttribute = session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME); + if (maxIdleAttribute != null) { + session.setMaxInactiveInterval(Integer.parseInt(maxIdleAttribute.toString())); + } + } catch (Exception e) { + logger.error("resetSessionMaxIdleTimeout failed", e); + } + + } + + /** + * + * @param jSessionKey + * @param sessionTimOutMilliSec + * @return + */ + private static PortalTimeoutVO getSingleSessionTimeoutObj(String jSessionKey, Long sessionTimOutMilliSec) { + return new PortalTimeoutVO(jSessionId(jSessionKey), sessionTimOutMilliSec); + } + + /** + * + * @param jSessionId + * @param portalJSessionId + * @return + */ + private static String jSessionKey(String jSessionId, String portalJSessionId) { + return portalJSessionId + "-" + jSessionId; + } + + /** + * + * @param jSessionKey + * @return + */ + private static String portalJSessionId(String jSessionKey) { + return jSessionKey.split("-")[0]; + } + + /** + * + * @param jSessionKey + * @return + */ + private static String jSessionId(String jSessionKey) { + return jSessionKey.split("-")[1]; + } + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/UserContextListener.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/UserContextListener.java new file mode 100644 index 00000000..d4793d27 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/UserContextListener.java @@ -0,0 +1,54 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.listener; + +import java.util.HashMap; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; +import javax.servlet.http.HttpSession; + +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; + +@WebListener +public class UserContextListener implements ServletContextListener{ + + public void contextInitialized(ServletContextEvent event){ + ServletContext context = event.getServletContext(); + // + // instanciate a map to store references to all the active + // sessions and bind it to context scope. + // + HashMap activeUsers = new HashMap(); + context.setAttribute(PortalApiConstants.ACTIVE_USERS_NAME, activeUsers); + } + + /** + * Needed for the ServletContextListener interface. + */ + public void contextDestroyed(ServletContextEvent event){ + // To overcome the problem with losing the session references + // during server restarts, put code here to serialize the + // activeUsers HashMap. Then put code in the contextInitialized + // method that reads and reloads it if it exists... + } +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/UserSessionListener.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/UserSessionListener.java new file mode 100644 index 00000000..88934282 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/listener/UserSessionListener.java @@ -0,0 +1,85 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.listener; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.annotation.WebListener; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; + +/** + * Listens to session-create and session-destroy events. + */ +@WebListener +public class UserSessionListener implements HttpSessionListener { + + private Log logger = LogFactory.getLog(getClass()); + + public static Map activeSessions = new Hashtable(); + + public void init(ServletConfig config) { + } + + /** + * Adds sessions to the context-scoped HashMap when they begin. + */ + public void sessionCreated(HttpSessionEvent event) { + HttpSession session = event.getSession(); + ServletContext context = session.getServletContext(); + @SuppressWarnings("unchecked") + HashMap activeUsers = (HashMap) context + .getAttribute(PortalApiConstants.ACTIVE_USERS_NAME); + if (activeUsers != null) + activeUsers.put(session.getId(), session); + context.setAttribute(PortalApiConstants.ACTIVE_USERS_NAME, activeUsers); + activeSessions.put(session.getId(), session); + session.getServletContext().setAttribute(PortalApiConstants.MAX_IDLE_TIME, session.getMaxInactiveInterval()); + } + + /** + * Removes sessions from the context-scoped HashMap when they expire or are + * invalidated. + */ + public void sessionDestroyed(HttpSessionEvent event) { + try { + HttpSession session = event.getSession(); + ServletContext context = session.getServletContext(); + @SuppressWarnings("unchecked") + HashMap activeUsers = (HashMap) context + .getAttribute(PortalApiConstants.ACTIVE_USERS_NAME); + if (activeUsers != null) + activeUsers.remove(session.getId()); + activeSessions.remove(session.getId()); + PortalTimeoutHandler.sessionDestroyed(session); + } catch (Exception e) { + logger.warn(e.getMessage(), e); + } + } +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java new file mode 100644 index 00000000..b4ca4755 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java @@ -0,0 +1,51 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.rest; + +/** + * Provides a convenience method for fetching the favorites for a user from the + * ECOMP Portal. + */ +public class FavoritesClient { + + /** + * Fetches the favorites data from portal + * + * @param userId + * userId value that it should be using to fetch the + * data + * @param appName + * Application name for logging etc. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction; if null, a new one is generated. + * @param appUserName + * REST API user-name + * @param appPassword + * REST API decrypted password + * @return JSON with favorites + * @throws Exception + * on any failure + */ + public static String getFavorites(String userId, String appName, String requestId, String appUserName, + String appPassword) throws Exception { + return RestWebServiceClient.getInstance().getPortalContent("/getFavorites", userId, appName, requestId, appUserName, + appPassword); + } +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java new file mode 100644 index 00000000..a3a320eb --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java @@ -0,0 +1,54 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.rest; + +/** + * Provides a convenience method for fetching the functional menu for a user + * from the ECOMP Portal via UEB. + */ +public class FunctionalMenuClient { + + /** + * Fetches the functional menu data from the configured ECOMP Portal + * instance. + * + * @param userId + * userId for the user to whom the menu will be shown + * @param appName + * Application name for logging etc. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction; if + * null, a new one is generated. + * @param appUserName + * REST API user name, used by Portal to authenticate the request + * @param appPassword + * REST API password (in the clear, not encrypted), used by + * Portal to authenticate the request + * @return JSON with functional menu + * @throws Exception + * on any failure + */ + public static String getFunctionalMenu(String userId, String appName, String requestId, String appUserName, + String appPassword) throws Exception { + return RestWebServiceClient.getInstance().getPortalContent("/functionalMenuItemsForUser", userId, appName, + requestId, appUserName, appPassword); + } + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java new file mode 100644 index 00000000..f01590d4 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java @@ -0,0 +1,342 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.rest; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.UUID; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; + +/** + * Simple REST client for GET-ing content from and POST-ing content to the + * Portal application. + */ +public class RestWebServiceClient { + + private final Log logger = LogFactory.getLog(RestWebServiceClient.class); + + /** + * Singleton instance + */ + private static RestWebServiceClient instance = null; + + /** + * Constructor is private. Clients should obtain an instance via + * getInstance(). + */ + private RestWebServiceClient() { + } + + /** + * Gets the static instance of RestWebServiceClient; creates it if + * necessary. Synchronized to be thread safe. + * + * @return Static instance of RestWebServiceClient. + */ + public static synchronized RestWebServiceClient getInstance() { + if (instance == null) + instance = new RestWebServiceClient(); + return instance; + } + + /** + * Convenience method that fetches the URL for the Portal REST API endpoint + * and the application UEB key, then calls + * {@link #get(String, String, String, String, String, String, String)} to + * access the Portal's REST endpoint. + * + * @param restPath + * Partial path of the endpoint; e.g., "/specialRestService" + * @param userId + * userId for the user originating the request + * @param appName + * Application Name for logging. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction. + * @param appUserName + * REST API user name for Portal to authenticate the request + * @param appPassword + * REST API password (in the clear, not encrypted) for Portal to + * authenticate the request + * @return Content from REST endpoint + * @throws Exception + * on any failure + */ + public String getPortalContent(String restPath, String userId, String appName, String requestId, String appUserName, + String appPassword) throws Exception { + String restURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL); + if (restURL == null) { + // should never happen + String msg = "getPortalContent: failed to get property " + PortalApiConstants.ECOMP_REST_URL; + logger.error(msg); + throw new Exception(msg); + } + String appUebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + if (appUebKey == null) { + // should never happen + String msg = "getPortalContent: failed to get property " + PortalApiConstants.UEB_APP_KEY; + logger.error(msg); + throw new Exception(msg); + } + final String restEndpointUrl = restURL + restPath; + return get(restEndpointUrl, userId, appName, requestId, appUebKey, appUserName, appPassword); + + } + + /** + * Makes a call to a Portal REST API using the specified URL and parameters. + * + * @param url + * Complete URL of the REST endpoint. + * @param loginId + * User that it should be fetching the data + * @param appName + * Application name for logging; if null or empty, defaulted to + * Unknown. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction; if + * null or empty, one is generated. + * @param appUebKey + * Unique key for the application, used by Portal to authenticate + * the request + * @param appUserName + * REST API user name, used by Portal to authenticate the request + * @param appPassword + * REST API password, used by Portal to authenticate the request + * @return Content from REST endpoint + * @throws Exception + * On any failure; e.g., unknown host. + */ + public String get(String url, String loginId, String appName, String requestId, String appUebKey, + String appUserName, String appPassword) throws Exception { + + logger.debug("RestWebServiceClient.get (" + url + ") operation is started."); + + if (appName == null || appName.trim().length() == 0) + appName = "Unknown"; + if (requestId == null || requestId.trim().length() == 0) + requestId = UUID.randomUUID().toString(); + + URL obj = new URL(url); + // Create the connection object + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("GET"); + con.setConnectTimeout(3000); + con.setReadTimeout(8000); + + // add request header + con.setRequestProperty("uebkey", appUebKey); + con.setRequestProperty("username", appUserName); + con.setRequestProperty("password", appPassword); + con.setRequestProperty("LoginId", loginId); + con.setRequestProperty("user-agent", appName); + con.setRequestProperty("X-ECOMP-RequestID", requestId); + + int responseCode = con.getResponseCode(); + logger.debug("get: received response code '" + responseCode + "' while getting the '" + url + "' for user: " + + loginId); + + StringBuffer sb = new StringBuffer(); + BufferedReader in = null; + try { + in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); + String inputLine = null; + while ((inputLine = in.readLine()) != null) + sb.append(inputLine); + } finally { + try { + if (in != null) + in.close(); + } catch (IOException ex) { + logger.error("get: failed to close reader", ex); + } + } + + final String response = sb.toString(); + if (logger.isDebugEnabled()) + logger.debug("get: url " + url + " yielded " + response); + return response; + } + + /** + * Convenience method that fetches the URL for the Portal REST API endpoint + * and the application UEB key, then calls + * {@link #post(String, String, String, String, String, String, String, String, String)} + * to access the Portal's REST endpoint. + * + * @param restPath + * Partial path of the endpoint; e.g., "/specialRestService" + * @param userId + * ID for the user originating the request + * @param appName + * Application Name for logging. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction. + * @param appUserName + * REST API user name for Portal to authenticate the request; + * ignored if null + * @param appPassword + * REST API password (in the clear, not encrypted) for Portal to + * authenticate the request; ignored if null + * @param contentType + * content type for header + * @param content + * String to post + * @return Content from REST endpoint + * @throws Exception + * on any failure + */ + public String postPortalContent(String restPath, String userId, String appName, String requestId, + String appUserName, String appPassword, String contentType, String content) throws Exception { + String restURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL); + if (restURL == null) { + // should never happen + String msg = "getPortalContent: failed to get property " + PortalApiConstants.ECOMP_REST_URL; + logger.error(msg); + throw new Exception(msg); + } + String appUebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); + if (appUebKey == null) { + // should never happen + String msg = "getPortalContent: failed to get property " + PortalApiConstants.UEB_APP_KEY; + logger.error(msg); + throw new Exception(msg); + } + final String separator = restURL.endsWith("/") || restPath.startsWith("/") ? "" : "/"; + final String restEndpointUrl = restURL + separator + restPath; + return post(restEndpointUrl, userId, appName, requestId, appUebKey, appUserName, appPassword, contentType, + content); + } + + /** + * Makes a POST call to a Portal REST API using the specified URL and + * parameters. + * + * @param url + * Complete URL of the REST endpoint. + * @param loginId + * User who is fetching the data + * @param appName + * Application name for logging; if null or empty, defaulted to + * Unknown. + * @param requestId + * 128-bit UUID value to uniquely identify the transaction; if + * null or empty, one is generated. + * @param appUebKey + * Unique key for the application, used by Portal to authenticate + * the request + * @param appUserName + * REST API user name used by Portal to authenticate the request; + * ignored if null + * @param appPassword + * REST API password used by Portal to authenticate the request; + * ignored if null + * @param contentType + * MIME header + * @param content + * Content to POST + * @return Any content read from the endpoint + * @throws Exception + * On any error + */ + public String post(String url, String loginId, String appName, String requestId, String appUebKey, + String appUserName, String appPassword, String contentType, String content) throws Exception { + + if (logger.isDebugEnabled()) + logger.debug("RestWebServiceClient.post to URL " + url); + if (appName == null || appName.trim().length() == 0) + appName = "Unknown"; + if (requestId == null || requestId.trim().length() == 0) + requestId = UUID.randomUUID().toString(); + + URL obj = new URL(url); + // Create the connection object + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("POST"); + con.setConnectTimeout(3000); + con.setReadTimeout(15000); + + // add request header + con.setRequestProperty("uebkey", appUebKey); + if (appUserName != null) + con.setRequestProperty("username", appUserName); + if (appPassword != null) + con.setRequestProperty("password", appPassword); + con.setRequestProperty("LoginId", loginId); + con.setRequestProperty("user-agent", appName); + con.setRequestProperty("X-ECOMP-RequestID", requestId); + con.setRequestProperty("Content-Type", contentType); + + con.setDoInput(true); + con.setDoOutput(true); + con.getOutputStream().write(content.getBytes()); + con.getOutputStream().flush(); + con.getOutputStream().close(); + + int responseCode = con.getResponseCode(); + logger.debug("Response Code : " + responseCode); + + StringBuffer sb = new StringBuffer(); + InputStreamReader in = null; + char[] buf = new char[8196]; + int bytes; + try { + in = new InputStreamReader(con.getInputStream(), "UTF-8"); + while ((bytes = in.read(buf)) > 0) + sb.append(new String(buf, 0, bytes)); + } finally { + try { + if (in != null) + in.close(); + } catch (IOException ex) { + logger.warn("get: failed to close reader", ex); + } + } + + return sb.toString(); + } + + /** + * Basic unit test for the client to call Portal app on localhost. + * + * @param args + * Ignored + * @throws Exception + */ + public static void main(String[] args) throws Exception { + RestWebServiceClient client = RestWebServiceClient.getInstance(); + final String getUrl = "http://www.ecomp.openecomp.org:8080/ecompportal/auxapi/analytics"; + String get = client.get(getUrl, "userId", "appName", null, "appUebKey", "appUserName", "appPassword"); + System.out.println("Get result:\n" + get); + final String postUrl = "http://www.ecomp.openecomp.org:8080/ecompportal/auxapi/storeAnalytics"; + final String content = " { " + " \"action\" : \"test1\", " + " \"page\" : \"test2\", " + + " \"function\" : \"test3\", " + " \"userid\" : \"ab1234\" " + "}"; + String post = client.post(postUrl, "userId", "appName", null, "appUebKey", "appUserName", "appPassword", + "application/json", content); + System.out.println("Post result:\n" + post); + } +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/CipherUtil.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/CipherUtil.java new file mode 100644 index 00000000..e376cd4c --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/CipherUtil.java @@ -0,0 +1,125 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.util; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Base64; + +public class CipherUtil { + + private final static String key = "AGLDdG4D04BKm2IxIWEr8o==!"; + + /** + * @param plainText + * @param secretKey + * @return encrypted version of plain text. + * @throws Exception + */ + public static String encrypt(String plainText, String secretKey) throws Exception{ + byte[] rawKey; + String encryptedString; + SecretKeySpec sKeySpec; + byte[] encryptText = plainText.getBytes("UTF-8"); + Cipher cipher; + rawKey = Base64.decodeBase64(secretKey); + sKeySpec = new SecretKeySpec(rawKey, "AES"); + cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, sKeySpec); + encryptedString = Base64.encodeBase64String(cipher.doFinal(encryptText)); + + return encryptedString; + } + + /** + * + * @param plainText + * @return Encrypted Text + * @throws Exception + */ + public static String encrypt(String plainText) throws Exception + { + return CipherUtil.encrypt(plainText,key); + } + + /** + * @param encryptedText + * @param secretKey + * @return plain text version of encrypted text + * @throws Exception + */ + public static String decrypt(String encryptedText, String secretKey) throws Exception { + Cipher cipher; + String encryptedString; + byte[] encryptText = null; + byte[] rawKey; + SecretKeySpec sKeySpec; + + rawKey = Base64.decodeBase64(secretKey); + sKeySpec = new SecretKeySpec(rawKey, "AES"); + encryptText = Base64.decodeBase64(encryptedText.getBytes("UTF-8")); + cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, sKeySpec); + encryptedString = new String(cipher.doFinal(encryptText)); + + return encryptedString; + } + + /** + * @param encryptedText + * @return Decrypted Text + * @throws Exception + */ + public static String decrypt(String encryptedText) throws Exception + { + return CipherUtil.decrypt(encryptedText,key); + } + + + public static void main(String[] args) throws Exception { + + String password = "Welcome123"; + String encrypted; + String decrypted; + + if (args.length != 2) { + System.out.println("Default password testing... "); + System.out.println("Plain password: " + password); + encrypted = encrypt(password); + System.out.println("Encrypted password: " + encrypted); + decrypted = decrypt(encrypted); + System.out.println("Decrypted password: " + decrypted); + } else { + String whatToDo = args[0]; + if (whatToDo.equalsIgnoreCase("d")) { + encrypted = args[1]; + System.out.println("Encrypted Text: " + encrypted); + decrypted = decrypt(encrypted); + System.out.println("Decrypted Text: " + decrypted); + } else { + decrypted = args[1]; + System.out.println("Plain Text: " + decrypted); + encrypted = encrypt(decrypted); + System.out.println("Encrypted Text" + encrypted); + } + } + } +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/PortalApiConstants.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/PortalApiConstants.java new file mode 100644 index 00000000..e706b7ec --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/PortalApiConstants.java @@ -0,0 +1,64 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.util; + +public interface PortalApiConstants { + public static final String API_PREFIX = "/api/v2"; + public static final String PORTAL_JSESSION_ID = "PORTAL_JSESSION_ID"; + public static final String PORTAL_JSESSION_BIND = "PORTAL_JSESSION_BIND"; + public static final String ACTIVE_USERS_NAME = "activeUsers"; + + /** Portal service cookie name */ + public static final String EP_SERVICE = "EPService"; + + public static final String GLOBAL_SESSION_MAX_IDLE_TIME = "global_session_max_idle_time"; + public static final String PORTAL_SESSION_SLOT_CHECK = "portal_session_slot_check"; + public static final String SESSION_PREVIOUS_ACCESS_TIME = "session_previous_access_time"; + public static final String MAX_IDLE_TIME = "max.idle.time"; + + // Names of keys in the portal.properties file + public static final String PORTAL_API_IMPL_CLASS = "portal.api.impl.class"; + public static final String ECOMP_REDIRECT_URL = "ecomp_redirect_url"; + public static final String ECOMP_REST_URL = "ecomp_rest_url"; + public static final String CSP_COOKIE_NAME = "csp_cookie_name"; + public static final String CSP_GATE_KEEPER_PROD_KEY = "csp_gate_keeper_prod_key"; + + // UEB related + public static final String UEB_URL_LIST = "ueb_url_list"; // In properties file + public static final String ECOMP_PORTAL_INBOX_NAME = "ecomp_portal_inbox_name"; + public static final String ECOMP_DEFAULT_MSG_ID = "0"; + public static final String ECOMP_GENERAL_UEB_PARTITION = "EPGeneralPartition"; + public static final String UEB_LISTENERS_ENABLE = "ueb_listeners_enable"; + public static final String UEB_APP_INBOUND_MAILBOX_NAME = "ueb_app_mailbox_name"; + public static final String UEB_APP_CONSUMER_GROUP_NAME = "ueb_app_consumer_group_name"; + // UebManager generates a consumer group name for special token {UUID} + public static final String UEB_APP_CONSUMER_GROUP_NAME_GENERATOR = "{UUID}"; + public static final String UEB_APP_KEY = "ueb_app_key"; + public static final String UEB_APP_SECRET = "ueb_app_secret"; + public static final String ECOMP_UEB_INVALID_MSG = "100: Invalid Message format."; + public static final String ECOMP_UEB_TIMEOUT_ERROR = "101: Timeout"; + public static final String ECOMP_UEB_UNKNOWN_PUBLISH_ERROR = "102: Unknown error during publish"; + public static final String ECOMP_UEB_UNKNOWN_CONSUME_ERROR = "103: Unknown error during consume"; + public static final String USE_REST_FOR_FUNCTIONAL_MENU = "use_rest_for_functional_menu"; + + //encrpt key + public static final String Decryption_Key = "decryption_key"; + +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/PortalApiProperties.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/PortalApiProperties.java new file mode 100644 index 00000000..93572ee9 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/PortalApiProperties.java @@ -0,0 +1,102 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.util; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Singleton Class representing portal properties. Searches the classpath for + * the file "portal.properties". + * + * To put the file "portal.properties" on the classpath, it can be in the same + * directory where the first package folder is - 'myClasses' folder in the + * following case as an example: + * + */ +public class PortalApiProperties { + + private static final Log logger = LogFactory.getLog(PortalApiProperties.class); + + private static Properties properties; + private static String propertyFileName = "portal.properties"; + + /** + * Constructor is private. + */ + private PortalApiProperties() { + } + + /** + * Gets the property value for the specified key. If a value is found, + * leading and trailing space is trimmed. + * + * @param property + * @return Value for the named property; null if the property file was not + * loaded or the key was not found. + */ + public static String getProperty(String property) { + if (properties == null) { + synchronized (propertyFileName) { + try { + if (!initialize()) { + logger.error("Failed to read property file " + propertyFileName); + return null; + } + } catch (IOException e) { + logger.error("Failed to read property file " + propertyFileName, e); + return null; + } + } + } + String value = properties.getProperty(property); + if (value != null) + value = value.trim(); + return value; + } + + /** + * Reads properties from a portal.properties file on the classpath. + * + * Clients do NOT need to call this method. Clients MAY call this method to + * test whether the properties file can be loaded successfully. + * + * @return True if properties were successfully loaded, else false. + * @throws IOException + */ + public static boolean initialize() throws IOException { + if (properties != null) + return true; + InputStream in = PortalApiProperties.class.getClassLoader().getResourceAsStream(propertyFileName); + if (in == null) + return false; + properties = new Properties(); + try { + properties.load(in); + } finally { + in.close(); + } + return true; + } +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/SSOFilter.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/SSOFilter.java new file mode 100644 index 00000000..1d8a9620 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/SSOFilter.java @@ -0,0 +1,75 @@ +/* ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.onboarding.util; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalRestAPIProxy; +import org.openecomp.portalsdk.core.onboarding.exception.PortalAPIException; + +public class SSOFilter implements Filter { + + private final Log logger = LogFactory.getLog(getClass()); + + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws java.io.IOException, ServletException { + + try { + if (PortalRestAPIProxy.getPortalRestApiServiceImpl().getUserId((HttpServletRequest) request) == null) { + String redirectURL = SSOUtil.getECOMPSSORedirectURL(((HttpServletRequest) request), + ((HttpServletResponse) response), + (((HttpServletRequest) request).getRequestURI() + .substring(((HttpServletRequest) request).getContextPath().length() + 1) + + (((HttpServletRequest) request).getQueryString() != null + ? ("?" + ((HttpServletRequest) request).getQueryString()) : ""))); + + ((HttpServletResponse) response).sendRedirect(redirectURL); + + } else { + // Pass request back down the filter chain + chain.doFilter(request, response); + + } + } catch (PortalAPIException e) { + logger.error("Issue calling getUserId method "); + throw new ServletException(e); + } + + } + + public void destroy() { + + } + + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/SSOUtil.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/SSOUtil.java new file mode 100644 index 00000000..67ac567d --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/onboarding/util/SSOUtil.java @@ -0,0 +1,45 @@ +package org.openecomp.portalsdk.core.onboarding.util; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class SSOUtil { + + private static final Log logger = LogFactory.getLog(SSOUtil.class); + + /** + * Constructs a path for this server, this app's context, etc. + * + * @param request + * @param response + * @param forwardPath + * @return + */ + public static String getECOMPSSORedirectURL(HttpServletRequest request, HttpServletResponse response, + String forwardPath) { + String appURL = (request.isSecure() ? "https://" : "http://") + request.getServerName() + ":" + + request.getServerPort() + request.getContextPath() + "/" + forwardPath; + String encodedAppURL = null; + try { + encodedAppURL = URLEncoder.encode(appURL, "UTF-8"); + } catch (UnsupportedEncodingException ex) { + logger.error("getECOMPSSORedirectURL: Failed to encode app URL " + + appURL); + } + String portalURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); + if (portalURL == null || portalURL.length() == 0) { + logger.error("getECOMPSSORedirectURL: Failed to get property " + + PortalApiConstants.ECOMP_REDIRECT_URL); + return null; + } + String redirectURL = portalURL + "?redirectUrl=" + encodedAppURL; + return redirectURL; + } + +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java new file mode 100644 index 00000000..28b74a86 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java @@ -0,0 +1,87 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.restful.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * This bean holds the information for a role in the role and user management + * REST API. + */ + +@JsonIgnoreProperties(ignoreUnknown = true) +public class EcompRole implements Comparable{ + + protected Long id; + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EcompRole other = (EcompRole) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + @Override + public String toString() { + String s = "@EcompRole[id: " + id + "; name: " + name + "]"; + return s; + } + + @Override + public int compareTo(EcompRole o) { + return this.id.compareTo(o.id); + } + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java new file mode 100644 index 00000000..dde16df8 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java @@ -0,0 +1,197 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.restful.domain; + +import java.util.Set; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * This bean holds the information for a user in the role and user management + * REST API. + */ + +@JsonIgnoreProperties(ignoreUnknown = true) +public class EcompUser implements Comparable{ + + private Long orgId; + private String managerId; + private String firstName; + private String middleInitial; + private String lastName; + private String phone; + private String email; + private String hrid; + private String orgUserId; + private String orgCode; + private String orgManagerUserId; + private String jobTitle; + private String loginId; + private boolean active; + + + private Set roles; + + public Long getOrgId() { + return orgId; + } + + public void setOrgId(Long orgId) { + this.orgId = orgId; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getMiddleInitial() { + return middleInitial; + } + + public void setMiddleInitial(String middleInitial) { + this.middleInitial = middleInitial; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getHrid() { + return hrid; + } + + public void setHrid(String hrid) { + this.hrid = hrid; + } + + public String getOrgUserId() { + return orgUserId; + } + + public void setOrgUserId(String orgUserId) { + this.orgUserId = orgUserId; + } + + public String getOrgCode() { + return orgCode; + } + + public void setOrgCode(String orgCode) { + this.orgCode = orgCode; + } + + public String getOrgManagerUserId() { + return orgManagerUserId; + } + + public void setOrgManagerUserId(String orgManagerUserId) { + this.orgManagerUserId = orgManagerUserId; + } + + public String getJobTitle() { + return jobTitle; + } + + public void setJobTitle(String jobTitle) { + this.jobTitle = jobTitle; + } + + public String getLoginId() { + return loginId; + } + + public void setLoginId(String loginId) { + this.loginId = loginId; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public Set getRoles() { + return roles; + } + + public void setRoles(Set roles) { + this.roles = roles; + } + + public String getManagerId() { + return managerId; + } + + public void setManagerId(String managerId) { + this.managerId = managerId; + } + + @Override + public String toString() { + String s = "@EcompUser[orgId: " + orgId // + + ", firstName: " + firstName // + + ", mi: " + middleInitial // + + ", lastName: " + lastName // + + ", phone: " + phone // + + ", email: " + email // + + ", hrid: " + hrid // + + ", orgUserId: " + orgUserId // + + ", orgCode: " + orgCode // + + ", orgManagerUserId: " + orgManagerUserId // + + ", jobTitle: " + jobTitle // + + ", loginId: " + loginId // + + ", active:" + active // + + "]"; + return s; + } + + @Override + public int compareTo(EcompUser o) { + return this.loginId.compareTo(o.loginId); + } + + +} diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/PortalTimeoutVO.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/PortalTimeoutVO.java new file mode 100644 index 00000000..a8e100e5 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/PortalTimeoutVO.java @@ -0,0 +1,63 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.restful.domain; + +public class PortalTimeoutVO implements Comparable{ + + private String jSessionId; + private Long sessionTimOutMilliSec; + + public PortalTimeoutVO(){ + + } + + public PortalTimeoutVO(String _jSessionId, Long _sessionTimOutMilliSec) { + setjSessionId(_jSessionId); + setSessionTimOutMilliSec(_sessionTimOutMilliSec); + + } + + public String getjSessionId() { + return jSessionId; + } + + public void setjSessionId(String jSessionId) { + this.jSessionId = jSessionId; + } + + public Long getSessionTimOutMilliSec() { + return sessionTimOutMilliSec; + } + + public void setSessionTimOutMilliSec(Long sessionTimOutMilliSec) { + this.sessionTimOutMilliSec = sessionTimOutMilliSec; + } + + @Override + public int compareTo(PortalTimeoutVO o) { + return sessionTimOutMilliSec.compareTo(o.sessionTimOutMilliSec); + } + + + + + + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java new file mode 100644 index 00000000..80ed4859 --- /dev/null +++ b/ecomp-sdk/epsdk-fw/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java @@ -0,0 +1,300 @@ +/*- + * ================================================================================ + * ECOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.core.restful.domain; + +/** + * Bean that represents shared-context data transferred in JSON objects. This is + * a minimum example: + * + *
        + * {
        + *   "context_id": "abc123",
        + *   "ckey": "myKey",
        + *   "cvalue": "my context value to share"
        + * }
        + * 
        + */ +public class SharedContext { + + // Response field indicates nothing else is present + private String response; + // Required fields when data is present + private String context_id, ckey, cvalue; + private Long id, create_time; + // Additional database fields from the DomainVO object. + private String created, modified, createdId, modifiedId, auditUserId, auditTrail, rowNum; + + /** + * Gets the response field. + * + * @return response + */ + public String getResponse() { + return response; + } + + /** + * Sets the response field. + * + * @param response + * The response to set + */ + public void setResponse(final String response) { + this.response = response; + } + + /** + * Gets the database row ID. + * + * @return Database row ID + */ + public Long getId() { + return id; + } + + /** + * Sets the database row ID. + * + * @param id + */ + public void setId(final Long id) { + this.id = id; + } + + /** + * Gets the creation time + * + * @return Creation time as a Long + */ + public Long getCreate_time() { + return create_time; + } + + /** + * Sets the creation time + * + * @param create_time + */ + public void setCreate_time(final Long create_time) { + this.create_time = create_time; + } + + /** + * Gets the context ID + * + * @return Context ID + */ + public String getContext_id() { + return context_id; + } + + /** + * Sets the context ID + * + * @param context_id + */ + public void setContext_id(final String context_id) { + this.context_id = context_id; + } + + /** + * Gets the key of the key-value pair. Called ckey because "key" is a + * reserved word in Mysql. + * + * @return The key + */ + public String getCkey() { + return ckey; + } + + /** + * Sets the key of the key-value pair. + * + * @param ckey + */ + public void setCkey(final String ckey) { + this.ckey = ckey; + } + + /** + * Gets the value of the key-value pair. Called cvalue because "value" is a + * reserved word in Mysql. + * + * @return Value of the key-value pair. + */ + public String getCvalue() { + return cvalue; + } + + /** + * Sets the value of the key-value pair. + * + * @param cvalue + */ + public void setCvalue(final String cvalue) { + this.cvalue = cvalue; + } + + /** + * Gets the created value. + * + * @return Created info from database + */ + public String getCreated() { + return created; + } + + /** + * Sets the created value. + * + * @param created + */ + public void setCreated(String created) { + this.created = created; + } + + /** + * Gets the modified value. + * + * @return Modified info from database + */ + public String getModified() { + return modified; + } + + /** + * Sets the modified value. + * + * @param modified + */ + public void setModified(String modified) { + this.modified = modified; + } + + /** + * Gets the createdId value. + * + * @return CreatedId info from database + */ + public String getCreatedId() { + return createdId; + } + + /** + * Sets the createdId value. + * + * @param createdId + */ + public void setCreatedId(String createdId) { + this.createdId = createdId; + } + + /** + * Gets the modifiedId value. + * + * @return ModifiedId info from database + */ + public String getModifiedId() { + return modifiedId; + } + + /** + * Sets the modifiedId value. + * + * @param modifiedId + */ + public void setModifiedId(String modifiedId) { + this.modifiedId = modifiedId; + } + + /** + * Gets the audit user ID value. + * + * @return AuditUserId from database + */ + public String getAuditUserId() { + return auditUserId; + } + + /** + * Sets the audit user ID value. + * + * @param auditUserId + */ + public void setAuditUserId(String auditUserId) { + this.auditUserId = auditUserId; + } + + /** + * Gets the audit trail value. + * + * @return AuditTrail from database. + */ + public String getAuditTrail() { + return auditTrail; + } + + /** + * Sets the audit trail value. + * + * @param auditTrail + */ + public void setAuditTrail(String auditTrail) { + this.auditTrail = auditTrail; + } + + /** + * Gets the row num value. + * + * @return rowNum from database. + */ + public String getRowNum() { + return rowNum; + } + + /** + * Sets the row num value. + * + * @param rowNum + */ + public void setRowNum(String rowNum) { + this.rowNum = rowNum; + } + + @Override + public boolean equals(Object obj) { + SharedContext other = (SharedContext) obj; + return this.id == other.id && this.context_id.equals(other.context_id) && this.ckey.equals(other.ckey) + && this.cvalue.equals(other.cvalue); + } + + @Override + public int hashCode() { + return (int) (id + context_id.hashCode() + ckey.hashCode() + cvalue.hashCode()); + } + + @Override + public String toString() { + String s = "@SharedContext[id: " + id + "; context_id: " + context_id + "; ckey: " + ckey + "; cvalue: " + + cvalue + "]"; + return s; + } + +} \ No newline at end of file diff --git a/ecomp-sdk/epsdk-workflow/.gitignore b/ecomp-sdk/epsdk-workflow/.gitignore new file mode 100644 index 00000000..aa0c881b --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/.gitignore @@ -0,0 +1,5 @@ +/target +/bin/ +/.settings/ +.project +.classpath diff --git a/ecomp-sdk/epsdk-workflow/README.md b/ecomp-sdk/epsdk-workflow/README.md new file mode 100644 index 00000000..0e919a47 --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/README.md @@ -0,0 +1,18 @@ +# ECOMP Portal SDK Workflow + +## Overview + +This is the Maven project for the ECOMP Portal SDK Workflow library, +which is distributed as epsdk-workflow-N.N.N.jar. This library +requires Hibernate and Spring, and provides features including +schedulers, workflows and R Cloud integration. + +## Release Notes + +### OpenECOMP Distributions + +Version 1.1.0 +- [Portal-7] Improvements added as part of the rebasing process + +Version 1.0.0 +- Initial release diff --git a/ecomp-sdk/epsdk-workflow/pom.xml b/ecomp-sdk/epsdk-workflow/pom.xml new file mode 100644 index 00000000..5ed229f2 --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/pom.xml @@ -0,0 +1,114 @@ + + + 4.0.0 + + + org.openecomp.ecompsdkos + epsdk-project + 1.1.0-SNAPSHOT + + + + epsdk-workflow + + jar + ECOMP Portal SDK Workflow + Provides workflow features for SDK applications + + + + + + + org.openecomp.ecompsdkos + epsdk-core + ${project.version} + + + + com.fasterxml.jackson.core + jackson-annotations + 2.6.3 + + + com.fasterxml.jackson.core + jackson-core + 2.6.3 + + + com.fasterxml.jackson.core + jackson-databind + 2.6.3 + + + javax.servlet + javax.servlet-api + 3.1.0 + + + org.hibernate + hibernate-core + ${hibernate.version} + + + org.hibernate + hibernate-validator + 5.1.3.Final + + + org.json + json + 20160212 + + + org.quartz-scheduler + quartz + 2.2.1 + + + + c3p0 + c3p0 + + + + + + org.slf4j + jcl-over-slf4j + 1.7.12 + + + org.springframework + spring-context-support + ${springframework.version} + + + org.springframework + spring-core + ${springframework.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-tx + ${springframework.version} + + + org.springframework + spring-web + ${springframework.version} + + + org.springframework + spring-webmvc + ${springframework.version} + + + + diff --git a/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookController.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookController.java new file mode 100644 index 00000000..8b8ad5c9 --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookController.java @@ -0,0 +1,53 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.rnotebookintegration.controller; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.controller.RestrictedBaseController; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.service.UserProfileService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.ModelAndView; + +@Controller +@RequestMapping("/") +public class NotebookController extends RestrictedBaseController{ + @Autowired + UserProfileService service; + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(NotebookController.class); + + @RequestMapping(value = {"/notebook" }, method = RequestMethod.GET) + public ModelAndView noteBook(HttpServletRequest request) { + + try { + + } catch (Exception e) { + + + } + return new ModelAndView(getViewName()); + } + + +} diff --git a/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookTestController.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookTestController.java new file mode 100644 index 00000000..ac56b6c6 --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookTestController.java @@ -0,0 +1,55 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.rnotebookintegration.controller; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.portalsdk.core.controller.RestrictedBaseController; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.service.UserProfileService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.ModelAndView; + +@Controller +@RequestMapping("/") +public class NotebookTestController extends RestrictedBaseController{ + @Autowired + UserProfileService service; + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(NotebookTestController.class); + + @RequestMapping(value = {"/nbooktest" }, method = RequestMethod.GET) + public ModelAndView noteBook(HttpServletRequest request) { + + try { + + } catch (Exception e) { + + + } + return new ModelAndView(getViewName()); + } + + +} diff --git a/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookController.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookController.java new file mode 100644 index 00000000..00d97268 --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookController.java @@ -0,0 +1,100 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.rnotebookintegration.controller; + +import java.util.HashMap; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.hibernate.validator.internal.util.privilegedactions.GetMethodFromPropertyName; +import org.openecomp.portalsdk.core.controller.RestrictedBaseController; +import org.openecomp.portalsdk.core.controller.RestrictedRESTfulBaseController; +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; +import org.openecomp.portalsdk.core.util.SystemProperties; +import org.openecomp.portalsdk.core.web.support.JsonMessage; +import org.openecomp.portalsdk.core.web.support.UserUtils; +import org.openecomp.portalsdk.rnotebookintegration.exception.RNotebookIntegrationException; +import org.openecomp.portalsdk.rnotebookintegration.service.RNoteBookIntegrationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Controller +@RequestMapping("/rNotebook/") + +public class RNoteBookController extends RestrictedRESTfulBaseController { + + @Autowired + private RNoteBookIntegrationService rNoteBookIntegrationService; + + + + public RNoteBookIntegrationService getrNoteBookIntegrationService() { + return rNoteBookIntegrationService; + } + + + + public void setrNoteBookIntegrationService( + RNoteBookIntegrationService rNoteBookIntegrationService) { + this.rNoteBookIntegrationService = rNoteBookIntegrationService; + } + + + + @RequestMapping(value = { "authCr" }, method = RequestMethod.GET, produces = "application/json") + public @ResponseBody ResponseEntity getRNotebookCredentials (String token) throws Exception { + //ObjectMapper mapper = new ObjectMapper(); + //mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + //JsonNode root = mapper.readTree(request.getReader()); + //String token = root.get("authenticationToken").textValue(); + + String returnJSON = ""; + try{ + returnJSON = this.getrNoteBookIntegrationService().getRNotebookCredentials(token); + } catch(RNotebookIntegrationException re){ + if (re.getErrorCode().equals(RNotebookIntegrationException.ERROR_CODE_TOKEN_EXPIRED)){ + return new ResponseEntity(JsonMessage.buildJsonResponse(false, re.getMessage()), HttpStatus.BAD_REQUEST); + } + else { + return new ResponseEntity(JsonMessage.buildJsonResponse(false, re.getMessage()), HttpStatus.BAD_REQUEST); + } + } + catch (Exception e){ + return new ResponseEntity(JsonMessage.buildJsonResponse(false, e.getMessage()), HttpStatus.BAD_REQUEST); + } + + return new ResponseEntity(returnJSON, HttpStatus.OK); + + } + + +} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookFEController.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookFEController.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookFEController.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookFEController.java diff --git a/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/domain/RNoteBookCredentials.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/domain/RNoteBookCredentials.java new file mode 100644 index 00000000..d2928495 --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/domain/RNoteBookCredentials.java @@ -0,0 +1,94 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.rnotebookintegration.domain; + +import java.util.Date; +import java.util.Map; + +import org.openecomp.portalsdk.core.domain.User; +import org.openecomp.portalsdk.core.domain.support.DomainVo; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class RNoteBookCredentials extends DomainVo { + private EcompUser userInfo; + private String token; + private Date createdDate; + private String notebookID; + private Map parameters; + private Date tokenReadDate; + @JsonIgnore + private String userString; + @JsonIgnore + private String parametersString; + + public String getToken() { + return token; + } + public void setToken(String token) { + this.token = token; + } + public Date getCreatedDate() { + return createdDate; + } + public void setCreatedDate(Date createdDate) { + this.createdDate = createdDate; + } + public String getNotebookID() { + return notebookID; + } + public EcompUser getUserInfo() { + return userInfo; + } + public void setUserInfo(EcompUser userInfo) { + this.userInfo = userInfo; + } + public void setNotebookID(String notebookID) { + this.notebookID = notebookID; + } + public String getUserString() { + return userString; + } + public void setUserString(String userString) { + this.userString = userString; + } + public Map getParameters() { + return parameters; + } + public void setParameters(Map parameters) { + this.parameters = parameters; + } + public String getParametersString() { + return parametersString; + } + public void setParametersString(String parametersString) { + this.parametersString = parametersString; + } + public Date getTokenReadDate() { + return tokenReadDate; + } + public void setTokenReadDate(Date tokenReadDate) { + this.tokenReadDate = tokenReadDate; + } + + + +} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/exception/RNotebookIntegrationException.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/exception/RNotebookIntegrationException.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/exception/RNotebookIntegrationException.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/exception/RNotebookIntegrationException.java diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationService.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationService.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationService.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationService.java diff --git a/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationServiceImpl.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationServiceImpl.java new file mode 100644 index 00000000..fe21cd13 --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationServiceImpl.java @@ -0,0 +1,146 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.rnotebookintegration.service; + +import java.security.SecureRandom; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; +import org.openecomp.portalsdk.core.service.DataAccessService; +import org.openecomp.portalsdk.core.web.support.UserUtils; +import org.openecomp.portalsdk.rnotebookintegration.domain.RNoteBookCredentials; +import org.openecomp.portalsdk.rnotebookintegration.exception.RNotebookIntegrationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Service("RNoteBookIntegrationService") +@Transactional +public class RNoteBookIntegrationServiceImpl implements RNoteBookIntegrationService { + + private final long tokenTTL = 50000L; + + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RNoteBookIntegrationServiceImpl.class); + + + @Autowired + private DataAccessService dataAccessService; + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + @Override + public String getRNotebookCredentials(String token) throws RNotebookIntegrationException, Exception { + String retString = ""; + + try{ + RNoteBookCredentials notebookCredentials = (RNoteBookCredentials) this.getDataAccessService().getDomainObject(RNoteBookCredentials.class, token, new HashMap()); + if (notebookCredentials.getToken() == null || notebookCredentials.getToken().equals("")){ + throw new RNotebookIntegrationException(RNotebookIntegrationException.ERROR_CODE_TOKEN_INVALID); + } + Date currDate = new Date(); + if ((currDate.getTime() - notebookCredentials.getCreatedDate().getTime() > tokenTTL) || (notebookCredentials.getTokenReadDate() != null)){ + throw new RNotebookIntegrationException(RNotebookIntegrationException.ERROR_CODE_TOKEN_EXPIRED); + } + ObjectMapper mapper = new ObjectMapper(); + + try{ + EcompUser userInfo = mapper.readValue(notebookCredentials.getUserString(), EcompUser.class); + notebookCredentials.setUserInfo(userInfo); + } catch(JsonMappingException me){ + logger.error("error converting string to user. from JSON" + me.getMessage()); + } catch(JsonParseException pe){ + logger.error("error converting string to user. from JSON" + pe.getMessage()); + } + + try{ + Map params = mapper.readValue(notebookCredentials.getParametersString(), HashMap.class); + notebookCredentials.setParameters(params); + } catch(JsonMappingException me){ + logger.error("error converting string to parameters. from JSON" + me.getMessage()); + } catch(JsonParseException pe){ + logger.error("error converting string to parameters. from JSON" + pe.getMessage()); + } + + //expiring the token + try{ + notebookCredentials.setTokenReadDate(new Date()); + this.getDataAccessService().saveDomainObject(notebookCredentials, null); + } catch(Exception e){ + logger.info("Error while expiring the token"); + logger.error(e.getMessage()); + throw new Exception(); + } + //notebookCredentials.setUserString(null); + retString = mapper.writeValueAsString(notebookCredentials); + } catch(RNotebookIntegrationException re){ + logger.error(re.getMessage()); + throw re; + } catch(Exception e){ + logger.info("Error while parsing the rcloud notebook credentials"); + logger.error(e.getMessage()); + throw new Exception(); + } + + return retString; + } + + @Override + public String saveRNotebookCredentials(String notebookId, EcompUser user, Map params) throws RNotebookIntegrationException, Exception { + + String token = ""; + try{ + token = UUID.randomUUID().toString(); + + ObjectMapper mapper = new ObjectMapper(); + ; + RNoteBookCredentials rc = new RNoteBookCredentials(); + rc.setToken(token); + rc.setCreatedDate(new Date()); + rc.setNotebookID(notebookId); + rc.setParametersString(mapper.writeValueAsString(params)); + rc.setUserString(mapper.writeValueAsString(user)); + + this.getDataAccessService().saveDomainObject(rc, null); + + } catch(Exception e){ + logger.info("Error while parsing the rcloud notebook credentials"); + logger.error(e.getMessage()); + throw new Exception(); + } + + return token; + } + + +} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/controllers/WorkflowController.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/controllers/WorkflowController.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/controllers/WorkflowController.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/controllers/WorkflowController.java diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAO.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAO.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAO.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAO.java diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAOImpl.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAOImpl.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAOImpl.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/WorkflowDAOImpl.java diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/domain/WorkflowSchedule.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/domain/WorkflowSchedule.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/domain/WorkflowSchedule.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/domain/WorkflowSchedule.java diff --git a/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/Workflow.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/Workflow.java new file mode 100644 index 00000000..3193f9cd --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/Workflow.java @@ -0,0 +1,203 @@ + +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.workflow.models; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +import org.openecomp.portalsdk.core.domain.User; + +@Entity +@Table(name = "fn_workflow") +public class Workflow implements Serializable{ + + private static final long serialVersionUID = -3155065449938005856L; + + @Id + @Column(name = "id") + @GeneratedValue + private Long id; + + @Column + private String name; + + @Column (name = "workflow_key") + private String workflowKey; + + @Column + private String description; + + @Column(name = "created") + private Date created; + + @OneToOne(fetch = FetchType.EAGER)//, cascade = CascadeType.ALL) + @JoinColumn(name = "created_by") + private User createdBy; + + @Column(name = "modified") + private Date lastUpdated; + + @OneToOne(fetch = FetchType.EAGER)//, cascade = CascadeType.ALL) + @JoinColumn(name = "modified_by") + private User modifiedBy; + + @Column(name = "active_yn") + private Boolean active; + + @Column(name = "run_link") + private String runLink; + + @Column(name = "suspend_link") + private String suspendLink; + + @Column(name = "modified_link") + private String modifiedLink; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getRunLink() { + return runLink; + } + + public void setRunLink(String runLink) { + this.runLink = runLink; + } + + public String getSuspendLink() { + return suspendLink; + } + + public void setSuspendLink(String suspendLink) { + this.suspendLink = suspendLink; + } + + public String getModifiedLink() { + return modifiedLink; + } + + public void setModifiedLink(String modifiedLink) { + this.modifiedLink = modifiedLink; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public User getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(User createdBy) { + this.createdBy = createdBy; + } + + public Date getLastUpdated() { + return lastUpdated; + } + + public void setLastUpdated(Date lastUpdated) { + this.lastUpdated = lastUpdated; + } + + public User getModifiedBy() { + return modifiedBy; + } + + public void setModifiedBy(User modifiedBy) { + this.modifiedBy = modifiedBy; + } + + public String getWorkflowKey() { + return workflowKey; + } + + public void setWorkflowKey(String workflowKey) { + this.workflowKey = workflowKey; + } + + public Boolean getActive() { + return active; + } + + public void setActive(Boolean active) { + this.active = active; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Workflow other = (Workflow) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } +} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/WorkflowLite.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/WorkflowLite.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/WorkflowLite.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/WorkflowLite.java diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleJob.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleJob.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleJob.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleJob.java diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleRegistry.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleRegistry.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleRegistry.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/scheduler/WorkFlowScheduleRegistry.java diff --git a/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleExecutor.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleExecutor.java new file mode 100644 index 00000000..ea04e69e --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleExecutor.java @@ -0,0 +1,108 @@ +/*- + * ================================================================================ + * eCOMP Portal SDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property + * ================================================================================ + * Licensed 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.openecomp.portalsdk.workflow.services; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; + +public class WorkflowScheduleExecutor { + private String serverURL; + private String workflowKey; + private String myUrl; + private String payload; + + //constructor + public WorkflowScheduleExecutor(String serverURL,String workflowKey){ + this.serverURL = serverURL; + this.workflowKey = workflowKey; + this.myUrl = this.serverURL + "/engine-rest/process-definition/key/" + this.workflowKey + "/submit-form";; + this.payload="{\"variables\":{}}"; + } + + public static void main(String [] args) throws Exception { + + } + + public void execute() { + POST_fromURL(myUrl,payload); + } + + public static String get_fromURL(String myURL) { + System.out.println("Requeted URL:" + myURL); + StringBuilder sb = new StringBuilder(); + URLConnection urlConn = null; + InputStreamReader in = null; + try { + URL url = new URL(myURL); + urlConn = url.openConnection(); + if (urlConn != null) + urlConn.setReadTimeout(60 * 1000); + if (urlConn != null && urlConn.getInputStream() != null) { + in = new InputStreamReader(urlConn.getInputStream(), + Charset.defaultCharset()); + BufferedReader bufferedReader = new BufferedReader(in); + if (bufferedReader != null) { + int cp; + while ((cp = bufferedReader.read()) != -1) { + sb.append((char) cp); + } + bufferedReader.close(); + } + } + in.close(); + } catch (Exception e) { + throw new RuntimeException("Exception while calling URL:"+ myURL, e); + } + return sb.toString(); + } + + + public static String POST_fromURL(String myURL, String payload) { + String line; + StringBuffer jsonString = new StringBuffer(); + try { + URL url = new URL(myURL); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoInput(true); + connection.setDoOutput(true); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Accept", "application/json"); + connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); + writer.write(payload); + writer.close(); + BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); + while ((line = br.readLine()) != null) { + jsonString.append(line); + } + br.close(); + connection.disconnect(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } + return jsonString.toString(); + } +} \ No newline at end of file diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleService.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleService.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleService.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleService.java diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleServiceImpl.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleServiceImpl.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleServiceImpl.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleServiceImpl.java diff --git a/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowService.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowService.java new file mode 100644 index 00000000..7bf133a7 --- /dev/null +++ b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowService.java @@ -0,0 +1,16 @@ +package org.openecomp.portalsdk.workflow.services; + +import java.util.List; + +import org.openecomp.portalsdk.workflow.domain.WorkflowSchedule; +import org.openecomp.portalsdk.workflow.models.Workflow; +import org.openecomp.portalsdk.workflow.models.WorkflowLite; + + +public interface WorkflowService { + public void saveCronJob(WorkflowSchedule domainCronJobData); + public Workflow addWorkflow(Workflow workflow, String creatorId); + public Workflow editWorkflow(WorkflowLite worklow, String creatorId); + public void deleteWorkflow(Long worklow); + public List getAllWorkflows(); +} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowServiceImpl.java b/ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowServiceImpl.java similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowServiceImpl.java rename to ecomp-sdk/epsdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowServiceImpl.java diff --git a/ecomp-sdk/sdk-workflow/src/main/resources/RNoteBookIntegration.hbm.xml b/ecomp-sdk/epsdk-workflow/src/main/resources/RNoteBookIntegration.hbm.xml similarity index 100% rename from ecomp-sdk/sdk-workflow/src/main/resources/RNoteBookIntegration.hbm.xml rename to ecomp-sdk/epsdk-workflow/src/main/resources/RNoteBookIntegration.hbm.xml diff --git a/ecomp-sdk/pom.xml b/ecomp-sdk/pom.xml index 25a7a63e..e802cff2 100644 --- a/ecomp-sdk/pom.xml +++ b/ecomp-sdk/pom.xml @@ -1,82 +1,60 @@ 4.0.0 + + org.openecomp.ecompsdkos - ecompSDK-project - pom - + epsdk-project 1.1.0-SNAPSHOT - Ecomp Portal SDK Project (parent) - https://wiki/display/EcompPortal + pom + ECOMP Portal SDK Project (parent) + https://wiki.onap.org/display/DW/Portal - scm:git:https://gitlab/scm/st_quantum/quantum.git - scm:git:ssh://git@gitlab/st_quantum/quantum.git - HEAD + scm:git:https://gitlab/scm/st_quantum/quantum.git + scm:git:ssh://git@gitlab/st_quantum/quantum.git + HEAD - - thirdparty - - quantum - sdk-analytics - sdk-workflow + epsdk-fw + epsdk-core + epsdk-analytics + epsdk-workflow + epsdk-app-common + epsdk-app-overlay + UTF-8 - 1.1.0-SNAPSHOT 4.2.0.RELEASE 4.3.11.Final true https://nexus.onap.org - /content/repositories/snapshots/ - /content/repositories/releases/ - /content/repositories/staging/ - /content/sites/site/org/openecomp/ecompsdkos/${project.version} + content/repositories/snapshots/ + content/repositories/releases/ + content/repositories/staging/ - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.4 - - false - org.umlgraph.doclet.UmlGraphDoc - - org.umlgraph - umlgraph - 5.6 - - -views - true - - - - - - - ecomp-releases - OpenECOMP - Release Repository - ${nexusproxy}/${releaseNexusPath} + + ecomp-releases + OpenECOMP - Release Repository + ${nexusproxy}/${releaseNexusPath} + + + + ecomp-snapshots + OpenECOMP - Snapshot Repository + ${nexusproxy}/${snapshotNexusPath} + + + ecomp-public + ecomp onap public Repository + https://nexus.onap.org/content/groups/public - - - ecomp-snapshots - OpenECOMP - Snapshot Repository - ${nexusproxy}/${snapshotNexusPath} - - - oss-sonatype - oss sonatype Central - https://oss.sonatype.org/service/local/repositories/releases/content/ - - @@ -103,34 +81,7 @@ - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - ${nexusproxy} - 176c31dfe190a - ecomp-staging - - - - org.codehaus.mojo - sonar-maven-plugin - 3.2 - - - org.apache.maven.plugins - maven-site-plugin - 3.6 - - - org.apache.maven.wagon - wagon-webdav-jackrabbit - 2.10 - - - + org.apache.maven.plugins @@ -139,7 +90,7 @@ developerConnection branch - feature/BRANCH_OS + feature/BRANCH_1707 @@ -163,7 +114,6 @@ ${project.version} - ${sdk-internal.version} @@ -213,19 +163,20 @@ - ecomp-releases - OpenECOMP - Release Repository - ${nexusproxy}/${releaseNexusPath} + ecomp-releases + OpenECOMP - Release Repository + ${nexusproxy}/${releaseNexusPath} - ecomp-snapshots - OpenECOMP - Snapshot Repository - ${nexusproxy}/${snapshotNexusPath} + ecomp-snapshots + OpenECOMP - Snapshot Repository + ${nexusproxy}/${snapshotNexusPath} - + - ecomp-site - dav:${nexusproxy}${sitePath} + ecomp-site + dav:${nexusproxy}${sitePath} + diff --git a/ecomp-sdk/quantum/.gitignore b/ecomp-sdk/quantum/.gitignore deleted file mode 100644 index ea8c4bf7..00000000 --- a/ecomp-sdk/quantum/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/ecomp-sdk/quantum/README.md b/ecomp-sdk/quantum/README.md deleted file mode 100644 index bf00b41d..00000000 --- a/ecomp-sdk/quantum/README.md +++ /dev/null @@ -1,11 +0,0 @@ -ECOMP Portal SDK Core -===================== - -This is the Maven project for the ECOMP Portal SDK Core, -which is distributed as ecompSDK-core-nnn.jar. This library -requires Hibernate and Spring, and provides many features -such as data access, session management, logging, on-boarding -and more. Most of these features are used in the ECOMP SDK -web application. - - diff --git a/ecomp-sdk/quantum/pom.xml b/ecomp-sdk/quantum/pom.xml deleted file mode 100644 index 2243be3d..00000000 --- a/ecomp-sdk/quantum/pom.xml +++ /dev/null @@ -1,330 +0,0 @@ - - 4.0.0 - - - org.openecomp.ecompsdkos - ecompSDK-project - 1.1.0-SNAPSHOT - - - ecompSDK-core - jar - Ecomp Portal SDK Core (quantum) - - - - 6.4.0.Final - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.19.1 - - ${skiptests} - - **/Test*.java - **/*Test.java - **/*TestCase.java - - - classpath: - - - - - - - - - - - - - org.openecomp.ecompsdkos - ecompFW - ${project.version} - - - commons-logging - commons-logging - - - log4j - log4j - - - log4j - apache-log4j-extras - - - org.slf4j - slf4j-log4j12 - - - - - - - - - org.drools - drools-compiler - ${drools.version} - - - - - org.springframework - spring-core - ${springframework.version} - - - commons-logging - commons-logging - - - - - org.springframework - spring-web - ${springframework.version} - - - org.springframework - spring-webmvc - ${springframework.version} - - - org.springframework - spring-tx - ${springframework.version} - - - org.springframework - spring-context-support - ${springframework.version} - - - org.springframework - spring-orm - ${springframework.version} - - - org.springframework - spring-test - ${springframework.version} - - - org.springframework - spring-aop - ${springframework.version} - - - org.springframework.boot - spring-boot-starter - 1.3.0.RELEASE - - - org.slf4j - log4j-over-slf4j - - - ch.qos.logback - logback-classic - - - - - - org.aspectj - aspectjrt - 1.8.9 - - - - org.aspectj - aspectjweaver - 1.8.9 - - - - - - org.hibernate - hibernate-core - ${hibernate.version} - - - org.hibernate - hibernate-validator - 5.1.3.Final - - - - javax.servlet - javax.servlet-api - 3.1.0 - - - javax.servlet.jsp - javax.servlet.jsp-api - 2.3.1 - - - javax.servlet - jstl - 1.2 - - - - org.slf4j - jcl-over-slf4j - 1.7.12 - - - - org.slf4j - log4j-over-slf4j - 1.7.12 - - - com.mchange - c3p0 - 0.9.5.2 - - - - org.apache.tiles - tiles-core - 3.0.5 - - - org.apache.tiles - tiles-jsp - 3.0.5 - - - - org.yaml - snakeyaml - 1.15 - - - - com.fasterxml.jackson.core - jackson-annotations - 2.6.3 - - - com.fasterxml.jackson.core - jackson-core - 2.6.3 - - - com.fasterxml.jackson.core - jackson-databind - 2.6.3 - - - mysql - mysql-connector-java - 5.1.22 - - - - org.apache.jcs - jcs - 1.3 - - - * - * - - - - - - - org.apache.tomcat - tomcat-websocket - 8.0.28 - provided - - - - concurrent - concurrent - 1.3.2 - - - * - * - - - - - - junit - junit - 4.12 - - - - - - commons-codec - commons-codec - 1.10 - - - commons-lang - commons-lang - 2.6 - - - - - org.quartz-scheduler - quartz - 2.2.1 - - - - c3p0 - c3p0 - - - - - - - org.elasticsearch - elasticsearch - 2.2.0 - - - io.searchbox - jest - 2.0.0 - - - commons-logging - commons-logging - - - - - - com.att.eelf - eelf-core - 0.0.1 - - - - diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/FusionObject.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/FusionObject.java deleted file mode 100644 index 00866388..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/FusionObject.java +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core; - -/** - *

        - * Title: FusionObject - *

        - * - *

        - * Description: This interface is implemented by all top-level support classes - * of each package in FUSION. This allows all top-level support classes to have - * some commonality for easier maintenance. - *

        - * - *

        - * Copyright: Copyright (c) 2007 - *

        - * - * - * @version 1.1 - */ -public interface FusionObject { - - public class Parameters { - // HashMap parameters passed to the Service and Dao tiers - public static final String PARAM_USERID = "userId"; - public static final String PARAM_HTTP_REQUEST = "request"; - public static final String PARAM_FILTERS = "filters"; - public static final String PARAM_CLIENT_DEVICE = "client_device"; - // Request parameters passed in the Web tier - public static final String REQUEST_PARAM_DISPLAY_SUCCESS_MESSAGE = "display_success_message"; - } - - /** - *

        - * Title: FusionObject.Utilities - *

        - * - *

        - * Description: Inner class that has some utility functions available for - * any class that implements it. - *

        - * - *

        - * Copyright: Copyright (c) 2007 - *

        - * - * - * @version 1.1 - */ - public class Utilities { - /** - * nvl - replaces a string value with an empty string if null. - * - * @param s - * String - the string value that needs to be checked - * @return String - returns the original string value if not null. - * Otherwise an empty string ("") is returned. - */ - public static String nvl(String s) { - return (s == null) ? "" : s; - } - - /** - * nvl - replaces a string value with a default value if null. - * - * @param s - * String - the string value that needs to be checked - * @param sDefault - * String - the default value - * @return String - returns the original string value if not null. - * Otherwise the default value is returned. - */ - public static String nvl(String s, String sDefault) { - return nvl(s).equals("") ? sDefault : s; - } - - /** - * Tests the specified string for nullity. - * - * @param a - * String to test for nullity. - * @return True if the specified string is null, empty or the 4-character - * sequence "null" (ignoring case); otherwise false. - */ - public static boolean isNull(String a) { - if ((a == null) || (a.length() == 0) || a.equalsIgnoreCase("null")) - return true; - else - return false; - } - - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/LoginBean.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/LoginBean.java deleted file mode 100644 index e5a58e82..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/LoginBean.java +++ /dev/null @@ -1,196 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.command; - -import java.util.Set; - -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.domain.support.FusionCommand; - -public class LoginBean extends FusionCommand { - - private String loginId; - private String loginPwd; - private String hrid; - private String userid; - private String siteAccess; - private String loginErrorMessage; - - private User user; - @SuppressWarnings("rawtypes") - private Set menu; - @SuppressWarnings("rawtypes") - private Set businessDirectMenu; - - /** - * getLoginId - * - * @return String - */ - public String getLoginId() { - return loginId; - } - - /** - * getLoginPwd - * - * @return String - */ - public String getLoginPwd() { - return loginPwd; - } - - /** - * getMenu - * - * @return Set - */ - @SuppressWarnings("rawtypes") - public Set getMenu() { - return menu; - } - - /** - * getUser - * - * @return User - */ - public User getUser() { - return user; - } - - /** - * getHrid - * - * @return String - */ - public String getHrid() { - return hrid; - } - - /** - * getSiteAccess - * - * @return String - */ - public String getSiteAccess() { - return siteAccess; - } - - /** - * getBusinessDirectMenu - * - * @return Set - */ - @SuppressWarnings("rawtypes") - public Set getBusinessDirectMenu() { - return businessDirectMenu; - } - - /** - * getLoginErrorMessage - * - * @return String - */ - public String getLoginErrorMessage() { - return loginErrorMessage; - } - - - - /** - * setLoginId - * - * @param loginId String - */ - public void setLoginId(String loginId) { - this.loginId = loginId; - } - - /** - * setLoginPwd - * - * @param loginPwd String - */ - public void setLoginPwd(String loginPwd) { - this.loginPwd = loginPwd; - } - - @SuppressWarnings("rawtypes") - public void setMenu(Set menu) { - this.menu = menu; - } - - /** - * setUser - * - * @param user User - */ - public void setUser(User user) { - this.user = user; - } - - /** - * setHrid - * - * @param hrid String - */ - public void setHrid(String hrid) { - this.hrid = hrid; - } - - /** - * setSiteAccess - * - * @param siteAccess String - */ - public void setSiteAccess(String siteAccess) { - this.siteAccess = siteAccess; - } - - /** - * setBusinessDirectMenu - * - * @param businessDirectMenu Set - */ - @SuppressWarnings("rawtypes") - public void setBusinessDirectMenu(Set businessDirectMenu) { - this.businessDirectMenu = businessDirectMenu; - } - - /** - * setLoginErrorMessage - * - * @param loginErrorMessage String - */ - public void setLoginErrorMessage(String loginErrorMessage) { - this.loginErrorMessage = loginErrorMessage; - } - - public String getUserid() { - return userid; - } - - public void setUserid(String userid) { - this.userid = userid; - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/PostSearchBean.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/PostSearchBean.java deleted file mode 100644 index b07b8fed..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/PostSearchBean.java +++ /dev/null @@ -1,374 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.command; - -import java.util.List; - -import org.openecomp.portalsdk.core.command.support.SearchBase; -import org.openecomp.portalsdk.core.domain.User; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -@JsonSerialize -public class PostSearchBean extends SearchBase { - - private User user = null; - private User userOrig = null; - private String[] selected; - private String[] postHrid; - private String[] postOrgUserId; - private String[] postFirstName; - private String[] postLastName; - private String[] postOrgCode; - private String[] postPhone; - private String[] postEmail; - private String[] postAddress1; - private String[] postAddress2; - private String[] postCity; - private String[] postState; - private String[] postZipCode; - private String[] postLocationClli; - private String[] postBusinessCountryCode; - private String[] postBusinessCountryName; - private String[] postDepartment; - private String[] postDepartmentName; - private String[] postBusinessUnit; - private String[] postBusinessUnitName; - private String[] postJobTitle; - private String[] postOrgManagerUserId; - private String[] postCommandChain; - private String[] postCompanyCode; - private String[] postCompany; - private String[] postCostCenter; - private String[] postSiloStatus; - private String[] postFinancialLocCode; - - - public PostSearchBean() { - this(null); - } // PostSearchBean - - @SuppressWarnings("rawtypes") - public PostSearchBean(List items) { - super(items); - - user = new User(); - userOrig = new User(); - - setSortBy1(""); - setSortBy1Orig(""); - - //setSortByList(...); - } // PostSearchBean - - - public String getFirstName() { return user.getFirstName(); } - public String getLastName() { return user.getLastName(); } - public String getHrid() { return user.getHrid(); } - public String getOrgUserId() { return user.getOrgUserId(); } - public String getOrgCode() { return user.getOrgCode(); } - public String getEmail() { return user.getEmail(); } - public String getOrgManagerUserId() { return user.getOrgManagerUserId(); } - - public String getFirstNameOrig() { return user.getFirstName(); } - public String getLastNameOrig() { return user.getLastName(); } - public String getHridOrig() { return user.getHrid(); } - public String getOrgUserIdOrig() { return user.getOrgUserId(); } - public String getOrgCodeOrig() { return user.getOrgCode(); } - public String getEmailOrig() { return user.getEmail(); } - public String getOrgManagerUserIdOrig() { return user.getOrgManagerUserId(); } - - - public User getUser() { return user; } - - public String[] getPostEmail() { - return postEmail; - } - - public String[] getPostFirstName() { - return postFirstName; - } - - public String[] getPostHrid() { - return postHrid; - } - - public String[] getPostLastName() { - return postLastName; - } - - public String[] getPostOrgCode() { - return postOrgCode; - } - - public String[] getPostPhone() { - return postPhone; - } - - public String[] getPostOrgUserId() { - return postOrgUserId; - } - - public String[] getSelected() { - return selected; - } - - public String[] getPostAddress1() { - return postAddress1; - } - - public String[] getPostBusinessCountryCode() { - return postBusinessCountryCode; - } - - public String[] getPostCity() { - return postCity; - } - - public String[] getPostCommandChain() { - return postCommandChain; - } - - public String[] getPostCompany() { - return postCompany; - } - - public String[] getPostCompanyCode() { - return postCompanyCode; - } - - public String[] getPostDepartment() { - return postDepartment; - } - - public String[] getPostDepartmentName() { - return postDepartmentName; - } - - public String[] getPostBusinessCountryName() { - return postBusinessCountryName; - } - - public String[] getPostJobTitle() { - return postJobTitle; - } - - public String[] getPostLocationClli() { - return postLocationClli; - } - - public String[] getPostOrgManagerUserId() { - return postOrgManagerUserId; - } - - public String[] getPostState() { - return postState; - } - - public String[] getPostZipCode() { - return postZipCode; - } - - public void setFirstName(String value) { user.setFirstName(value); } - public void setLastName(String value) { user.setLastName(value); } - public void setHrid(String value) { user.setHrid(value); } - public void setOrgUserId(String value) { user.setOrgUserId(value); } - public void setOrgCode(String value) { user.setOrgCode(value); } - public void setEmail(String value) { user.setEmail(value); } - public void setOrgManagerUserId(String value) { user.setOrgManagerUserId(value); } - - public void setFirstNameOrig(String value) { userOrig.setFirstName(value); } - public void setLastNameOrig(String value) { userOrig.setLastName(value); } - public void setHridOrig(String value) { userOrig.setHrid(value); } - public void setOrgUserIdOrig(String value) { userOrig.setOrgUserId(value); } - public void setOrgCodeOrig(String value) { userOrig.setOrgCode(value); } - public void setEmailOrig(String value) { userOrig.setEmail(value); } - public void setOrgManagerUserIdOrig(String value) { userOrig.setOrgManagerUserId(value); } - - public void setUser(User value) { this.user = value; } - - public void setPostEmail(String[] postEmail) { - this.postEmail = postEmail; - } - - public void setPostFirstName(String[] postFirstName) { - this.postFirstName = postFirstName; - } - - public void setPostHrid(String[] postHrid) { - this.postHrid = postHrid; - } - - public void setPostLastName(String[] postLastName) { - this.postLastName = postLastName; - } - - public void setPostOrgCode(String[] postOrgCode) { - this.postOrgCode = postOrgCode; - } - - public void setPostPhone(String[] postPhone) { - this.postPhone = postPhone; - } - - public void setPostOrgUserId(String[] postOrgUserId) { - this.postOrgUserId = postOrgUserId; - } - - public void setSelected(String[] selected) { - this.selected = selected; - } - - public void setPostAddress1(String[] postAddress1) { - this.postAddress1 = postAddress1; - } - - public void setPostBusinessCountryCode(String[] postBusinessCountryCode) { - this.postBusinessCountryCode = postBusinessCountryCode; - } - - public void setPostCity(String[] postCity) { - this.postCity = postCity; - } - - public void setPostCommandChain(String[] postCommandChain) { - this.postCommandChain = postCommandChain; - } - - public void setPostCompany(String[] postCompany) { - this.postCompany = postCompany; - } - - public void setPostCompanyCode(String[] postCompanyCode) { - this.postCompanyCode = postCompanyCode; - } - - public void setPostDepartment(String[] postDepartment) { - this.postDepartment = postDepartment; - } - - public void setPostDepartmentName(String[] postDepartmentName) { - this.postDepartmentName = postDepartmentName; - } - - public void setPostBusinessCountryName(String[] postBusinessCountryName) { - this.postBusinessCountryName = postBusinessCountryName; - } - - public void setPostJobTitle(String[] postJobTitle) { - this.postJobTitle = postJobTitle; - } - - public void setPostLocationClli(String[] postLocationClli) { - this.postLocationClli = postLocationClli; - } - - public void setPostOrgManagerUserId(String[] postOrgManagerUserId) { - this.postOrgManagerUserId = postOrgManagerUserId; - } - - public void setPostState(String[] postState) { - this.postState = postState; - } - - public void setPostZipCode(String[] postZipCode) { - this.postZipCode = postZipCode; - } - - public String[] getPostAddress2() { - return postAddress2; - } - - public void setPostAddress2(String[] postAddress2) { - this.postAddress2 = postAddress2; - } - - public User getUserOrig() { - return userOrig; - } - - public void setUserOrig(User userOrig) { - this.userOrig = userOrig; - } - - public String[] getPostBusinessUnit() { - return postBusinessUnit; - } - - public void setPostBusinessUnit(String[] postBusinessUnit) { - this.postBusinessUnit = postBusinessUnit; - } - - public String[] getPostBusinessUnitName() { - return postBusinessUnitName; - } - - public void setPostBusinessUnitName(String[] postBusinessUnitName) { - this.postBusinessUnitName = postBusinessUnitName; - } - - public String[] getPostCostCenter() { - return postCostCenter; - } - - public void setPostCostCenter(String[] postCostCenter) { - this.postCostCenter = postCostCenter; - } - - public String[] getPostSiloStatus() { - return postSiloStatus; - } - - public void setPostSiloStatus(String[] postSiloStatus) { - this.postSiloStatus = postSiloStatus; - } - - public String[] getPostFinancialLocCode() { - return postFinancialLocCode; - } - - public void setPostFinancialLocCode(String[] postFinancialLocCode) { - this.postFinancialLocCode = postFinancialLocCode; - } - - public void resetSearch() { - super.resetSearch(); - setUser(new User()); - } // resetSearch - - - public boolean isCriteriaUpdated() { - if(user==null&&userOrig==null) - return false; - else if(user==null||userOrig==null) - return true; - else - return (! ( - Utilities.nvl(user.getFirstName()).equals(Utilities.nvl(userOrig.getFirstName()))&& - Utilities.nvl(user.getLastName()).equals(Utilities.nvl(userOrig.getLastName()))&& - //Utilities.nvl(user.getHrid()).equals(Utilities.nvl(userOrig.getHrid()))&& - Utilities.nvl(user.getOrgUserId()).equals(Utilities.nvl(userOrig.getOrgUserId()))&& - Utilities.nvl(user.getOrgCode()).equals(Utilities.nvl(userOrig.getOrgCode()))&& - Utilities.nvl(user.getEmail()).equals(Utilities.nvl(userOrig.getEmail()))&& - Utilities.nvl(user.getOrgManagerUserId()).equals(Utilities.nvl(userOrig.getOrgManagerUserId()))&& - true)); - } // isCriteriaUpdated - -} // PostSearchBean diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/UserRowBean.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/UserRowBean.java deleted file mode 100644 index 7230add8..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/UserRowBean.java +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.command; - -import org.openecomp.portalsdk.core.domain.User; - -public class UserRowBean extends User { - - /** - * - */ - private static final long serialVersionUID = -2724597119083972190L; - private String sessionId; - private String lastAccess; - private String remaining; - private String loginTime; - private String LastLoginTime; - - - public String getLastAccess(){ - return this.lastAccess; - } - - - public void setLastAccess(String lastAccess){ - this.lastAccess = lastAccess; - } - - - public String getRemaining(){ - return this.remaining; - } - - - public void setRemaining(String remaining){ - this.remaining = remaining; - } - - - public String getSessionId() { - return sessionId; - } - - - public void setSessionId(String sessionId) { - this.sessionId = sessionId; - } - - - public String getLoginTime() { - return loginTime; - } - - - public void setLoginTime(String loginTime) { - this.loginTime = loginTime; - } - - - public String getLastLoginTime() { - return LastLoginTime; - } - - - public void setLastLoginTime(String lastLoginTime) { - LastLoginTime = lastLoginTime; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/support/SearchBase.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/support/SearchBase.java deleted file mode 100644 index 6fb60aa7..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/support/SearchBase.java +++ /dev/null @@ -1,268 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.command.support; - -import java.util.List; - -import org.openecomp.portalsdk.core.domain.support.FusionCommand; - -public abstract class SearchBase extends FusionCommand { - - public static String SORT_BY_MODIFIER_DESC = "D"; - public static String SORT_BY_MODIFIER_ASC = "A"; - public static String SORT_BY_MODIFIER_DESC_IMAGE_NAME = "sort_desc.gif"; - public static String SORT_BY_MODIFIER_ASC_IMAGE_NAME = "sort_asc.gif"; - - - private String sortBy1 = null; - private String sortBy2 = null; - private String sortBy3 = null; - - private String sortBy1Orig = null; - private String sortBy2Orig = null; - private String sortBy3Orig = null; - - private String sortByModifier1 = null; - private String sortByModifier2 = null; - private String sortByModifier3 = null; - - private String sortByModifier1Orig = null; - private String sortByModifier2Orig = null; - private String sortByModifier3Orig = null; - - private String accessType = "WRITE"; //null; - - private String submitAction = ""; - private String masterId = ""; - private String detailId = ""; - - private String showResult = "Y"; - - private SearchResult searchResult = null; - - @SuppressWarnings("rawtypes") - public SearchBase(List items) { - searchResult = (items == null) ? (new SearchResult()) : (new SearchResult(items)); - } // SearchBase - - - public String getSortBy1() { - return sortBy1; - } - - public String getSortBy2() { - return sortBy2; - } - - public String getSortBy3() { - return sortBy3; - } - - public String getSortBy1Orig() { - return sortBy1; - } - - public String getSortBy2Orig() { - return sortBy2; - } - - public String getSortBy3Orig() { - return sortBy3; - } - - public String getAccessType() { - return accessType; - } - - public String getSubmitAction() { - return submitAction; - } - - public String getMasterId() { - return masterId; - } - - public String getDetailId() { - return detailId; - } - - public String getShowResult() { - return showResult; - } - - //public ArrayList getSortByList() { return sortByList; } - - public SearchResult getSearchResult() { - return searchResult; - } - - public String getSortByModifier1() { - return sortByModifier1; - } - - public String getSortByModifier1Orig() { - return sortByModifier1; - } - - public String getSortByModifier2() { - return sortByModifier2; - } - - public String getSortByModifier2Orig() { - return sortByModifier2; - } - - public String getSortByModifier3() { - return sortByModifier3; - } - - public String getSortByModifier3Orig() { - return sortByModifier3; - } - - public int getPageNo() { - return (isCriteriaUpdated() || isSortingUpdated()) ? 0 : getSearchResult().getPageNo(); - } - - public int getPageSize() { - return getSearchResult().getPageSize(); - } - - public int getDataSize() { - return getSearchResult().getDataSize(); - } - - public int getNewDataSize() { - return isCriteriaUpdated() ? -1 : getDataSize(); - } - - - public void setSortBy1(String sortBy1) { - this.sortBy1 = sortBy1; - } - - public void setSortBy2(String sortBy2) { - this.sortBy2 = sortBy2; - } - - public void setSortBy3(String sortBy3) { - this.sortBy3 = sortBy3; - } - - public void setSortBy1Orig(String sortBy1Orig) { - this.sortBy1Orig = sortBy1Orig; - } - - public void setSortBy2Orig(String sortBy2Orig) { - this.sortBy2Orig = sortBy2Orig; - } - - public void setSortBy3Orig(String sortBy3Orig) { - this.sortBy3Orig = sortBy3Orig; - } - - public void setAccessType(String accessType) { - this.accessType = accessType; - } - - public void setSubmitAction(String submitAction) { - this.submitAction = submitAction; - } - - public void setMasterId(String masterId) { - this.masterId = masterId; - } - - public void setDetailId(String detailId) { - this.detailId = detailId; - } - - public void setShowResult(String showResult) { - this.showResult = showResult; - } - - public void setSearchResult(SearchResult searchResult) { - this.searchResult = searchResult; - } - - public void setSortByModifier1(String sortByModifier1) { - this.sortByModifier1 = sortByModifier1; - } - - public void setSortByModifier1Orig(String sortByModifier1Orig) { - this.sortByModifier1Orig = sortByModifier1Orig; - } - - public void setSortByModifier2(String sortByModifier2) { - this.sortByModifier2 = sortByModifier2; - } - - public void setSortByModifier2Orig(String sortByModifier2Orig) { - this.sortByModifier2Orig = sortByModifier2Orig; - } - - public void setSortByModifier3(String sortByModifier3) { - this.sortByModifier3 = sortByModifier3; - } - - public void setSortByModifier3Orig(String sortByModifier3Orig) { - this.sortByModifier3Orig = sortByModifier3Orig; - } - - public void setSortingUpdated(boolean sortingUpdated) { - } - - public void setPageNo(int pageNo) { - getSearchResult().setPageNo(pageNo); - } - - public void setPageSize(int pageSize) { - getSearchResult().setPageSize(pageSize); - } - - public void setDataSize(int dataSize) { - getSearchResult().setDataSize(dataSize); - } - - - public void resetSearch() { - setSortBy1(null); - setSortBy2(null); - setSortBy3(null); - setSortByModifier1(SearchBase.SORT_BY_MODIFIER_ASC); - setSortByModifier2(SearchBase.SORT_BY_MODIFIER_ASC); - setSortByModifier3(SearchBase.SORT_BY_MODIFIER_ASC); - setPageNo(0); - setDataSize( -1); - } // resetSearch - - - public abstract boolean isCriteriaUpdated(); - - public boolean isSortingUpdated() { - return (!(Utilities.nvl(sortBy1).equals(Utilities.nvl(sortBy1Orig)) && - Utilities.nvl(sortBy2).equals(Utilities.nvl(sortBy2Orig)) && - Utilities.nvl(sortBy3).equals(Utilities.nvl(sortBy3Orig)) && - Utilities.nvl(sortByModifier1).equals(Utilities.nvl(sortByModifier1Orig)) && - Utilities.nvl(sortByModifier2).equals(Utilities.nvl(sortByModifier2Orig)) && - Utilities.nvl(sortByModifier3).equals(Utilities.nvl(sortByModifier3Orig)))); - } // isSortingUpdated - -} // SearchBase diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/support/SearchResult.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/support/SearchResult.java deleted file mode 100644 index 4a2c05f1..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/command/support/SearchResult.java +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.command.support; - -import java.util.ArrayList; -import java.util.List; - -@SuppressWarnings("rawtypes") -public class SearchResult extends ArrayList implements java.io.Serializable { - /** - * - */ - private static final long serialVersionUID = -451947878984459011L; - private int pageNo = 0; - private int pageSize = 50; - private int dataSize = -1; - - private String accessType = null; - - public SearchResult() {} - - @SuppressWarnings("unchecked") - public SearchResult(List items) { - super(items); - } - - public int getPageNo() { return pageNo; } - public int getPageSize() { return pageSize; } - public int getDataSize() { return dataSize; } - - public int getSize() { return size(); } // for Struts bean property access - - public String getAccessType() { return accessType; } - - public void setPageNo(int pageNo) { this.pageNo=pageNo; } - public void setPageSize(int pageSize) { this.dataSize=pageSize; } - public void setDataSize(int dataSize) { this.dataSize=dataSize; } - - public void setAccessType(String accessType) { this.accessType = accessType; } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/AppConfig.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/AppConfig.java deleted file mode 100644 index 3a4753e3..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/AppConfig.java +++ /dev/null @@ -1,301 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.conf; - -import java.util.ArrayList; -import java.util.List; - -import javax.sql.DataSource; - -import org.openecomp.portalsdk.core.interceptor.ResourceInterceptor; -import org.openecomp.portalsdk.core.interceptor.SessionTimeoutInterceptor; -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.format.AppMessagesEnum; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.menu.MenuBuilder; -import org.openecomp.portalsdk.core.service.DataAccessService; -import org.openecomp.portalsdk.core.service.DataAccessServiceImpl; -import org.openecomp.portalsdk.core.util.CipherUtil; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.AppUtils; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.annotation.Bean; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; -import org.springframework.web.servlet.view.UrlBasedViewResolver; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; -import org.springframework.web.servlet.view.tiles3.TilesView; - -import com.mchange.v2.c3p0.ComboPooledDataSource; - -/** - * Configures Spring features in the ECOMP Portal SDK including request - * interceptors and view resolvers. Application should subclass and override - * methods as needed. - */ -public class AppConfig extends WebMvcConfigurerAdapter implements Configurable, ApplicationContextAware { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AppConfig.class); - - private final List tileDefinitions = new ArrayList(); - protected ApplicationContext appApplicationContext = null; - - public AppConfig() { - //loads all default fields and marks logging - //has been started for each log file type. - initGlobalLocalContext(); - } - - /** - * Creates and returns a new instance of a secondary (order=2) - * {@link ViewResolver} that finds files by adding prefix "/WEB-INF/jsp/" - * and suffix ".jsp" to the base view name. - * - * @return New instance of {@link ViewResolver}. - */ - @Bean - public ViewResolver viewResolver() { - InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); - viewResolver.setViewClass(JstlView.class); - viewResolver.setPrefix("/WEB-INF/jsp/"); - viewResolver.setSuffix(".jsp"); - viewResolver.setOrder(2); - return viewResolver; - } - - /** - * Loads all the default logging fields into the - * global MDC context and marks each log file type - * that logging has been started. - */ - private void initGlobalLocalContext() { - logger.init(); - } - - /* - * Any requests from the url pattern /static/**, Spring will look for the - * resources from the /static/ Same as in xml - */ - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - // registry.addResourceHandler("/static/**").addResourceLocations("/static/"); - registry.addResourceHandler("/**").addResourceLocations("/"); - } - - /** - * Creates and returns a new instance of a {@link DataAccessService} class. - * - * @return New instance of {@link DataAccessService}. - */ - @Bean - public DataAccessService dataAccessService() { - return new DataAccessServiceImpl(); - } - - /** - * Creates and returns a new instance of a {@link SystemProperties} class. - * - * @return New instance of {@link SystemProperties}. - */ - @Bean - public SystemProperties systemProperties() { - return new SystemProperties(); - } - - /** - * Creates and returns a new instance of a {@link MenuBuilder} class. - * - * @return New instance of {@link MenuBuilder}. - */ - @Bean - public MenuBuilder menuBuilder() { - return new MenuBuilder(); - } - - /** - * Creates and returns a new instance of a {@link UserUtils} class. - * - * @return New instance of {@link UserUtils}. - */ - @Bean - public UserUtils userUtil() { - return new UserUtils(); - } - - /** - * Creates and returns a new instance of an {@link AppUtils} class. - * - * @return New instance of {@link AppUtils}. - */ - @Bean - public AppUtils appUtils() { - return new AppUtils(); - } - - /** - * Creates and returns a new instance of a {@link TilesConfigurer} class. - * - * @return New instance of {@link TilesConfigurer}. - */ - @Bean - public TilesConfigurer tilesConfigurer() { - TilesConfigurer tilesConfigurer = new TilesConfigurer(); - tilesConfigurer.setDefinitions(tileDefinitions()); - tilesConfigurer.setCheckRefresh(true); - return tilesConfigurer; - } - - /** - * - * Application Data Source - * - * @return DataSource Object - */ - - @Bean - public DataSource dataSource() throws Exception { - systemProperties(); - ComboPooledDataSource dataSource = new ComboPooledDataSource(); - try { - dataSource.setDriverClass(SystemProperties.getProperty(SystemProperties.DB_DRIVER)); - dataSource.setJdbcUrl(SystemProperties.getProperty(SystemProperties.DB_CONNECTIONURL)); - dataSource.setUser(SystemProperties.getProperty(SystemProperties.DB_USERNAME)); - // dataSource.setPassword(SystemProperties.getProperty(SystemProperties.DB_PASSWOR)); - String password = SystemProperties.getProperty(SystemProperties.DB_PASSWOR); - if (SystemProperties.containsProperty(SystemProperties.DB_ENCRYPT_FLAG)) { - String encryptFlag = SystemProperties.getProperty(SystemProperties.DB_ENCRYPT_FLAG); - if (encryptFlag != null && encryptFlag.equalsIgnoreCase("true")) { - password = CipherUtil.decrypt(password); - } - } - dataSource.setPassword(password); - dataSource - .setMinPoolSize(Integer.parseInt(SystemProperties.getProperty(SystemProperties.DB_MIN_POOL_SIZE))); - dataSource - .setMaxPoolSize(Integer.parseInt(SystemProperties.getProperty(SystemProperties.DB_MAX_POOL_SIZE))); - dataSource.setIdleConnectionTestPeriod( - Integer.parseInt(SystemProperties.getProperty(SystemProperties.IDLE_CONNECTION_TEST_PERIOD))); - dataSource.setTestConnectionOnCheckout(true); - dataSource.setPreferredTestQuery("SELECT 1"); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Error initializing database, verify database settings in properties file: " - + UserUtils.getStackTrace(e),AlarmSeverityEnum.CRITICAL); - logger.error(EELFLoggerDelegate.debugLogger, "Error initializing database, verify database settings in properties file: " - + UserUtils.getStackTrace(e),AlarmSeverityEnum.CRITICAL); - // Raise an alarm that opening a connection to the database is - // failed. - logger.logEcompError(AppMessagesEnum.BeDaoSystemError); - throw e; - } - return dataSource; - } - - /* - * TODO: Check whether it is appropriate to extend the list of tile - * definitions at every invocation. - */ - protected String[] tileDefinitions() { - tileDefinitions.add("/WEB-INF/fusion/defs/definitions.xml"); - tileDefinitions.addAll(addTileDefinitions()); - - return tileDefinitions.toArray(new String[0]); - } - - /** - * Creates and returns a new empty list. This method should be overridden by - * child classes. - * - * @return An empty list. - */ - public List addTileDefinitions() { - return new ArrayList(); - } - - /** - * Creates and returns a new instance of a primary (order=1) - * {@link UrlBasedViewResolver} that finds files using the contents of - * definitions.xml files. - * - * @return New instance of {@link UrlBasedViewResolver} - */ - @Bean - public UrlBasedViewResolver tileViewResolver() { - UrlBasedViewResolver viewResolver = new UrlBasedViewResolver(); - viewResolver.setViewClass(TilesView.class); - viewResolver.setOrder(1); - return viewResolver; - } - - /** - * Adds new instances of the following interceptors to the specified - * interceptor registry: {@link SessionTimeoutInterceptor}, - * {@link ResourceInterceptor} - */ - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(new SessionTimeoutInterceptor()) - .excludePathPatterns(getExcludeUrlPathsForSessionTimeout()); - registry.addInterceptor(resourceInterceptor()); - } - - /** - * Creates and returns a new instance of a {@link ResourceInterceptor}. - * - * @return New instance of {@link ResourceInterceptor} - */ - @Bean - public ResourceInterceptor resourceInterceptor() { - return new ResourceInterceptor(); - } - - private String[] excludeUrlPathsForSessionTimeout = {}; - - /** - * Gets the array of Strings that are paths excluded for session timeout. - * - * @return Array of String - */ - public String[] getExcludeUrlPathsForSessionTimeout() { - return excludeUrlPathsForSessionTimeout; - } - - /** - * Sets the array of Strings that are paths excluded for session timeout. - */ - public void setExcludeUrlPathsForSessionTimeout(final String... excludeUrlPathsForSessionTimeout) { - this.excludeUrlPathsForSessionTimeout = excludeUrlPathsForSessionTimeout; - } - - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - appApplicationContext = applicationContext; - - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/AppInitializer.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/AppInitializer.java deleted file mode 100644 index df0d56d6..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/AppInitializer.java +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.conf; - -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; - -public abstract class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AppInitializer.class); - private final String activeProfile = "src"; - - @Override - protected WebApplicationContext createServletApplicationContext() { - WebApplicationContext context = super.createServletApplicationContext(); - - try { - - ((ConfigurableEnvironment) context.getEnvironment()).setActiveProfiles(activeProfile); - } catch (Exception e) { - - logger.error(EELFLoggerDelegate.errorLogger, "Unable to set the active profile" + e.getMessage(),AlarmSeverityEnum.MAJOR); - throw e; - - } - - return context; - } - - @Override - protected Class[] getRootConfigClasses() { - return null; - } - - @Override - protected Class[] getServletConfigClasses() { - - return new Class[] { AppConfig.class }; - } - - /* - * URL request will direct to the Spring dispatcher for processing - */ - @Override - protected String[] getServletMappings() { - return new String[] { "/" }; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/HibernateConfiguration.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/HibernateConfiguration.java deleted file mode 100644 index b70ced48..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/HibernateConfiguration.java +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.conf; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import javax.sql.DataSource; - -import org.hibernate.SessionFactory; -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.orm.hibernate4.HibernateTransactionManager; -import org.springframework.orm.hibernate4.LocalSessionFactoryBean; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import com.mchange.v2.c3p0.ComboPooledDataSource; - -@Configuration -@EnableTransactionManagement -public class HibernateConfiguration { - - @Autowired - private SystemProperties systemProperties; - - @Autowired - private HibernateMappingLocatable mappingLocate; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(HibernateConfiguration.class); - - DataSource dataSource; - - - @Bean - public LocalSessionFactoryBean sessionFactory() { - LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); - sessionFactory.setDataSource(getDataSource()); - sessionFactory.setPackagesToScan(new String[] { "org.openecomp"}); - sessionFactory.setHibernateProperties(hibernateProperties()); - sessionFactory.setMappingLocations(mappingLocate.getMappingLocations()); - return sessionFactory; - } - - - - - @SuppressWarnings("rawtypes") - @Bean - public Map dataSourceMap() throws Exception { - Connection conn = null; - Statement stmt = null; - Map dataSourceMap = new HashMap(); - - try { - conn = getDataSource().getConnection(); - stmt = conn.createStatement(); - String sql; - sql = "SELECT schema_id,datasource_type,connection_url,user_name,password,driver_class,min_pool_size,max_pool_size,idle_connection_test_period FROM schema_info"; - ResultSet rs = stmt.executeQuery(sql); - - while (rs.next()) { - ComboPooledDataSource dataSource = new ComboPooledDataSource(); - dataSource.setDriverClass(rs.getString("driver_class")); - dataSource.setJdbcUrl(rs.getString("connection_url")); - dataSource.setUser(rs.getString("user_name")); - dataSource.setPassword(rs.getString("password")); - dataSource.setMinPoolSize(rs.getInt("min_pool_size")); - dataSource.setMaxPoolSize(rs.getInt("max_pool_size")); - dataSource.setIdleConnectionTestPeriod(rs.getInt("idle_connection_test_period")); - dataSourceMap.put(rs.getString("schema_id"), dataSource); - } - rs.close(); - stmt.close(); - conn.close(); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Error initializing database, verify database settings in properties file: " + e.getMessage(),AlarmSeverityEnum.CRITICAL); - e.printStackTrace(); - dataSourceMap = null; - throw e; - } finally { - try { - if (stmt != null) - stmt.close(); - } catch (SQLException se2) {} - try { - if (conn != null) - conn.close(); - } catch (SQLException se) { se.printStackTrace();} - } - - return dataSourceMap; - } - - private Properties hibernateProperties() { - Properties properties = new Properties(); - properties.put("hibernate.dialect", SystemProperties.getProperty(SystemProperties.HB_DIALECT)); - properties.put("hibernate.show_sql", SystemProperties.getProperty(SystemProperties.HB_SHOW_SQL)); - return properties; - } - - @Bean - @Autowired - public HibernateTransactionManager transactionManager(SessionFactory s) { - HibernateTransactionManager txManager = new HibernateTransactionManager(); - txManager.setSessionFactory(s); - return txManager; - } - - public SystemProperties getSystemProperties() { - return systemProperties; - } - - public void setSystemProperties(SystemProperties systemProperties) { - this.systemProperties = systemProperties; - } - - - - - public DataSource getDataSource() { - return dataSource; - } - - - @Autowired - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/HibernateMappingLocatable.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/HibernateMappingLocatable.java deleted file mode 100644 index a3bbe18d..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/conf/HibernateMappingLocatable.java +++ /dev/null @@ -1,28 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.conf; - -import org.springframework.core.io.Resource; - -public interface HibernateMappingLocatable { - - public Resource[] getMappingLocations(); - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/AdminAuthGenericController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/AdminAuthGenericController.java deleted file mode 100644 index 8a1f1d2c..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/AdminAuthGenericController.java +++ /dev/null @@ -1,134 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; -/*package org.openecomp.portalsdk.core.controller; - -import java.io.IOException; -import java.util.List; - -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.onboarding.crossapi.IGenericRolesService; -import org.openecomp.portalsdk.core.onboarding.crossapi.IGenericUsersService; -import com.fasterxml.jackson.core.JsonProcessingException; - - -@RestController -@RequestMapping("/api") -public class AdminAuthGenericController extends RestrictedRESTfulBaseController { - protected final Log logger = LogFactory.getLog(getClass()); - @Autowired - IGenericUsersService genericUserService; - - @Autowired - IGenericRolesService genericRolesService; - - *//** - * RESTful service method to fetch available roles - * @return - *//* - @RequestMapping(value={"/roles"}, method = RequestMethod.GET, produces = "application/json") - public String getAvailableRoles() throws Exception{ - return genericRolesService.getAvailableRoles(); - } - - *//** - * RESTful service method to save user - expects user details in json string - * @param userJson - *//* - @RequestMapping(value={"/user"}, method = RequestMethod.POST) - public String pushUser(@RequestBody String userJson) throws Exception{ - return genericUserService.pushUser(userJson); - } - - *//** - * RESTful service method to edit user - expects user details in json string - * @param userJson - *//* - @RequestMapping(value={"/user/{loginId}"}, method = RequestMethod.POST) - public String editUser(@PathVariable("loginId") String loginId, @RequestBody String userJson) throws Exception{ - return genericUserService.editUser(loginId, userJson); - } - - *//** - * RESTful service method to save user role using user's login Id and details in role Json string - * @param loginId - * @param roleJson - * @throws JsonProcessingException - *//* - @RequestMapping(value={"/user/{loginId}/roles"}, method = RequestMethod.POST) - public String pushUserRole(@PathVariable("loginId") String loginId, @RequestBody String rolesJson) throws Exception{ - return genericRolesService.pushUserRole(loginId, rolesJson); - } - - - *//** - * Below method is to retrieve user - TODO @Talasila - Created to test the fn_app relation to fn_user_role. If not needed, please remove this method. - * @param id - * @return - * @throws Exception - *//* - @RequestMapping(value={"/user/{loginId}"}, method = RequestMethod.GET, produces = "application/json") - public String getUser(@PathVariable("loginId") String loginId) throws Exception{ - return genericUserService.getUser(loginId); - } - - @RequestMapping(value={"/users"}, method = RequestMethod.GET, produces = "application/json") - public String getUsers() throws Exception{ - return genericUserService.getUsers(); - } - - *//** - * RESTful service method to fetch individual user's roles using user's loginId - * @param loginId - * @return - *//* - @RequestMapping(value={"/user/{loginId}/roles"}, method = RequestMethod.GET, produces = "application/json") - public String getUserRoles(@PathVariable("loginId") String loginId) throws Exception{ - return genericRolesService.getUserRoles(loginId); - } - - *//** - * RESTful service method to fetch available roles - * @return - *//* - - //Commenting this out as it depends on Role API - Ikram - @RequestMapping(value={"/rolesFull"}, method = RequestMethod.GET, produces = "application/json") - public List getAvailableFullRoles(){ - return genericRolesService.getAvailableFullRoles(); - } - - @ExceptionHandler(Exception.class) - void handleBadRequests(Exception e, HttpServletResponse response) throws IOException { - response.sendError(HttpStatus.BAD_REQUEST.value(),e.getMessage()); - } -} -*/ diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/AngularAdminController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/AngularAdminController.java deleted file mode 100644 index e3aab7dd..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/AngularAdminController.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -@Controller -@RequestMapping("/") -public class AngularAdminController extends RestrictedBaseController{ - - @RequestMapping(value = {"/userProfile" }, method = RequestMethod.GET) - public ModelAndView view(HttpServletRequest request) { - Map model = new HashMap(); - - return new ModelAndView("user_profile_list","model", model); - } - - @RequestMapping(value = {"/admin" }, method = RequestMethod.GET) - public ModelAndView adminView(HttpServletRequest request) { - Map model = new HashMap(); - - return new ModelAndView(getViewName(),"model", model); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/BroadcastController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/BroadcastController.java deleted file mode 100644 index 6dfe9cac..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/BroadcastController.java +++ /dev/null @@ -1,130 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.BroadcastMessage; -import org.openecomp.portalsdk.core.service.BroadcastService; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.AppUtils; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Controller -@RequestMapping("/") -public class BroadcastController extends RestrictedBaseController { - - @Autowired - private BroadcastService broadcastService; - - @RequestMapping(value = { "/broadcast" }, method = RequestMethod.GET) - public ModelAndView broadcast(HttpServletRequest request) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - try { - model.put("broadcastMessage", mapper.writeValueAsString(broadcastService.getBroadcastMessage(request))); - model.put("broadcastSites", mapper.writeValueAsString(referenceData(request).get("broadcastSites"))); - } catch (Exception e) { - e.printStackTrace(); - } - return new ModelAndView(getViewName(), model); - } - - @RequestMapping(value = { "/get_broadcast" }, method = RequestMethod.GET) - public void getBroadcast(HttpServletRequest request, HttpServletResponse response) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - try { - - model.put("broadcastMessage", mapper.writeValueAsString(broadcastService.getBroadcastMessage(request))); - model.put("broadcastSites", mapper.writeValueAsString(referenceData(request).get("broadcastSites"))); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - - } catch (Exception e) { - e.printStackTrace(); - } - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected Map referenceData(HttpServletRequest request) { - Map lookupData = new HashMap(); - - if ("true".equals(SystemProperties.getProperty(SystemProperties.CLUSTERED))) { - lookupData.put("broadcastSites", AppUtils.getLookupList("fn_lu_broadcast_site", "broadcast_site_cd", - "broadcast_site_descr", "", "broadcast_site_descr")); - } - - return lookupData; - } - - @RequestMapping(value = { "/broadcast/save" }, method = RequestMethod.POST) - public ModelAndView save(HttpServletRequest request, HttpServletResponse response) throws Exception { - - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - BroadcastMessage broadcastMessage = mapper.readValue(root.get("broadcastMessage").toString(), - BroadcastMessage.class); - - broadcastService.saveBroadcastMessage(broadcastMessage); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - String responseString = mapper.writeValueAsString(broadcastMessage); - JSONObject j = new JSONObject("{broadcastMessage: " + responseString + "}"); - - out.write(j.toString()); - - return null; - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/BroadcastListController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/BroadcastListController.java deleted file mode 100644 index 7e0789c2..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/BroadcastListController.java +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.BroadcastMessage; -import org.openecomp.portalsdk.core.service.BroadcastService; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Controller -@RequestMapping("/") -public class BroadcastListController extends RestrictedBaseController { - - @Autowired - private BroadcastService broadcastService; - - @RequestMapping(value = { "/broadcast_list" }, method = RequestMethod.GET) - public ModelAndView broadcastList(HttpServletRequest request) { - Map model = new HashMap(); - - model.put("model", broadcastService.getBcModel(request)); - return new ModelAndView(getViewName(), model); - } - - @RequestMapping(value = { "/get_broadcast_list" }, method = RequestMethod.GET) - public void getBroadcast(HttpServletRequest request, HttpServletResponse response) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - try { - model.put("model", broadcastService.getBcModel(request)); - model.put("messagesList", broadcastService.getBcModel(request).get("messagesList")); - model.put("messageLocations", broadcastService.getBcModel(request).get("messageLocations")); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - @RequestMapping(value = { "/broadcast_list/remove" }, method = RequestMethod.POST) - public ModelAndView remove(HttpServletRequest request, HttpServletResponse response) throws Exception { - - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - BroadcastMessage broadcastMessage = mapper.readValue(root.get("broadcastMessage").toString(), - BroadcastMessage.class); - - broadcastService.removeBroadcastMessage(broadcastMessage); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - String responseString = mapper.writeValueAsString(broadcastMessage); - JSONObject j = new JSONObject("{broadcastMessage: " + responseString + "}"); - - out.write(j.toString()); - - return null; - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - @RequestMapping(value = { "/broadcast_list/toggleActive" }, method = RequestMethod.POST) - public ModelAndView toggleActive(HttpServletRequest request, HttpServletResponse response) throws Exception { - - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - BroadcastMessage broadcastMessage = mapper.readValue(root.get("broadcastMessage").toString(), - BroadcastMessage.class); - - broadcastService.saveBroadcastMessage(broadcastMessage); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - String responseString = mapper.writeValueAsString(broadcastMessage); - JSONObject j = new JSONObject("{broadcastMessage: " + responseString + "}"); - - out.write(j.toString()); - - return null; - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CacheAdminController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CacheAdminController.java deleted file mode 100644 index 095c41b6..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CacheAdminController.java +++ /dev/null @@ -1,252 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.jcs.JCS; -import org.apache.jcs.admin.CacheRegionInfo; -import org.apache.jcs.admin.JCSAdminBean; -import org.apache.jcs.engine.behavior.ICacheElement; -import org.json.JSONArray; -import org.json.JSONObject; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - -@Controller -@RequestMapping("/") -public class CacheAdminController extends RestrictedBaseController { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CacheAdminController.class); - private JCSAdminBean jcsAdminBean = new JCSAdminBean(); - - @RequestMapping(value = {"/jcs_admin" }, method = RequestMethod.GET) - public ModelAndView cacheAdmin(HttpServletRequest request) { - Map model = new HashMap(); - - model.put("model", getRegions()); - - return new ModelAndView(getViewName(),model); - } - - @RequestMapping(value = {"/get_regions" }, method = RequestMethod.GET) - public void getRegions(HttpServletRequest request,HttpServletResponse response) { - // ObjectMapper mapper = new ObjectMapper(); - try{ - JsonMessage msg = new JsonMessage(getRegions().toString()); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - }catch (Exception e) { - e.printStackTrace(); - } - - } - - @RequestMapping(value = {"/jcs_admin/clearRegion" }, method = RequestMethod.GET) - public void clearRegion(HttpServletRequest request,HttpServletResponse response) throws Exception { - String cacheName = (String) request.getParameter("cacheName"); - clearCacheRegion(cacheName); - - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.write(getRegions().toString()); - } - - @RequestMapping(value = {"/jcs_admin/clearAll" }, method = RequestMethod.GET) - public void clearAll(HttpServletRequest request,HttpServletResponse response) throws Exception { - clearAllRegions(); - - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.write(getRegions().toString()); - } - - @RequestMapping(value = {"/jcs_admin/clearItem" }, method = RequestMethod.GET) - public void clearItem(HttpServletRequest request,HttpServletResponse response) throws Exception { - String keyName = (String) request.getParameter("keyName"); - String cacheName = (String) request.getParameter("cacheName"); - clearCacheRegionItem(cacheName, keyName); - - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.write(getRegions().toString()); - } - - @RequestMapping(value = {"/jcs_admin/showItemDetails" }, method = RequestMethod.GET) - public void showItemDetails(HttpServletRequest request,HttpServletResponse response) throws Exception { - String cacheName = (String) request.getParameter("cacheName"); - String keyName = (String) request.getParameter("keyName"); - String details = null; - - try { - details = getItemDetails(cacheName, keyName); - } catch (Exception e) { - details = "There was an error retrieving the region details. Please try again."; - logger.error(EELFLoggerDelegate.errorLogger, "An error has occurred while retrieving the item details for the cache region - " - + cacheName + e.getMessage()); - - } - - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.write(details); - } - - @RequestMapping(value = {"/jcs_admin/showRegionDetails" }, method = RequestMethod.GET) - public void showRegionDetails(HttpServletRequest request,HttpServletResponse response) throws Exception { - String cacheName = (String) request.getParameter("cacheName"); - String details = null; - - try { - details = getRegionStats(cacheName); - } catch (Exception e) { - details = "There was an error retrieving the region details. Please try again."; - logger.error(EELFLoggerDelegate.errorLogger, "An error has occurred while retrieving the region details for the cache region - " - + cacheName + e.getMessage()); - - } - - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.write(details); - } - - @SuppressWarnings("unchecked") - public JSONArray getRegions(){ - LinkedList regions = null; - JSONArray ja = new JSONArray(); - try { - regions = getJcsAdminBean().buildCacheInfo(); - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); - for (CacheRegionInfo cri : regions) { - JSONObject jo = new JSONObject(); - jo.put("cacheName", cri.getCache().getCacheName()); - jo.put("size", cri.getCache().getSize()); - jo.put("byteCount", cri.getByteCount()); - jo.put("status", cri.getStatus()); - jo.put("hitCountRam", cri.getCache().getHitCountRam()); - jo.put("hitCountAux", cri.getCache().getHitCountAux()); - jo.put("missCountNotFound", cri.getCache().getMissCountNotFound()); - jo.put("missCountExpired", cri.getCache().getMissCountExpired()); - jo.put("items",new JSONArray(mapper.writeValueAsString(getRegionItems(cri.getCache().getCacheName())))); - ja.put(jo); - } - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "An error has occurred while retrieving the list of cache regions" + e.getMessage()); - - } - - return ja; - } - - private String getRegionStats(String cacheName) throws Exception { - String stats = ""; - - JCS cache = JCS.getInstance(cacheName); - stats = cache.getStats(); - - return stats; - } - - private String getItemDetails(String cacheName, String keyName) - throws Exception { - String details = ""; - - JCS cache = JCS.getInstance(cacheName); - ICacheElement element = cache.getCacheElement(keyName); - - if (element != null) { - ObjectMapper mapper = new ObjectMapper(); - mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); - details = mapper.writeValueAsString(element); - } - - return details; - } - - @SuppressWarnings("rawtypes") - private List getRegionItems(String cacheName) { - List items = null; - - try { - items = getJcsAdminBean().buildElementInfo(cacheName); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "An error has occurred while retrieving the list of items for cache region - " - + cacheName + e.getMessage()); - - } - - return items; - } - - private void clearAllRegions() { - try { - getJcsAdminBean().clearAllRegions(); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "An error has occurred while clearing all cache regions." + e.getMessage()); - - } - } - - private void clearCacheRegion(String cacheName) { - try { - getJcsAdminBean().clearRegion(cacheName); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "An error has occurred while clearing the cache region - " - + cacheName + e.getMessage()); - - } - } - - private void clearCacheRegionItem(String cacheName, String keyName) { - try { - getJcsAdminBean().removeItem(cacheName, keyName); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "An error has occurred while removing cache region item - " - + keyName + e.getMessage()); - - } - } - - public JCSAdminBean getJcsAdminBean() { - return jcsAdminBean; - } - - public void setJcsAdminBean(JCSAdminBean jcsAdminBean) { - this.jcsAdminBean = jcsAdminBean; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CollaborateListController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CollaborateListController.java deleted file mode 100644 index 9e43e948..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CollaborateListController.java +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.UserProfileService; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.databind.ObjectMapper; - -@Controller -@RequestMapping("/") -public class CollaborateListController extends RestrictedBaseController{ - @Autowired - UserProfileService service; - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CollaborateListController.class); - - @RequestMapping(value = {"/collaborate_list" }, method = RequestMethod.GET) - public ModelAndView ProfileSearch(HttpServletRequest request) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - User user = UserUtils.getUserSession(request); - - List profileList =null; - try { - profileList = service.findAllUserWithOnOffline(user.getOrgUserId()); - model.put("profileList", mapper.writeValueAsString(profileList)); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Error happened during collaborate list search" + e.getMessage()); - - } - return new ModelAndView(getViewName(),"model", model); - } - - @RequestMapping(value = {"/get_collaborate_list" }, method = RequestMethod.GET) - public void getCollaborateList(HttpServletRequest request,HttpServletResponse response) { - - ObjectMapper mapper = new ObjectMapper(); - User user = UserUtils.getUserSession(request); - - List profileList =null; - try { - profileList = service.findAllUserWithOnOffline(user.getOrgUserId()); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(profileList)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Error happened during get collaborate list" + e.getMessage()); - - } - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CollaborationController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CollaborationController.java deleted file mode 100644 index a9c1d44b..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/CollaborationController.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -@Controller -@RequestMapping("/") -public class CollaborationController extends RestrictedBaseController{ - - @RequestMapping(value = {"/collaboration" }, method = RequestMethod.GET) - public ModelAndView view(HttpServletRequest request) { - Map model = new HashMap(); - User user = UserUtils.getUserSession(request); - - model.put("name",(user.getFirstName() + " " + (user.getLastName() != null? user.getLastName().substring(0,1): "" ))); - return new ModelAndView(getViewName(),"model", model); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ElementModelController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ElementModelController.java deleted file mode 100644 index a6e7b966..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ElementModelController.java +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.openecomp.portalsdk.core.service.ElementLinkService; -import org.openecomp.portalsdk.core.service.ElementMapService; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - - -@Controller -@RequestMapping("/") -public class ElementModelController extends RestrictedBaseController{ - - @RequestMapping(value = {"/elementMapLayout" }, method = RequestMethod.POST) - public ModelAndView layout(HttpServletRequest request, - HttpServletResponse response) throws Exception{ - - Map model = new HashMap(); - String collapseDomains = request.getParameter("collapsedDomains"); - String expandDomains = request.getParameter("expandedDomains"); - - String contentFileName = request.getParameter("contentFileName"); - String layoutFileName = request.getParameter("layoutFileName"); - - ElementMapService main = new ElementMapService(); - String yamlString = main.main1(new String[]{collapseDomains,expandDomains, contentFileName, layoutFileName }); - - //response.setContentType("application/json"); - //PrintWriter out = response.getWriter(); - //out.print(yamlString); - //out.flush(); - - //return null; - model.put("output_string", yamlString); - return new ModelAndView("data_out", "model", model); - } - - @RequestMapping(value = {"/elementMapLink" }, method = RequestMethod.POST) - public ModelAndView callflow(HttpServletRequest request, - HttpServletResponse response) throws Exception{ - - Map model = new HashMap(); - String callFlowName = request.getParameter("callFlowName"); - String callFlowStep = request.getParameter("callFlowStep"); - - ElementLinkService main = new ElementLinkService(); - String yamlString = main.main1(new String[]{callFlowName,callFlowStep }); - model.put("output_string", yamlString); - return new ModelAndView("data_out", "model", model); - } - - public ModelAndView callflowAdditional(HttpServletRequest request, - HttpServletResponse response) throws Exception{ - - Map model = new HashMap(); - String callFlowName = request.getParameter("callFlowName"); - String callFlowStep = request.getParameter("callFlowStep"); - - ElementLinkService main = new ElementLinkService(); - String yamlString = main.main2(new String[]{callFlowName,callFlowStep }); - model.put("output_string", yamlString); - return new ModelAndView("data_out", "model", model); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ExternalLoginController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ExternalLoginController.java deleted file mode 100644 index 90e47d42..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ExternalLoginController.java +++ /dev/null @@ -1,121 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.openecomp.portalsdk.core.command.LoginBean; -import org.openecomp.portalsdk.core.menu.MenuProperties; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalTimeoutHandler; -import org.openecomp.portalsdk.core.service.LoginService; -import org.openecomp.portalsdk.core.service.ProfileService; -import org.openecomp.portalsdk.core.web.support.AppUtils; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.servlet.ModelAndView; - -@Controller -@RequestMapping("/") -public class ExternalLoginController extends UnRestrictedBaseController{ - @Autowired - ProfileService service; - @Autowired - private LoginService loginService; - String viewName; - - @RequestMapping(value = {"/login_external.htm" }, method = RequestMethod.GET) - public ModelAndView ExternalLogin(HttpServletRequest request) { - Map model = new HashMap(); - return new ModelAndView(getViewName(),"model", model); - } - - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @RequestMapping(value = {"/login_external/login" }, method = RequestMethod.POST) - public @ResponseBody String ExternalLogin(HttpServletRequest request, HttpServletResponse response) throws Exception{ - - Map model = new HashMap(); - LoginBean commandBean = new LoginBean(); - String loginId = request.getParameter("loginId"); - String password = request.getParameter("password"); - commandBean.setLoginId(loginId); - commandBean.setLoginPwd(password); - HashMap additionalParamsMap = new HashMap(); - - commandBean = getLoginService().findUser(commandBean, (String)request.getAttribute(MenuProperties.MENU_PROPERTIES_FILENAME_KEY), - additionalParamsMap); - - if (commandBean.getUser() == null) { - String loginErrorMessage = (commandBean.getLoginErrorMessage() != null) ? commandBean.getLoginErrorMessage() - : "login.error.external.invalid"; - model.put("error", loginErrorMessage); - String[] errorCodes = new String[1]; - errorCodes[0] = loginErrorMessage; - return "failure"; - - } - else { - // store the currently logged in user's information in the session - UserUtils.setUserSession(request, commandBean.getUser(), commandBean.getMenu(), commandBean.getBusinessDirectMenu(), - null); - initateSessionMgtHandler(request); - // user has been authenticated, now take them to the welcome page - return "success"; - - } - - - } - - public String getJessionId(HttpServletRequest request){ - - return request.getSession().getId(); - - } - - protected void initateSessionMgtHandler(HttpServletRequest request) { - String jSessionId = getJessionId(request); - PortalTimeoutHandler.sessionCreated(jSessionId, jSessionId, AppUtils.getSession(request)); - } - - public String getViewName() { - return viewName; - } - public void setViewName(String viewName) { - this.viewName = viewName; - } - public LoginService getLoginService() { - return loginService; - } - - public void setLoginService(LoginService loginService) { - this.loginService = loginService; - } - -} - diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FavoritesController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FavoritesController.java deleted file mode 100644 index b2ad61f4..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FavoritesController.java +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.App; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.aspect.AuditLog; -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.onboarding.rest.FavoritesClient; -import org.openecomp.portalsdk.core.service.AppService; -import org.openecomp.portalsdk.core.util.CipherUtil; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.slf4j.MDC; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.EnableAspectJAutoProxy; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -@Controller -@RequestMapping("/") -@org.springframework.context.annotation.Configuration -@EnableAspectJAutoProxy -@AuditLog -public class FavoritesController extends UnRestrictedBaseController { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(FavoritesController.class); - - @Autowired - AppService appService; - - /** - * Makes the REST API call to Portal Back-end and retrieves Favorite menu - * items for the currently logged in user. - * - * @param request - * @param response - */ - @RequestMapping(value = { "/get_favorites" }, method = RequestMethod.GET) - public void getFavorites(HttpServletRequest request, HttpServletResponse response) { - String appName = ""; - String requestId = ""; - String appUserName = ""; - String decryptedPwd = ""; - - try { - HttpSession session = request.getSession(); - User user = (User) session.getAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME)); - if (user == null || user.getId() == null) { - logger.info(EELFLoggerDelegate.errorLogger, - ("Http request did not contain user info, cannot retrieve favorites.")); - - response.setContentType("application/json"); - JSONArray jsonResponse = new JSONArray(); - JSONObject error = new JSONObject(); - error.put("error", "Http request did not contain user info, cannot retrieve favorites."); - jsonResponse.put(error); - response.getWriter().write(jsonResponse.toString()); - } else { - logger.info(EELFLoggerDelegate.errorLogger, - "Retrieving Favorites for the user '" + MDC.get(SystemProperties.MDC_LOGIN_ID) + "'."); - - App app = appService.getDefaultApp(); - if (app!=null) { - appName = app.getName(); - appUserName = app.getUsername(); - try{ - decryptedPwd = CipherUtil.decrypt(app.getAppPassword(), SystemProperties.getProperty(SystemProperties.Decryption_Key)); - } catch(Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred in WebServiceCallServiceImpl.get while decrypting the password. Details: " + e.getMessage()); - } - } else { - logger.warn(EELFLoggerDelegate.errorLogger, "Unable to locate the app information from the database."); - appName = SystemProperties.SDK_NAME; - } - requestId = MDC.get(MDC_KEY_REQUEST_ID); - - String jsonResponse = FavoritesClient.getFavorites(MDC.get(SystemProperties.MDC_LOGIN_ID), appName, requestId, appUserName, decryptedPwd); - - logger.debug(EELFLoggerDelegate.debugLogger, "FavoritesMenu response: " + jsonResponse); - - response.setContentType("application/json"); - response.getWriter().write(jsonResponse); - } - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, - "Exception occurred in FavoritesController.getFavorites while performing get_favorites. Details: " - + e.getMessage(), AlarmSeverityEnum.MINOR); - } - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FnMenuController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FnMenuController.java deleted file mode 100644 index f19a6f19..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FnMenuController.java +++ /dev/null @@ -1,224 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.Menu; -import org.openecomp.portalsdk.core.domain.MenuData; -import org.openecomp.portalsdk.core.service.FnMenuService; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * Description: this java class is a controller for Admin to add/edit/delete menu items from FN_MENU - */ - -@Controller -@RequestMapping("/") -public class FnMenuController extends RestrictedBaseController { - @Autowired - FnMenuService service; - - String viewName; - - @RequestMapping(value = {"/admin_fn_menu/get_parent_list" }, method = RequestMethod.GET) - public void getParentList(HttpServletRequest request,HttpServletResponse response) throws Exception { - ObjectMapper mapper = new ObjectMapper(); - try{ - - response.getWriter().write(mapper.writeValueAsString(service.getParentList())); - - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - - } - - } - - @RequestMapping(value = {"/admin_fn_menu/get_function_cd_list" }, method = RequestMethod.GET) - public void getFunctionCDList(HttpServletRequest request,HttpServletResponse response) throws Exception { - ObjectMapper mapper = new ObjectMapper(); - try{ - - response.getWriter().write(mapper.writeValueAsString(service.getFunctionCDList())); - - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - - } - - } - - @RequestMapping(value = {"/admin_fn_menu" }, method = RequestMethod.GET) - public void getFnMenuList(HttpServletRequest request,HttpServletResponse response) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - List temp =null; - List> childItemList = new ArrayList>(); - List parentList = new ArrayList<>(); - - try { - temp = service.getFnMenuItems(); - for(MenuData menu: temp){ - MenuData parentData = new MenuData(); - parentData.setId(menu.getId()); - parentData.setLabel(menu.getLabel()); - if(menu.getParentMenu()!=null){ - parentData.setParentId(menu.getParentMenu().getId()); - } - parentData.setAction(menu.getAction()); - parentData.setFunctionCd(menu.getFunctionCd()); - parentData.setImageSrc(menu.getImageSrc()); - parentData.setSortOrder(menu.getSortOrder()); - parentData.setActive(menu.isActive()); - parentData.setServlet(menu.getServlet()); - parentData.setQueryString(menu.getQueryString()); - parentData.setExternalUrl(menu.getExternalUrl()); - parentData.setTarget(menu.getTarget()); - parentData.setMenuSetCode(menu.getMenuSetCode()); - parentData.setSeparator(menu.isSeparator()); - parentData.setImageSrc(menu.getImageSrc()); - parentList.add(parentData); - List tempList = new ArrayList(); - childItemList.add(tempList); - } - model.put("fnMenuItems", parentList); - - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - } catch (JsonGenerationException e) { - e.printStackTrace(); - } catch (JsonMappingException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - } - - - @RequestMapping(value = {"/admin_fn_menu/updateFnMenu" }, method = RequestMethod.POST) - public ModelAndView updateFnMenu(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - try { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - Menu fnMenuItem = mapper.readValue(root.get("availableFnMenuItem").toString(), Menu.class); - - service.saveFnMenu(fnMenuItem); - request.getSession().removeAttribute(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_ATTRIBUTE_NAME)); - request.getSession().removeAttribute(SystemProperties.LEFT_MENU_CHILDREND); - request.getSession().removeAttribute(SystemProperties.LEFT_MENU_PARENT); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - String responseString = mapper.writeValueAsString(service.getMenuItem(fnMenuItem.getId())); - - out.write(responseString); - - return null; - - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - - } - return null; - - } - - @RequestMapping(value = {"/admin_fn_menu/removeMenuItem" }, method = RequestMethod.POST) - public ModelAndView removeFnMenu(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - try { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - Menu fnMenuItem = mapper.readValue(root.get("fnMenuItem").toString(), Menu.class); - Menu fnMenuItemRow = service.getMenuItemRow(fnMenuItem.getId()); - - service.removeMenuItem(fnMenuItemRow); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - String responseString = mapper.writeValueAsString(service.getMenuItem(fnMenuItem.getId())); - out.write(responseString); - - return null; - - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - - - } - return null; - - } - - public String getViewName() { - return viewName; - } - public void setViewName(String viewName) { - this.viewName = viewName; - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FuncMenuController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FuncMenuController.java deleted file mode 100644 index 5baebf00..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/FuncMenuController.java +++ /dev/null @@ -1,174 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; - -import java.io.IOException; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.App; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.aspect.AuditLog; -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; -import org.openecomp.portalsdk.core.onboarding.rest.FunctionalMenuClient; -import org.openecomp.portalsdk.core.onboarding.ueb.UebException; -import org.openecomp.portalsdk.core.onboarding.ueb.UebManager; -import org.openecomp.portalsdk.core.onboarding.ueb.UebMsg; -import org.openecomp.portalsdk.core.onboarding.ueb.UebMsgTypes; -import org.openecomp.portalsdk.core.service.AppService; -import org.openecomp.portalsdk.core.util.CipherUtil; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.slf4j.MDC; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.EnableAspectJAutoProxy; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -@Controller -@RequestMapping("/") -@org.springframework.context.annotation.Configuration -@EnableAspectJAutoProxy -public class FuncMenuController extends UnRestrictedBaseController{ - - @Autowired - AppService appService; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(FuncMenuController.class); - - @AuditLog - @RequestMapping(value = {"/get_functional_menu" }, method = RequestMethod.GET) - public void functionalMenu(HttpServletRequest request, HttpServletResponse response) { - - User user = UserUtils.getUserSession(request); - //JSONArray validMenu = new JSONArray("[{\"menuId\":140,\"column\":1,\"text\":\"RT SDK Menu\",\"parentMenuId\":139,\"url\":\"http://www.cnn.com\"},{\"menuId\":139,\"column\":1,\"text\":\"RT Menu\",\"parentMenuId\":11,\"url\":\"\"},{\"menuId\":11,\"column\":1,\"text\":\"Product Design\",\"parentMenuId\":1,\"url\":\"\"},{\"menuId\":1,\"column\":1,\"text\":\"Design\",\"url\":\"\"}]"); - - try { - if ( user != null ) { - String useRestForFunctionalMenu = PortalApiProperties.getProperty(PortalApiConstants.USE_REST_FOR_FUNCTIONAL_MENU); - String funcMenuJsonString = ""; - if (useRestForFunctionalMenu==null || useRestForFunctionalMenu=="" || useRestForFunctionalMenu.equalsIgnoreCase("false")) { - logger.info(EELFLoggerDelegate.errorLogger, "Making use of UEB communication and Requesting functional menu for user " + user.getOrgUserId()); - funcMenuJsonString = getFunctionalMenu(user.getOrgUserId()); - } else { - funcMenuJsonString = getFunctionalMenuViaREST(user.getOrgUserId()); - } - response.setContentType("application/json"); - response.getWriter().write(funcMenuJsonString); - } else { - logger.info(EELFLoggerDelegate.errorLogger, "Http request did not contain user info, cannot retrieve functional menu"); - response.setContentType("application/json"); - JSONArray jsonResponse = new JSONArray(); - JSONObject error = new JSONObject(); - error.put("error","Http request did not contain user info, cannot retrieve functional menu"); - jsonResponse.put(error); - response.getWriter().write(jsonResponse.toString()); - } - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - response.setContentType("application/json"); - JSONArray jsonResponse = new JSONArray(); - JSONObject error = new JSONObject(); - try { - if ( null == e.getMessage() ) { - error.put("error","No menu data"); - } else { - error.put("error",e.getMessage()); - } - jsonResponse.put(error); - response.getWriter().write(jsonResponse.toString()); - logger.error(EELFLoggerDelegate.errorLogger, "Error getting functional_menu: " + e.getMessage(),AlarmSeverityEnum.MAJOR); - } catch (IOException e1) { - e1.printStackTrace(); - } - } - - } - - //-------------------------------------------------------------------------- - // Makes a synchronous call to ECOMP Portal to get the JSON file that - // contains the contents of the functional menu. The JSON file will be - // in the payload of the returned UEB message. - //-------------------------------------------------------------------------- - private String getFunctionalMenu(String userId) throws UebException - { - String returnString = null; - UebMsg funcMenuUebMsg = null; - UebMsg msg = new UebMsg(); - msg.putMsgType(UebMsgTypes.UEB_MSG_TYPE_GET_FUNC_MENU); - msg.putUserId(userId); - funcMenuUebMsg = UebManager.getInstance().requestReply(msg); - if (funcMenuUebMsg != null) { - if (funcMenuUebMsg.getPayload().startsWith("Error:")) { - logger.error(EELFLoggerDelegate.errorLogger, "getFunctionalMenu received an error in UEB msg = " + funcMenuUebMsg.getPayload()); - } else { - returnString = funcMenuUebMsg.getPayload(); - } - } - - logger.debug(EELFLoggerDelegate.debugLogger, "FunctionalMenu response: " + returnString); - - return returnString; - } - - private String getFunctionalMenuViaREST(String userId) { - String appName = ""; - String requestId = ""; - String appUserName = ""; - String decryptedPwd = ""; - - logger.info(EELFLoggerDelegate.debugLogger, "Making use of REST API communication and Requesting functional menu for user " + userId); - - App app = appService.getDefaultApp(); - if (app!=null) { - appName = app.getName(); - appUserName = app.getUsername(); - try{ - decryptedPwd = CipherUtil.decrypt(app.getAppPassword(), SystemProperties.getProperty(SystemProperties.Decryption_Key)); - } catch(Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred in WebServiceCallServiceImpl.get while decrypting the password. Details: " + e.toString()); - } - } else { - logger.warn(EELFLoggerDelegate.errorLogger, "Unable to locate the app information from the database."); - appName = SystemProperties.SDK_NAME; - } - requestId = MDC.get(MDC_KEY_REQUEST_ID); - - String fnMenu = null; - try { - fnMenu = FunctionalMenuClient.getFunctionalMenu(userId, appName, requestId, appUserName, decryptedPwd); - }catch(Exception ex) { - fnMenu = "Failed to get functional menu: " + ex.toString(); - } - - logger.debug(EELFLoggerDelegate.debugLogger, "FunctionalMenu response: {}", fnMenu); - - return fnMenu; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/LogoutController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/LogoutController.java deleted file mode 100644 index 57983621..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/LogoutController.java +++ /dev/null @@ -1,110 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import org.springframework.web.servlet.ModelAndView; - -@Controller -@RequestMapping("/") -public class LogoutController extends UnRestrictedBaseController{ - - private User user; - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(LogoutController.class); - /** - * @param request - * @param response - * @return modelView - * - * globalLogout will invalid the current application session, then redirects to portal logout - */ - @RequestMapping(value = {"/logout.htm" }, method = RequestMethod.GET) - public ModelAndView globalLogout(HttpServletRequest request, HttpServletResponse response) { - ModelAndView modelView = null; - try{ - chatRoomLogout(request); - request.getSession().invalidate(); - String portalUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); - String portalDomain = portalUrl.substring(0, portalUrl.lastIndexOf('/')); - String redirectUrl = portalDomain+"/logout.htm"; - modelView = new ModelAndView("redirect:"+redirectUrl); - }catch(Exception e){ - logger.error(EELFLoggerDelegate.errorLogger, "Logout Error: " + e.getMessage(),AlarmSeverityEnum.MAJOR); - } - return modelView; - } - - /** - * @param request - * @param response - * @return modelView - * - * appLogout is a function that will invalid the current session (application logout) and redirects user to Portal. - */ - @RequestMapping(value = {"/app_logout.htm" }, method = RequestMethod.GET) - public ModelAndView appLogout(HttpServletRequest request, HttpServletResponse response) { - ModelAndView modelView = null; - try{ - chatRoomLogout(request); - modelView = new ModelAndView("redirect:"+PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL)); - UserUtils.clearUserSession(request); - request.getSession().invalidate(); - }catch(Exception e){ - logger.error(EELFLoggerDelegate.errorLogger, "Application Logout Error: " + e.getMessage(),AlarmSeverityEnum.MAJOR); - } - return modelView; - } - - - public void chatRoomLogout(HttpServletRequest request){ - request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest(); - setUser(UserUtils.getUserSession(request)); - // if(getUser()!=null){ - // Long login_IdLong = getUser().getId(); - // String name = getUser().getFirstName(); - // String login_IdStr = Long.toString(login_IdLong); - // } - //UserListName.getInstance().delUserName(name); - //UserListID.getInstance().delUserName(login_IdStr); - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/MenuListController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/MenuListController.java deleted file mode 100644 index ee66a948..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/MenuListController.java +++ /dev/null @@ -1,245 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.MenuData; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; -import org.openecomp.portalsdk.core.restful.client.SharedContextRestClient; -import org.openecomp.portalsdk.core.restful.domain.SharedContext; -import org.openecomp.portalsdk.core.service.AppService; -import org.openecomp.portalsdk.core.service.FnMenuService; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import com.fasterxml.jackson.databind.ObjectMapper; - - -@Controller -@RequestMapping("/") -public class MenuListController extends UnRestrictedBaseController{ - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MenuListController.class); - @Autowired - AppService appService; - @Autowired - FnMenuService fnMenuService; - @Autowired - SharedContextRestClient sharedContextRestClient; - /** - * - * Get Menu items and store into session. - * - * @param request - * @param response - */ - @SuppressWarnings("unchecked") - @RequestMapping(value = {"/get_menu" }, method = RequestMethod.GET) - public void ProfileSearch(HttpServletRequest request, HttpServletResponse response) { - logger.info("calling /get_menu.."); - try { - ObjectMapper mapper = new ObjectMapper(); - Set menuResult=null; - HttpSession session = request.getSession(); - List> childItemList = (List>) session.getAttribute(SystemProperties.LEFT_MENU_CHILDREND); - List parentList = (List) session.getAttribute(SystemProperties.LEFT_MENU_PARENT); - if(parentList==null || childItemList==null || parentList.size()==0 || childItemList.size()==0){ - childItemList=new ArrayList>(); - parentList = new ArrayList(); - menuResult = (Set) session.getAttribute(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_ATTRIBUTE_NAME)); - fnMenuService.setMenuDataStructure(childItemList, parentList, menuResult); - logger.info("storing leftmenu items into session"); - session.setAttribute(SystemProperties.LEFT_MENU_PARENT, parentList); - session.setAttribute(SystemProperties.LEFT_MENU_CHILDREND, childItemList); - } - String userName = (String) session.getAttribute(SystemProperties.getProperty(SystemProperties.USER_NAME)); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(parentList),mapper.writeValueAsString(childItemList),userName); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - logger.info("done with /get_menu call without any errors"); - } catch (Exception e) { - logger.info("errors while calling /get_menu",e); - } - } - - /** - * - * Get app name from system.properties file. - * - * @param request - * @param response - */ - - @RequestMapping(value = {"/get_app_name" }, method = RequestMethod.GET) - public void getAppName(HttpServletRequest request, HttpServletResponse response) { - logger.info("calling /get_app_name."); - HttpSession session = request.getSession(true); - try { - // String appName = SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME); - String appName = (String) session.getAttribute(SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME)); - if(appName!=null && appName.equals("app_display_name")){ - appName = ""; - } - JsonMessage msg = new JsonMessage(appName); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - logger.info("done with /get_app_name call without any errors"); - } catch (Exception e) { - logger.error("errors while calling /get_app_name",e); - } - } - - @SuppressWarnings("unchecked") - @ModelAttribute("menu") - public Map getLeftMenuJSP(HttpServletRequest request) { - logger.info("invoking getting left menu"); - ObjectMapper mapper = new ObjectMapper(); - Map model = new HashMap(); - try { - HttpSession session = request.getSession(); - List> childItemList = (List>) session.getAttribute(SystemProperties.LEFT_MENU_CHILDREND); - List parentList = (List) session.getAttribute(SystemProperties.LEFT_MENU_PARENT); - if(parentList==null || childItemList==null){ - childItemList=new ArrayList>(); - parentList = new ArrayList(); - Set menuResult = (Set) session.getAttribute(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_ATTRIBUTE_NAME)); - fnMenuService.setMenuDataStructure(childItemList, parentList, menuResult); - session.setAttribute(SystemProperties.LEFT_MENU_PARENT, parentList); - session.setAttribute(SystemProperties.LEFT_MENU_CHILDREND, childItemList); - } - model.put("childItemList",mapper.writeValueAsString(childItemList)); - model.put("parentList",mapper.writeValueAsString(parentList)); - } catch (Exception e) { - logger.info("errors while getting left menu",e); - } - logger.info("done with getting left menu without any errors"); - return model; - } - - /** - * Answers requests for user information, which is fetched from the shared context at Portal. - * - * @param request - * @param response - * @return JSON block with user information. - */ - @RequestMapping(value = {"/get_userinfo" }, method = RequestMethod.GET) - public String getUserInfo(HttpServletRequest request, HttpServletResponse response) { - logger.info(EELFLoggerDelegate.debugLogger, "Getting shared context for user"); - try{ - String contextId= null; - if(request.getCookies()!=null){ - for(Cookie ck :request.getCookies()){ - if(ck.getName().equalsIgnoreCase("EPService")) - contextId = ck.getValue(); - } - } - logger.info(EELFLoggerDelegate.debugLogger, "ContextId is : " + contextId); - List sharedContextRes = sharedContextRestClient.getUserContext(contextId); - logger.info(EELFLoggerDelegate.debugLogger, "Shared Context Response is : " + sharedContextRes); - Map model = new HashMap(); - for(SharedContext sharedContext: sharedContextRes){ - model.put(sharedContext.getCkey(), sharedContext.getCvalue()); - } - JSONObject j = new JSONObject(model); - response.getWriter().write(j.toString()); - } catch(Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Failed to get shared context for user" + e.getMessage()); - } - return null; - } - - /** - * Get User information from app sessions - * @param request - * @param response - */ - @RequestMapping(value = {"/get_topMenuInfo" }, method = RequestMethod.GET) - public void getTopMenu(HttpServletRequest request, HttpServletResponse response) { - - HttpSession session = request.getSession(); - try { - String userName = (String) session.getAttribute(SystemProperties.getProperty(SystemProperties.USER_NAME)); - String firstName = (String) session.getAttribute(SystemProperties.FIRST_NAME); - String lastName = (String) session.getAttribute(SystemProperties.LAST_NAME); - User user = (User) session.getAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME)); - Map map = new HashMap(); - String redirectUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); - String portalDomain = redirectUrl.substring(0, redirectUrl.lastIndexOf('/')); - String portalUrl = portalDomain + "/processSingleSignOn"; - String getAccessUrl = portalDomain + "/get_access"; - String email = user.getEmail(); - String contactUsLink = SystemProperties.getProperty(SystemProperties.CONTACT_US_LINK); - String userId = UserUtils.getUserIdFromCookie(request); - - map.put("portalUrl", portalUrl); - map.put("contactUsLink", contactUsLink); - map.put("userName", userName); - map.put("firstName", firstName); - map.put("lastName", lastName); - map.put("userid", userId); - map.put("email", email); - map.put("getAccessUrl",getAccessUrl); - JSONObject j = new JSONObject(map); - response.getWriter().write(j.toString()); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Failed to serialize JSON" + e.getMessage()); - } - - } - - @RequestMapping(value = {"/page_redirect" }, method = RequestMethod.GET) - public void pageRedirect(HttpServletRequest request, HttpServletResponse response) { - String pageToURL=null; - try { - String pageTo = request.getParameter("page"); - if(pageTo.equals("contact")) - pageToURL = SystemProperties.getProperty(SystemProperties.CONTACT_US_LINK); - else if(pageTo.equals("access")){ - String redirectUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); - String portalDomain = redirectUrl.substring(0, redirectUrl.lastIndexOf('/')); - pageToURL = portalDomain + "/get_access"; - } - response.getWriter().write(pageToURL); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Failed to serialize JSON" + e.getMessage()); - } - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/PostSearchController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/PostSearchController.java deleted file mode 100644 index fa5a1082..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/PostSearchController.java +++ /dev/null @@ -1,219 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.command.PostSearchBean; -import org.openecomp.portalsdk.core.domain.Lookup; -import org.openecomp.portalsdk.core.domain.Profile; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.LdapService; -import org.openecomp.portalsdk.core.service.PostSearchService; -import org.openecomp.portalsdk.core.service.ProfileService; -import org.openecomp.portalsdk.core.service.UserProfileService; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Controller -@RequestMapping("/") -public class PostSearchController extends RestrictedBaseController { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PostSearchController.class); - - @SuppressWarnings("rawtypes") - private static List sortByList = null; - - @Autowired - private PostSearchService postSearchService; - - @Autowired - LdapService ldapService; - - @Autowired - private ProfileService profileService; - - @Autowired - UserProfileService userProfileService; - - public UserProfileService getUserProfileService() { - return userProfileService; - } - - public void setUserProfileService(UserProfileService userProfileService) { - this.userProfileService = userProfileService; - } - - @RequestMapping(value = { "/post_search" }, method = RequestMethod.GET) - public ModelAndView welcome(HttpServletRequest request, - @ModelAttribute("postSearchBean") PostSearchBean postSearchBean) { - Map model = new HashMap(); - - ObjectMapper mapper = new ObjectMapper(); - try { - postSearchBean = new PostSearchBean(); - model.put("profileList", mapper.writeValueAsString(postSearchBean.getSearchResult())); - model.put("postSearchBean", mapper.writeValueAsString(postSearchBean)); - model.put("existingUsers", mapper.writeValueAsString(getExistingUsers())); - model.put("sortByList", mapper.writeValueAsString(getSortByList())); - } catch (Exception ex) { - logger.error(EELFLoggerDelegate.errorLogger, "welcome: failed to write JSON" + ex.getMessage()); - } - - return new ModelAndView(getViewName(), model); - } - - @RequestMapping(value = { "/post_search_sample" }, method = RequestMethod.GET) - public void getPostSearchProfile(HttpServletRequest request, HttpServletResponse response, - @ModelAttribute("postSearchBean") PostSearchBean postSearchBean) { - Map model = new HashMap(); - - ObjectMapper mapper = new ObjectMapper(); - try { - postSearchBean = new PostSearchBean(); - model.put("profileList", mapper.writeValueAsString(postSearchBean.getSearchResult())); - model.put("postSearchBean", mapper.writeValueAsString(postSearchBean)); - model.put("existingUsers", mapper.writeValueAsString(getExistingUsers())); - model.put("sortByList", mapper.writeValueAsString(getSortByList())); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - } catch (Exception ex) { - logger.error(EELFLoggerDelegate.errorLogger, "getPostSearchProfile: failed to write JSON" + ex.getMessage()); - } - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private HashMap getExistingUsers() { - HashMap existingUsers = new HashMap(); - - List list = profileService.findAll(); - - if (list != null) { - Iterator i = list.iterator(); - while (i.hasNext()) { - Profile user = i.next(); - String orgUserId = user.getOrgUserId(); - Long id = user.getId(); // id scalar - if (orgUserId != null) - existingUsers.put(orgUserId, id); - } - } - return existingUsers; - } - - @RequestMapping(value = { "/post_search/search" }, method = RequestMethod.POST) - public ModelAndView search(HttpServletRequest request, HttpServletResponse response) throws Exception { - try { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - PostSearchBean postSearchBean = mapper.readValue(root.get("postSearchBean").toString(), - PostSearchBean.class); - - //postSearchBean.setSearchResult(loadSearchResultData(request, postSearchBean)); - List users = loadSearchResultDataFromFnTableOrExt(request,postSearchBean); - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - String responseString = mapper.writeValueAsString(users); - JSONObject j = new JSONObject("{users: " + responseString + "}"); - - out.write(j.toString()); - } catch (Exception ex) { - logger.error(EELFLoggerDelegate.errorLogger, "search: failed to send search result" + ex.getMessage()); - } - - return null; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static List getSortByList() { - if (sortByList == null) { - sortByList = new ArrayList(); - sortByList.add(new Lookup("Last Name", "last_name")); - sortByList.add(new Lookup("First Name", "first_name")); - sortByList.add(new Lookup("HRID", "hrid")); - sortByList.add(new Lookup("SBCID", "sbcid")); - sortByList.add(new Lookup("Organization", "org_code")); - sortByList.add(new Lookup("Email", "email")); - } // if - - return sortByList; - } // getSortByList - - private List loadSearchResultDataFromFnTableOrExt(HttpServletRequest request, PostSearchBean searchCriteria) - throws Exception { - return userProfileService.searchPost(searchCriteria.getUser(), searchCriteria.getSortBy1(), - searchCriteria.getSortBy2(), searchCriteria.getSortBy3(), searchCriteria.getPageNo(), - searchCriteria.getNewDataSize(), UserUtils.getUserSession(request).getId().intValue()); - } - - @RequestMapping(value = { "/post_search/process" }, method = RequestMethod.POST) - public ModelAndView process(HttpServletRequest request, HttpServletResponse response) throws Exception { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); - JsonNode root = mapper.readTree(request.getReader()); - PostSearchBean postSearch = mapper.readValue(root.get("postSearchBean").toString(), PostSearchBean.class); - - postSearchService.process(request, postSearch); - List users = loadSearchResultDataFromFnTableOrExt(request,postSearch); - - logger.info(EELFLoggerDelegate.auditLogger, "Import new user from webphone "); - - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - String userString = mapper.writeValueAsString(users); - JSONObject j = new JSONObject("{users: " + userString + ",existingUsers: " - + mapper.writeValueAsString(getExistingUsers()) + "}"); - - out.write(j.toString()); - - return null; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ProfileController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ProfileController.java deleted file mode 100644 index 1fd7800f..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ProfileController.java +++ /dev/null @@ -1,349 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.RoleService; -import org.openecomp.portalsdk.core.service.UserProfileService; -import org.openecomp.portalsdk.core.web.support.AppUtils; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Controller -@RequestMapping("/") -public class ProfileController extends RestrictedBaseController { - - @Autowired - UserProfileService service; - @Autowired - RoleService roleService; - - String viewName; - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ProfileController.class); - - @RequestMapping(value = { "/profile" }, method = RequestMethod.GET) - public ModelAndView profile(HttpServletRequest request) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - User profile = null; - Long profileId = null; - - if (request.getRequestURI().indexOf("self_profile.htm") > -1) { - profile = UserUtils.getUserSession(request); - profileId = profile.getId(); - } else { - profileId = Long.parseLong(request.getParameter("profile_id")); - profile = (User) service.getUser(request.getParameter("profile_id")); - } - - try { - model.put("stateList", mapper.writeValueAsString(getStates())); - model.put("countries", mapper.writeValueAsString(getCountries())); - model.put("timeZones", mapper.writeValueAsString(getTimeZones())); - model.put("availableRoles", mapper.writeValueAsString(getAvailableRoles())); - model.put("profile", mapper.writeValueAsString(profile)); - model.put("profileId", mapper.writeValueAsString(profileId)); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "profile: failed to write JSON" + e.getMessage()); - } - return new ModelAndView("profile", "model", model); - } - - @RequestMapping(value = { "/self_profile" }, method = RequestMethod.GET) - public ModelAndView self_profile(HttpServletRequest request) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - User profile = null; - Long profileId = null; - - profile = UserUtils.getUserSession(request); - profileId = profile.getId(); - profile = (User) service.getUser(profileId.toString()); - - try { - model.put("stateList", mapper.writeValueAsString(getStates())); - model.put("countries", mapper.writeValueAsString(getCountries())); - model.put("timeZones", mapper.writeValueAsString(getTimeZones())); - model.put("availableRoles", mapper.writeValueAsString(getAvailableRoles())); - model.put("profile", mapper.writeValueAsString(profile)); - model.put("profileId", mapper.writeValueAsString(profileId)); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "self_profile: failed to write JSON" + e.getMessage()); - } - return new ModelAndView("profile", "model", model); - } - - @RequestMapping(value = { "/get_self_profile" }, method = RequestMethod.GET) - public void getSelfProfile(HttpServletRequest request, HttpServletResponse response) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - User profile = null; - Long profileId = null; - - profile = UserUtils.getUserSession(request); - profileId = profile.getId(); - profile = (User) service.getUser(profileId.toString()); - - try { - model.put("stateList", mapper.writeValueAsString(getStates())); - model.put("countries", mapper.writeValueAsString(getCountries())); - model.put("timeZones", mapper.writeValueAsString(getTimeZones())); - model.put("availableRoles", mapper.writeValueAsString(getAvailableRoles())); - model.put("profile", mapper.writeValueAsString(profile)); - model.put("profileId", mapper.writeValueAsString(profileId)); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "getSelfProfile: failed to write JSON" + e.getMessage()); - } - - } - - @RequestMapping(value = { "/get_profile" }, method = RequestMethod.GET) - public void GetUser(HttpServletRequest request, HttpServletResponse response) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - try { - User profile = null; - Long profileId = null; - if (request.getRequestURI().indexOf("self_profile.htm") > -1) { - profile = UserUtils.getUserSession(request); - profileId = profile.getId(); - } else { - profileId = Long.parseLong(request.getParameter("profile_id")); - profile = (User) service.getUser(request.getParameter("profile_id")); - } - model.put("stateList", mapper.writeValueAsString(getStates())); - model.put("countries", mapper.writeValueAsString(getCountries())); - model.put("timeZones", mapper.writeValueAsString(getTimeZones())); - model.put("availableRoles", mapper.writeValueAsString(getAvailableRoles())); - model.put("profile", mapper.writeValueAsString(profile)); - model.put("profileId", mapper.writeValueAsString(profileId)); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "GetUser: failed to write JSON" + e.getMessage()); - } - } - - @RequestMapping(value = { "/profile/saveProfile" }, method = RequestMethod.POST) - public ModelAndView saveProfile(HttpServletRequest request, HttpServletResponse response) { - logger.info(EELFLoggerDelegate.debugLogger, "ProfileController.save"); - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - User user = mapper.readValue(root.get("profile").toString(), User.class); - - String selectedCountry = mapper.readValue(root.get("selectedCountry").toString(), String.class); - String selectedState = mapper.readValue(root.get("selectedState").toString(), String.class); - String selectedTimeZone = mapper.readValue(root.get("selectedTimeZone").toString(), String.class); - - Long profileId = Long.parseLong(request.getParameter("profile_id")); - - User domainUser = (User) service.getUser(request.getParameter("profile_id")); - // user.setRoles(domainUser.getRoles()); - user.setPseudoRoles(domainUser.getPseudoRoles()); - user.setUserApps(domainUser.getUserApps()); - if (!selectedCountry.equals("")) { - user.setCountry(selectedCountry); - } - if (!selectedState.equals("")) { - user.setState(selectedState); - } - if (!selectedTimeZone.equals("")) { - user.setTimeZoneId(Long.parseLong(selectedTimeZone)); - } - service.saveUser(user); - logger.info(EELFLoggerDelegate.auditLogger, "Save user's profile for user " + profileId); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - out.write("" + profileId); - return null; - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - try { - request.setCharacterEncoding("UTF-8"); - } catch (UnsupportedEncodingException e1) { - - e1.printStackTrace(); - - } - PrintWriter out = null; - try { - out = response.getWriter(); - } catch (IOException e1) { - logger.error(EELFLoggerDelegate.errorLogger, "saveProfile: failed to get writer" + e1.getMessage()); - } - out.write(e.getMessage()); - return null; - } - } - - @RequestMapping(value = { "/profile/removeRole" }, method = RequestMethod.POST) - public ModelAndView removeRole(HttpServletRequest request, HttpServletResponse response) throws Exception { - - logger.info(EELFLoggerDelegate.debugLogger, "ProfileController.save"); - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - Role role = mapper.readValue(root.get("role").toString(), Role.class); - - // Long profileId = Long.parseLong(request.getParameter("profile_id")); - - User domainUser = (User) service.getUser(request.getParameter("profile_id")); - - domainUser.removeRole(role.getId()); - - service.saveUser(domainUser); - logger.info(EELFLoggerDelegate.auditLogger, "Remove role " + role.getId() + " from user " + request.getParameter("profile_id")); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - - Map model = new HashMap(); - model.put("profile", mapper.writeValueAsString(domainUser)); - JSONObject j = new JSONObject(mapper.writeValueAsString(domainUser)); - - out.write(j.toString()); - - return null; - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "removeRole" + e.getMessage()); - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - @RequestMapping(value = { "/profile/addNewRole" }, method = RequestMethod.POST) - public ModelAndView addNewRole(HttpServletRequest request, HttpServletResponse response) throws Exception { - - logger.info(EELFLoggerDelegate.debugLogger, "ProfileController.save" ); - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - Role role = mapper.readValue(root.get("role").toString(), Role.class); - - // Long profileId = Long.parseLong(request.getParameter("profile_id")); - - User domainUser = (User) service.getUser(request.getParameter("profile_id")); - - domainUser.addRole(role); - - service.saveUser(domainUser); - logger.info(EELFLoggerDelegate.auditLogger, "Add new role " + role.getName() + " to user " + request.getParameter("profile_id")); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - - Map model = new HashMap(); - model.put("profile", mapper.writeValueAsString(domainUser)); - JSONObject j = new JSONObject(mapper.writeValueAsString(domainUser)); - - out.write(j.toString()); - - return null; - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "addNewRole" + e.getMessage()); - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - public String getViewName() { - return viewName; - } - - public void setViewName(String viewName) { - this.viewName = viewName; - } - - @SuppressWarnings("rawtypes") - public List getStates() { - return AppUtils.getLookupList("FN_LU_STATE", "STATE_CD", "STATE", null, "STATE_CD"); - } - - @SuppressWarnings("rawtypes") - public List getCountries() { - return AppUtils.getLookupList("FN_LU_COUNTRY", "COUNTRY_CD", "COUNTRY", null, "COUNTRY"); - } - - @SuppressWarnings("rawtypes") - public List getTimeZones() { - return AppUtils.getLookupList("FN_LU_TIMEZONE", "TIMEZONE_ID", "TIMEZONE_NAME", null, "TIMEZONE_NAME"); - } - - @SuppressWarnings("rawtypes") - public List getAvailableRoles() { - return roleService.getAvailableRoles(); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ProfileSearchController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ProfileSearchController.java deleted file mode 100644 index 42ebd41e..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/ProfileSearchController.java +++ /dev/null @@ -1,149 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.MenuData; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.FnMenuService; -import org.openecomp.portalsdk.core.service.UserProfileService; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.databind.ObjectMapper; - -@Controller -@RequestMapping("/") -public class ProfileSearchController extends RestrictedBaseController{ - @Autowired - UserProfileService service; - @Autowired - FnMenuService fnMenuService; - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ProfileSearchController.class); - @RequestMapping(value = {"/profile_search" }, method = RequestMethod.GET) - public ModelAndView ProfileSearch(HttpServletRequest request) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - List profileList =null; - logger.info(EELFLoggerDelegate.applicationLogger, "Initiating ProfileSearch in ProfileSearchController"); - try { - profileList = service.findAll(); - model.putAll(setDashboardData(request)); - model.put("profileList", mapper.writeValueAsString(profileList)); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.applicationLogger, "error while profile_search process in ProfileSearchController" + e.getMessage()); - } - return new ModelAndView(getViewName(),"model", model); - } - - @RequestMapping(value = {"/get_user" }, method = RequestMethod.GET) - public void GetUser(HttpServletRequest request, HttpServletResponse response) { - logger.info(EELFLoggerDelegate.applicationLogger, "Initiating get_user in ProfileSearchController"); - ObjectMapper mapper = new ObjectMapper(); - List profileList =null; - try { - profileList = service.findAll(); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(profileList)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - - } catch (Exception e) { - logger.error(EELFLoggerDelegate.applicationLogger, "error while get_user process in ProfileSearchController" + e.getMessage()); - } - } - - @RequestMapping(value = {"/get_user_pagination" }, method = RequestMethod.GET) - public void getUserPagination(HttpServletRequest request, HttpServletResponse response) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - logger.info(EELFLoggerDelegate.applicationLogger, "Initiating get_user_pagination in ProfileSearchController"); - int pageNum = Integer.parseInt(request.getParameter("pageNum")); - int viewPerPage = Integer.parseInt(request.getParameter("viewPerPage")); - List profileList =null; - try { - profileList = service.findAll(); - model.put("totalPage",(int) Math.ceil((double)profileList.size() / viewPerPage)); - profileList = profileList.subList(viewPerPage*(pageNum-1)setDashboardData(HttpServletRequest request) throws Exception{ - ObjectMapper mapper = new ObjectMapper(); - Map model = new HashMap(); - List> childItemList = new ArrayList>(); - List parentList = new ArrayList(); - logger.info(EELFLoggerDelegate.applicationLogger, "Initiating setDashboardData in ProfileSearchController"); - HttpSession session = request.getSession(); - try{ - Set menuResult = (Set) session.getAttribute(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_ATTRIBUTE_NAME)); - fnMenuService.setMenuDataStructure(childItemList, parentList, menuResult); - }catch(Exception e){ - logger.error(EELFLoggerDelegate.applicationLogger, "error while setDashboardData process in ProfileSearchController" + e.getMessage()); - } - model.put("childItemList",mapper.writeValueAsString(childItemList)); - model.put("parentList",mapper.writeValueAsString(parentList)); - return model; - } - - @RequestMapping(value = {"/profile/toggleProfileActive" }, method = RequestMethod.GET) - public void toggleProfileActive(HttpServletRequest request, HttpServletResponse response) throws IOException { - try{ - logger.info(EELFLoggerDelegate.applicationLogger, "Initiating toggleProfileActive in ProfileSearchController"); - String userId = request.getParameter("profile_id"); - User user = (User)service.getUser(userId); - user.setActive(!user.getActive()); - service.saveUser(user); - logger.info(EELFLoggerDelegate.auditLogger, "Change active status for user " + user.getId() + " to " + user.getActive()); - ObjectMapper mapper = new ObjectMapper(); - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.write(mapper.writeValueAsString(user.getActive())); - }catch(Exception e){ - logger.error(EELFLoggerDelegate.applicationLogger, "error while toggleProfileActive process in ProfileSearchController" + e.getMessage()); - } - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleController.java deleted file mode 100644 index 0419e2b8..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleController.java +++ /dev/null @@ -1,332 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.domain.RoleFunction; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.RoleService; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.ServletRequestUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.type.TypeFactory; - -@Controller -@RequestMapping("/") -public class RoleController extends RestrictedBaseController { - @Autowired - RoleService service; - - String viewName; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RoleController.class); - - @RequestMapping(value = { "/role" }, method = RequestMethod.GET) - public ModelAndView role(HttpServletRequest request) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - Role role = service.getRole(new Long(ServletRequestUtils.getIntParameter(request, "role_id", 0))); - logger.info("role_id" + role.getId()); - try { - model.put("availableRoleFunctions", mapper.writeValueAsString(service.getRoleFunctions())); - model.put("availableRoles", mapper.writeValueAsString(service.getAvailableChildRoles(role.getId()))); - model.put("role", mapper.writeValueAsString(role)); - } catch (Exception e) { - logger.error("role: failed", e); - logger.error(EELFLoggerDelegate.errorLogger, "Unable to set the active profile" + e.getMessage()); - } - return new ModelAndView(getViewName(), model); - } - - @RequestMapping(value = { "/get_role" }, method = RequestMethod.GET) - public void getRole(HttpServletRequest request, HttpServletResponse response) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - Role role = service.getRole(new Long(ServletRequestUtils.getIntParameter(request, "role_id", 0))); - logger.info(EELFLoggerDelegate.applicationLogger, "role_id" + role.getId()); - try { - model.put("availableRoleFunctions", mapper.writeValueAsString(service.getRoleFunctions())); - model.put("availableRoles", mapper.writeValueAsString(service.getAvailableChildRoles(role.getId()))); - model.put("role", mapper.writeValueAsString(role)); - - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "getRole failed" + e.getMessage()); - } - - } - - @RequestMapping(value = { "/role/saveRole" }, method = RequestMethod.POST) - public ModelAndView saveRole(HttpServletRequest request, HttpServletResponse response) throws Exception { - - logger.info(EELFLoggerDelegate.applicationLogger, "RoleController.save"); - logger.info(EELFLoggerDelegate.auditLogger, "RoleController.save"); - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - Role role = mapper.readValue(root.get("role").toString(), Role.class); - - List childRoles = mapper.readValue(root.get("childRoles").toString(), - TypeFactory.defaultInstance().constructCollectionType(List.class, Role.class)); - - List roleFunctions = mapper.readValue(root.get("roleFunctions").toString(), - TypeFactory.defaultInstance().constructCollectionType(List.class, RoleFunction.class)); - - Role domainRole = null; - if (role.getId() != null) { - logger.info(EELFLoggerDelegate.auditLogger, "updating existing role " + role.getId()); - domainRole = service.getRole(role.getId()); - - domainRole.setName(role.getName()); - domainRole.setPriority(role.getPriority()); - } else { - logger.info(EELFLoggerDelegate.auditLogger, "saving as new role"); - domainRole = new Role(); - domainRole.setName(role.getName()); - domainRole.setPriority(role.getPriority()); - if (role.getChildRoles().size() > 0) { - for (Object childRole : childRoles) { - domainRole.addChildRole((Role) childRole); - } - } - if (role.getRoleFunctions().size() > 0) { - for (Object roleFunction : roleFunctions) { - domainRole.addRoleFunction((RoleFunction) roleFunction); - } - } - } - - service.saveRole(domainRole); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - String responseString = mapper.writeValueAsString(domainRole); - JSONObject j = new JSONObject("{role: " + responseString + "}"); - - out.write(j.toString()); - - return null; - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "saveRole failed" + e.getMessage()); - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - @RequestMapping(value = { "/role/removeRoleFunction" }, method = RequestMethod.POST) - public ModelAndView removeRoleFunction(HttpServletRequest request, HttpServletResponse response) throws Exception { - - logger.info(EELFLoggerDelegate.applicationLogger, "RoleController.removeRoleFunction"); - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - RoleFunction roleFunction = mapper.readValue(root.get("roleFunction").toString(), RoleFunction.class); - - Role domainRole = service.getRole(new Long(ServletRequestUtils.getIntParameter(request, "role_id", 0))); - logger.info(EELFLoggerDelegate.auditLogger, "Remove role function " + roleFunction.getCode() + " from role " + ServletRequestUtils.getIntParameter(request, "role_id", 0)); - - domainRole.removeRoleFunction(roleFunction.getCode()); - - service.saveRole(domainRole); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - - String responseString = mapper.writeValueAsString(domainRole); - JSONObject j = new JSONObject("{role: " + responseString + "}"); - out.write(j.toString()); - - return null; - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "removeRole failed" + e.getMessage()); - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - @RequestMapping(value = { "/role/addRoleFunction" }, method = RequestMethod.POST) - public ModelAndView addRoleFunction(HttpServletRequest request, HttpServletResponse response) throws Exception { - - logger.info(EELFLoggerDelegate.applicationLogger, "RoleController.removeRoleFunction"); - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - RoleFunction roleFunction = mapper.readValue(root.get("roleFunction").toString(), RoleFunction.class); - - Role domainRole = service.getRole(new Long(ServletRequestUtils.getIntParameter(request, "role_id", 0))); - - domainRole.addRoleFunction(roleFunction); - - service.saveRole(domainRole); - logger.info(EELFLoggerDelegate.auditLogger, "Add role function " + roleFunction.getCode() + " to role " + ServletRequestUtils.getIntParameter(request, "role_id", 0)); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - - String responseString = mapper.writeValueAsString(domainRole); - JSONObject j = new JSONObject("{role: " + responseString + "}"); - out.write(j.toString()); - - return null; - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "removeRoleFunction failed" + e.getMessage()); - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - @RequestMapping(value = { "/role/removeChildRole" }, method = RequestMethod.POST) - public ModelAndView removeChildRole(HttpServletRequest request, HttpServletResponse response) throws Exception { - - logger.info(EELFLoggerDelegate.applicationLogger, "RoleController.removeChileRole"); - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - Role childRole = mapper.readValue(root.get("childRole").toString(), Role.class); - - Role domainRole = service.getRole(new Long(ServletRequestUtils.getIntParameter(request, "role_id", 0))); - - domainRole.removeChildRole(childRole.getId()); - logger.info(EELFLoggerDelegate.auditLogger, "remove child role " + childRole.getId() + " from role " + ServletRequestUtils.getIntParameter(request, "role_id", 0)); - - - service.saveRole(domainRole); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - - String responseString = mapper.writeValueAsString(domainRole); - JSONObject j = new JSONObject("{role: " + responseString + "}"); - out.write(j.toString()); - - return null; - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "removeChildRole failed" + e.getMessage()); - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - @RequestMapping(value = { "/role/addChildRole" }, method = RequestMethod.POST) - public ModelAndView addChildRole(HttpServletRequest request, HttpServletResponse response) throws Exception { - - logger.info(EELFLoggerDelegate.applicationLogger, "RoleController.addChileRole"); - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - Role childRole = mapper.readValue(root.get("childRole").toString(), Role.class); - - Role domainRole = service.getRole(new Long(ServletRequestUtils.getIntParameter(request, "role_id", 0))); - - domainRole.addChildRole(childRole); - - service.saveRole(domainRole); - logger.info(EELFLoggerDelegate.auditLogger, "Add child role " + childRole.getId() + " to role " + ServletRequestUtils.getIntParameter(request, "role_id", 0)); - - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - - String responseString = mapper.writeValueAsString(domainRole); - JSONObject j = new JSONObject("{role: " + responseString + "}"); - out.write(j.toString()); - - return null; - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "addChildRole failed" + e.getMessage()); - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - public String getViewName() { - return viewName; - } - - public void setViewName(String viewName) { - this.viewName = viewName; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleFunctionListController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleFunctionListController.java deleted file mode 100644 index 3b9eed62..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleFunctionListController.java +++ /dev/null @@ -1,184 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.RoleFunction; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.RoleService; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Controller -@RequestMapping("/") -public class RoleFunctionListController extends RestrictedBaseController { - @Autowired - RoleService service; - - String viewName; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RoleFunctionListController.class); - - @RequestMapping(value = {"/role_function_list" }, method = RequestMethod.GET) - public ModelAndView welcome(HttpServletRequest request) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - try { - model.put("availableRoleFunctions", mapper.writeValueAsString(service.getRoleFunctions())); - } catch (JsonGenerationException e) { - e.printStackTrace(); - } catch (JsonMappingException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - return new ModelAndView(getViewName(),model); - } - - @RequestMapping(value = {"/get_role_functions" }, method = RequestMethod.GET) - public void getRoleFunctionList(HttpServletRequest request,HttpServletResponse response) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - try { - model.put("availableRoleFunctions", mapper.writeValueAsString(service.getRoleFunctions())); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - } catch (JsonGenerationException e) { - e.printStackTrace(); - } catch (JsonMappingException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - } - - @RequestMapping(value = {"/role_function_list/saveRoleFunction" }, method = RequestMethod.POST) - public ModelAndView saveRoleFunction(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - RoleFunction availableRoleFunction = mapper.readValue(root.get("availableRoleFunction").toString(), RoleFunction.class); - - RoleFunction domainRoleFunction = service.getRoleFunction(availableRoleFunction.getCode()); - - //role. toggle active ind - domainRoleFunction.setName(availableRoleFunction.getName()); - domainRoleFunction.setCode(availableRoleFunction.getCode()); - - service.saveRoleFunction(domainRoleFunction); - logger.info(EELFLoggerDelegate.auditLogger, "Save role function " + domainRoleFunction.getName()); - - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - String responseString = mapper.writeValueAsString(service.getRoleFunctions()); - JSONObject j = new JSONObject("{availableRoleFunctions: "+responseString+"}"); - - out.write(j.toString()); - - return null; - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - @RequestMapping(value = {"/role_function_list/removeRoleFunction" }, method = RequestMethod.POST) - public ModelAndView removeRoleFunction(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - RoleFunction availableRoleFunction = mapper.readValue(root.get("availableRoleFunction").toString(), RoleFunction.class); - - RoleFunction domainRoleFunction = service.getRoleFunction(availableRoleFunction.getCode()); - - service.deleteRoleFunction(domainRoleFunction); - logger.info(EELFLoggerDelegate.auditLogger, "Remove role function " + domainRoleFunction.getName()); - - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - - String responseString = mapper.writeValueAsString(service.getRoleFunctions()); - JSONObject j = new JSONObject("{availableRoleFunctions: "+responseString+"}"); - out.write(j.toString()); - - return null; - } catch (Exception e) { - System.out.println(e); - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - public String getViewName() { - return viewName; - } - public void setViewName(String viewName) { - this.viewName = viewName; - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleListController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleListController.java deleted file mode 100644 index 78fbc19f..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/RoleListController.java +++ /dev/null @@ -1,179 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONObject; -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.RoleService; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Controller -@RequestMapping("/") -public class RoleListController extends RestrictedBaseController { - @Autowired - RoleService service; - String viewName; - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RoleListController.class); - - - @RequestMapping(value = {"/role_list" }, method = RequestMethod.GET) - public ModelAndView role(HttpServletRequest request) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - try { - model.put("availableRoles", mapper.writeValueAsString(service.getAvailableRoles())); - } catch (JsonGenerationException e) { - e.printStackTrace(); - } catch (JsonMappingException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - return new ModelAndView(getViewName(),model); - } - - @RequestMapping(value = {"/get_roles" }, method = RequestMethod.GET) - public void getRoles(HttpServletRequest request, HttpServletResponse response) { - Map model = new HashMap(); - ObjectMapper mapper = new ObjectMapper(); - - try { - model.put("availableRoles", mapper.writeValueAsString(service.getAvailableRoles())); - JsonMessage msg = new JsonMessage(mapper.writeValueAsString(model)); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - } catch (JsonGenerationException e) { - e.printStackTrace(); - } catch (JsonMappingException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - - @RequestMapping(value = {"/role_list/toggleRole" }, method = RequestMethod.POST) - public ModelAndView toggleRole(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - Role role = mapper.readValue(root.get("role").toString(), Role.class); - - Role domainRole = service.getRole(role.getId()); - //role. toggle active ind - boolean active = domainRole.getActive(); - domainRole.setActive(!active); - - service.saveRole(domainRole); - logger.info(EELFLoggerDelegate.auditLogger, "Toggle active status for role " + domainRole.getId()); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - String responseString = mapper.writeValueAsString(service.getAvailableRoles()); - JSONObject j = new JSONObject("{availableRoles: "+responseString+"}"); - - out.write(j.toString()); - - return null; - } catch (Exception e) { - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - @RequestMapping(value = {"/role_list/removeRole" }, method = RequestMethod.POST) - public ModelAndView removeRole(HttpServletRequest request, - HttpServletResponse response) throws Exception { - - try { - - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNode root = mapper.readTree(request.getReader()); - Role role = mapper.readValue(root.get("role").toString(), Role.class); - - Role domainRole = service.getRole(role.getId()); - - service.deleteDependcyRoleRecord(role.getId()); - service.deleteRole(domainRole); - logger.info(EELFLoggerDelegate.auditLogger, "Remove role " + domainRole.getId()); - - response.setCharacterEncoding("UTF-8"); - response.setContentType("application / json"); - request.setCharacterEncoding("UTF-8"); - - PrintWriter out = response.getWriter(); - - String responseString = mapper.writeValueAsString(service.getAvailableRoles()); - JSONObject j = new JSONObject("{availableRoles: "+responseString+"}"); - out.write(j.toString()); - - return null; - } catch (Exception e) { - System.out.println(e); - response.setCharacterEncoding("UTF-8"); - request.setCharacterEncoding("UTF-8"); - PrintWriter out = response.getWriter(); - out.write(e.getMessage()); - return null; - } - - } - - public String getViewName() { - return viewName; - } - public void setViewName(String viewName) { - this.viewName = viewName; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/SingleSignOnController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/SingleSignOnController.java deleted file mode 100644 index 4a0fb6f7..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/SingleSignOnController.java +++ /dev/null @@ -1,232 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.openecomp.portalsdk.core.command.LoginBean; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.menu.MenuProperties; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalTimeoutHandler; -import org.openecomp.portalsdk.core.service.LoginService; -import org.openecomp.portalsdk.core.service.ProfileService; -import org.openecomp.portalsdk.core.util.CipherUtil; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.AppUtils; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.util.WebUtils; - -@Controller -@RequestMapping("/") -public class SingleSignOnController extends UnRestrictedBaseController { - - private static final String EP_SERVICE = "EPService"; - private static final String USER_ID = "UserId"; - public static final String DEFAULT_SUCCESS_VIEW = "welcome"; - public static final String DEFAULT_FAILURE_VIEW = "login"; - public static final String ERROR_MESSAGE_KEY = "error"; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SingleSignOnController.class); - - @Autowired - ProfileService service; - @Autowired - private LoginService loginService; - String viewName; - private String welcomeView; - - public String getWelcomeView() { - return welcomeView; - } - - public void setWelcomeView(String welcomeView) { - this.welcomeView = welcomeView; - } - - /** - * Handles requests directed to the single sign-on page by the session - * timeout interceptor. - * - * @param request - * @return Redirect to an appropriate address - * @throws Exception - */ - @RequestMapping(value = { "/single_signon.htm" }, method = RequestMethod.GET) - public ModelAndView singleSignOnLogin(HttpServletRequest request) throws Exception { - - Map model = new HashMap(); - HashMap additionalParamsMap = new HashMap(); - LoginBean commandBean = new LoginBean(); - - // SessionTimeoutInterceptor sets these parameters - String forwardURL = URLDecoder.decode(request.getParameter("forwardURL"), "UTF-8"); - String redirectToPortal = request.getParameter("redirectToPortal"); - - if (isLoginCookieExist(request) && redirectToPortal == null) { - HttpSession session = null; - session = AppUtils.getSession(request); - User user = UserUtils.getUserSession(request); - if (session == null || user == null) { - String orgUserId = ""; - orgUserId = getUserIdFromCookie(request); - commandBean.setUserid(orgUserId); - commandBean = getLoginService().findUser(commandBean, - (String) request.getAttribute(MenuProperties.MENU_PROPERTIES_FILENAME_KEY), - additionalParamsMap); - if (commandBean.getUser() == null) { - String loginErrorMessage = (commandBean.getLoginErrorMessage() != null) - ? commandBean.getLoginErrorMessage() - : SystemProperties.MESSAGE_KEY_LOGIN_ERROR_USER_NOT_FOUND; - model.put(ERROR_MESSAGE_KEY, SystemProperties.getProperty(loginErrorMessage)); - final String redirectUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL) - + "?noUserError=Yes"; - logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: user is null, redirect URL is {}", - redirectUrl); - return new ModelAndView("redirect:" + redirectUrl); - } else { - // store the user's information in the session - - UserUtils.setUserSession(request, commandBean.getUser(), commandBean.getMenu(), - commandBean.getBusinessDirectMenu(), ""); - initateSessionMgtHandler(request); - logger.debug(EELFLoggerDelegate.debugLogger, - "singleSignOnLogin: create new user session for expired user {}; user {} exists in the system", - commandBean.getUser().getOrgUserId()); - return new ModelAndView("redirect:" + forwardURL); - } - } // user is null or session is null - else { - // both user and session are non-null. - logger.info(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: redirecting to the forwardURL {}", - forwardURL); - return new ModelAndView("redirect:" + forwardURL); - } - - } else { - /* - * Login cookie not found, or redirect-to-portal parameter was found. - * - * Redirect the user to the portal with a suitable return URL. The - * forwardURL parameter that arrives as a parameter is a partial - * (not absolute) request path for a page in the application. The - * challenge here is to compute the correct absolute path for the - * original request so the portal can redirect the user back to the - * right place. - */ - String returnToAppUrl = null; - if (SystemProperties.containsProperty(SystemProperties.APP_BASE_URL)) { - // New feature: - // application can publish a base URL in system.properties - String appUrl = SystemProperties.getProperty(SystemProperties.APP_BASE_URL); - returnToAppUrl = appUrl + (appUrl.endsWith("/") ? "" : "/") + forwardURL; - logger.debug(EELFLoggerDelegate.debugLogger, - "singleSignOnLogin: using app base URL {} and redirectURL {}", appUrl, returnToAppUrl); - } else { - // Be backward compatible with applications that don't need this - // feature. - // This is the controller for the single_signon.htm page, so the - // replace - // should always find the specified token. - returnToAppUrl = ((HttpServletRequest) request).getRequestURL().toString().replace("single_signon.htm", - forwardURL); - logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: computed redirectURL {}", returnToAppUrl); - } - final String encodedReturnToAppUrl = URLEncoder.encode(returnToAppUrl, "UTF-8"); - // Also send the application's UEB key so Portal can block URL - // reflection attacks. - final String uebAppKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); - final String url = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); - final String portalUrl = url.substring(0, url.lastIndexOf('/')) + "/processSingleSignOn"; - final String redirectUrl = portalUrl + "?uebAppKey=" + uebAppKey + "&redirectUrl=" + encodedReturnToAppUrl; - logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: portal-bound redirect URL is {}", - redirectUrl); - return new ModelAndView("redirect:" + redirectUrl); - } - } - - protected void initateSessionMgtHandler(HttpServletRequest request) { - String portalJSessionId = getPortalJSessionId(request); - String jSessionId = getJessionId(request); - PortalTimeoutHandler.sessionCreated(portalJSessionId, jSessionId, AppUtils.getSession(request)); - } - - public boolean isLoginCookieExist(HttpServletRequest request) { - Cookie ep = WebUtils.getCookie(request, EP_SERVICE); - return (ep != null); - } - - public static String getUserIdFromCookie(HttpServletRequest request) throws Exception { - String userId = ""; - Cookie[] cookies = request.getCookies(); - Cookie userIdcookie = null; - if (cookies != null) - for (Cookie cookie : cookies) - if (cookie.getName().equals(USER_ID)) - userIdcookie = cookie; - if(userIdcookie!=null){ - userId = CipherUtil.decrypt(userIdcookie.getValue(), - SystemProperties.getProperty(SystemProperties.Decryption_Key)); - } - return userId; - - } - - public String getPortalJSessionId(HttpServletRequest request) { - Cookie ep = WebUtils.getCookie(request, EP_SERVICE); - return ep.getValue(); - - } - - public String getJessionId(HttpServletRequest request) { - return request.getSession().getId(); - } - - public String getViewName() { - return viewName; - } - - public void setViewName(String viewName) { - this.viewName = viewName; - } - - public LoginService getLoginService() { - return loginService; - } - - public void setLoginService(LoginService loginService) { - this.loginService = loginService; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/UsageListController.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/UsageListController.java deleted file mode 100644 index c5616575..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/controller/UsageListController.java +++ /dev/null @@ -1,163 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.controller; - -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.openecomp.portalsdk.core.command.UserRowBean; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.util.UsageUtils; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -@Controller -@RequestMapping("/") -public class UsageListController extends RestrictedBaseController { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(UsageListController.class); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @RequestMapping(value = { "/usage_list" }, method = RequestMethod.GET) - public ModelAndView usageList(HttpServletRequest request) { - Map model = new HashMap(); - - HttpSession httpSession = request.getSession(); - HashMap activeUsers = (HashMap) httpSession.getServletContext().getAttribute("activeUsers"); - if (activeUsers.size() == 0) { - activeUsers.put(httpSession.getId(), httpSession); - httpSession.getServletContext().setAttribute("activeUsers", activeUsers); - } - ArrayList rows = UsageUtils.getActiveUsers(activeUsers); - JSONArray ja = new JSONArray(); - try { - for (UserRowBean userRowBean : rows) { - JSONObject jo = new JSONObject(); - jo.put("id", userRowBean.getId()); - jo.put("lastName", userRowBean.getLastName()); - jo.put("email", userRowBean.getEmail()); - jo.put("lastAccess", userRowBean.getLastAccess()); - jo.put("remaining", userRowBean.getRemaining()); - jo.put("sessionId", userRowBean.getSessionId()); - if (!(httpSession.getId().equals(userRowBean.getSessionId()))) { - jo.put("delete", "yes"); - } else { - jo.put("delete", "no"); - } - ja.put(jo); - } - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "usageList 1: failed" + e.getMessage()); - } - - model.put("model", ja); - - return new ModelAndView(getViewName(), model); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @RequestMapping(value = { "/get_usage_list" }, method = RequestMethod.GET) - public void usageList(HttpServletRequest request, HttpServletResponse response) { - HttpSession httpSession = request.getSession(); - HashMap activeUsers = (HashMap) httpSession.getServletContext().getAttribute("activeUsers"); - if (activeUsers.size() == 0) { - activeUsers.put(httpSession.getId(), httpSession); - httpSession.getServletContext().setAttribute("activeUsers", activeUsers); - } - ArrayList rows = UsageUtils.getActiveUsers(activeUsers); - JSONArray ja = new JSONArray(); - try { - for (UserRowBean userRowBean : rows) { - JSONObject jo = new JSONObject(); - jo.put("id", userRowBean.getId()); - jo.put("lastName", userRowBean.getLastName()); - jo.put("email", userRowBean.getEmail()); - jo.put("lastAccess", userRowBean.getLastAccess()); - jo.put("remaining", userRowBean.getRemaining()); - jo.put("sessionId", userRowBean.getSessionId()); - if (!(httpSession.getId().equals(userRowBean.getSessionId()))) { - jo.put("delete", "yes"); - } else { - jo.put("delete", "no"); - } - ja.put(jo); - } - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "usageList 2: failed" + e.getMessage()); - } - JsonMessage msg; - try { - msg = new JsonMessage(ja.toString()); - JSONObject j = new JSONObject(msg); - response.getWriter().write(j.toString()); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "usageList 3: failed" + e.getMessage()); - } - - } - - @SuppressWarnings("rawtypes") - @RequestMapping(value = { "/usage_list/removeSession" }, method = RequestMethod.GET) - public void removeSession(HttpServletRequest request, HttpServletResponse response) throws Exception { - HashMap activeUsers = (HashMap) request.getSession().getServletContext().getAttribute("activeUsers"); - UserRowBean data = new UserRowBean(); - data.setSessionId(request.getParameter("deleteSessionId")); - UsageUtils.getActiveUsersAfterDelete(activeUsers, data); - - HttpSession httpSession = request.getSession(); - ArrayList rows = UsageUtils.getActiveUsers(activeUsers); - JSONArray ja = new JSONArray(); - try { - for (UserRowBean userRowBean : rows) { - JSONObject jo = new JSONObject(); - jo.put("id", userRowBean.getId()); - jo.put("lastName", userRowBean.getLastName()); - jo.put("email", userRowBean.getEmail()); - jo.put("lastAccess", userRowBean.getLastAccess()); - jo.put("remaining", userRowBean.getRemaining()); - jo.put("sessionId", userRowBean.getSessionId()); - if (!(httpSession.getId().equals(userRowBean.getSessionId()))) { - jo.put("delete", "yes"); - } else { - jo.put("delete", "no"); - } - ja.put(jo); - } - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "removeSession: failed" + e.getMessage()); - } - - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.write(ja.toString()); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDaoImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDaoImpl.java deleted file mode 100644 index 8d8d0d6e..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/ProfileDaoImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.dao; - -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.criterion.Restrictions; -import org.openecomp.portalsdk.core.domain.Profile; -import org.springframework.stereotype.Repository; - -@Repository("profileDao") -public class ProfileDaoImpl extends AbstractDao implements ProfileDao{ - - - public List findAll() { - Criteria crit = getSession().createCriteria(Profile.class); - @SuppressWarnings("unchecked") - List p = crit.list(); - - return p; - } - - - public Profile getProfile(int id) { - Criteria crit = getSession().createCriteria(Profile.class); - crit.add(Restrictions.eq("id", id)); - Profile profile = (Profile) crit.uniqueResult(); - - return profile; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/support/FusionDao.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/support/FusionDao.java deleted file mode 100644 index 75b3c80b..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/dao/support/FusionDao.java +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.dao.support; - -import org.hibernate.SessionFactory; -import org.openecomp.portalsdk.core.FusionObject; - -public class FusionDao implements FusionObject { - private SessionFactory sessionFactory; - - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - public SessionFactory getSessionFactory() { - return this.sessionFactory; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/AuditLog.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/AuditLog.java deleted file mode 100644 index f861232f..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/AuditLog.java +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain; - -import java.util.Date; - -import org.openecomp.portalsdk.core.domain.support.DomainVo; -public class AuditLog extends DomainVo { - - /** - * - */ - private static final long serialVersionUID = 1L; - public static final String CD_ACTIVITY_LOGIN = "login"; - public static final String CD_ACTIVITY_LOGOUT = "logout"; - public static final String CD_ACTIVITY_MOBILE_LOGIN = "mobile_login"; - public static final String CD_ACTIVITY_MOBILE_LOGOUT = "mobile_logout"; - - /*-------Profile activities -----------*/ - public static final String CD_ACTIVITY_ROLE_ADD = "add_role"; - public static final String CD_ACTIVITY_ROLE_REMOVE = "remove_role"; - public static final String CD_ACTIVITY_CHILD_ROLE_ADD = "add_child_role"; - public static final String CD_ACTIVITY_CHILD_ROLE_REMOVE = "remove_child_role"; - public static final String CD_ACTIVITY_ROLE_ADD_FUNCTION = "add_role_function"; - public static final String CD_ACTIVITY_ROLE_REMOVE_FUNCTION = "remove_role_function"; - public static final String CD_ACTIVITY_USER_ROLE_ADD = "add_user_role"; - public static final String CD_ACTIVITY_USER_ROLE_REMOVE = "remove_user_role"; - - - private String activityCode; - private String affectedRecordId; - private String comments; - - public AuditLog() { - setCreated(new Date()); - } - - public String getActivityCode() { - return activityCode; - } - - public String getComments() { - return comments; - } - - public String getAffectedRecordId() { - return affectedRecordId; - } - - public void setActivityCode(String activityCode) { - this.activityCode = activityCode; - } - - public void setComments(String comments) { - this.comments = comments; - } - - public void setAffectedRecordId(String affectedRecordId) { - this.affectedRecordId = affectedRecordId; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/BroadcastMessage.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/BroadcastMessage.java deleted file mode 100644 index e005df41..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/BroadcastMessage.java +++ /dev/null @@ -1,123 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain; - -import java.util.Date; - -import org.openecomp.portalsdk.core.domain.support.DomainVo; - -public class BroadcastMessage extends DomainVo{ - /** - * - */ - private static final long serialVersionUID = 1L; - - public BroadcastMessage() { - } - - public static final String ID_MESSAGE_LOCATION_LOGIN = "10"; - public static final String ID_MESSAGE_LOCATION_WELCOME = "20"; - - private String messageText; - private Integer locationId; - private Date startDate; - private Date endDate; - private Integer sortOrder; - private Boolean active; - private String siteCd; - - public Boolean getActive() { - return active; - } - - public Date getEndDate() { - return endDate; - } - - public Integer getLocationId() { - return locationId; - } - - public String getMessageText() { - return messageText; - } - - public Integer getSortOrder() { - return sortOrder; - } - - public Date getStartDate() { - return startDate; - } - - public String getSiteCd() { - return siteCd; - } - - - public void setActive(Boolean active) { - this.active = active; - } - - public void setEndDate(Date endDate) { - this.endDate = endDate; - } - - public void setLocationId(Integer locationId) { - this.locationId = locationId; - } - - public void setMessageText(String messageText) { - this.messageText = messageText; - } - - public void setSortOrder(Integer sortOrder) { - this.sortOrder = sortOrder; - } - - public void setStartDate(Date startDate) { - this.startDate = startDate; - } - - public void setSiteCd(String siteCd) { - this.siteCd = siteCd; - } - - - public int compareTo(Object obj){ - Integer c1 = getLocationId(); - Integer c2 = ((BroadcastMessage)obj).getLocationId(); - - if (c1.compareTo(c2) == 0) { - c1 = getSortOrder(); - c2 = ((BroadcastMessage)obj).getSortOrder(); - - if (c1.compareTo(c2) == 0) { - Long c3 = getId(); - Long c4 = ((BroadcastMessage)obj).getId(); - - return c3.compareTo(c4); - } - } - - return c1.compareTo(c2); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/FnMenu.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/FnMenu.java deleted file mode 100644 index e2c1f46d..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/FnMenu.java +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain; - - -import org.openecomp.portalsdk.core.domain.support.DomainVo; - -/** - *

        RoleFunction.java

        - * - *

        Represents a role function data object.

        - * - * @version 1.0 - */ -public class FnMenu extends DomainVo { - /** - * - */ - private static final long serialVersionUID = 1L; - - public FnMenu() {} - - private Integer menuId; - private String label; - private Integer parentId; - private String action; - private String functionCd; - private Integer sortOrder; - private String servlet; - private String queryString; - private String externalUrl; - private String target; - private String active; - private String separator; - private String imageSrc; - private String menuSetCode; - - public Integer getMenuId() { - return menuId; - } - public void setMenuId(Integer menuId) { - this.menuId = menuId; - } - public String getLabel() { - return label; - } - public void setLabel(String label) { - this.label = label; - } - public Integer getParentId() { - return parentId; - } - public void setParentId(Integer parentId) { - this.parentId = parentId; - } - public String getAction() { - return action; - } - public void setAction(String action) { - this.action = action; - } - public String getFunctionCd() { - return functionCd; - } - public void setFunctionCd(String functionCd) { - this.functionCd = functionCd; - } - public Integer getSortOrder() { - return sortOrder; - } - public void setSortOrder(Integer sortOrder) { - this.sortOrder = sortOrder; - } - public String getServlet() { - return servlet; - } - public void setServlet(String servlet) { - this.servlet = servlet; - } - public String getQueryString() { - return queryString; - } - public void setQueryString(String queryString) { - this.queryString = queryString; - } - public String getExternalUrl() { - return externalUrl; - } - public void setExternalUrl(String externalUrl) { - this.externalUrl = externalUrl; - } - public String getTarget() { - return target; - } - public void setTarget(String target) { - this.target = target; - } - public String getActive() { - return active; - } - public void setActive(String active) { - this.active = active; - } - public String getSeparator() { - return separator; - } - public void setSeparator(String separator) { - this.separator = separator; - } - public String getImageSrc() { - return imageSrc; - } - public void setImageSrc(String imageSrc) { - this.imageSrc = imageSrc; - } - public String getMenuSetCode() { - return menuSetCode; - } - public void setMenuSetCode(String menuSetCode) { - this.menuSetCode = menuSetCode; - } - - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/LoginBean.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/LoginBean.java deleted file mode 100644 index 52c6d00e..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/LoginBean.java +++ /dev/null @@ -1,187 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain; - -import java.util.Set; - -import org.openecomp.portalsdk.core.domain.support.FusionCommand; - -@SuppressWarnings("rawtypes") -public class LoginBean extends FusionCommand { - - private String loginId; - private String loginPwd; - private String hrid; - private String orgUserId; - private String siteAccess; - private String loginErrorMessage; - - private User user; - private Set menu; - private Set businessDirectMenu; - - /** - * getLoginId - * - * @return String - */ - public String getLoginId() { - return loginId; - } - - /** - * getLoginPwd - * - * @return String - */ - public String getLoginPwd() { - return loginPwd; - } - - /** - * getMenu - * - * @return Set - */ - public Set getMenu() { - return menu; - } - - /** - * getUser - * - * @return User - */ - public User getUser() { - return user; - } - - /** - * getHrid - * - * @return String - */ - public String getHrid() { - return hrid; - } - - /** - * getSiteAccess - * - * @return String - */ - public String getSiteAccess() { - return siteAccess; - } - - /** - * getBusinessDirectMenu - * - * @return Set - */ - public Set getBusinessDirectMenu() { - return businessDirectMenu; - } - - /** - * getLoginErrorMessage - * - * @return String - */ - public String getLoginErrorMessage() { - return loginErrorMessage; - } - - public String getOrgUserId() { - return orgUserId; - } - - /** - * setLoginId - * - * @param loginId String - */ - public void setLoginId(String loginId) { - this.loginId = loginId; - } - - /** - * setLoginPwd - * - * @param loginPwd String - */ - public void setLoginPwd(String loginPwd) { - this.loginPwd = loginPwd; - } - - public void setMenu(Set menu) { - this.menu = menu; - } - - /** - * setUser - * - * @param user User - */ - public void setUser(User user) { - this.user = user; - } - - /** - * setHrid - * - * @param hrid String - */ - public void setHrid(String hrid) { - this.hrid = hrid; - } - - /** - * setSiteAccess - * - * @param siteAccess String - */ - public void setSiteAccess(String siteAccess) { - this.siteAccess = siteAccess; - } - - /** - * setBusinessDirectMenu - * - * @param businessDirectMenu Set - */ - public void setBusinessDirectMenu(Set businessDirectMenu) { - this.businessDirectMenu = businessDirectMenu; - } - - /** - * setLoginErrorMessage - * - * @param loginErrorMessage String - */ - public void setLoginErrorMessage(String loginErrorMessage) { - this.loginErrorMessage = loginErrorMessage; - } - - public void setOrgUserId(String orgUserId) { - this.orgUserId = orgUserId; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/Lookup.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/Lookup.java deleted file mode 100644 index a71bdfc1..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/Lookup.java +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain; - -import java.io.Serializable; - -import org.openecomp.portalsdk.core.domain.support.NameValueId; - -public class Lookup extends FusionVo implements Serializable { - - /** - * - */ - private static final long serialVersionUID = 1L; - private NameValueId nameValueId = new NameValueId(); - - public Lookup() {} - - public Lookup(String label, String value) { - this(); - setLabel(label); - setValue(value); - } - - public String getValue() { - return getNameValueId().getVal(); - } - - public String getLabel() { - return getNameValueId().getLab(); - } - - public void setValue(String value) { - getNameValueId().setVal(value); - } - - public void setLabel(String label) { - getNameValueId().setLab(label); - } - - public NameValueId getNameValueId() { - return nameValueId; - } - - public void setNameValueId(NameValueId nameValueId) { - this.nameValueId = nameValueId; - } - - // required by ZK for to set the selectedItems of Listboxes (used heavily for -style drop-downs) - public int hashCode() { - int hash = getUrl().hashCode(); - hash = hash + getFunctionCd().hashCode(); - - return hash; - } - - public boolean equals( Object obj ) { - boolean equivalent = false; - - UrlsAccessible lookup = (UrlsAccessible)obj; - if( lookup.getUrl().equals(getUrl()) && lookup.getFunctionCd().equals(getFunctionCd())) { - equivalent = true; - } - - return equivalent; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessibleKey.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessibleKey.java deleted file mode 100644 index f1cec496..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UrlsAccessibleKey.java +++ /dev/null @@ -1,90 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain; - -import java.io.Serializable; - - -public class UrlsAccessibleKey implements Serializable { - - /** - * - */ - private static final long serialVersionUID = 1L; - private String url; - private String functionCd; - - public UrlsAccessibleKey() { - } - - public UrlsAccessibleKey(String url, String functionCd) { - setUrl(url); - setFunctionCd(functionCd); - } - - - public String getUrl() { - return url; - } - - - public String getFunctionCd() { - return functionCd; - } - - - public void setUrl(String url) { - this.url = url; - } - - - public void setFunctionCd(String functionCd) { - this.functionCd = functionCd; - } - - - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null) { - return false; - } - - if (!(o instanceof UrlsAccessibleKey)) { - return false; - } - - final UrlsAccessibleKey key = (UrlsAccessibleKey)o; - - if (getFunctionCd().equals(key.getFunctionCd()) & getUrl().equals(key.getUrl())) { - return true; - } - - return false; - } - - - public int hashCode() { - return getUrl().hashCode() + getFunctionCd().hashCode(); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/User.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/User.java deleted file mode 100644 index e6c4a178..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/User.java +++ /dev/null @@ -1,585 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain; - - -import java.util.Date; -import java.util.Iterator; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.openecomp.portalsdk.core.domain.support.DomainVo; - -/** - *

        User.java

        - * - *

        Represents a user data object.

        - * - * @version 1.0 - */ -@SuppressWarnings("rawtypes") -public class User extends DomainVo { - - /** - * - */ - private static final long serialVersionUID = 1L; - private Long orgId; - private Long managerId; - private String firstName; - private String middleInitial; - private String lastName; - private String phone; - private String fax; - private String cellular; - private String email; - private Long addressId; - private String alertMethodCd; - private String hrid; - private String orgUserId; - private String orgCode; - private String address1; - private String address2; - private String city; - private String state; - private String zipCode; - private String country; - private String orgManagerUserId; - private String locationClli; - private String businessCountryCode; - private String businessCountryName; - private String businessUnit; - private String businessUnitName; - private String department; - private String departmentName; - private String companyCode; - private String company; - private String zipCodeSuffix; - private String jobTitle; - private String commandChain; - private String siloStatus; - private String costCenter; - private String financialLocCode; - - - - private String loginId; - private String loginPwd; - private Date lastLoginDate; - private boolean active; - private boolean internal; - private Long selectedProfileId; - private Long timeZoneId; - private boolean online; - private String chatId; - - private Set userApps = new TreeSet(); - - private Set pseudoRoles = new TreeSet(); - - - public User() {} - - public Long getAddressId() { - return addressId; - } - - public String getAlertMethodCd() { - return alertMethodCd; - } - - public String getCellular() { - return cellular; - } - - public String getEmail() { - return email; - } - - public String getFax() { - return fax; - } - - public String getFirstName() { - return firstName; - } - - public String getHrid() { - return hrid; - } - - public Date getLastLoginDate() { - return lastLoginDate; - } - - public String getLastName() { - return lastName; - } - - public String getFullName() { - return getFirstName() + " " + getLastName(); - } - - public String getLoginId() { - return loginId; - } - - public String getLoginPwd() { - return loginPwd; - } - - public Long getManagerId() { - return managerId; - } - - public String getMiddleInitial() { - return middleInitial; - } - - public String getOrgCode() { - return orgCode; - } - - public Long getOrgId() { - return orgId; - } - - public String getPhone() { - return phone; - } - - public String getOrgUserId() { - return orgUserId; - } - - public boolean getActive() { - return active; - } - - public boolean getInternal() { - return internal; - } - - public String getAddress1() { - return address1; - } - - public String getAddress2() { - return address2; - } - - public String getCity() { - return city; - } - - public String getCountry() { - return country; - } - - public String getState() { - return state; - } - - public String getZipCode() { - return zipCode; - } - - public String getBusinessCountryCode() { - return businessCountryCode; - } - - public String getCommandChain() { - return commandChain; - } - - public String getCompany() { - return company; - } - - public String getCompanyCode() { - return companyCode; - } - - public String getDepartment() { - return department; - } - - public String getJobTitle() { - return jobTitle; - } - - public String getLocationClli() { - return locationClli; - } - - public String getOrgManagerUserId() { - return orgManagerUserId; - } - - public String getZipCodeSuffix() { - return zipCodeSuffix; - } - - public String getBusinessCountryName() { - return businessCountryName; - } - - public Set getPseudoRoles() { - return pseudoRoles; - } - - public Long getSelectedProfileId() { - return selectedProfileId; - } - - public void setAddressId(Long addressId) { - this.addressId = addressId; - } - - public void setAlertMethodCd(String alertMethodCd) { - this.alertMethodCd = alertMethodCd; - } - - public void setCellular(String cellular) { - this.cellular = cellular; - } - - public void setEmail(String email) { - this.email = email; - } - - public void setFax(String fax) { - this.fax = fax; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public void setHrid(String hrid) { - this.hrid = hrid; - } - - public void setLastLoginDate(Date lastLoginDate) { - this.lastLoginDate = lastLoginDate; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public void setLoginId(String loginId) { - this.loginId = loginId; - } - - public void setLoginPwd(String loginPwd) { - this.loginPwd = loginPwd; - } - - public void setManagerId(Long managerId) { - this.managerId = managerId; - } - - public void setMiddleInitial(String middleInitial) { - this.middleInitial = middleInitial; - } - - public void setOrgCode(String orgCode) { - this.orgCode = orgCode; - } - - public void setOrgId(Long orgId) { - this.orgId = orgId; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - public void setOrgUserId(String orgUserId) { - this.orgUserId = orgUserId; - } - - public void setActive(boolean active) { - this.active = active; - } - - public void setInternal(boolean internal) { - this.internal = internal; - } - - public void setAddress1(String address1) { - this.address1 = address1; - } - - public void setAddress2(String address2) { - this.address2 = address2; - } - - public void setCity(String city) { - this.city = city; - } - - public void setCountry(String country) { - this.country = country; - } - - public void setState(String state) { - this.state = state; - } - - public void setZipCode(String zipCode) { - this.zipCode = zipCode; - } - - public void setBusinessCountryCode(String businessCountryCode) { - this.businessCountryCode = businessCountryCode; - } - - public void setCommandChain(String commandChain) { - this.commandChain = commandChain; - } - - public void setCompany(String company) { - this.company = company; - } - - public void setCompanyCode(String companyCode) { - this.companyCode = companyCode; - } - - public void setDepartment(String department) { - this.department = department; - } - - public void setJobTitle(String jobTitle) { - this.jobTitle = jobTitle; - } - - public void setLocationClli(String locationClli) { - this.locationClli = locationClli; - } - - public void setOrgManagerUserId(String orgManagerUserId) { - this.orgManagerUserId = orgManagerUserId; - } - - public void setZipCodeSuffix(String zipCodeSuffix) { - this.zipCodeSuffix = zipCodeSuffix; - } - - public void setBusinessCountryName(String businessCountryName) { - this.businessCountryName = businessCountryName; - } - - public void setPseudoRoles(Set pseudoRoles) { - this.pseudoRoles = pseudoRoles; - } - - public void setSelectedProfileId(Long selectedProfileId) { - this.selectedProfileId = selectedProfileId; - } - - public Long getTimeZoneId() { - return timeZoneId; - } - - public void setTimeZoneId(Long timeZoneId) { - this.timeZoneId = timeZoneId; - } - - public String getBusinessUnit() { - return businessUnit; - } - - public void setBusinessUnit(String businessUnit) { - this.businessUnit = businessUnit; - } - - public String getSiloStatus() { - return siloStatus; - } - - public void setSiloStatus(String siloStatus) { - this.siloStatus = siloStatus; - } - - public String getCostCenter() { - return costCenter; - } - - public void setCostCenter(String costCenter) { - this.costCenter = costCenter; - } - - public String getFinancialLocCode() { - return financialLocCode; - } - - public void setFinancialLocCode(String financialLocCode) { - this.financialLocCode = financialLocCode; - } - - public String getBusinessUnitName() { - return businessUnitName; - } - - public void setBusinessUnitName(String businessUnitName) { - this.businessUnitName = businessUnitName; - } - - public String getDepartmentName() { - return departmentName; - } - - public void setDepartmentName(String departmentName) { - this.departmentName = departmentName; - } - - public int compareTo(Object obj){ - User user = (User)obj; - - String c1 = getLastName() + getFirstName() + getMiddleInitial(); - String c2 = user.getLastName() + user.getFirstName() + user.getMiddleInitial(); - - return c1.compareTo(c2); - } - - public boolean isOnline() { - return online; - } - - public void setOnline(boolean online) { - this.online = online; - } - - public String getChatId() { - return chatId; - } - - public void setChatId(String chatId) { - this.chatId = chatId; - } - - public Set getUserApps() { - return userApps; - } - - public void setUserApps(Set userApps) { - this.userApps = userApps; - } - - @SuppressWarnings("unchecked") - public void addAppRoles(App app, SortedSet roles) { - if(roles!=null){ - //add all - Set userApps = new TreeSet(); - Iterator itr = roles.iterator(); - while(itr.hasNext()){ - Role role = (Role) itr.next(); - UserApp userApp = new UserApp(); - userApp.setUserId(this.id); - userApp.setApp(app); - userApp.setRole(role); - userApps.add(userApp); - } - setUserApps(userApps); - } else { - //remove all - this.userApps.clear(); - } - - - } - - @SuppressWarnings("unchecked") - public SortedSet getAppRoles(App app) { - SortedSet roles = new TreeSet(); - Set apps = getUserApps(); - Iterator appsItr = apps.iterator(); - UserApp userApp = null; - //getting default app - while(appsItr.hasNext()){ - UserApp tempUserApp = (UserApp)appsItr.next(); - if(tempUserApp.getApp().getId().equals(app.getId())){ - userApp = tempUserApp; - roles.add(userApp.getRole()); - } - } - return roles; - } - - public SortedSet getRoles() { - App app = new App(); - app.setId(new Long(1)); - app.setName("Default"); - return getAppRoles(app); - } - - public UserApp getDefaultUserApp(){ - Set apps = getUserApps(); - Iterator appsItr = apps.iterator(); - UserApp userApp = null; - //getting default app - while(appsItr.hasNext()){ - UserApp tempApp = (UserApp)appsItr.next(); - if(tempApp.equals(new Long(1))){ - userApp = tempApp; - break; - } - } - return userApp; - } - - public void setRoles(SortedSet roles) { - App app = new App(); - app.setId(new Long(1)); - app.setName("Default"); - addAppRoles(app,roles); - } - - public void removeRole(Long roleId) { - Set apps = getUserApps(); - Iterator appsItr = apps.iterator(); - //getting default app - while(appsItr.hasNext()){ - UserApp tempUserApp = (UserApp)appsItr.next(); - if(tempUserApp.getRole().getId().equals(roleId)){ - appsItr.remove(); - } - } - - } - - @SuppressWarnings("unchecked") - public void addRole(Role role){ - if(role!=null){ - SortedSet roles = getRoles(); - if(roles==null){ - roles = new TreeSet(); - } - roles.add(role); - setRoles(roles); - } - - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UserApp.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UserApp.java deleted file mode 100644 index 5c2c383f..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/UserApp.java +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain; - -// Generated Aug 27, 2014 5:51:36 PM by Hibernate Tools 3.4.0.CR1 - -/** - * FnUserRole generated by hbm2java - */ -@SuppressWarnings("rawtypes") -public class UserApp implements java.io.Serializable, Comparable { - - /** - * - */ - private static final long serialVersionUID = 1L; - private Long userId; - private App app; - private Role role; - private Short priority; - - public UserApp() { - } - - public Long getUserId() { - return userId; - } - - public void setUserId(Long userId) { - this.userId = userId; - } - - public App getApp() { - return app; - } - - public void setApp(App app) { - this.app = app; - } - - public Role getRole() { - return role; - } - - public void setRole(Role role) { - this.role = role; - } - - public Short getPriority() { - return this.priority; - } - - public void setPriority(Short priority) { - this.priority = priority; - } - - public boolean equals(Object other) { - if ((this == other)) - return true; - if ((other == null)) - return false; - if (!(other instanceof UserApp)) - return false; - UserApp castOther = (UserApp) other; - - return (this.getUserId().equals(castOther.getUserId())) - && (this.getApp().getId().equals(castOther.getApp().getId())) - && (this.getRole().getId().equals(castOther.getRole().getId())) - && ((this.priority==null && castOther.getPriority()==null) || this.getPriority().equals(castOther.getPriority())); - } - - public int hashCode() { - int result = 17; - - result = 37 * result + (int) (this.getUserId()==null ? 0 : this.getUserId().intValue()); - result = 37 * result + (int) (this.getApp().getId()==null ? 0 : this.getApp().getId().intValue()); - result = 37 * result + (int) (this.getRole().getId()==null ? 0 : this.getRole().getId().intValue()); - result = 37 * result + (int) (this.priority==null ? 0 : this.priority); - return result; - } - - public int compareTo(Object other){ - UserApp castOther = (UserApp) other; - - Long c1 = (this.getUserId()==null ? 0 : this.getUserId()) + (this.getApp()==null||this.getApp().getId()==null ? 0 : this.getApp().getId()) + (this.getRole()==null||this.getRole().getId()==null ? 0 : this.getRole().getId()) + (this.priority==null ? 0 : this.priority); - Long c2 = (castOther.getUserId()==null ? 0 : castOther.getUserId()) + (castOther.getApp()==null||castOther.getApp().getId()==null ? 0 : castOther.getApp().getId()) + (castOther.getRole()==null||castOther.getRole().getId()==null ? 0 : castOther.getRole().getId()) + (castOther.priority==null ? 0 : castOther.priority); - - return c1.compareTo(c2); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/sessionmgt/TimeoutVO.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/sessionmgt/TimeoutVO.java deleted file mode 100644 index 57e474c2..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/sessionmgt/TimeoutVO.java +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain.sessionmgt; - -public class TimeoutVO implements Comparable{ - - private String jSessionId; - private Long sessionTimOutMilliSec; - - public TimeoutVO(){ - - } - - public TimeoutVO(String _jSessionId, Long _sessionTimOutMilliSec) { - setjSessionId(_jSessionId); - setSessionTimOutMilliSec(_sessionTimOutMilliSec); - - } - - public String getjSessionId() { - return jSessionId; - } - - public void setjSessionId(String jSessionId) { - this.jSessionId = jSessionId; - } - - public Long getSessionTimOutMilliSec() { - return sessionTimOutMilliSec; - } - - public void setSessionTimOutMilliSec(Long sessionTimOutMilliSec) { - this.sessionTimOutMilliSec = sessionTimOutMilliSec; - } - - @Override - public int compareTo(TimeoutVO o) { - return sessionTimOutMilliSec.compareTo(o.sessionTimOutMilliSec); - } - - - - - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Container.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Container.java deleted file mode 100644 index 7d52af40..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Container.java +++ /dev/null @@ -1,331 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain.support; - -import java.util.List; -import java.util.Map; - -public class Container { - - String id; - - public String name; - - Size size; - - Position p; - - public Map containerRowCol; - - public Map elementRowCol; - - int numOfRows; - - int numOfCols; - - double sum = 0; - - double interEleWd; - - double interEleH; - - double interEleToContainerWd; - - double interEleToContainerH; - - double interEleToInnerContainerWd; - - double interEleToInnerContainerH; - - public double top; - - public double left; - - public double height; - - public double width; - - public String visibilityType; - - - - - - public Container(String id, String name, int numOfRows, int numOfCols, double interEleWd, double interEleH, - double interEleToContainerWd, double interEleToContainerH, double interEleToInnerContainerWd, - double interEleToInnerContainerH) { - - this.id = id; - this.name = name; - this.numOfRows = numOfRows; - this.numOfCols = numOfCols; - this.interEleWd = interEleWd; - this.interEleH = interEleH; - this.interEleToContainerWd = interEleToContainerWd; - this.interEleToContainerH = interEleToContainerH; - this.interEleToInnerContainerWd = interEleToInnerContainerWd; - this.interEleToInnerContainerH = interEleToInnerContainerH; - - } - - - public List innerCList; - - public List elementList; - - public Container() { - - } - - - - public Map getContainerRowCol() { - return containerRowCol; - } - - - - - public Map getElementRowCol() { - return elementRowCol; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - - public void setInnerContainer(Map innerCon) { - containerRowCol = innerCon; - } - - public void setElements(Map innerE) { - elementRowCol = innerE; - } - - - public Position getP() { - return p; - } - - public void setP(Position p) { - this.p = p; - } - - - public void setTop(double top) { - this.top = top; - } - - - public void setLeft(double left) { - this.left = left; - } - - - public void setHeight(double height) { - this.height = height; - } - - - public void setWidth(double width) { - this.width = width; - } - - - public void setInnerCList(List innerCList) { - this.innerCList = innerCList; - } - - - - public void setElementList(List elementList) { - this.elementList = elementList; - } - - public void setVisibilityType(String visibilityType) { - this.visibilityType = visibilityType; - } - - public Size computeSize() { - Size size = new Size(); - double width = 0; - double height = 0; - // System.out.println("Inside computesize"); - for (int i = 0; i0; chk--) { - if (containerRowCol.containsKey(String.valueOf(k)+ String.valueOf(chk-1))) { - if (containerRowCol.get(String.valueOf(k)+ String.valueOf(chk-1)).computeSize().getWidth() - + containerRowCol.get(String.valueOf(k)+ String.valueOf(chk-1)).getP().getX() > p.x) { - ysum+= containerRowCol.get(String.valueOf(k)+ String.valueOf(chk-1)).computeSize().getHeight(); - break; - } - } - } - } - - } - if (this.getName().equals("Broadworks complex") || this.getName().equals("Application Servers") - || this.getName().equals("Call Session Control") || this.getName().equals("GMLC Provider") || this.getName().equals("Neo") || this.getName().equals("Support")) { - p.y = this.getP().getY()+ysum+i*interEleH+interEleToInnerContainerH+1; - } else { - // System.out.println("element name "+e.getName()+" this.getP().getY() "+this.getP().getY() - // +" ysum " +ysum+" i*interEleH "+i*interEleH+" interEleToContainerH " +interEleToContainerH); - if (e.getName().equals("")) { - p.y = this.getP().getY()+ysum+i*interEleH+(interEleToContainerH); - System.out.println("test element name "+this.getName()+" Container height "+this.computeSize().getHeight()+" this.getP().getY() "+this.getP().getY() - +" ysum " +ysum+" i*interEleH "+i*interEleH+" interEleToContainerH-3 " +interEleToContainerH+" p.y "+p.y); - }else - p.y = this.getP().getY()+ysum+i*interEleH+interEleToContainerH; - // System.out.println(e.getName()+"My contain this.getP().getY() "+this.getP().getY() - // +"elements Y "+p.y); - } - xsum+= e.computeSize().getWidth(); - e.setP(p); - System.out.println("my element name "+e.getName()+" e.getP().getX() "+e.getP().getX()); - System.out.println(); - } - } - xsum = 0; - } - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Domain.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Domain.java deleted file mode 100644 index 3e742785..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Domain.java +++ /dev/null @@ -1,259 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain.support; - -import java.util.List; -import java.util.Map; - -public class Domain { - // Unique identifier of the domain - String id; - // List cList; - - public String name; - Size size; - Position p; - - //Attribute1 at; - - public Position getP() { - return p; - } - - public void setP(Position p) { - this.p = p; - } - - //Horizontal space between a pair of containers - double interContWd = 1.0; - //Vertical space between a pair of containers - double interContH; - double domainToLayoutWd; - double domainToContH; - double domainToLayoutH; - int numOfRowsofContainer; - int numOfColsofContainer; - boolean indexChanged; - Map containerRowCol; - public Domain(String id, String name, double interContWd, double interContH, double domainToLayoutWd, - double domainToLayoutH, double domainToContH, int numOfRowsofContainer, int numOfColsofContainer) { - this.id = id; - this.name = name; - this.interContWd = interContWd; - this.interContH = interContH; - this.domainToLayoutWd = domainToLayoutWd; - this.domainToLayoutH = domainToLayoutH; - this.domainToContH = domainToContH; - this.numOfRowsofContainer = numOfRowsofContainer; - this.numOfColsofContainer = numOfColsofContainer; - // at = new Attribute1(); - } - - - - - public double top; - - public double left; - - public double height; - - public double width; - - public List containerList; - - public double newXafterColl; - - public double YafterColl; - - public void setNewXafterColl(double newXafterColl) { - this.newXafterColl = newXafterColl; - } - - public double getNewXafterColl() { - return newXafterColl; - } - - public double getYafterColl() { - return YafterColl; - } - - public void setYafterColl(double yafterColl) { - YafterColl = yafterColl; - } - - public void setDomainToLayoutWd(double domainToLayoutWd) { - this.domainToLayoutWd = domainToLayoutWd; - } - - public double getDomainToLayoutWd() { - return domainToLayoutWd; - } - - public double getTop() { - return top; - } - - public void setTop(double top) { - this.top = top; - } - - public double getLeft() { - return left; - } - - public void setLeft(double left) { - this.left = left; - } - - public double getHeight() { - return height; - } - - public void setHeight(double height) { - this.height = height; - } - - public double getWidth() { - return width; - } - - public void setWidth(double width) { - this.width = width; - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setContainers(Map containerRowCol) { - this.containerRowCol = containerRowCol; - } - - public Map getContainerRowCol() { - return containerRowCol; - } - - - /* public Attribute1 getAt() { - return at; - } - - public void setAt(Attribute1 at) { - this.at = at; - }*/ - - public void setContainerList(List containerList) { - // new ArrayList(); - this.containerList = containerList; - } - - - -/* public boolean isCollapsed() { - return collapsed; - } - - public void setCollapsed(boolean collapsed) { - this.collapsed = collapsed; - }*/ - - public boolean isIndexChanged() { - return indexChanged; - } - - public void setIndexChanged(boolean indexChanged) { - this.indexChanged = indexChanged; - } - - //Compute the size of any domain - public Size computeSize() { - size = new Size(); - size.setHeight(5); - double width = 0; - for (int i = 0; i < numOfRowsofContainer; i++) { - if (containerRowCol!=null && containerRowCol.containsKey(String.valueOf(i)+String.valueOf(numOfColsofContainer-1))) { - for (int j = 0; j < numOfColsofContainer; j++) { - width+=containerRowCol.get(String.valueOf(i)+String.valueOf(j)).computeSize().getWidth(); - } - break; - } - - } - width+=(numOfColsofContainer-1)*interContWd; - if (this.getName().equals("VNI")) - size.setWidth(width-4); - else - size.setWidth(width); - return size; - } - - public void computeConatinerPositions() { - - double xsum = 0; - double ysum = 0; - for (int i=0; i< numOfRowsofContainer; i++){ - for (int j=0; j0 && containerRowCol.containsKey(String.valueOf(k)+ String.valueOf(j-1)) && - !containerRowCol.get(String.valueOf(i)+ String.valueOf(j)).getName().equals("Alpharetta")) { - ysum+= containerRowCol.get(String.valueOf(k)+ String.valueOf(j-1)).computeSize().getHeight(); - } - } - System.out.println("C name "+c.getName()+" ysum "+ysum+" domainToLayoutH "+domainToLayoutH+" this.computeSize().getHeight() "+ - this.computeSize().getHeight()+" domainToContH "+domainToContH+" interContH "+interContH); - p.y = domainToLayoutH+ysum+this.computeSize().getHeight()+ - domainToContH+i*interContH; - - c.setP(p); - xsum+= c.computeSize().getWidth(); - - } - } - xsum = 0; - - } - - } - -} - - diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/DomainVo.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/DomainVo.java deleted file mode 100644 index 645a9132..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/DomainVo.java +++ /dev/null @@ -1,179 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain.support; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.Date; -import java.util.Set; - -import org.openecomp.portalsdk.core.domain.FusionVo; - - -/* Super class from which all data objects descend */ -@SuppressWarnings("rawtypes") -public class DomainVo extends FusionVo implements Serializable, Cloneable, Comparable { - - /** - * - */ - private static final long serialVersionUID = 1L; - protected Long id; - protected Date created; - protected Date modified; - protected Long createdId; - protected Long modifiedId; - protected Long rowNum; - - protected Serializable auditUserId; - - Set auditTrail = null; - - public DomainVo() {} - - - public void setId(Long i) { - id = i; - } - - public void setCreated(Date created) { - this.created = created; - } - - public void setModified(Date modified) { - this.modified = modified; - } - - public void setCreatedId(Long createdId) { - this.createdId = createdId; - } - - public void setModifiedId(Long modifiedId) { - this.modifiedId = modifiedId; - } - - public void setAuditUserId(Serializable auditUserId) { - this.auditUserId = auditUserId; - } - - public void setRowNum(Long rowNum) { - this.rowNum = rowNum; - } - - public void setAuditTrail(Set auditTrail) { - this.auditTrail = auditTrail; - } - - public Long getId() { - return id; - } - - public Date getCreated() { - return created; - } - - public Date getModified() { - return modified; - } - - public Long getCreatedId() { - return createdId; - } - - public Long getModifiedId() { - return modifiedId; - } - - public Serializable getAuditUserId() { - return auditUserId; - } - - public Long getRowNum() { - return rowNum; - } - - public Set getAuditTrail() { - return auditTrail; - } - -/* public void addAuditTrailLog(AuditLog auditLog) { - if (getAuditTrail() == null) { - setAuditTrail(new HashSet()); - } - - getAuditTrail().add(auditLog); - }*/ - - - public Object clone() throws CloneNotSupportedException { - return super.clone(); - } - - - public Object copy() { - return copy(false); - } - - - public Object copy(boolean isIdNull) { - // let's create a "copy" of the object using serialization - ByteArrayOutputStream baos = null; - ByteArrayInputStream bais = null; - ObjectOutputStream oos = null; - ObjectInputStream ois = null; - - DomainVo newVo = null; - - try { - - baos = new ByteArrayOutputStream(); - oos = new ObjectOutputStream(baos); - oos.writeObject(this); - - bais = new ByteArrayInputStream(baos.toByteArray()); - ois = new ObjectInputStream(bais); - newVo = (DomainVo)ois.readObject(); - - if (isIdNull) { - newVo.setId(null); - } - - } - catch (Exception e) { - e.printStackTrace(); - } - - return newVo; - } - - - - public int compareTo(Object obj){ - Long c1 = getId(); - Long c2 = ((DomainVo)obj).getId(); - - return (c1 == null || c2 == null) ? 1 : c1.compareTo(c2); - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Element.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Element.java deleted file mode 100644 index 84f929fd..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Element.java +++ /dev/null @@ -1,161 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain.support; - -public class Element { - - public String id; - public String name; - - public double top; - - public double left; - - public double height; - - public String imgFileName; - - public String borderType; - - public String bgColor; - - public ElementDetails details; - - //public List details; - - - public void setBgColor(String bgColor) { - this.bgColor = bgColor; - } - - public void setId(String id) { - this.id = id; - } - - public void setTop(double top) { - this.top = top; - } - - public void setLeft(double left) { - this.left = left; - } - - public void setHeight(double height) { - this.height = height; - } - - public void setWidth(double width) { - this.width = width; - } - - - public double width; - - - public String getId() { - return id; - } - - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - - Position p; - - public Position getP() { - return p; - } - - public void setP(Position p) { - this.p = p; - } - - - - public Element(String id, String name, String imgPath, String bgColor, String logical_group, String display_longname, - String description, String primary_function, String key_interfaces, String location, String vendor, String vendor_shortname) { - this.id = id; - this.name = name; - this.imgFileName = imgPath; - this.bgColor = bgColor; - - - } - - public Element(String id, String name) { - this.id = id; - this.name = name; - } - - public Element(String id, String name, String imgFilename, String bgColor, String borderType, ElementDetails details) { - this.id = id; - this.name = name; - this.imgFileName = imgFilename; - this.bgColor = bgColor; - this.borderType = borderType; - this.details = details; - - } - - - public void setBorderType(String borderType) { - this.borderType = borderType; - } - - public String getImgFileName() { - return imgFileName; - } - - public void setImgFileName(String imgFileName) { - this.imgFileName = imgFileName; - } - - public String getBorderType() { - return borderType; - } - - - - public ElementDetails getDetails() { - return details; - } - - - - public void setDetails(ElementDetails details) { - this.details = details; - } - - public Size computeSize() { - Size size= new Size(); - size.setWidth(0.5*7.0); - size.setHeight(0.5*3.0); - // size.setWidth(0.5*10.0); - // size.setHeight(0.5*6.0); - return size; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/ElementDetails.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/ElementDetails.java deleted file mode 100644 index cebaeddc..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/ElementDetails.java +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain.support; - -public class ElementDetails { - public String logical_group; - public String display_longname; - public String description; - public String primary_function; - public String network_function; - public String key_interfaces; - public String location; - public String vendor; - public String vendor_shortname; - public String enclosingContainer; - - -// public Map details1; - -// public ElementDetails(Map details) { - - // this.details = new HashMap(); - // this.details1 = details; -// } - - - - - - public ElementDetails(String logical_group, String display_longname, String description, String primary_function, String network_function, - String key_interfaces, String location, String vendor, String vendor_shortname, String enclosingContainer) { - - this.logical_group = logical_group; - this.display_longname = display_longname; - this.description = description; - this.primary_function = primary_function; - this.network_function = network_function; - this.key_interfaces = key_interfaces; - this.location = location; - this.vendor = vendor; - this.vendor_shortname = vendor_shortname; - this.enclosingContainer = enclosingContainer; - } - - public void setLogical_group(String logical_group) { - this.logical_group = logical_group; - } - - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Layout.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Layout.java deleted file mode 100644 index 58056232..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/Layout.java +++ /dev/null @@ -1,991 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain.support; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -public class Layout { - - public Map domainRowCol; - - Map originalDomainRowCol; - - //Horizontal space between a pair of domains - double interDomainWd; - //Vertical space between a pair of domains - double interDomainH; - //Computing the co-ordinates of any domain - int numberofRowsofDomains; - - int numberofColsofDomains; - - Map collapsedDomains; - - List collapsedDomainsNewList; - - public List getCollapsedDomainsNewList() { - return collapsedDomainsNewList; - } - - public void setCollapsedDomainsNewList(List collapsedDomainsNewList) { - this.collapsedDomainsNewList = collapsedDomainsNewList; - } - - public void setCollapsedDomains(Map collapsedDomains) { - this.collapsedDomains = collapsedDomains; - } - - public Map getCollapsedDomains() { - return collapsedDomains; - } - - public int getNumberofColsofDomains() { - return numberofColsofDomains; - } - - public void setNumberofColsofDomains(int numberofColsofDomains) { - this.numberofColsofDomains = numberofColsofDomains; - } - - public Layout(Map domainRowCol, double interDomainWd, double interDomainH, - int numberofRowsofDomains, int numberofColsofDomains) { - - this.domainRowCol = domainRowCol; - this.interDomainWd = interDomainWd; - this.interDomainH = interDomainH; - this.numberofRowsofDomains = numberofRowsofDomains; - this.numberofColsofDomains = numberofColsofDomains; - this.collapsedDomains = new HashMap(); - this.originalDomainRowCol = new TreeMap(); - this.collapsedDomainsNewList = new ArrayList(); - } - - public Map getDomainRowCol() { - return domainRowCol; - } - - public void setDomainRowCol(Map domainRowCol) { - this.domainRowCol = domainRowCol; - } - - - public void computeDomainPositions() { - double xsum = 0; - double domainTolayout = 10.6; - for (int i=0; i< numberofRowsofDomains; i++){ - for (int j=0; j 0) - p.x+= accountForPlusSpaceBefore(d); - xsum+=d.computeSize().getWidth(); - double ysum=0; - for (int k=0; k enclosedContainers = d.getContainerRowCol(); - for (Map.Entry entry : enclosedContainers.entrySet()) { - if (entry.getKey().equals("00")) { - double containerX = entry.getValue().getP().getX(); - p.x = containerX; - double ysum=0; - for (int k=0; k updatedRC = new HashMap(); - - for (Map.Entry copyEntry : domainRowCol.entrySet()) { - updatedRC.put(copyEntry.getKey(), copyEntry.getValue()); - System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); - } - - Map updatedRCSorted = new TreeMap(updatedRC); - - Map collapsedDomainMap = getCollapsedDomains(); - - List collapsedDomainNewL = getCollapsedDomainsNewList(); - - - if (collapsedDomainNewL.size() == 0) { - for (Map.Entry copyEntry : domainRowCol.entrySet()) { - originalDomainRowCol.put(copyEntry.getKey(), copyEntry.getValue()); - } - } - - - Map updatedRCSortedTrunc = new TreeMap(); - - int colToDelete = 0; - for (Map.Entry entry : updatedRCSorted.entrySet()) { - if (entry.getValue().getName().equals(domainsToCollapse)) { - if (entry.getValue().isIndexChanged()) { - collapsedDomainMap.put("0"+String.valueOf(Integer.parseInt(entry.getKey())+1), entry.getValue()); - - } - else { - collapsedDomainMap.put(entry.getKey(),entry.getValue()); - } - - collapsedDomainNewL.add(entry.getValue()); - setNumberofColsofDomains(getNumberofColsofDomains()-1); - updatedRC.remove(entry.getKey()); - colToDelete = Character.getNumericValue(entry.getKey().toCharArray()[1]); - break; - } - } - - - for (Map.Entry copyEntry : updatedRCSorted.entrySet()) { - updatedRCSortedTrunc.put(copyEntry.getKey(), copyEntry.getValue()); - System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); - } - - for (Map.Entry rmv : updatedRCSorted.entrySet()) { - if (Character.getNumericValue(rmv.getKey().toCharArray()[1]) <= colToDelete) { - updatedRCSortedTrunc.remove(rmv.getKey()); - } - } - - for (Map.Entry updateOthers : updatedRCSortedTrunc.entrySet()) { - char update[] = updateOthers.getKey().toCharArray(); - int charToupdate = Character.getNumericValue(update[1]); - --charToupdate; - String resultRowCol = String.valueOf(update[0])+String.valueOf(charToupdate); - updateOthers.getValue().setIndexChanged(true); - updatedRC.put(resultRowCol, updateOthers.getValue()); - updatedRC.remove(updateOthers.getKey()); - - } - setDomainRowCol(updatedRC); - - double currDistFromLftM = 11.0; - for (Map.Entry cd : updatedRC.entrySet()) { - - Domain d = cd.getValue(); - double accountPlus = accountForPlusSpaceBefore(d); - d.setDomainToLayoutWd(currDistFromLftM+accountPlus); - d.computeConatinerPositions(); - for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { - Container c = entry1.getValue(); - c.computeSize(); - c.computeElementPositions(); - if (c.getContainerRowCol() != null) { - for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { - Container inner = entryInner.getValue(); - inner.computeElementPositions(); - } - } - } - currDistFromLftM += d.computeSize().getWidth()+2; - - } - - - - - //nline - // Insert method invocation - updatePlusPosition(collapsedDomainNewL, updatedRC); - - //order changed - setCollapsedDomains(collapsedDomainMap); - setCollapsedDomainsNewList(collapsedDomainNewL); - - - computeDomainPositionsModified(); - return this; - } - - - - public Layout collapseDomainNew(String domainsToCollapse) { - - if(domainsToCollapse == null || domainsToCollapse.isEmpty()) - return null; - - Map updatedRC = new HashMap(); - - for (Map.Entry copyEntry : domainRowCol.entrySet()) { - updatedRC.put(copyEntry.getKey(), copyEntry.getValue()); - System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); - } - - Map updatedRCSorted = new TreeMap(updatedRC); - - Map collapsedDomainMap = getCollapsedDomains(); - - List collapsedDomainNewL = getCollapsedDomainsNewList(); - - - if (collapsedDomainNewL.size() == 0) { - for (Map.Entry copyEntry : domainRowCol.entrySet()) { - originalDomainRowCol.put(copyEntry.getKey(), copyEntry.getValue()); - } - } - - - Map updatedRCSortedTrunc = new TreeMap(); - - int colToDelete = 0; - for (Map.Entry entry : updatedRCSorted.entrySet()) { - if (entry.getValue().getName().equals(domainsToCollapse)) { - if (entry.getValue().isIndexChanged()) { - collapsedDomainMap.put("0"+String.valueOf(Integer.parseInt(entry.getKey())+1), entry.getValue()); - - } - else { - collapsedDomainMap.put(entry.getKey(),entry.getValue()); - } - - collapsedDomainNewL.add(entry.getValue()); - setNumberofColsofDomains(getNumberofColsofDomains()-1); - updatedRC.remove(entry.getKey()); - colToDelete = Character.getNumericValue(entry.getKey().toCharArray()[1]); - break; - } - } - - - for (Map.Entry copyEntry : updatedRCSorted.entrySet()) { - updatedRCSortedTrunc.put(copyEntry.getKey(), copyEntry.getValue()); - System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); - } - - for (Map.Entry rmv : updatedRCSorted.entrySet()) { - if (Character.getNumericValue(rmv.getKey().toCharArray()[1]) <= colToDelete) { - updatedRCSortedTrunc.remove(rmv.getKey()); - } - } - - for (Map.Entry updateOthers : updatedRCSortedTrunc.entrySet()) { - char update[] = updateOthers.getKey().toCharArray(); - int charToupdate = Character.getNumericValue(update[1]); - --charToupdate; - String resultRowCol = String.valueOf(update[0])+String.valueOf(charToupdate); - updateOthers.getValue().setIndexChanged(true); - updatedRC.put(resultRowCol, updateOthers.getValue()); - updatedRC.remove(updateOthers.getKey()); - - } - setDomainRowCol(updatedRC); - - double currDistFromLftM = 11.0; - - boolean isDisplayed; - for (Map.Entry orgEntry : originalDomainRowCol.entrySet()) { - isDisplayed = false; - for (Map.Entry cd : updatedRC.entrySet()) { - if (cd.getValue().getName().equals(orgEntry.getValue().getName())) { - Domain d = cd.getValue(); - d.setDomainToLayoutWd(currDistFromLftM); - d.computeConatinerPositions(); - for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { - Container c = entry1.getValue(); - c.computeSize(); - c.computeElementPositions(); - if (c.getContainerRowCol() != null) { - for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { - Container inner = entryInner.getValue(); - inner.computeElementPositions(); - } - } - } - currDistFromLftM += d.computeSize().getWidth()+1; - isDisplayed = true; - break; - } - } - - if (!isDisplayed) { - Domain myCollapsed = orgEntry.getValue(); - myCollapsed.setNewXafterColl(currDistFromLftM); - myCollapsed.setYafterColl(myCollapsed.getP().getY()); - currDistFromLftM += 4; - } - } - - setCollapsedDomains(collapsedDomainMap); - setCollapsedDomainsNewList(collapsedDomainNewL); - - - computeDomainPositionsModified(); - return this; - - } - - - public Layout collapseDomain(String domainsToCollapse) { - - Map updatedRC = new HashMap(); - - for (Map.Entry copyEntry : domainRowCol.entrySet()) { - updatedRC.put(copyEntry.getKey(), copyEntry.getValue()); - System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); - } - - Map updatedRCSorted = new TreeMap(updatedRC); - - Map collapsedDomainMap = getCollapsedDomains(); - - if (collapsedDomainMap.size() == 0) { - for (Map.Entry copyEntry : domainRowCol.entrySet()) { - originalDomainRowCol.put(copyEntry.getKey(), copyEntry.getValue()); - } - } - - - double prevDomXCordinate = 0.0; - Map updatedRCSortedTrunc = new TreeMap(); - int colToDelete = 0; - for (Map.Entry entry : updatedRCSorted.entrySet()) { - if (entry.getValue().getName().equals(domainsToCollapse)) { - if (entry.getValue().isIndexChanged()) - collapsedDomainMap.put("0"+String.valueOf(Integer.parseInt(entry.getKey())+1), entry.getValue()); - else - collapsedDomainMap.put(entry.getKey(),entry.getValue()); - prevDomXCordinate = entry.getValue().getP().getX(); - entry.getValue().getP().setX(prevDomXCordinate-2); - setNumberofColsofDomains(getNumberofColsofDomains()-1); - updatedRC.remove(entry.getKey()); - colToDelete = Character.getNumericValue(entry.getKey().toCharArray()[1]); - break; - } - } - - setCollapsedDomains(collapsedDomainMap); - - for (Map.Entry copyEntry : updatedRCSorted.entrySet()) { - updatedRCSortedTrunc.put(copyEntry.getKey(), copyEntry.getValue()); - System.out.println("copyEntry.getKey() "+copyEntry.getKey()+ " copyEntry.getValue() "+copyEntry.getValue()); - } - - for (Map.Entry rmv : updatedRCSorted.entrySet()) { - if (Character.getNumericValue(rmv.getKey().toCharArray()[1]) <= colToDelete) { - updatedRCSortedTrunc.remove(rmv.getKey()); - } - } - - for (Map.Entry updateOthers : updatedRCSortedTrunc.entrySet()) { - char update[] = updateOthers.getKey().toCharArray(); - int charToupdate = Character.getNumericValue(update[1]); - --charToupdate; - String resultRowCol = String.valueOf(update[0])+String.valueOf(charToupdate); - updateOthers.getValue().setIndexChanged(true); - updatedRC.put(resultRowCol, updateOthers.getValue()); - updatedRC.remove(updateOthers.getKey()); - } - - setDomainRowCol(updatedRC); - - - - for (Map.Entry entry : updatedRCSortedTrunc.entrySet()) { - Domain d = entry.getValue(); - if (collapsedDomains.size() == 2 && collapsedDomains.containsKey("00") && collapsedDomains.containsKey("01") && domainsToCollapse.equals("RAN")) { - if (d.getName().equals("USP")) - d.setDomainToLayoutWd(prevDomXCordinate); - else if (d.getName().equals("VNI")) - d.setDomainToLayoutWd(prevDomXCordinate+8); - else - d.setDomainToLayoutWd(prevDomXCordinate+10); - } - else if (domainsToCollapse.equals("RAN") && !d.getName().equals("EPC") && collapsedDomains.size() < 3) - d.setDomainToLayoutWd(prevDomXCordinate+11); - else if (domainsToCollapse.equals("RAN") && collapsedDomains.size() == 3 && collapsedDomains.containsKey("01") && collapsedDomains.containsKey("04")) { - if (d.getName().equals("USP")) - d.setDomainToLayoutWd(prevDomXCordinate); - else - d.setDomainToLayoutWd(prevDomXCordinate+10); - } - - else if (collapsedDomains.containsKey("00") && collapsedDomains.size() == 3 && collapsedDomains.containsKey("01") && collapsedDomains.containsKey("02")) { - if (d.getName().equals("VNI")) - d.setDomainToLayoutWd(prevDomXCordinate+10); - else - d.setDomainToLayoutWd(prevDomXCordinate); - - } - - else if (collapsedDomains.containsKey("00") && collapsedDomains.size() == 3 && collapsedDomains.containsKey("01") && collapsedDomains.containsKey("03")) { - if (d.getName().equals("VNI")) - d.setDomainToLayoutWd(prevDomXCordinate+10); - else - d.setDomainToLayoutWd(prevDomXCordinate); - - } - - - - else { - d.setDomainToLayoutWd(prevDomXCordinate); - } - d.computeConatinerPositions(); - prevDomXCordinate = d.getP().getX(); - for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { - Container c = entry1.getValue(); - c.computeSize(); - c.computeElementPositions(); - if (c.getContainerRowCol() != null) { - for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { - Container inner = entryInner.getValue(); - inner.computeElementPositions(); - } - } - } - } - computeDomainPositions(); - return this; - - } - - public Layout uncollapseDomainModified(String domainToUnCollapse) { - Map currentDomainsSorted = new TreeMap(domainRowCol); - Map updateDomains = new TreeMap(); - Map collapsedDomainList = getCollapsedDomains(); - Map collapsedDomainListSorted = new TreeMap(collapsedDomainList); - - List domainstoUpd = new ArrayList(); - - int colToUnCollapse = 99; - - Domain domainToInsert = null; - - if (collapsedDomains.size() == 0) { - for (Map.Entry unindexDomain : originalDomainRowCol.entrySet()) { - Domain dm = unindexDomain.getValue(); - dm.setIndexChanged(false); - } - } - - - for (Map.Entry entry : collapsedDomainListSorted.entrySet()) { - if (entry.getValue().getName().equals(domainToUnCollapse)) { - colToUnCollapse = Character.getNumericValue(entry.getKey().toCharArray()[1]); - domainToInsert = entry.getValue(); - collapsedDomainList.remove(entry.getKey()); - break; - } - } - - domainstoUpd.add(domainToInsert); - - for (Map.Entry e : originalDomainRowCol.entrySet()) - System.out.println("Original key value"+e.getKey()+":"+e.getValue().getName()); - - int lastKeyCol = -1; - for (Map.Entry entry : originalDomainRowCol.entrySet()) { - int currcol = Character.getNumericValue(entry.getKey().toCharArray()[1]); - if (currcol < colToUnCollapse) { - for (Map.Entry currDomainsEntry : currentDomainsSorted.entrySet()) { - if (currDomainsEntry.getValue().getName().equals(entry.getValue().getName())) { - updateDomains.put(currDomainsEntry.getKey(), currDomainsEntry.getValue()); - lastKeyCol = Character.getNumericValue(currDomainsEntry.getKey().toCharArray()[1]); - break; - } - } - } else { - String newKey = "0"+String.valueOf(lastKeyCol+1); - if (currcol == colToUnCollapse) { - updateDomains.put(newKey, domainToInsert); - ++lastKeyCol; - } else { - for (Map.Entry currDomainsEnt : currentDomainsSorted.entrySet()) { - if (currDomainsEnt.getValue().getName().equals(entry.getValue().getName())) { - updateDomains.put(newKey, currDomainsEnt.getValue()); - domainstoUpd.add(currDomainsEnt.getValue()); - ++lastKeyCol; - break; - } - } - } - - } - } - - setNumberofColsofDomains(getNumberofColsofDomains()+1); - setDomainRowCol(updateDomains); - setCollapsedDomains(collapsedDomainList); - - for (Map.Entry e : updateDomains.entrySet()) - System.out.println("me Updatedomains key value"+e.getKey()+":"+e.getValue().getName()); - - for (int i = 0; i < domainstoUpd.size(); i++) { - Domain d = domainstoUpd.get(i); - double newX = 0.0; - if (i+1 < domainstoUpd.size()) - newX = domainstoUpd.get(i+1).getP().getX(); - else - newX = domainstoUpd.get(i).getP().getX()+32; - - if (d.getName().equals("Datacenter")) - newX+= 2; - d.setDomainToLayoutWd(newX); - d.computeConatinerPositions(); - for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { - Container c = entry1.getValue(); - c.computeSize(); - c.computeElementPositions(); - if (c.getContainerRowCol() != null) { - for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { - Container inner = entryInner.getValue(); - inner.computeElementPositions(); - } - } - } - } - - computeDomainPositions(); - return this; - - } - - - - public Layout uncollapseDomain(String domainToCollapse) { - Map currentDomainsSorted = new TreeMap(domainRowCol); - Map updateDomains = new TreeMap(); - Map collapsedDomainList = getCollapsedDomains(); - Map collapsedDomainListSorted = new TreeMap(collapsedDomainList); - - List domainstoUpd = new ArrayList(); - - - for (Map.Entry entry : collapsedDomainListSorted.entrySet()) { - if (entry.getValue().getName().equals(domainToCollapse)) { - if (currentDomainsSorted != null) { - int colToUnCollapse = Character.getNumericValue(entry.getKey().toCharArray()[1]); - for (Map.Entry curr : currentDomainsSorted.entrySet()) { - if (Character.getNumericValue(curr.getKey().toCharArray()[1]) < colToUnCollapse) { - updateDomains.put(curr.getKey(),curr.getValue()); - } else { - updateDomains.put("0"+String.valueOf(Integer.parseInt(curr.getKey())+1),curr.getValue()); - domainstoUpd.add(curr.getValue()); - } - } - } - updateDomains.put(entry.getKey(), entry.getValue()); - collapsedDomainList.remove(entry.getKey()); - break; - - } - } - setNumberofColsofDomains(getNumberofColsofDomains()+1); - setDomainRowCol(updateDomains); - setCollapsedDomains(collapsedDomainList); - - for (Map.Entry e : updateDomains.entrySet()) - System.out.println("Updatedomains key value"+e.getKey()+":"+e.getValue().getName()); - - - for (int i = 0; i < domainstoUpd.size(); i++) { - Domain d = domainstoUpd.get(i); - double newX = 0.0; - if (i+1 < domainstoUpd.size()) - newX = domainstoUpd.get(i+1).getP().getX(); - else - newX = domainstoUpd.get(i).getP().getX()+38; - - if (d.getName().equals("Datacenter")) - newX+= 5; - d.setDomainToLayoutWd(newX); - d.computeConatinerPositions(); - for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { - Container c = entry1.getValue(); - c.computeSize(); - c.computeElementPositions(); - if (c.getContainerRowCol() != null) { - for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { - Container inner = entryInner.getValue(); - inner.computeElementPositions(); - } - } - } - } - - computeDomainPositions(); - return this; - } - - public Layout uncollapseDomainNew(String domainToUnCollapse) { - Map currentDomainsSorted = new TreeMap(domainRowCol); - Map updateDomains = new TreeMap(); - Map collapsedDomainList = getCollapsedDomains(); - List domainstoUpd = new ArrayList(); - - //nline - List collapsedDomainNewLL = getCollapsedDomainsNewList(); - - int colToUnCollapse = 99; - - Domain domainToInsert = null; - - //nline - if (collapsedDomainNewLL.size() == 0) { - for (Map.Entry unindexDomain : originalDomainRowCol.entrySet()) { - Domain dm = unindexDomain.getValue(); - dm.setIndexChanged(false); - } - } - - - for (Map.Entry entry : originalDomainRowCol.entrySet()) { - if (entry.getValue().getName().equals(domainToUnCollapse)) { - colToUnCollapse = Character.getNumericValue(entry.getKey().toCharArray()[1]); - domainToInsert = entry.getValue(); - collapsedDomainList.remove(entry.getKey()); - //nline - collapsedDomainNewLL.remove(entry.getValue()); - break; - } - } - - domainstoUpd.add(domainToInsert); - - for (Map.Entry e : originalDomainRowCol.entrySet()) - System.out.println("Original key value"+e.getKey()+":"+e.getValue().getName()); - - int lastKeyCol = -1; - for (Map.Entry entry : originalDomainRowCol.entrySet()) { - int currcol = Character.getNumericValue(entry.getKey().toCharArray()[1]); - if (currcol < colToUnCollapse) { - for (Map.Entry currDomainsEntry : currentDomainsSorted.entrySet()) { - if (currDomainsEntry.getValue().getName().equals(entry.getValue().getName())) { - updateDomains.put(currDomainsEntry.getKey(), currDomainsEntry.getValue()); - lastKeyCol = Character.getNumericValue(currDomainsEntry.getKey().toCharArray()[1]); - break; - } - } - } else { - String newKey = "0"+String.valueOf(lastKeyCol+1); - if (currcol == colToUnCollapse) { - updateDomains.put(newKey, domainToInsert); - ++lastKeyCol; - } else { - for (Map.Entry currDomainsEnt : currentDomainsSorted.entrySet()) { - if (currDomainsEnt.getValue().getName().equals(entry.getValue().getName())) { - updateDomains.put(newKey, currDomainsEnt.getValue()); - domainstoUpd.add(currDomainsEnt.getValue()); - ++lastKeyCol; - break; - } - } - } - - } - } - - setNumberofColsofDomains(getNumberofColsofDomains()+1); - setDomainRowCol(updateDomains); - - for (Map.Entry e : updateDomains.entrySet()) - System.out.println("me Updatedomains key value"+e.getKey()+":"+e.getValue().getName()); - - - - double currDistFromLftMargin = 11.0; - for (Map.Entry cd : updateDomains.entrySet()) { - Domain d = cd.getValue(); - double accountPlus = accountForPlusSpaceBefore(d); - d.setDomainToLayoutWd(currDistFromLftMargin+accountPlus); - d.computeConatinerPositions(); - for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { - Container c = entry1.getValue(); - c.computeSize(); - c.computeElementPositions(); - if (c.getContainerRowCol() != null) { - for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { - Container inner = entryInner.getValue(); - inner.computeElementPositions(); - } - } - } - currDistFromLftMargin += d.computeSize().getWidth()+2; - - } - - //nline - updatePlusPosition(collapsedDomainNewLL, updateDomains); - - //order changed - setCollapsedDomains(collapsedDomainList); - - //nline - setCollapsedDomainsNewList(collapsedDomainNewLL); - - - computeDomainPositionsModified(); - return this; - - } - - public Layout uncollapseDomainNew1(String domainToUnCollapse) { - - if(domainToUnCollapse == null || domainToUnCollapse.isEmpty()) - return null; - - Map currentDomainsSorted = new TreeMap(domainRowCol); - Map updateDomains = new TreeMap(); - Map collapsedDomainList = getCollapsedDomains(); - List domainstoUpd = new ArrayList(); - - //nline - List collapsedDomainNewLL = getCollapsedDomainsNewList(); - - int colToUnCollapse = 99; - - Domain domainToInsert = null; - - //nline - if (collapsedDomainNewLL.size() == 0) { - for (Map.Entry unindexDomain : originalDomainRowCol.entrySet()) { - Domain dm = unindexDomain.getValue(); - dm.setIndexChanged(false); - } - } - - - for (Map.Entry entry : originalDomainRowCol.entrySet()) { - if (entry.getValue().getName().equals(domainToUnCollapse)) { - colToUnCollapse = Character.getNumericValue(entry.getKey().toCharArray()[1]); - domainToInsert = entry.getValue(); - collapsedDomainList.remove(entry.getKey()); - //nline - collapsedDomainNewLL.remove(entry.getValue()); - break; - } - } - - domainstoUpd.add(domainToInsert); - - for (Map.Entry e : originalDomainRowCol.entrySet()) - System.out.println("Original key value"+e.getKey()+":"+e.getValue().getName()); - - int lastKeyCol = -1; - for (Map.Entry entry : originalDomainRowCol.entrySet()) { - int currcol = Character.getNumericValue(entry.getKey().toCharArray()[1]); - if (currcol < colToUnCollapse) { - for (Map.Entry currDomainsEntry : currentDomainsSorted.entrySet()) { - if (currDomainsEntry.getValue().getName().equals(entry.getValue().getName())) { - updateDomains.put(currDomainsEntry.getKey(), currDomainsEntry.getValue()); - lastKeyCol = Character.getNumericValue(currDomainsEntry.getKey().toCharArray()[1]); - break; - } - } - } else { - String newKey = "0"+String.valueOf(lastKeyCol+1); - if (currcol == colToUnCollapse) { - updateDomains.put(newKey, domainToInsert); - ++lastKeyCol; - } else { - for (Map.Entry currDomainsEnt : currentDomainsSorted.entrySet()) { - if (currDomainsEnt.getValue().getName().equals(entry.getValue().getName())) { - updateDomains.put(newKey, currDomainsEnt.getValue()); - domainstoUpd.add(currDomainsEnt.getValue()); - ++lastKeyCol; - break; - } - } - } - - } - } - - setNumberofColsofDomains(getNumberofColsofDomains()+1); - setDomainRowCol(updateDomains); - - for (Map.Entry e : updateDomains.entrySet()) - System.out.println("me Updatedomains key value"+e.getKey()+":"+e.getValue().getName()); - - - - - double currDistFromLftM = 11.0; - - boolean isDisplayed; - for (Map.Entry orgEntry : originalDomainRowCol.entrySet()) { - isDisplayed = false; - for (Map.Entry cd : updateDomains.entrySet()) { - if (cd.getValue().getName().equals(orgEntry.getValue().getName())) { - Domain d = cd.getValue(); - d.setDomainToLayoutWd(currDistFromLftM); - d.computeConatinerPositions(); - for (Map.Entry entry1 : d.getContainerRowCol().entrySet()) { - Container c = entry1.getValue(); - c.computeSize(); - c.computeElementPositions(); - if (c.getContainerRowCol() != null) { - for (Map.Entry entryInner : c.getContainerRowCol().entrySet()) { - Container inner = entryInner.getValue(); - inner.computeElementPositions(); - } - } - } - currDistFromLftM += d.computeSize().getWidth()+1; - isDisplayed = true; - break; - } - } - - if (!isDisplayed) { - Domain myCollapsed = orgEntry.getValue(); - myCollapsed.setNewXafterColl(currDistFromLftM); - currDistFromLftM += 4; - } - } - - - //order changed - setCollapsedDomains(collapsedDomainList); - - //nline - setCollapsedDomainsNewList(collapsedDomainNewLL); - - - computeDomainPositionsModified(); - return this; - - } - - private void updatePlusPosition(List collapsedDNewL, Map displayedDomainMap) { - List copyCollapseList = new ArrayList(); - - for (Domain copyCollapse : collapsedDNewL) { - copyCollapseList.add(copyCollapse); - } - - int orgColofCollapsed = -1; - int orgColofDisplayed = -1; - int orgColofDisplayedOtherPlus = -1; - for (Domain plus : collapsedDNewL) { - double distOfCollFrmLft = 0.0; - for (Map.Entry colCheck : originalDomainRowCol.entrySet()) { - if (colCheck.getValue().getName().equals(plus.getName())) { - orgColofCollapsed = Character.getNumericValue(colCheck.getKey().toCharArray()[1]); - break; - } - } - for (Map.Entry displayedEntry : displayedDomainMap.entrySet()) { - - for (Map.Entry colCheck1 : originalDomainRowCol.entrySet()) { - if (colCheck1.getValue().getName().equals(displayedEntry.getValue().getName())) { - orgColofDisplayed = Character.getNumericValue(colCheck1.getKey().toCharArray()[1]); - break; - } - } - if (orgColofDisplayed < orgColofCollapsed) { - distOfCollFrmLft+= displayedEntry.getValue().computeSize().getWidth(); - - } - - } - - for (Domain collp : copyCollapseList) { - if (!collp.getName().equals(plus.getName())) { - for (Map.Entry colCheck2 : originalDomainRowCol.entrySet()) { - if (colCheck2.getValue().getName().equals(collp.getName())) { - orgColofDisplayedOtherPlus = Character.getNumericValue(colCheck2.getKey().toCharArray()[1]); - break; - } - } - if (orgColofDisplayedOtherPlus < orgColofCollapsed) { - distOfCollFrmLft+=3.0; - } - } - } - - plus.setNewXafterColl(distOfCollFrmLft+1.5); - - - } - } - - - private double accountForPlusSpaceBefore(Domain d) { - - int orgColofCollapsed = 0; - int orgColofDisplayed = 0; - double distFromLftM = 0.0; - - for (Map.Entry colCheckk : originalDomainRowCol.entrySet()) { - if (colCheckk.getValue().getName().equals(d.getName())) { - orgColofDisplayed = Character.getNumericValue(colCheckk.getKey().toCharArray()[1]); - break; - } - } - - for (Domain collapsed : getCollapsedDomainsNewList()) { - for (Map.Entry colCheck : originalDomainRowCol.entrySet()) { - if (colCheck.getValue().getName().equals(collapsed.getName())) { - orgColofCollapsed = Character.getNumericValue(colCheck.getKey().toCharArray()[1]); - break; - } - } - - if (orgColofCollapsed < orgColofDisplayed) { - distFromLftM+= 2; - } - } - return distFromLftM; - - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/NameValueId.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/NameValueId.java deleted file mode 100644 index 52d03c5f..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/domain/support/NameValueId.java +++ /dev/null @@ -1,94 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.domain.support; - -import java.io.Serializable; - - -public class NameValueId implements Serializable { - - /** - * - */ - private static final long serialVersionUID = 1L; - private String lab; - private String val; - - public NameValueId() { - } - - public NameValueId(String value, String label) { - setVal(value); - setLab(label); - } - - - public String getLab() { - return lab; - } - - - public String getVal() { - return val; - } - - - public void setLab(String label) { - this.lab = label; - } - - - public void setVal(String value) { - this.val = value; - } - - - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null) { - return false; - } - - if (!(o instanceof NameValueId)) { - return false; - } - - final NameValueId nameValueId = (NameValueId)o; - - if (!getVal().equals(nameValueId.getVal())) { - return false; - } - - if (!getLab().equals(nameValueId.getLab())) { - return false; - } - - return true; - } - - - public int hashCode() { - return getVal().hashCode(); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleServiceImpl.java deleted file mode 100644 index 7328c472..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/drools/DroolsRuleServiceImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.drools; - - -/** - * - * This is POC test class to execute sample rules - */ -public class DroolsRuleServiceImpl implements DroolsRuleService{ - - - private String state; - private String resultsString; - - public DroolsRuleServiceImpl() { - - } - - public void init(String... params) { - this.state = params[0]; - } - - - - public String getState() { - return state; - } - - public String accessLabel() { - return "Drools POC Test"; - } - - public String getResultsString() { - return resultsString; - } - - public void setResultsString(String resultsString) { - this.resultsString = resultsString; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/FusionExceptionResolver.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/FusionExceptionResolver.java deleted file mode 100644 index f756d760..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/FusionExceptionResolver.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.exception; - -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.servlet.ModelAndView; - -@ControllerAdvice -public class FusionExceptionResolver { - - @ExceptionHandler(UrlAccessRestrictedException.class) - public ModelAndView handleUrlAccessException(UrlAccessRestrictedException ex) { - ModelAndView model = new ModelAndView("error"); - model.addObject("errMsg", ex.getMessage()); - return model; - - } - @ExceptionHandler(SessionExpiredException.class) - public ModelAndView handleSessionException(SessionExpiredException ex) { - ModelAndView model = new ModelAndView("error"); - model.addObject("errMsg", ex.getMessage()); - return model; - } - @ExceptionHandler(Exception.class) - public ModelAndView handleAllException(Exception ex) { - ModelAndView model = new ModelAndView("error"); - model.addObject("errMsg", ex.getMessage()); - return model; - - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/SessionExpiredException.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/SessionExpiredException.java deleted file mode 100644 index ba8f76bd..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/SessionExpiredException.java +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.exception; - -import org.openecomp.portalsdk.core.exception.support.FusionRuntimeException; - -public class SessionExpiredException extends FusionRuntimeException { - /** - * - */ - private static final long serialVersionUID = 1L; - public static final String MESSAGE = "Your session has expired. Please login again."; - - public SessionExpiredException() { - super(MESSAGE); - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/UrlAccessRestrictedException.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/UrlAccessRestrictedException.java deleted file mode 100644 index 39fe264a..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/UrlAccessRestrictedException.java +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.exception; - -import org.openecomp.portalsdk.core.exception.support.FusionRuntimeException; - -public class UrlAccessRestrictedException extends FusionRuntimeException { - /** - * - */ - private static final long serialVersionUID = 1L; - public static final String MESSAGE = "Authorization Denied"; - - public UrlAccessRestrictedException() { - super(MESSAGE); - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionRuntimeException.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionRuntimeException.java deleted file mode 100644 index f7ca61fa..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/exception/support/FusionRuntimeException.java +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.exception.support; - -public class FusionRuntimeException extends RuntimeException implements FusionException { - /** - * - */ - private static final long serialVersionUID = 1L; - - public FusionRuntimeException() { - this(""); - } - - public FusionRuntimeException(String message) { - super(message); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/interceptor/ResourceInterceptor.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/interceptor/ResourceInterceptor.java deleted file mode 100644 index 24088cdb..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/interceptor/ResourceInterceptor.java +++ /dev/null @@ -1,164 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.interceptor; - -import java.net.HttpURLConnection; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.openecomp.portalsdk.core.controller.FusionBaseController; -import org.openecomp.portalsdk.core.domain.App; -import org.openecomp.portalsdk.core.exception.UrlAccessRestrictedException; -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.objectcache.AbstractCacheManager; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalTimeoutHandler; -import org.openecomp.portalsdk.core.service.DataAccessService; -import org.openecomp.portalsdk.core.service.LoginService; -import org.openecomp.portalsdk.core.service.WebServiceCallService; -import org.openecomp.portalsdk.core.util.CipherUtil; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; - -public class ResourceInterceptor extends HandlerInterceptorAdapter { - public static final String APP_METADATA = "APP.METADATA"; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ResourceInterceptor.class); - - @Autowired - private DataAccessService dataAccessService; - @Autowired - private LoginService loginService; - @Autowired - private WebServiceCallService webServiceCallService; - - private AbstractCacheManager cacheManager; - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) - throws Exception { - String uri = request.getRequestURI(); - String url = uri.substring(uri.indexOf("/", 1) + 1); - logger.info(EELFLoggerDelegate.debugLogger, "Url - " + url); - logger.info(EELFLoggerDelegate.debugLogger, "lastIndexOf - " + uri.substring(uri.lastIndexOf("/") + 1)); - if (handler instanceof HandlerMethod) { - HandlerMethod method = (HandlerMethod) handler; - FusionBaseController controller = (FusionBaseController) method.getBean(); - if (!controller.isAccessible()) { - if (controller.isRESTfulCall()) { - // check user authentication for RESTful calls - String secretKey = null; - try { - if (!webServiceCallService.verifyRESTCredential(secretKey, request.getHeader("username"), - request.getHeader("password"))) { - logger.error(EELFLoggerDelegate.errorLogger, "Error accesing RESTful service. Un-authorized",AlarmSeverityEnum.MINOR); - throw new UrlAccessRestrictedException(); - } - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Error authenticating RESTful service :" + e,AlarmSeverityEnum.MINOR); - ((HttpServletResponse) response).setStatus(HttpURLConnection.HTTP_UNAUTHORIZED); - return false; - } - } - if (!UserUtils.isUrlAccessible(request, url)) { - logger.error(EELFLoggerDelegate.errorLogger, "Error accesing URL. Un-authorized",AlarmSeverityEnum.MINOR); - throw new UrlAccessRestrictedException(); - } - } - } - - logger.debug("successfully authorized rest call"); - logger.info(EELFLoggerDelegate.debugLogger, "successfully authorized rest call"); - handleSessionUpdates(request); - logger.debug("handled session updates for synchronization"); - logger.info(EELFLoggerDelegate.debugLogger, "handled session updates for synchronization"); - return super.preHandle(request, response, handler); - } - - /** - * - * @param request - */ - protected void handleSessionUpdates(HttpServletRequest request) { - - App app = null; - Object appObj = getCacheManager().getObject(APP_METADATA); - if (appObj == null) { - app = findApp(); - getCacheManager().putObject(APP_METADATA, app); - - } else { - app = (App) appObj; - } - - String ecompRestURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL); - String decreptedPwd = ""; - try { - decreptedPwd = CipherUtil.decrypt(app.getAppPassword(), - SystemProperties.getProperty(SystemProperties.Decryption_Key)); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Could not decrypt Password" + e.getMessage(),AlarmSeverityEnum.MINOR); - } - - PortalTimeoutHandler.handleSessionUpdatesNative(request, app.getUsername(), decreptedPwd, - PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY), ecompRestURL, null); - } - - public App findApp() { - List list = null; - StringBuffer criteria = new StringBuffer(); - criteria.append(" where id = 1"); - list = getDataAccessService().getList(App.class, criteria.toString(), null, null); - return (list == null || list.size() == 0) ? null : (App) list.get(0); - } - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - public LoginService getLoginService() { - return loginService; - } - - public void setLoginService(LoginService loginService) { - this.loginService = loginService; - } - - @Autowired - public void setCacheManager(AbstractCacheManager cacheManager) { - this.cacheManager = cacheManager; - } - - public AbstractCacheManager getCacheManager() { - return cacheManager; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/listener/ApplicationContextListener.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/listener/ApplicationContextListener.java deleted file mode 100644 index 10e2b2d9..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/listener/ApplicationContextListener.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.listener; - -import javax.servlet.ServletContext; -import javax.servlet.annotation.WebListener; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.stereotype.Component; - -@WebListener -@Component -public class ApplicationContextListener implements ApplicationListener { - - @Autowired - ServletContext context; - - - public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent ) { - -// String contextPath = context.getContextPath(); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/AuditLog.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/AuditLog.java deleted file mode 100644 index 5a1a8640..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/AuditLog.java +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.logging.aspect; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -public @interface AuditLog { - String value() default ""; -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAdvice.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAdvice.java deleted file mode 100644 index 5264c70b..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/aspect/EELFLoggerAdvice.java +++ /dev/null @@ -1,193 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.logging.aspect; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.logging.format.AuditLogFormatter; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.AppService; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.util.SystemProperties.SecurityEventTypeEnum; -import org.slf4j.MDC; -import org.springframework.beans.factory.annotation.Autowired; - -import com.att.eelf.configuration.Configuration; - -@org.springframework.context.annotation.Configuration -public class EELFLoggerAdvice { - - @Autowired - AppService appService; - - EELFLoggerDelegate adviceLogger = EELFLoggerDelegate.getLogger(EELFLoggerAdvice.class); - - //DateTime Format according to the ECOMP Application Logging Guidelines. - private static final SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); - - public Object[] before(SecurityEventTypeEnum securityEventType, Object[] args, Object[] passOnArgs) { - try { - String className = ""; - if (passOnArgs[0]!=null) { - className = passOnArgs[0].toString(); - } - - String methodName = ""; - if (passOnArgs[1]!=null) { - methodName = passOnArgs[1].toString(); - } - - String appName = appService.getDefaultAppName(); - if (appName==null || appName=="") { - appName = SystemProperties.SDK_NAME; - } - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className); - - //Initialize Request defaults only for controller methods. - MDC.put(className + methodName + SystemProperties.METRICSLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC()); - MDC.put(SystemProperties.TARGET_ENTITY, appName + "_BE"); - MDC.put(SystemProperties.TARGET_SERVICE_NAME, methodName); - if (securityEventType!=null) { - MDC.put(className + methodName + SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC()); - HttpServletRequest req = null; - if (args[0]!=null && args[0] instanceof HttpServletRequest ) { - req = (HttpServletRequest)args[0]; - logger.setRequestBasedDefaultsIntoGlobalLoggingContext(req, appName); - } - } - logger.debug(EELFLoggerDelegate.debugLogger, (methodName +" was invoked.")); - } catch(Exception e) { - adviceLogger.error(EELFLoggerDelegate.errorLogger, "Exception occurred in EELFLoggerAdvice.before() method. Details: " + e.getMessage()); - } - - return new Object[] {""}; - } - - public void after(SecurityEventTypeEnum securityEventType, String result, Object[] args, Object[] returnArgs, Object[] passOnArgs) { - try { - String className = ""; - if (passOnArgs[0]!=null) { - className = passOnArgs[0].toString(); - } - - String methodName = ""; - if (passOnArgs[1]!=null) { - methodName = passOnArgs[1].toString(); - } - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className); - - String appName = appService.getDefaultAppName(); - if (appName==null || appName=="") { - appName = SystemProperties.SDK_NAME; - } - - if (MDC.get(SystemProperties.TARGET_SERVICE_NAME) == null || MDC.get(SystemProperties.TARGET_SERVICE_NAME) == "") { - MDC.put(SystemProperties.TARGET_SERVICE_NAME, methodName); - } - - if (MDC.get(SystemProperties.TARGET_ENTITY) == null || MDC.get(SystemProperties.TARGET_ENTITY) == "") { - MDC.put(SystemProperties.TARGET_ENTITY, appName + "_BE"); - } - - MDC.put(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP, MDC.get(className + methodName + SystemProperties.METRICSLOG_BEGIN_TIMESTAMP)); - MDC.put(SystemProperties.METRICSLOG_END_TIMESTAMP, getCurrentDateTimeUTC()); - this.calculateDateTimeDifference(MDC.get(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP), MDC.get(SystemProperties.METRICSLOG_END_TIMESTAMP)); - - logger.info(EELFLoggerDelegate.metricsLogger, methodName + " operation is completed."); - logger.debug(EELFLoggerDelegate.debugLogger, "Finished executing " + methodName + "."); - - if (securityEventType!=null) { - - MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, MDC.get(className + methodName + SystemProperties.AUDITLOG_BEGIN_TIMESTAMP)); - MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, getCurrentDateTimeUTC()); - this.calculateDateTimeDifference(MDC.get(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP), MDC.get(SystemProperties.AUDITLOG_END_TIMESTAMP)); - - this.logSecurityMessage(logger, securityEventType, result, methodName); - - //clear when finishes audit logging - MDC.remove(Configuration.MDC_KEY_REQUEST_ID); - MDC.remove(SystemProperties.PARTNER_NAME); - MDC.remove(SystemProperties.MDC_LOGIN_ID); - MDC.remove(SystemProperties.PROTOCOL); - MDC.remove(SystemProperties.FULL_URL); - MDC.remove(Configuration.MDC_SERVICE_NAME); - MDC.remove(SystemProperties.RESPONSE_CODE); - MDC.remove(SystemProperties.STATUS_CODE); - MDC.remove(className + methodName + SystemProperties.AUDITLOG_BEGIN_TIMESTAMP); - MDC.remove(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP); - MDC.remove(SystemProperties.AUDITLOG_END_TIMESTAMP); - } - - MDC.remove(className + methodName + SystemProperties.METRICSLOG_BEGIN_TIMESTAMP); - MDC.remove(SystemProperties.METRICSLOG_BEGIN_TIMESTAMP); - MDC.remove(SystemProperties.METRICSLOG_END_TIMESTAMP); - MDC.remove(SystemProperties.MDC_TIMER); - MDC.remove(SystemProperties.TARGET_ENTITY); - MDC.remove(SystemProperties.TARGET_SERVICE_NAME); - } catch(Exception e) { - adviceLogger.error(EELFLoggerDelegate.errorLogger, "Exception occurred in EELFLoggerAdvice.after() method. Details: " + e.getMessage()); - } - } - - private void logSecurityMessage(EELFLoggerDelegate logger, SecurityEventTypeEnum securityEventType, String result, String restMethod) { - StringBuilder additionalInfoAppender = new StringBuilder(); - String auditMessage = ""; - - additionalInfoAppender.append(String.format("%s request was received.", restMethod)); - - //Status code - MDC.put(SystemProperties.STATUS_CODE, result); - - String fullURL = MDC.get(SystemProperties.FULL_URL); - if (fullURL!=null && fullURL!="") { - additionalInfoAppender.append(" Request-URL:" + MDC.get(SystemProperties.FULL_URL)); - } - - auditMessage = AuditLogFormatter.getInstance().createMessage( MDC.get(SystemProperties.PROTOCOL), - securityEventType.name(), - MDC.get(SystemProperties.MDC_LOGIN_ID), - additionalInfoAppender.toString()); - - logger.info(EELFLoggerDelegate.auditLogger, auditMessage); - } - - private String getCurrentDateTimeUTC() { - String currentDateTime = ecompLogDateFormat.format(new Date()); - return currentDateTime; - } - - private void calculateDateTimeDifference(String beginDateTime, String endDateTime) { - if (beginDateTime!=null && endDateTime!=null) { - try { - Date beginDate = ecompLogDateFormat.parse(beginDateTime); - Date endDate = ecompLogDateFormat.parse(endDateTime); - String timeDifference = String.format("%d ms", endDate.getTime() - beginDate.getTime()); - MDC.put(SystemProperties.MDC_TIMER, timeDifference); - } catch(Exception e) { - adviceLogger.error(EELFLoggerDelegate.errorLogger, "Exception occurred in EELFLoggerAdvice.calculateDateTimeDifference() method. Details: " + e.getMessage()); - } - } - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorCodesEnum.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorCodesEnum.java deleted file mode 100644 index 59fe2bb7..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/format/ErrorCodesEnum.java +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.logging.format; - -import com.att.eelf.i18n.EELFResolvableErrorEnum; -//import com.att.eelf.i18n.EELFResourceManager; - -public enum ErrorCodesEnum implements EELFResolvableErrorEnum { - BERESTAPIAUTHENTICATIONERROR, - BEHTTPCONNECTIONERROR_ONE_ARGUMENT, - BEUEBAUTHENTICATIONERROR_ONE_ARGUMENT, - - INTERNALAUTHENTICATIONINFO_ONE_ARGUMENT, - INTERNALAUTHENTICATIONWARNING_ONE_ARGUMENT, - INTERNALAUTHENTICATIONERROR_ONE_ARGUMENT, - INTERNALAUTHENTICATIONFATAL_ONE_ARGUMENT, - - BEHEALTHCHECKRECOVERY, - BEHEALTHCHECKMYSQLRECOVERY, - BEHEALTHCHECKUEBCLUSTERRECOVERY, - FEHEALTHCHECKRECOVERY, - BeHEALTHCHECKERROR, - - BEHEALTHCHECKMYSQLERROR, - BEHEALTHCHECKUEBCLUSTERERROR, - FEHEALTHCHECKERROR, - BEUEBCONNECTIONERROR_ONE_ARGUMENT, - BEUEBUNKOWNHOSTERROR_ONE_ARGUMENT, - BEUEBREGISTERONBOARDINGAPPERROR, - - INTERNALCONNECTIONINFO_ONE_ARGUMENT, - INTERNALCONNECTIONWARNING_ONE_ARGUMENT, - INTERNALCONNECTIONERROR_ONE_ARGUMENT, - INTERNALCONNECTIONFATAL_ONE_ARGUMENT, - - BEUEBOBJECTNOTFOUNDERROR_ONE_ARGUMENT, - BEUSERMISSINGERROR_ONE_ARGUMENT, - - BEUSERINACTIVEWARNING_ONE_ARGUMENT, - BEUSERADMINPRIVILEGESINFO_ONE_ARGUMENT, - - BEINVALIDJSONINPUT, - BEINCORRECTHTTPSTATUSERROR, - - BEINITIALIZATIONERROR, - BEUEBSYSTEMERROR, - BEDAOSYSTEMERROR, - BESYSTEMERROR, - BEEXECUTEROLLBACKERROR, - - FEHTTPLOGGINGERROR, - FEPORTALSERVLETERROR, - BEDAOCLOSESESSIONERROR, - - BERESTAPIGENERALERROR, - FEHEALTHCHECKGENERALERROR, - - INTERNALUNEXPECTEDINFO_ONE_ARGUMENT, - INTERNALUNEXPECTEDWARNING_ONE_ARGUMENT, - INTERNALUNEXPECTEDERROR_ONE_ARGUMENT, - INTERNALUNEXPECTEDFATAL_ONE_ARGUMENT, - - ; - - /** - * Static initializer to ensure the resource bundles for this class are loaded... - * Here this application loads messages from three bundles - */ - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/logic/EELFLoggerDelegate.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/logic/EELFLoggerDelegate.java deleted file mode 100644 index 7cf5ee40..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/logging/logic/EELFLoggerDelegate.java +++ /dev/null @@ -1,323 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.logging.logic; - -import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY; -import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID; -import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; -import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN; -import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS; -import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID; -import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; - -import java.net.InetAddress; -import java.text.MessageFormat; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.format.AppMessagesEnum; -import org.openecomp.portalsdk.core.logging.format.ErrorSeverityEnum; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.slf4j.MDC; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.att.eelf.configuration.SLF4jWrapper; - -public class EELFLoggerDelegate extends SLF4jWrapper implements EELFLogger { - - public static EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger(); - public static EELFLogger applicationLogger = EELFManager.getInstance().getApplicationLogger(); - public static EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger(); - public static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); - public static EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger(); - private String className; - private static ConcurrentMap classMap = new ConcurrentHashMap(); - - public EELFLoggerDelegate(String _className) { - super(_className); - className = _className; - } - - public static EELFLoggerDelegate getLogger(Class clazz) { - - String className = clazz.getName(); - EELFLoggerDelegate delegate = classMap.get(className); - if (delegate == null) { - delegate = new EELFLoggerDelegate(className); - classMap.put(className, delegate); - } - - return delegate; - - } - - public static EELFLoggerDelegate getLogger(String className) { - if (className==null || className=="") { - className = EELFLoggerDelegate.class.getName(); - } - EELFLoggerDelegate delegate = classMap.get(className); - if (delegate == null) { - delegate = new EELFLoggerDelegate(className); - classMap.put(className, delegate); - } - - return delegate; - } - - public void debug(EELFLogger logger, String msg) { - if (logger.isDebugEnabled()) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.debug(msg); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - } - - public void debug(EELFLogger logger, String msg, Object... arguments) { - if (logger.isDebugEnabled()) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.debug(msg, arguments); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - } - - public void debug(EELFLogger logger, String msg, Throwable th) { - if (logger.isDebugEnabled()) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.debug(msg, th); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - } - - // does not solve the superfluous overhead of string append - public void info(EELFLogger logger, String msg) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.info(msg); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void info(EELFLogger logger, String msg, Object... arguments) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.info(msg, arguments); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void info(EELFLogger logger, String msg, Throwable th) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.info(msg, th); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void warn(EELFLogger logger, String msg) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.warn(msg); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void warn(EELFLogger logger, String msg, Object... arguments) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.warn(msg, arguments); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void warn(EELFLogger logger, String msg, Throwable th) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.warn(msg, th); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void error(EELFLogger logger, String msg) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.error(msg); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void error(EELFLogger logger, String msg, Object... arguments) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.warn(msg, arguments); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void error(EELFLogger logger, String msg, Throwable th) { - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.warn(msg, th); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void error(EELFLogger logger, String msg, AlarmSeverityEnum severtiy) { - MDC.put(MDC_ALERT_SEVERITY, severtiy.name()); - MDC.put(SystemProperties.MDC_CLASS_NAME, className); - logger.error(msg); - MDC.remove(MDC_ALERT_SEVERITY); - MDC.remove(SystemProperties.MDC_CLASS_NAME); - } - - public void init() { - // Initialize the logger context - setGlobalLoggingContext(); - - String msg = "############################ Logging is started. ############################"; - info(applicationLogger, msg); - error(errorLogger, msg); - info(auditLogger, msg); - info(metricsLogger, msg); - debug(debugLogger, msg); - info(errorLogger, "Successfully initialized the Global logger context."); - } - - public void logEcompError(AppMessagesEnum epMessageEnum, String... param) { - try { - AlarmSeverityEnum alarmSeverityEnum = epMessageEnum.getAlarmSeverity(); - ErrorSeverityEnum errorSeverityEnum = epMessageEnum.getErrorSeverity(); - - MDC.put(MDC_ALERT_SEVERITY, alarmSeverityEnum.name()); - MDC.put("ErrorCode", epMessageEnum.getErrorCode()); - MDC.put("ErrorDescription", epMessageEnum.getErrorDescription()); - - String resolution = this.formatMessage(epMessageEnum.getDetails() + " " + epMessageEnum.getResolution(), (Object[]) param); - if (errorSeverityEnum == ErrorSeverityEnum.WARN) { - errorLogger.warn(resolution); - } else if(errorSeverityEnum == ErrorSeverityEnum.INFO) { - errorLogger.info(resolution); - } else { - errorLogger.error(resolution); - } - } catch(Exception e) { - errorLogger.error("Failed to log the error code. Details: " + UserUtils.getStackTrace(e)); - } finally { - MDC.remove("ErrorCode"); - MDC.remove("ErrorDescription"); - MDC.remove(MDC_ALERT_SEVERITY); - } - } - - private String formatMessage(String message, Object...args) { - StringBuilder sbFormattedMessage = new StringBuilder(); - if (args!=null && args.length>0 && message!=null && message != "") { - MessageFormat mf = new MessageFormat(message); - sbFormattedMessage.append(mf.format(args)); - } else { - sbFormattedMessage.append(message); - } - - return sbFormattedMessage.toString(); - } - - /** - * Loads all the default logging fields into the MDC context. - */ - private void setGlobalLoggingContext() { - MDC.put(MDC_SERVICE_INSTANCE_ID, ""); - MDC.put(MDC_ALERT_SEVERITY, AlarmSeverityEnum.INFORMATIONAL.toString()); - try { - MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName()); - MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); - MDC.put(MDC_INSTANCE_UUID, SystemProperties.getProperty(SystemProperties.INSTANCE_UUID)); - } catch (Exception e) { - } - } - - public static void mdcPut(String key, String value) { - MDC.put(key, value); - } - - public static String mdcGet(String key) { - return MDC.get(key); - } - - public static void mdcRemove(String key) { - MDC.remove(key); - } - - /** - * Loads the RequestId/TransactionId into the MDC which it should be receiving - * with an each incoming REST API request. Also, configures few other request - * based logging fields into the MDC context. - * @param req - */ - public void setRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req, String appName) { - //Load the default fields - setGlobalLoggingContext(); - - //Load the request based fields - if (req!=null) { - //Load the Request into MDC context. - String requestId = UserUtils.getRequestId(req); - MDC.put(MDC_KEY_REQUEST_ID, requestId); - - //Load user agent into MDC context, if available. - String accessingClient = "Unknown"; - accessingClient = req.getHeader(SystemProperties.USERAGENT_NAME); - if (accessingClient!=null && accessingClient!="" && - (accessingClient.contains("Mozilla") || accessingClient.contains("Chrome") || accessingClient.contains("Safari"))) { - accessingClient = appName + "_FE"; - } - MDC.put(SystemProperties.PARTNER_NAME, accessingClient); - - //Protocol, Rest URL & Rest Path - String restURL = ""; - MDC.put(SystemProperties.FULL_URL, SystemProperties.UNKNOWN); - MDC.put(SystemProperties.PROTOCOL, SystemProperties.HTTP); - restURL = UserUtils.getFullURL(req); - if (restURL!=null && restURL!="") { - MDC.put(SystemProperties.FULL_URL, restURL); - if (restURL.toLowerCase().contains("https")) { - MDC.put(SystemProperties.PROTOCOL, SystemProperties.HTTPS); - } - } - - //Rest Path - MDC.put(MDC_SERVICE_NAME, req.getServletPath()); - - //Client IPAddress i.e. IPAddress of the remote host who is making this request. - String clientIPAddress = ""; - clientIPAddress = req.getHeader("X-FORWARDED-FOR"); - if (clientIPAddress == null) { - clientIPAddress = req.getRemoteAddr(); - } - MDC.put(SystemProperties.CLIENT_IP_ADDRESS, clientIPAddress); - - //Load loginId into MDC context. - MDC.put(SystemProperties.MDC_LOGIN_ID, "Unknown"); - String loginId = ""; - try { - loginId = UserUtils.getUserIdFromCookie(req); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - if (loginId == null || loginId == "") { - User user = UserUtils.getUserSession(req); - if (user != null) { - loginId = user.getLoginId(); - } - } - - if (loginId!=null && loginId!="") { - MDC.put(SystemProperties.MDC_LOGIN_ID, loginId); - } - } - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/menu/MenuBuilder.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/menu/MenuBuilder.java deleted file mode 100644 index aac57025..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/menu/MenuBuilder.java +++ /dev/null @@ -1,164 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.menu; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.FusionObject; -import org.openecomp.portalsdk.core.domain.MenuData; -import org.openecomp.portalsdk.core.service.DataAccessService; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; - -@SuppressWarnings("rawtypes") -public class MenuBuilder implements FusionObject { - - @Autowired - private DataAccessService dataAccessService; - - public MenuBuilder() { - } - - - @SuppressWarnings("unchecked") - public Set getMenu(String menuSetName, DataAccessService dataAccessService) { - - Set menu = null; - MenuData root = null; - - HashMap params = new HashMap(); - - params.put("menu_set_cd", menuSetName); - - // execute a query of the latest configuration of the FN_MENU table for the given menu_set_cd. - List menuItems = dataAccessService.executeNamedQuery(SystemProperties.getProperty(SystemProperties.MENU_QUERY_NAME), params, null); - - Iterator i = menuItems.iterator(); - if (i.hasNext()) { - root = (MenuData)i.next(); - menu = root.getChildMenus(); - } - - return menu; - } - - @SuppressWarnings("unchecked") - public Set getMenu(String menuSetName) { - - Set menu = null; - MenuData root = null; - - HashMap params = new HashMap(); - - params.put("menu_set_cd", menuSetName); - - // execute a query of the latest configuration of the FN_MENU table for the given menu_set_cd. - List menuItems = getDataAccessService().executeNamedQuery(SystemProperties.getProperty(SystemProperties.MENU_QUERY_NAME), params, null); - - Iterator i = menuItems.iterator(); - if (i.hasNext()) { - root = (MenuData)i.next(); - menu = root.getChildMenus(); - } - - return menu; - } - - public static Set filterMenu(Set menus, HttpServletRequest request) { - Iterator j = menus.iterator(); - - while (j.hasNext()) { - MenuData menuItem = (MenuData)j.next(); - - if (!UserUtils.isAccessible(request, menuItem.getFunctionCd())) { - // remove the menu if the user doesn't have access to it - j.remove(); - } - else { - // if an accessible menu has a child menu, let's filter that recursively - - Set childMenus = menuItem.getChildMenus(); - if (childMenus != null && childMenus.size() > 0) { - filterMenu(childMenus, request); - } - - } - } - - return menus; - } - - - public static String getUrlHtml(MenuData menuData) { - String html = ""; - - if (menuData.getExternalUrl() != null && menuData.getExternalUrl().length() > 0) { - html = menuData.getExternalUrl(); - } - else if (menuData.getServlet() != null && menuData.getServlet().length() > 0) { - html = "/" + menuData.getServlet(); - } - else if (menuData.getAction() != null && menuData.getAction().length() > 0) { - html = "/" + menuData.getAction(); - } - - return html; - } - - - public static String getTargetHtml(MenuData menuData) { - String html = ""; - - if (menuData.getTarget() != null && menuData.getTarget().length() > 0) { - html = "target=\"" + menuData.getTarget() + "\""; - } - - return html; - } - - - public static String getQueryStringHtml(MenuData menuData) { - String html = ""; - - if (menuData.getQueryString() != null && menuData.getQueryString().length() > 0) { - html = "?" + menuData.getQueryString(); - } - - return html; - } - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - -} - - diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/menu/MenuProperties.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/menu/MenuProperties.java deleted file mode 100644 index 007a7f30..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/menu/MenuProperties.java +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.menu; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Properties; - -import javax.servlet.ServletContext; - -import org.openecomp.portalsdk.core.util.SystemProperties; - - -/* - MenuProperties contains a list of constants used during the creation, - privilege screening, and rendering of the application menu. -*/ -public class MenuProperties { - private MenuProperties() { - // cannot instantiate - } - - @SuppressWarnings("rawtypes") - private static HashMap menuProperties = new HashMap(); - - // keys used to reference values in the menu.properties file - public static final String WIDTH = "width"; - public static final String LEFT_POSITION = "left_position"; - public static final String TOP_POSITION = "top_position"; - public static final String FONT_COLOR = "font_color"; - public static final String MOUSEOVER_FONT_COLOR = "mouseover_font_color"; - public static final String BACKGROUND_COLOR = "background_color"; - public static final String MOUSEOVER_BACKGROUND_COLOR = "mouseover_background_color"; - public static final String BORDER_COLOR = "border_color"; - public static final String SEPARATOR_COLOR = "separator_color"; - public static final String IMAGE_SRC = "image_src"; - public static final String IMAGE_SRC_LEFT = "image_src_left"; - public static final String IMAGE_SRC_OVER = "image_src_over"; - public static final String IMAGE_SRC_LEFT_OVER = "image_src_left_over"; - public static final String EVALUATE_UPON_TREE_SHOW = "evaluate_upon_tree_show"; - public static final String EVALUATE_UPON_TREE_HIDE = "evaluate_upon_tree_hide"; - public static final String TOP_IS_PERMANENT = "top_is_permanent"; - public static final String TOP_IS_HORIZONTAL = "top_is_horizontal"; - public static final String TREE_IS_HORIZONTAL = "tree_is_horizontal"; - public static final String POSITION_UNDER = "position_under"; - public static final String TOP_MORE_IMAGES_VISIBLE = "top_more_images_visible"; - public static final String TREE_MORE_IMAGES_VISIBLE = "tree_more_images_visible"; - public static final String RIGHT_TO_LEFT = "right_to_left"; - public static final String DISPLAY_ON_CLICK = "display_on_click"; - public static final String TOP_IS_VARIABLE_WIDTH = "top_is_variable_width"; - public static final String TREE_IS_VARIABLE_WIDTH = "tree_is_variable_width"; - public static final String TOP_KEEP_IN_WINDOW_X = "top_keep_in_window_x"; - public static final String TOP_KEEP_IN_WINDOW_Y = "top_keep_in_window_y"; - public static final String MENU_ID_ADMIN = "menu_id_admin"; - public static final String MENU_ID_LOGOUT = "menu_id_logout"; - public static final String MENU_FRAME = "menu_frame"; - public static final String MAIN_FRAME = "main_frame"; - public static final String NESTED_MAIN_FRAME = "nested_main_frame"; - public static final String ROLE_FUNCTIONS_TAG = "role_functions_tag"; - - public static final String MAX_DISPLAYABLE_ADMIN_MENU_SORT_ORDER = "max_displayable_admin_menu_sort_order"; - public static final String MENU_PROPERTIES_FILENAME_KEY = "menu_properties_filename"; - public static final String DEFAULT_SERVLET_NAME = "dispatcher"; - public static final String DEFAULT_TARGET = "_self"; - - public static final String TOP_MENU_CLASS = "top_menu_class"; - public static final String TOP_MENU_LINK_CLASS = "top_menu_link_class"; - - public static final String ON_MOUSE_OUT_TRAILER = "on_mouse_out_trailer"; - public static final String ON_MOUSE_OVER_TRAILER = "on_mouse_over_trailer"; - public static final String ON_CLICK_TRAILER = "on_click_trailer"; - - public static final String MENU_ID_PREFIX = "menu_id_prefix"; - - - @SuppressWarnings("unchecked") -public static void loadFromFile(ServletContext servletContext, String filename, String menuSetName) throws IOException { - Properties p = new Properties(); - - if (filename == null) { - filename = SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_PROPERTIES_NAME); - } - - p.load(servletContext.getResourceAsStream(SystemProperties.getProperty(SystemProperties.MENU_PROPERTIES_FILE_LOCATION) + filename)); - menuProperties.put(menuSetName, p); - } // loadMenuProperties - - public static String getProperty(String key) { - return getProperty(key, SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_SET_NAME)); - } - - public static String getProperty(String key, String menuSetName) { - Properties p = (Properties)menuProperties.get(menuSetName); - return p.getProperty(key); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/AbstractCacheManager.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/AbstractCacheManager.java deleted file mode 100644 index 6fb56d9d..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/AbstractCacheManager.java +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.objectcache; - -import java.io.IOException; - -import org.openecomp.portalsdk.core.objectcache.support.FusionCacheManager; - - -public abstract class AbstractCacheManager implements FusionCacheManager { - public AbstractCacheManager() { - super(); - // TODO Auto-generated constructor stub - } - - public Object getObject(String key) { - // TODO Auto-generated method stub - return null; - } - - public void putObject(String key, Object objectToCache) { - // TODO Auto-generated method stub - } - - public boolean isObjectInCache(String key) { - // TODO Auto-generated method stub - return false; - } - - public void removeObject(String key) { - // TODO Auto-generated method stub - } - - public void clearCache() { - // TODO Auto-generated method stub - } - - public void configure() throws IOException { - // TODO Auto-generated method stub - - } -} - diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/support/FusionCacheManager.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/support/FusionCacheManager.java deleted file mode 100644 index 01cc9ce0..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/objectcache/support/FusionCacheManager.java +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.objectcache.support; - -import java.io.IOException; - -import org.openecomp.portalsdk.core.FusionObject; - -public interface FusionCacheManager extends FusionObject { - - Object getObject(String key); - void putObject(String key, Object objectToCache); - boolean isObjectInCache(String key); - - void removeObject(String key); - void clearCache(); - void configure() throws IOException; -} - diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/client/AppContextManager.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/client/AppContextManager.java deleted file mode 100644 index 0e564457..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/client/AppContextManager.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.client; - -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.stereotype.Component; - -/** - * - * - * Use this class to get access to ApplicationContext for classes who were not created by Spring. - */ - - -@Component -public class AppContextManager implements ApplicationContextAware{ - private static ApplicationContext _appCtx; - - @Override - public void setApplicationContext(ApplicationContext ctx){ - _appCtx = ctx; - } - - public static ApplicationContext getAppContext(){ - return _appCtx; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/client/OnBoardingApiServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/client/OnBoardingApiServiceImpl.java deleted file mode 100644 index 1d71afd6..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/onboarding/client/OnBoardingApiServiceImpl.java +++ /dev/null @@ -1,316 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.client; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.domain.UserApp; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.onboarding.crossapi.IPortalRestAPIService; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalAPIException; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalTimeoutHandler; -import org.openecomp.portalsdk.core.restful.domain.EcompRole; -import org.openecomp.portalsdk.core.restful.domain.EcompUser; -import org.openecomp.portalsdk.core.service.RoleService; -import org.openecomp.portalsdk.core.service.UserProfileService; -import org.openecomp.portalsdk.core.service.WebServiceCallService; -import org.openecomp.portalsdk.core.util.JSONUtil; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.slf4j.MDC; -import org.springframework.context.ApplicationContext; - -/** - * Implements the REST API interface to answer requests made by Portal app about - * users and active sessions. - * - * Since an instance of this class will be instantiated by the OnBoarding - * servlet from the ecompFW library, we cannot use Spring injections here. This - * 'injection' is done indirectly using AppContextManager class. - * - - */ -@SuppressWarnings("rawtypes") -public class OnBoardingApiServiceImpl implements IPortalRestAPIService { - RoleService roleService; - UserProfileService userProfileService; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(OnBoardingApiServiceImpl.class); - - public OnBoardingApiServiceImpl() { - // Defend against null-pointer exception during server startup - // that was caused by a spurious Spring annotation on this class. - ApplicationContext appContext = AppContextManager.getAppContext(); - if (appContext == null) - throw new RuntimeException("OnBoardingApiServiceImpl ctor failed to get appContext"); - roleService = appContext.getBean(RoleService.class); - userProfileService = appContext.getBean(UserProfileService.class); - } - - private void setCurrentAttributes(User user, EcompUser userJson) { - - user.setEmail(userJson.getEmail()); - user.setFirstName(userJson.getFirstName()); - user.setHrid(userJson.getHrid()); - user.setJobTitle(userJson.getJobTitle()); - user.setLastName(userJson.getLastName()); - user.setLoginId(userJson.getLoginId()); - user.setOrgManagerUserId(userJson.getOrgManagerUserId()); - user.setMiddleInitial(userJson.getMiddleInitial()); - user.setOrgCode(userJson.getOrgCode()); - user.setOrgId(userJson.getOrgId()); - user.setPhone(userJson.getPhone()); - user.setOrgUserId(userJson.getOrgUserId()); - user.setActive(userJson.isActive()); - // user.setRoles(new TreeSet(userJson.getRoles())); - } - - @Override - public void pushUser(EcompUser userJson) throws PortalAPIException { - - if (logger.isDebugEnabled()) - logger.debug(EELFLoggerDelegate.debugLogger, "pushUser was invoked: " + userJson); - User user = new User(); - String response = ""; - try { - // Set input attributes to the object obout to be saved - setCurrentAttributes(user, userJson); - user.setRoles(new TreeSet()); - user.setUserApps(new TreeSet()); - user.setPseudoRoles(new TreeSet()); - userProfileService.saveUser(user); - logger.debug(EELFLoggerDelegate.debugLogger, "push user success."); - response = "push user success."; - response = JSONUtil.convertResponseToJSON(response); - } catch (Exception e) { - response = "OnboardingApiService.pushUser failed"; - logger.error(EELFLoggerDelegate.errorLogger, response, e); - throw new PortalAPIException(response, e); - } finally { - MDC.remove(SystemProperties.MDC_TIMER); - } - } - - @Override - public void editUser(String loginId, EcompUser userJson) throws PortalAPIException { - - if (logger.isDebugEnabled()) - logger.debug(EELFLoggerDelegate.debugLogger, "OnboardingApi editUser was invoked with loginID " + loginId + ", JSON: " + userJson); - User editUser = new User(); - String response = ""; - try { - setCurrentAttributes(editUser, userJson); - if (editUser.getOrgUserId() != null) { - editUser.setLoginId(editUser.getOrgUserId()); - } - User domainUser = userProfileService.getUserByLoginId(loginId); - if (domainUser != null) - domainUser = JSONUtil.mapToDomainUser(domainUser, editUser); - else - domainUser = editUser; - userProfileService.saveUser(domainUser); - logger.debug(EELFLoggerDelegate.debugLogger, "edit user success."); - response = "edit user success."; - response = JSONUtil.convertResponseToJSON(response); - } catch (Exception e) { - response = "OnboardingApiService.editUser failed"; - logger.error(EELFLoggerDelegate.errorLogger, response, e); - throw new PortalAPIException(response, e); - } finally { - MDC.remove(SystemProperties.MDC_TIMER); - } - - // return response; - } - - @Override - public EcompUser getUser(String loginId) throws PortalAPIException { - try { - if (logger.isDebugEnabled()) - logger.debug(EELFLoggerDelegate.debugLogger, "## REST API ## loginId: " + loginId); - User user = userProfileService.getUserByLoginId(loginId); - if (user == null) { - logger.info(EELFLoggerDelegate.debugLogger, "User + " + loginId + " doesn't exist"); - return null; - // Unforunately, Portal is not ready to accept proper error - // response yet .. - // commenting throw clauses until portal is ready - // throw new PortalAPIException("User + " + loginId + " doesn't - // exist"); - } else - return UserUtils.convertToEcompUser(user); - } catch (Exception e) { - String response = "OnboardingApiService.getUser failed"; - logger.error(EELFLoggerDelegate.errorLogger, response, e); - return null; - // Unforunately, Portal is not ready to accept proper error response - // yet .. commenting throw clauses until portal is ready - // throw new PortalAPIException(response, e); - } - - } - - @Override - public List getUsers() throws PortalAPIException { - try { - List users = userProfileService.findAllActive(); - List ecompUsers = new ArrayList(); - for (User user : users) - ecompUsers.add(UserUtils.convertToEcompUser(user)); - return ecompUsers; - } catch (Exception e) { - String response = "OnboardingApiService.getUsers failed"; - logger.error(EELFLoggerDelegate.errorLogger, response, e); - throw new PortalAPIException(response, e); - } - } - - @Override - public List getAvailableRoles() throws PortalAPIException { - try { - List roles = roleService.getActiveRoles(); - List ecompRoles = new ArrayList(); - for (Role role : roles) - ecompRoles.add(UserUtils.convertToEcompRole(role)); - return ecompRoles; - } catch (Exception e) { - String response = "OnboardingApiService.getAvailableRoles failed"; - logger.error(EELFLoggerDelegate.errorLogger, response, e); - throw new PortalAPIException(response, e); - } - } - - @Override - public void pushUserRole(String loginId, List rolesJson) throws PortalAPIException { - String response = ""; - try { - logger.debug(EELFLoggerDelegate.debugLogger, "## REST API ## loginId: " + loginId); - logger.debug(EELFLoggerDelegate.debugLogger, "## REST API ## rolesJson: " + rolesJson); - User user = userProfileService.getUserByLoginId(loginId); - /* - * List ecompRoles = mapper.readValue(rolesJson, - * TypeFactory.defaultInstance().constructCollectionType(List.class, - * EcompRole.class)); - */ - SortedSet roles = new TreeSet(); - for (EcompRole role : rolesJson) { - roles.add(roleService.getRole(role.getId())); - } - // Replace existing roles with new ones - replaceExistingRoles(roles, user); - - logger.debug(EELFLoggerDelegate.debugLogger, "push user role success."); - response = "push user role success."; - response = JSONUtil.convertResponseToJSON(response); - - } catch (Exception e) { - response = "OnboardingApiService.pushUserRole failed"; - logger.error(EELFLoggerDelegate.errorLogger, response, e); - throw new PortalAPIException(response, e); - } finally { - MDC.remove(SystemProperties.MDC_TIMER); - } - - } - - @Override - public List getUserRoles(String loginId) throws PortalAPIException { - if (logger.isDebugEnabled()) - logger.debug(EELFLoggerDelegate.debugLogger, "## REST API ## loginId: " + loginId); - List ecompRoles = new ArrayList(); - try { - User user = userProfileService.getUserByLoginId(loginId); - SortedSet currentRoles = null; - if (user != null) { - currentRoles = user.getRoles(); - if (currentRoles != null) - for (Role role : currentRoles) - ecompRoles.add(UserUtils.convertToEcompRole(role)); - } - return ecompRoles; - } catch (Exception e) { - String response = "OnboardingApiService.getUserRoles failed"; - logger.error(EELFLoggerDelegate.errorLogger, response, e); - throw new PortalAPIException(response, e); - } - } - - @SuppressWarnings("unchecked") - private void replaceExistingRoles(SortedSet roles, User user) { - // 1. remove existing roles - Set userApps = user.getUserApps(); - Iterator appsItr = userApps.iterator(); - while (appsItr.hasNext()) { - UserApp tempUserApp = (UserApp) appsItr.next(); - boolean roleFound = false; - for (Role role : roles) { - if (tempUserApp.getRole().getId().equals(role.getId())) { - roleFound = true; - break; - } - } - if (!roleFound) - appsItr.remove(); - } - user.setUserApps(userApps); - userProfileService.saveUser(user); - - // 2. add new roles - user.setRoles(roles); - userProfileService.saveUser(user); - } - - @Override - public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException { - WebServiceCallService securityService = AppContextManager.getAppContext().getBean(WebServiceCallService.class); - try { - String appUser = request.getHeader("username"); - String password = request.getHeader("password"); - // System.out.println("username = " + appUser); - // System.out.println("password = " + password); - boolean flag = securityService.verifyRESTCredential(null, appUser, password); - // System.out.println("username = " + appUser); - // System.out.println("password = " + password); - return flag; - - } catch (Exception e) { - String response = "OnboardingApiService.isAppAuthenticated failed"; - logger.error(EELFLoggerDelegate.errorLogger, response, e); - throw new PortalAPIException(response, e); - } - } - - public String getSessionTimeOuts() throws Exception { - return PortalTimeoutHandler.gatherSessionExtensions(); - } - - public void updateSessionTimeOuts(String sessionMap) throws Exception { - PortalTimeoutHandler.updateSessionExtensions(sessionMap); - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/PortalRestClientBase.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/PortalRestClientBase.java deleted file mode 100644 index a7c517ec..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/PortalRestClientBase.java +++ /dev/null @@ -1,171 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.restful.client; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; - -import javax.servlet.http.HttpServletResponse; - -import org.apache.http.Consts; -import org.apache.http.HttpEntity; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; -import org.openecomp.portalsdk.core.domain.App; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; -import org.openecomp.portalsdk.core.service.AppService; -import org.openecomp.portalsdk.core.util.CipherUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Provides a basic client to access a REST endpoint at the Portal via get or - * post. Usage caveats: - *
          - *
        1. Must be auto-wired by Spring, because this in turn auto-wires a - * data-access service to read application credentials from the FN_APP table. - *
        2. If HTTP access is used and the server uses a self-signed certificate, the - * local trust store must be extended appropriately. The HTTP client throws - * exceptions if the JVM cannot validate the server certificate. - *
        - */ -@Component -public class PortalRestClientBase { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PortalRestClientBase.class); - - @Autowired - AppService appService; - - /** - * Constructs and sends a GET request for the URI, with REST application - * credentials in the header as the Portal expects. - * - * @param uri - * URI of the service - * @return Result of the get; null if an error happens - * @throws URISyntaxException - * @throws IOException - * @throws ClientProtocolException - */ - public HttpStatusAndResponse getRestWithCredentials(final URI uri) throws Exception { - - String uebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); - App app = appService.getDefaultApp(); - if (uebKey == null || app == null || app.getUsername() == null || app.getAppPassword() == null) - throw new Exception("Missing one or more required properties and/or database entries"); - String decryptedPassword = CipherUtil.decrypt(app.getAppPassword()); - CloseableHttpClient httpClient = HttpClients.createDefault(); - HttpGet httpGet = new HttpGet(uri); - httpGet.setHeader("uebkey", uebKey); - httpGet.setHeader("username", app.getUsername()); - httpGet.setHeader("password", decryptedPassword); - - String responseJson = null; - CloseableHttpResponse response = null; - try { - logger.info(EELFLoggerDelegate.debugLogger, "GET from " + uri); - response = httpClient.execute(httpGet); - logger.info(EELFLoggerDelegate.debugLogger, "Status is " + response.getStatusLine()); - if (response.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK) - logger.info(EELFLoggerDelegate.debugLogger, "Status is " + response.getStatusLine().toString()); - HttpEntity entity = response.getEntity(); - if (entity == null) { - logger.info(EELFLoggerDelegate.debugLogger, "Entity is null!"); - } else { - // entity content length is never set. - // this naively tries to read everything. - responseJson = EntityUtils.toString(entity); - logger.info(EELFLoggerDelegate.debugLogger, responseJson); - EntityUtils.consume(entity); - } - } finally { - if (response != null) - response.close(); - } - if (response == null) - return null; - return new HttpStatusAndResponse(response.getStatusLine().getStatusCode(), responseJson); - } - - /** - * Constructs and sends a POST request using the specified body, with REST - * application credentials in the header as the Portal expects. - * - * @param uri - * REST endpoint - * @param json - * Content to post - * @return Result of the post; null if an error happens - * @throws Exception - */ - public HttpStatusAndResponse postRestWithCredentials(final URI uri, final String json) throws Exception { - - String uebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); - App app = appService.getDefaultApp(); - if (uebKey == null || app == null || app.getUsername() == null || app.getAppPassword() == null) - throw new Exception("Missing one or more required properties and/or database entries"); - - CloseableHttpClient httpClient = HttpClients.createDefault(); - HttpPost httpPost = new HttpPost(uri); - httpPost.setHeader("uebkey", uebKey); - httpPost.setHeader("username", app.getUsername()); - httpPost.setHeader("password", app.getAppPassword()); - - StringEntity postEntity = new StringEntity(json, ContentType.create("application/json", Consts.UTF_8)); - httpPost.setEntity(postEntity); - - String responseJson = null; - CloseableHttpResponse response = null; - try { - logger.info(EELFLoggerDelegate.debugLogger, "POST to " + uri); - response = httpClient.execute(httpPost); - logger.info(EELFLoggerDelegate.debugLogger, "Status is " + response.getStatusLine()); - if (response.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK) - throw new Exception("Status is " + response.getStatusLine().toString()); - - HttpEntity entity = response.getEntity(); - if (entity == null) { - logger.info(EELFLoggerDelegate.debugLogger, "Entity is null!"); - } else { - // entity content length is never set. - // this naively tries to read everything. - responseJson = EntityUtils.toString(entity); - logger.info(EELFLoggerDelegate.debugLogger, responseJson); - EntityUtils.consume(entity); - } - } finally { - if (response != null) - response.close(); - } - return new HttpStatusAndResponse(response.getStatusLine().getStatusCode(), responseJson); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/SharedContextRestClient.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/SharedContextRestClient.java deleted file mode 100644 index f017a7df..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/restful/client/SharedContextRestClient.java +++ /dev/null @@ -1,330 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.restful.client; - -import java.net.URI; -import java.util.HashMap; -import java.util.List; - -import org.apache.http.client.utils.URIBuilder; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; -import org.openecomp.portalsdk.core.restful.domain.SharedContext; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * Provides convenience methods to use the shared-context service at Portal. - * This hides all JSON; instead it accepts and returns Java objects. - * Usage caveats (repeated from superclass): - *
          - *
        1. Must be auto-wired by Spring, because this in turn auto-wires a data - * access service to read application credentials from the FN_APP table. - *
        2. If HTTP access is used and the server uses a self-signed certificate, the - * local trust store must be extended appropriately. The HTTP client throws - * exceptions if the JVM cannot validate the server certificate. - *
        - */ -@Component -public class SharedContextRestClient extends PortalRestClientBase { - - @Autowired - SystemProperties systemProperties; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SharedContextRestClient.class); - - /** - * Reusable JSON (de)serializer - */ - private final ObjectMapper mapper = new ObjectMapper(); - - /** - * Gets the shared-context value for the specified context ID and key. - * - * @param contextId - * An Ecomp Portal session ID - * @param key - * Key for the shared-context entry; e.g., "lastName" - * @return SharedContext object; null if not found. - * @throws Exception - */ - public SharedContext getContextValue(String contextId, String key) throws Exception { - HttpStatusAndResponse hsr = getContext("get", contextId, key); - logger.info(EELFLoggerDelegate.debugLogger, "getSharedContext: resp is " + hsr); - if (hsr == null) { - logger.error(EELFLoggerDelegate.applicationLogger, "getContextValue: unexpected null response"); - return null; - } - SharedContext jsonObj = null; - try { - jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); - } catch (JsonMappingException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "getContextValue: failed to map response onto object" + ex.getMessage()); - } catch (JsonParseException ex) { - logger.info(EELFLoggerDelegate.applicationLogger, "getContextValue: failed to parse response" + ex.getMessage()); - } - if (jsonObj != null && jsonObj.getResponse() != null) - return null; - return jsonObj; - } - - /** - * Gets user information for the specified context ID. - * - * @param contextId - * An Ecomp Portal session ID - * @return List of SharedContext objects corresponding to the following - * keys: USER_FIRST_NAME, USER_LAST_NAME, USER_EMAIL and - * USER_ORGUSERID; empty if none were found; null if an error happens. - * @throws Exception - */ - public List getUserContext(String contextId) throws Exception { - HttpStatusAndResponse hsr = getContext("get_user", contextId, null); - logger.info(EELFLoggerDelegate.debugLogger, "getUserContext: resp is " + hsr); - if (hsr == null) { - logger.error(EELFLoggerDelegate.applicationLogger, "getUserContext: unexpected null response"); - return null; - } - List jsonList = null; - try { - TypeReference> typeRef = new TypeReference>() { - }; - jsonList = mapper.readValue(hsr.getResponse(), typeRef); - } catch (JsonMappingException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "getUserContext: failed to map response onto object" + ex.getMessage()); - } catch (JsonParseException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "getUserContext: failed to parse response" + ex.getMessage()); - } - return jsonList; - } - - /** - * Checks whether a shared-context entry exists for the specified context ID - * and key. - * - * @param contextId - * An Ecomp Portal session ID - * @param key - * Key for the shared-context entry; e.g., "lastName" - * @return True if the object exists, false otherwise; null on error. - * @throws Exception - */ - public Boolean checkSharedContext(String contextId, String key) throws Exception { - HttpStatusAndResponse hsr = getContext("check", contextId, key); - logger.info(EELFLoggerDelegate.debugLogger, "checkSharedContext: resp is " + hsr); - if (hsr == null) { - logger.error(EELFLoggerDelegate.applicationLogger, "checkSharedContext: unexpected null response"); - return null; - } - String response = null; - try { - SharedContext jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); - response = jsonObj.getResponse(); - } catch (JsonMappingException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "checkSharedContext: failed to map response onto object" + ex.getMessage()); - } catch (JsonParseException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "checkSharedContext: failed to parse response" + ex.getMessage()); - } - if (response == null) - return null; - return ("exists".equals(response)); - } - - /** - * Removes a shared-context entry with the specified context ID and key. - * - * @param contextId - * An Ecomp Portal session ID - * @param key - * Key for the shared-context entry; e.g., "lastName" - * @return True if the entry was removed, false otherwise; null on error. - * @throws Exception - */ - public Boolean removeSharedContext(String contextId, String key) throws Exception { - HttpStatusAndResponse hsr = getContext("remove", contextId, key); - logger.info(EELFLoggerDelegate.debugLogger, "removeSharedContext: resp is " + hsr); - if (hsr == null) { - logger.error(EELFLoggerDelegate.applicationLogger, "removeSharedContext: unexpected null response"); - return null; - } - SharedContext jsonObj = null; - try { - jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); - } catch (JsonMappingException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "removeSharedContext: failed to map response onto object" + ex.getMessage()); - } catch (JsonParseException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "removeSharedContext: failed to parse response" + ex.getMessage()); - } - if (jsonObj == null) - return null; - String response = jsonObj.getResponse(); - return ("removed".equals(response)); - } - - /** - * Clears the shared context for the specified context ID; i.e., removes all - * key-value pairs. - * - * @param contextId - * An Ecomp Portal session ID - * @return Number of key-value pairs removed; -1 if not found or any - * problems occur. - * @throws Exception - */ - public int clearSharedContext(String contextId) throws Exception { - HttpStatusAndResponse hsr = getContext("remove", contextId, null); - logger.info(EELFLoggerDelegate.debugLogger, "clearSharedContext: resp is " + hsr); - if (hsr == null) { - logger.error(EELFLoggerDelegate.applicationLogger, "clearSharedContext: unexpected null response"); - return -1; - } - SharedContext jsonObj = null; - try { - jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); - } catch (JsonMappingException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "clearSharedContext: failed to map response onto object" + ex.getMessage()); - } catch (JsonParseException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "clearSharedContext: failed to parse response" + ex.getMessage()); - } - if (jsonObj == null) - return -1; - String response = jsonObj.getResponse(); - if (response == null) - return -1; - return Integer.parseInt(response); - } - - /** - * Creates a shared-context entry. - * - * @param contextId - * An Ecomp Portal session ID - * @param key - * Key for the shared-context entry; e.g., "lastName" - * @param value - * Value for the entry - * @throws Exception - * @return True if the object previously existed, false otherwise; null if - * any problem happened. - */ - public Boolean setSharedContext(String contextId, String key, String value) throws Exception { - String body = buildContext(contextId, key, value); - HttpStatusAndResponse hsr = postContext("set", body); - logger.info(EELFLoggerDelegate.debugLogger, "setSharedContext: resp is " + hsr); - if (hsr == null) { - logger.error(EELFLoggerDelegate.applicationLogger, "setSharedContext: unexpected null response"); - return null; - } - SharedContext jsonObj = null; - try { - jsonObj = mapper.readValue(hsr.getResponse(), SharedContext.class); - } catch (JsonMappingException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "setSharedContext: failed to map response onto object" + ex.getMessage()); - } catch (JsonParseException ex) { - logger.error(EELFLoggerDelegate.applicationLogger, "setSharedContext: failed to parse response" + ex.getMessage()); - } - if (jsonObj == null) - return null; - String response = jsonObj.getResponse(); - return ("replaced".equals(response)); - } - - /** - * Builds the full URL with the specified parameters, then calls the method - * that adds credentials and GETs. - * - * @param requestPath - * @param contextId - * @param contextKey - * @return HttpStatusAndResponse object; may be null. - * @throws Exception - */ - @SuppressWarnings("unused") - private HttpStatusAndResponse getContext(String requestPath, String contextId, String contextKey) throws Exception{ - String restUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL); - String portalDomain = restUrl.substring(0, restUrl.lastIndexOf('/')); - String contextRestUrl = portalDomain + "/context"; - if (contextRestUrl == null) - throw new Exception("getContext: failed to get property " + SystemProperties.ECOMP_SHARED_CONTEXT_REST_URL); - URIBuilder uriBuilder = new URIBuilder(contextRestUrl + "/" + requestPath); - uriBuilder.addParameter("context_id", contextId); - if (contextKey != null) - uriBuilder.addParameter("ckey", contextKey); - final URI uri = uriBuilder.build(); - return getRestWithCredentials(uri); - } - - /** - * Builds the full URL, then calls the method that adds credentials and - * POSTs. - * - * @param requestPath - * @param contextId - * @param contextKey - * @return HttpStatusAndResponse object; may be null. - * @throws Exception - */ - private HttpStatusAndResponse postContext(String requestPath, String json) throws Exception { - String contextRestUrl = SystemProperties.getProperty(SystemProperties.ECOMP_SHARED_CONTEXT_REST_URL); - if (contextRestUrl == null) - throw new Exception("postContext: failed to get property " + SystemProperties.ECOMP_SHARED_CONTEXT_REST_URL); - URIBuilder uriBuilder = new URIBuilder(contextRestUrl + "/" + requestPath); - URI uri = uriBuilder.build(); - return postRestWithCredentials(uri, json); - } - - /** - * Builds a JSON block with a single shared-context entry. - * - * @param cxid - * Context ID - * @param ckey - * Context Key - * @param cvalue - * Context value - * @return JSON block - */ - private String buildContext(String cxid, String ckey, String cvalue) throws JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); - HashMap stringMap = new HashMap(); - stringMap.put("context_id", cxid); - stringMap.put("ckey", ckey); - stringMap.put("cvalue", cvalue); - String json = mapper.writeValueAsString(stringMap); - return json; - } - - // Simple test scaffold - public static void main(String[] args) throws Exception { - - SharedContextRestClient client = new SharedContextRestClient(); - SharedContext get = client.getContextValue("abc", "123"); - System.out.println("Get yields " + get.toString()); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/scheduler/CronRegistry.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/scheduler/CronRegistry.java deleted file mode 100644 index fdfda984..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/scheduler/CronRegistry.java +++ /dev/null @@ -1,124 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.scheduler; - -import java.text.ParseException; -import java.util.Map; - -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.quartz.CronTrigger; -import org.springframework.scheduling.quartz.CronTriggerFactoryBean; -import org.springframework.scheduling.quartz.JobDetailFactoryBean; -import org.springframework.scheduling.quartz.QuartzJobBean; - -import com.mchange.v2.c3p0.ComboPooledDataSource; - -public abstract class CronRegistry { - - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CronRegistry.class); - protected JobDetailFactoryBean jobDetailFactory; - protected CronTriggerFactoryBean cronTriggerFactory; - - private ComboPooledDataSource dataSource; - - public CronRegistry() { - try { - jobDetailFactoryBean(); - cronTriggerFactoryBean(); - } - catch(Exception e) { - logger.error(EELFLoggerDelegate.debugLogger, e.getMessage()); - } - } - - //@Autowired - public CronRegistry(ComboPooledDataSource dataSource) { - try { - this.dataSource = dataSource; - jobDetailFactoryBean(); - cronTriggerFactoryBean(); - } - catch(Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AlarmSeverityEnum.MAJOR); - } - } - - //@Autowired - public CronRegistry(Object... initializeObjects) { - try { - initializeObjects(initializeObjects); - jobDetailFactoryBean(); - cronTriggerFactoryBean(); - } - catch(Exception e) { - logger.info(EELFLoggerDelegate.errorLogger, e.getMessage()); - } - } - - protected void initializeObjects(Object... initializeObjects) { - } - - public abstract JobDetailFactoryBean jobDetailFactoryBean() throws ParseException; - - protected JobDetailFactoryBean jobDetailFactoryBean(String groupName, String jobName, - Class jobClass, Map map) { - - jobDetailFactory = new JobDetailFactoryBean(); - jobDetailFactory.setJobClass(jobClass); - jobDetailFactory.setJobDataAsMap(map); - jobDetailFactory.setGroup(groupName); - jobDetailFactory.setName(jobName); - jobDetailFactory.afterPropertiesSet(); - - return jobDetailFactory; - } - - public abstract CronTriggerFactoryBean cronTriggerFactoryBean() throws ParseException; - - protected CronTriggerFactoryBean cronTriggerFactoryBean(String groupName, String triggerName, String cronExpression) throws ParseException { - cronTriggerFactory = new CronTriggerFactoryBean(); - cronTriggerFactory.setJobDetail(jobDetailFactory.getObject()); - cronTriggerFactory.setStartDelay(3000); - cronTriggerFactory.setName(triggerName); - cronTriggerFactory.setGroup(groupName); - logger.info(EELFLoggerDelegate.applicationLogger, triggerName + " Scheduled: " + cronExpression); - cronTriggerFactory.setCronExpression( cronExpression); //"0 * * * * ? *" - cronTriggerFactory.afterPropertiesSet(); - return cronTriggerFactory; - } - - public CronTrigger getTrigger() { - return cronTriggerFactory.getObject(); - } - - - public void setDataSource(ComboPooledDataSource dataSource) { - this.dataSource = dataSource; - } - - - public ComboPooledDataSource getDataSource() { - return dataSource; - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AppServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AppServiceImpl.java deleted file mode 100644 index 30e566a2..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AppServiceImpl.java +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.List; - -import org.openecomp.portalsdk.core.domain.App; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("appService") -@Transactional -public class AppServiceImpl implements AppService{ - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AppServiceImpl.class); - - @Autowired - private DataAccessService dataAccessService; - - /** - * Loads the appName once from database and - * keep refers to it as required. - */ - private static String defaultAppName = ""; - - /* - * (non-Javadoc) - * @see org.openecomp.portalsdk.core.service.AppService#getApps() - */ - @SuppressWarnings("unchecked") - @Override - public List getApps() { - return getDataAccessService().getList(App.class, null); - } - - /* - * (non-Javadoc) - * @see org.openecomp.portalsdk.core.service.AppService#getApp(long) - */ - @Override - public App getApp(Long appId) { - return (App)getDataAccessService().getDomainObject(App.class, appId, null); - } - - /* - * (non-Javadoc) - * @see org.openecomp.portalsdk.core.service.AppService#getApp() - */ - @Override - public App getDefaultApp() { - return getApp(1L); - } - - /** - * Gets the data access service. - * @return DataAccessService - */ - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - /** - * Sets the data access service. - * @param dataAccessService - */ - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - /** - * Fetches the application name once from database - * and keep refers to the same name later on as required. - * @return Default Application Name - */ - @Override - public String getDefaultAppName() { - if (AppServiceImpl.defaultAppName==null || AppServiceImpl.defaultAppName=="") { - App app = getApp(1L); - if (app!=null) { - AppServiceImpl.defaultAppName = app.getName(); - } else { - logger.warn(EELFLoggerDelegate.errorLogger, ("Unable to locate the app information from the database.")); - } - } - return AppServiceImpl.defaultAppName; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AuditService.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AuditService.java deleted file mode 100644 index b632c92c..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AuditService.java +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.HashMap; - -import org.openecomp.portalsdk.core.domain.AuditLog; - -public interface AuditService { - /** - * - * Update log data in database - * - * @param auditLog - * @param additionalParams - */ - @SuppressWarnings("rawtypes") - void logActivity(AuditLog auditLog, HashMap additionalParams); -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AuditServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AuditServiceImpl.java deleted file mode 100644 index 8fbd550c..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/AuditServiceImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.HashMap; - -import org.openecomp.portalsdk.core.domain.AuditLog; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("auditService") -@Transactional -public class AuditServiceImpl implements AuditService { - public AuditServiceImpl() {} - - @Autowired - private DataAccessService dataAccessService; - - @SuppressWarnings("rawtypes") - public void logActivity(AuditLog auditLog, HashMap additionalParams) { - getDataAccessService().saveDomainObject(auditLog, additionalParams); - } - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/BroadcastService.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/BroadcastService.java deleted file mode 100644 index 8d60e74b..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/BroadcastService.java +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.HashMap; -import java.util.Hashtable; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.domain.BroadcastMessage; - -@SuppressWarnings("rawtypes") -public interface BroadcastService { - HashMap getBcModel(HttpServletRequest request); - Hashtable getBroadcastMessages(); - void loadMessages(); - BroadcastMessage getBroadcastMessage(HttpServletRequest request); - void saveBroadcastMessage(BroadcastMessage broadcastMessage); - void removeBroadcastMessage(BroadcastMessage broadcastMessage); -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/BroadcastServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/BroadcastServiceImpl.java deleted file mode 100644 index def1c1a6..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/BroadcastServiceImpl.java +++ /dev/null @@ -1,248 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.Calendar; -import java.util.Collections; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.domain.BroadcastMessage; -import org.openecomp.portalsdk.core.domain.Lookup; -import org.openecomp.portalsdk.core.service.support.FusionService; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.AppUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.ServletRequestBindingException; -import org.springframework.web.bind.ServletRequestUtils; - -@SuppressWarnings("rawtypes") -@Service("broadcastService") -@Transactional -public class BroadcastServiceImpl extends FusionService implements BroadcastService { - - public BroadcastServiceImpl() { - } - - @Autowired - private DataAccessService dataAccessService; - private static Hashtable broadcastMessages = new Hashtable(); - - @SuppressWarnings("unchecked") - public void loadMessages() { - List messageLocations = AppUtils.getLookupListNoCache("fn_lu_message_location", "message_location_id", "message_location_descr", "", "message_location_id"); - - for (int i=0; i < messageLocations.size(); i++) { - Lookup location = (Lookup)messageLocations.get(i); - String locationId = location.getValue(); - - broadcastMessages.put(locationId, getPersistedBroadcastMessages(locationId)); - } - } - - @SuppressWarnings("unchecked") - public HashMap getBcModel(HttpServletRequest request){ - HashMap bcModel = new HashMap(); - - List items = null; - int messageId = ServletRequestUtils.getIntParameter(request, "message_id", 0); - String task = ServletRequestUtils.getStringParameter(request, "task", "get"); - - // delete or toggle activation on the selected record (if applicable) - if (messageId != 0 && (task.equals("delete") || task.equals("toggleActive"))) { - BroadcastMessage message = (BroadcastMessage)getDataAccessService().getDomainObject(BroadcastMessage.class, new Long(messageId), null); - - if (task.equals("delete")) { - getDataAccessService().deleteDomainObject(message, null); - } - else if (task.equals("toggleActive")) { - HashMap additionalParams = new HashMap(); - additionalParams.put(Parameters.PARAM_HTTP_REQUEST, request); - - message.setActive(new Boolean(!message.getActive().booleanValue())); - getDataAccessService().saveDomainObject(message, additionalParams); - } - loadMessages(); - } - - items = getDataAccessService().getList(BroadcastMessage.class, null); - Collections.sort(items); - bcModel.put("messagesList", packageMessages(items)); - - List locations = AppUtils.getLookupList("fn_lu_message_location", "message_location_id", "message_location_descr", "", "message_location_id"); - bcModel.put("messageLocations", locations); - - if ("true".equals(SystemProperties.getProperty(SystemProperties.CLUSTERED))) { - List sites = AppUtils.getLookupList("fn_lu_broadcast_site", "broadcast_site_cd", "broadcast_site_descr", "", "broadcast_site_descr"); - bcModel.put("broadcastSites", sites); - } - - return bcModel; - } - - @SuppressWarnings("unchecked") - private HashMap packageMessages(List messages) { - HashMap messagesList = new HashMap(); - Set locationMessages = null; - - Integer previousLocationId = null; - - for (int i=0; i < messages.size(); i++) { - BroadcastMessage message = (BroadcastMessage)messages.get(i); - - if (!message.getLocationId().equals(previousLocationId)) { - if (previousLocationId != null) { - messagesList.put(previousLocationId.toString(), locationMessages); - } - - locationMessages = new TreeSet(); - previousLocationId = message.getLocationId(); - } - - locationMessages.add(message); - } - - if (previousLocationId != null) { - messagesList.put(previousLocationId.toString(), locationMessages); - } - - return messagesList; - } - - - @SuppressWarnings("unchecked") - private List getPersistedBroadcastMessages(String locationId) { - - HashMap params = new HashMap(); - params.put("location_id", new Integer(locationId)); - Calendar calInstanceToday = Calendar.getInstance(); - calInstanceToday.set(Calendar.HOUR, 0); - calInstanceToday.set(Calendar.MINUTE, 0); - calInstanceToday.set(Calendar.SECOND, 0); - params.put("today_date", calInstanceToday.getTime()); - - return getDataAccessService().executeNamedQuery("broadcastMessages", params, null); - } - - public Hashtable getBroadcastMessages() { - return broadcastMessages; - } - - public static List getBroadcastMessages(String locationId) { - return (List)broadcastMessages.get(locationId); - } - - public static String displayMessages(String locationId) { - return displayServerMessages(locationId, null); - } - - public static String displayServerMessages(String locationId, String siteCd) { - StringBuffer html = new StringBuffer(); - - List messages = getBroadcastMessages(locationId); - - for (int i=0; i < messages.size(); i++) { - BroadcastMessage message = (BroadcastMessage)messages.get(i); - - if ((message.getSiteCd() == null) || ((message.getSiteCd() != null) && message.getSiteCd().equals(siteCd))) { - html.append("
      • ") - .append(message.getMessageText()); - } - } - - if (html.length() > 0) { - html.insert(0, "
          "); - html.append("
        "); - } - - return html.toString(); - } - - public static boolean hasMessages(String locationId) { - return hasServerMessages(locationId, null); - } - - public static boolean hasServerMessages(String locationId, String siteCd) { - List messages = getBroadcastMessages(locationId); - - boolean messagesExist = !((messages == null) || messages.size() == 0); - - if (siteCd == null) { - return messagesExist; - } - else { - for (int i=0; i < messages.size(); i++) { - BroadcastMessage message = (BroadcastMessage)messages.get(i); - - if ((message.getSiteCd() == null) || message.getSiteCd().equals(siteCd)) { - return true; - } - } - return false; - } - } - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - public BroadcastMessage getBroadcastMessage(HttpServletRequest request) { - long messageId = ServletRequestUtils.getLongParameter(request, "message_id", 0); - - BroadcastMessage message = new BroadcastMessage(); - if(messageId!=0) - message = (BroadcastMessage)getDataAccessService().getDomainObject(BroadcastMessage.class, new Long(messageId), null); - - if (message.getLocationId() == null) { - try { - message.setLocationId(new Integer(ServletRequestUtils.getStringParameter(request, "message_location_id"))); - } catch (NumberFormatException e) { - e.printStackTrace(); - } catch (ServletRequestBindingException e) { - e.printStackTrace(); - } - message.setActive(Boolean.TRUE); - } - - return message; - } - - @Override - public void saveBroadcastMessage(BroadcastMessage broadcastMessage) { - dataAccessService.saveDomainObject(broadcastMessage, null); - } - - @Override - public void removeBroadcastMessage(BroadcastMessage broadcastMessage) { - dataAccessService.deleteDomainObject(broadcastMessage, null); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/DataAccessServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/DataAccessServiceImpl.java deleted file mode 100644 index a4644b72..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/DataAccessServiceImpl.java +++ /dev/null @@ -1,592 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.hibernate.Criteria; -import org.hibernate.FetchMode; -import org.hibernate.Query; -import org.hibernate.SQLQuery; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.Criterion; -import org.hibernate.criterion.Order; -import org.hibernate.criterion.ProjectionList; -import org.openecomp.portalsdk.core.domain.Lookup; -import org.openecomp.portalsdk.core.domain.support.DomainVo; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.support.FusionService; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -/** - * Provides implementations of methods in {@link DataAccessService}. - */ -@Transactional -public class DataAccessServiceImpl extends FusionService implements DataAccessService { - - @Autowired - private SessionFactory sessionFactory; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(DataAccessServiceImpl.class); - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#getDomainObject(java.lang. - * Class, java.io.Serializable, java.util.HashMap) - */ - @Override - public DomainVo getDomainObject(Class domainClass, Serializable id, HashMap additionalParams) { - DomainVo vo = null; - Session session = sessionFactory.getCurrentSession(); - logger.info(EELFLoggerDelegate.debugLogger, "Getting " + domainClass.getName() + " record for id - " + id.toString()); - vo = (DomainVo) session.get(domainClass, id); - - if (vo == null) { - try { - vo = (DomainVo) domainClass.newInstance(); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "An error occured while instantiating a class of " + domainClass.getName() + e.getMessage()); - } - } - return vo; - } - - /* - * (non-Javadoc) - * - */ - @Override - public void deleteDomainObject(DomainVo domainObject, HashMap additionalParams) { - Session session = sessionFactory.getCurrentSession(); - session.delete(domainObject); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#deleteDomainObjects(java. - * lang.Class, java.lang.String, java.util.HashMap) - */ - @Override - public void deleteDomainObjects(Class domainClass, String whereClause, HashMap additionalParams) { - Session session = sessionFactory.getCurrentSession(); - - StringBuffer sql = new StringBuffer("delete from "); - - sql.append(domainClass.getName()).append(" where ").append(whereClause); - - session.createQuery(sql.toString()).executeUpdate(); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#saveDomainObject - */ - @Override - public void saveDomainObject(DomainVo vo, HashMap additionalParams) { - Integer userId = 1; - if (additionalParams != null) { - // look for a passed user id - // userId = (Integer)additionalParams.get(Parameters.PARAM_USERID); - Object uid = additionalParams.get(Parameters.PARAM_USERID); - if (uid instanceof Integer) { - userId = (Integer) uid; - } else if (uid instanceof Long) { - userId = ((Long) uid).intValue(); - } - // if (userId == null) { - // look for a passed request to get the user id from - // userId = new - // Integer(UserUtils.getUserId((HttpServletRequest)additionalParams.get(Parameters.PARAM_HTTP_REQUEST))); - // } - } - _update(vo, userId); - } - - /** - * Creates or updates the specified virtual object. Uses the specified user - * ID as the creator and modifier if a new object is created; uses ID only - * as modifier if an object already exists. - * - * @param vo - * @param userId - * Ignored if value is zero. - */ - protected final void _update(DomainVo vo, int userId) { - Date timestamp = new Date(); - - Session session = sessionFactory.getCurrentSession(); - - if (vo.getId() == null || vo.getId().intValue() == 0) { // add new - vo.setCreated(timestamp); - vo.setModified(timestamp); - - if (userId != 0 - && userId != Integer.parseInt(SystemProperties.getProperty(SystemProperties.APPLICATION_USER_ID))) { - vo.setCreatedId(new Long(userId)); - vo.setModifiedId(new Long(userId)); - } - } else { // update existing - vo.setModified(timestamp); - - if (userId != 0 - && userId != Integer.parseInt(SystemProperties.getProperty(SystemProperties.APPLICATION_USER_ID))) { - vo.setModifiedId(new Long(userId)); - } - } - - session.saveOrUpdate(vo); - } - - /** - * generic get list method - * - * @param domainClass - * @param filterClause - * @param fromIndex - * @param toIndex - * @param orderBy - * @return - */ - private List getListCommon(Class domainClass, String filterClause, Integer fromIndex, Integer toIndex, - String orderBy) { - List list = null; - String className = domainClass.getName(); - Session session = sessionFactory.getCurrentSession(); - - if (logger.isInfoEnabled()) { - logger.info(EELFLoggerDelegate.debugLogger, "Getting " + className.toLowerCase() + " records" - + ((fromIndex != null) ? " from rows " + fromIndex.toString() + " to " + toIndex.toString() : "") - + "..."); - if (filterClause != null && filterClause.length() > 0) - logger.info(EELFLoggerDelegate.debugLogger, "Filtering " + className + " by: " + filterClause); - } - - list = session.createQuery("from " + className + Utilities.nvl(filterClause, "") - + ((orderBy != null) ? " order by " + orderBy : "")).list(); - list = (fromIndex != null) ? list.subList(fromIndex.intValue() - 1, toIndex.intValue()) : list; - - if (orderBy == null && list != null) - Collections.sort(list); - - return list; - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, - * java.util.HashMap) - */ - @Override - public List getList(Class domainClass, HashMap additionalParams) { - return getListCommon(domainClass, null, null, null, null); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, - * java.lang.String, java.lang.String, java.util.HashMap) - */ - @Override - public List getList(Class domainClass, String filter, String orderBy, HashMap additionalParams) { - return getListCommon(domainClass, filter, null, null, orderBy); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, - * java.lang.String, int, int, java.lang.String, java.util.HashMap) - */ - @Override - public List getList(Class domainClass, String filter, int fromIndex, int toIndex, String orderBy, - HashMap additionalParams) { - return getListCommon(domainClass, filter, new Integer(fromIndex), new Integer(toIndex), orderBy); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, - * org.hibernate.criterion.ProjectionList, java.util.List, java.util.List) - */ - @Override - public List getList(Class domainClass, ProjectionList projectionsList, List restrictionsList, - List orderByList) { - - Session session = sessionFactory.getCurrentSession(); - - Criteria criteria = session.createCriteria(domainClass); - - if (projectionsList != null) { - criteria.setProjection(projectionsList); - } - - if (restrictionsList != null && !restrictionsList.isEmpty()) { - for (Criterion criterion : restrictionsList) - criteria.add(criterion); - } - - if (orderByList != null && !orderByList.isEmpty()) { - for (Order order : orderByList) - criteria.addOrder(order); - } - /* - * if(fetchModeMap!=null){ Iterator itr = - * fetchModeMap.keySet().iterator(); String key=null; - * while(itr.hasNext()){ key = itr.next(); - * criteria.setFetchMode(key,fetchModeMap.get(key)); } } - */ - return criteria.list(); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#getLookupList(java.lang. - * String, java.lang.String, java.lang.String, java.lang.String, - * java.lang.String, java.util.HashMap) - */ - @Override - public List getLookupList(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy, - HashMap additionalParams) { - if (logger.isInfoEnabled()) - logger.info(EELFLoggerDelegate.debugLogger, "Retrieving " + dbTable + " lookup list..."); - String dbOrderByCol = dbOrderBy; - - Session session = sessionFactory.getCurrentSession(); - - // default the orderBy if null; - if (Utilities.nvl(dbOrderBy).length() == 0) { - dbOrderByCol = dbLabelCol; - dbOrderBy = dbLabelCol; - } else { - if (dbOrderBy.lastIndexOf(" ") > -1) { - dbOrderByCol = dbOrderBy.substring(0, dbOrderBy.lastIndexOf(" ")); - } - } - - StringBuffer sql = new StringBuffer(); - - sql.append("select distinct ").append(dbLabelCol).append(" as lab, ").append(dbValueCol).append(" as val, ") - .append(dbOrderByCol).append(" as sortOrder ").append("from ").append(dbTable).append(" ") - .append((Utilities.nvl(dbFilter).length() == 0) ? "" : (" where " + dbFilter)).append(" order by ") - .append(dbOrderBy); - - List list = null; - try { - list = session.createSQLQuery(sql.toString()).addEntity(Lookup.class).list(); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.debugLogger, "Failed to create SQL lookup query for [" + sql + "]" + e.getMessage()); - } - return list; - } - - /* - * methods accepting a Map of additional params to passed to the DAO (for - * extensibility, just in case) - */ - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeSQLQuery(java.lang. - * String, java.lang.Class, java.util.HashMap) - */ - @Override - public List executeSQLQuery(String sql, Class domainClass, HashMap additionalParams) { - return executeSQLQuery(sql, domainClass, null, null, additionalParams); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeSQLQuery(java.lang. - * String, java.lang.Class, java.lang.Integer, java.lang.Integer, - * java.util.HashMap) - */ - @Override - public List executeSQLQuery(String sql, Class domainClass, Integer fromIndex, Integer toIndex, - HashMap additionalParams) { - Session session = sessionFactory.getCurrentSession(); - - SQLQuery query = session.createSQLQuery(sql).addEntity(domainClass.getName().toLowerCase(), domainClass); - - if (fromIndex != null && toIndex != null) { - query.setFirstResult(fromIndex.intValue()); - int pageSize = (toIndex.intValue() - fromIndex.intValue()) + 1; - query.setMaxResults(pageSize); - } - - return query.list(); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeQuery(java.lang. - * String, java.util.HashMap) - */ - @Override - public List executeQuery(String sql, HashMap additionalParams) { - return executeQuery(sql, null, null, additionalParams); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeQuery(java.lang. - * String, java.lang.Integer, java.lang.Integer, java.util.HashMap) - */ - @Override - public List executeQuery(String sql, Integer fromIndex, Integer toIndex, HashMap additionalParams) { - Session session = sessionFactory.getCurrentSession(); - - Query query = session.createQuery(sql); - - if (fromIndex != null && toIndex != null) { - query.setFirstResult(fromIndex.intValue()); - int pageSize = (toIndex.intValue() - fromIndex.intValue()) + 1; - query.setMaxResults(pageSize); - } - - return query.list(); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedQuery(java.lang - * .String, java.lang.Integer, java.lang.Integer, java.util.HashMap) - */ - @Override - public List executeNamedQuery(String queryName, Integer fromIndex, Integer toIndex, HashMap additionalParams) { - return executeNamedQuery(queryName, null, fromIndex, toIndex, additionalParams); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedQuery(java.lang - * .String, java.util.Map, java.util.HashMap) - */ - @Override - public List executeNamedQuery(String queryName, Map params, HashMap additionalParams) { - return executeNamedQuery(queryName, params, null, null, additionalParams); - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedQuery(java.lang - * .String, java.util.Map, java.lang.Integer, java.lang.Integer, - * java.util.HashMap) - */ - @Override - public List executeNamedQuery(String queryName, Map params, Integer fromIndex, Integer toIndex, - HashMap additionalParams) { - Session session = sessionFactory.getCurrentSession(); - Query query = session.getNamedQuery(queryName); - bindQueryParameters(query, params); - if (fromIndex != null && toIndex != null) { - query.setFirstResult(fromIndex.intValue()); - int pageSize = (toIndex.intValue() - fromIndex.intValue()) + 1; - query.setMaxResults(pageSize); - } - return query.list(); - } - - /** - * Stores parameters into the query using String keys from the map. Gives - * special treatment to map values of Collection and array type. - * - * @param query - * Query with parameters - * @param params - * Map of String to Object. - */ - private void bindQueryParameters(Query query, Map params) { - if (params != null) { - for (Iterator i = params.entrySet().iterator(); i.hasNext();) { - Map.Entry entry = (Map.Entry) i.next(); - - Object parameterValue = entry.getValue(); - - if (!(parameterValue instanceof Collection) && !(parameterValue instanceof Object[])) { - query.setParameter((String) entry.getKey(), parameterValue); - } else if (parameterValue instanceof Collection) { - query.setParameterList((String) entry.getKey(), (Collection) parameterValue); - } else if (parameterValue instanceof Object[]) { - query.setParameterList((String) entry.getKey(), (Object[]) parameterValue); - } - } - } - } - - // With Where Clause & RAPTOR's ZK - - /* - * (non-Javadoc) - * - * @see org.openecomp.portalsdk.core.service.DataAccessService# - * executeNamedQueryWithOrderBy(java.lang.Class, java.lang.String, - * java.util.Map, java.lang.String, boolean, java.lang.Integer, - * java.lang.Integer, java.util.HashMap) - */ - @Override - public List executeNamedQueryWithOrderBy(Class entity, String queryName, Map params, String _orderBy, boolean asc, - Integer fromIndex, Integer toIndex, HashMap additionalParams) { - // TODO Auto-generated method stub - logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); - return null; - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedCountQuery(java - * .lang.Class, java.lang.String, java.lang.String, java.util.Map) - */ - @Override - public List executeNamedCountQuery(Class entity, String queryName, String whereClause, Map params) { - // TODO Auto-generated method stub - logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); - return null; - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedQuery(java.lang - * .Class, java.lang.String, java.lang.String, java.util.Map, - * java.lang.Integer, java.lang.Integer, java.util.HashMap) - */ - @Override - public List executeNamedQuery(Class entity, String queryName, String whereClause, Map params, Integer fromIndex, - Integer toIndex, HashMap additionalParams) { - // TODO Auto-generated method stub - logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); - return null; - } - - /* - * (non-Javadoc) - * - * @see org.openecomp.portalsdk.core.service.DataAccessService# - * executeNamedQueryWithOrderBy(java.lang.Class, java.lang.String, - * java.lang.String, java.util.Map, java.lang.String, boolean, - * java.lang.Integer, java.lang.Integer, java.util.HashMap) - */ - @Override - public List executeNamedQueryWithOrderBy(Class entity, String queryName, String whereClause, Map params, - String _orderBy, boolean asc, Integer fromIndex, Integer toIndex, HashMap additionalParams) { - // TODO Auto-generated method stub - logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); - return null; - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#getList(java.lang.Class, - * org.hibernate.criterion.ProjectionList, java.util.List, java.util.List, - * java.util.HashMap) - */ - @Override - public List getList(Class domainClass, ProjectionList projectionsList, List restrictionsList, - List orderByList, HashMap fetchModeMap) { - // TODO Auto-generated method stub - logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); - return null; - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeUpdateQuery(java. - * lang.String, java.util.HashMap) - */ - @Override - public int executeUpdateQuery(String sql, HashMap additionalParams) throws RuntimeException { - // TODO Auto-generated method stub - logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); - return 0; - } - - /* - * (non-Javadoc) - * - * @see - * org.openecomp.portalsdk.core.service.DataAccessService#executeNamedUpdateQuery( - * java.lang.String, java.util.Map, java.util.HashMap) - */ - @Override - public int executeNamedUpdateQuery(String queryName, Map params, HashMap additionalParams) throws RuntimeException { - // TODO Auto-generated method stub - logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); - return 0; - } - - /* - * (non-Javadoc) - * - * @see org.openecomp.portalsdk.core.service.DataAccessService#synchronize(java.util. - * HashMap) - */ - @Override - public void synchronize(HashMap additionalParams) { - // TODO Auto-generated method stub - logger.info(EELFLoggerDelegate.debugLogger, "Not implemented"); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ElementLinkService.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ElementLinkService.java deleted file mode 100644 index 948b635f..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ElementLinkService.java +++ /dev/null @@ -1,269 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.util.YamlUtils; - - - -public class ElementLinkService { - - - public String main1(String[] args) throws Exception{ - String filePath; - if(args[0].startsWith("custom")){ - filePath = SystemProperties.getProperty("customCallFlow_path"); - }else{ - filePath = SystemProperties.getProperty("element_map_file_path") + File.separator; - } - - String callFlowBusinessYml = ""; - String callFlowStep = ""; - - if(args != null && args.length > 0 ) { - - if( args[0] != null) { - callFlowBusinessYml = args[0] + ".yml"; - } - - if( args[1] != null) { - callFlowStep = args[1]; - } - } - - - ElementLinkService mapper = new ElementLinkService(); - - return mapper.createLinkFile(filePath, callFlowBusinessYml, callFlowStep); - } - - public String main2(String[] args) throws Exception{ - - String filePath = SystemProperties.getProperty("element_map_file_path") + File.separator; - String callFlowBusinessYml = ""; - String callFlowStep = ""; - - if(args != null && args.length > 0 ) { - - if( args[0] != null) { - callFlowBusinessYml = args[0] + "-Override.yml"; - } - - if( args[1] != null) { - callFlowStep = args[1]; - } - } - - - ElementLinkService mapper = new ElementLinkService(); - - return mapper.createLinkFileAdditional(filePath, callFlowBusinessYml, callFlowStep); - } - - - public static void main(String[] args) throws Exception{ - - String filePath = "C:\\Users\\statta\\git\\D2Platform\\war\\WEB-INF\\resources\\trisim_files"; - String callFlowBusinessYml = "call_flow_hc-origination-termination-to-volteue-3.3.16-Override.yml"; - - - ElementLinkService mapper = new ElementLinkService(); - System.out.print(mapper.createLinkFileAdditional(filePath, callFlowBusinessYml, "Step_2")); - } - - @SuppressWarnings("unchecked") - protected String createLinkFile(String resourceFilePath, String callFLowBsFileName, String callFlowStep) throws Exception { - - Map callFlowBs = YamlUtils.readYamlFile(resourceFilePath, callFLowBsFileName); - - List> callSteps = (List>) callFlowBs.get("callSequenceSteps"); - String callFlowName = (String) callFlowBs.get("shortName"); - return addLinks( resourceFilePath, callFlowName, callSteps, callFlowStep); - - - } - - @SuppressWarnings("unchecked") - protected String createLinkFileAdditional(String resourceFilePath, String callFLowBsFileName, String callFlowStep) throws Exception { - - Map callFlowBs; - - try{ - callFlowBs = YamlUtils.readYamlFile(resourceFilePath, callFLowBsFileName); - - List> callSteps = (List>) callFlowBs.get("callSequenceSteps"); - String callFlowName = (String) callFlowBs.get("shortName"); - return addLinksAdditional( resourceFilePath, callFlowName, callSteps, callFlowStep); - - } catch (Exception e) { - - return ""; - } - - - } - - @SuppressWarnings("unchecked") - protected String addLinks(String filePath, String callFlowName, - List> callSteps, String callFlowStep) throws IOException { - - Map> checkDuplicateMap = new HashMap>(); - - for(Map callStep : callSteps) { - - if(((String)callStep.get("name")).split(":")[0].trim().replace(" ", "_").equals(callFlowStep)) { - - List> links = new ArrayList>(); - - List> subSteps = (List>)callStep.get("subSteps"); - - for(Map subStep : subSteps) { - Map link = new HashMap(); - - String source = (String) subStep.get("source_tosca_id"); - String destination = (String) subStep.get("destination_tosca_id"); - - if((checkDuplicateMap.get(source) == null || checkDuplicateMap.get(source).isEmpty() || !checkDuplicateMap.get(source).contains(destination)) && !source.equals(destination)) { - if(checkDuplicateMap.get(destination) == null) { - List toscaList = new ArrayList(); - checkDuplicateMap.put(destination, toscaList); - } - - if(checkDuplicateMap.get(source) == null) { - List toscaList = new ArrayList(); - checkDuplicateMap.put(source, toscaList); - } - - - List toscaSourceList = checkDuplicateMap.get(destination); - toscaSourceList.add(source); - - List toscaDestinationList = checkDuplicateMap.get(source); - toscaDestinationList.add(destination); - - link.put("s", source); - link.put("d", destination); - links.add(link); - - } - - } - - Map callFlowUI = new HashMap(); - callFlowUI.put("linkList", links); - - return YamlUtils.returnYaml(callFlowUI); - - } - - - } - return ""; - } - - protected String addLinksAdditional(String filePath, String callFlowName, - List> callSteps, String callFlowStep) throws IOException { - - - for(Map callStep : callSteps) { - - if(((String)callStep.get("name")).split(":")[0].trim().replace(" ", "_").equals(callFlowStep)) { - - Map callFlowUI = new HashMap(); - try{ - List> links = addLinkVertices(callStep); - callFlowUI.put("linkList", links); } - catch(Exception e) {} - try{ - List activeIds = addActiveNodes(callStep); - callFlowUI.put("activeIds", activeIds);} - catch(Exception e) {} - try{ - List> disconnectLinks = addDisconnectLinks(callStep); - callFlowUI.put("disconnectLinks", disconnectLinks); } - catch(Exception e) {} - - return YamlUtils.returnYaml(callFlowUI); - } - } - - return ""; - } - - @SuppressWarnings("unchecked") - List addActiveNodes(Map callStep) { - - List activeIds = (List)callStep.get("activeIds"); - - return activeIds; - } - - @SuppressWarnings("unchecked") - List> addDisconnectLinks(Map callStep) { - - List> disconnectLinks = (List>)callStep.get("disconnectLinks"); - - return disconnectLinks; - } - - @SuppressWarnings("unchecked") - List> addLinkVertices(Map callStep) { - List> links = new ArrayList>(); - - List> vertices = (List>)callStep.get("vertices"); - - for(int i=0; i< vertices.size()-1;i++) { - Map vertex = (Map) vertices.get(i); - Map vertexNext = (Map) vertices.get(i+1); - - Integer sourceX = (Integer) vertex.get("x"); - Integer sourceY = (Integer) vertex.get("y"); - String sourceD = (String) vertex.get("D"); - String sourceL = (vertex.get("L") != null) ? (String) vertex.get("L") : "-"; - - if(sourceX == -999) // there is a break in the linkage - continue; - - Integer destinationX = (Integer) vertexNext.get("x"); - Integer destinationY = (Integer) vertexNext.get("y"); - String destinationD = (String) vertexNext.get("D"); - - if(destinationX == -999) // there is a break in the linkage - continue; - - Map link = new HashMap(); - - link.put("s", sourceX + "," + sourceY +","+sourceD + "," + sourceL); - link.put("d", destinationX + "," + destinationY +"," + destinationD); - links.add(link); - } - return links; - } -} - - diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ElementMapService.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ElementMapService.java deleted file mode 100644 index d88213f3..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ElementMapService.java +++ /dev/null @@ -1,915 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.apache.commons.lang.StringUtils; -import org.openecomp.portalsdk.core.domain.support.Container; -import org.openecomp.portalsdk.core.domain.support.Domain; -import org.openecomp.portalsdk.core.domain.support.Element; -import org.openecomp.portalsdk.core.domain.support.ElementDetails; -import org.openecomp.portalsdk.core.domain.support.Layout; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.util.YamlUtils; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -public class ElementMapService { - - public String convertToYAML(Layout layout) throws Exception{ - Map resultDomain= layout.domainRowCol; - Map> domainMap = new HashMap>(); - List domainList = new ArrayList(); - String pathToImg = SystemProperties.getProperty("element_map_icon_path"); //"static/img/map/icons/"; - for (Domain d : resultDomain.values()) { - - d.setWidth(10*d.computeSize().getWidth()); - d.setHeight(10*d.computeSize().getHeight()); - d.setLeft(10*d.getP().getX()); - d.setTop(10*d.getP().getY()); - - - List containerList = new ArrayList(); - for (Container c : d.getContainerRowCol().values()) { - c.setWidth(10*c.computeSize().getWidth()); - c.setHeight(10*c.computeSize().getHeight()); - c.setLeft(10*c.getP().getX()); - c.setTop(10*c.getP().getY()); - Element ue = (Element)c.getElementRowCol().values().toArray()[0]; - if (ue.getName().equals("ue1") || ue.getName().equals("ue2") || ue.getName().equals("ue3") || - ue.getName().equals("ue4") || ue.getName().equals("ue5") || ue.getName().equals("ue6")) { - c.setVisibilityType("invisible"); - } - - if (c.getContainerRowCol() != null) { - List innerContainerList = new ArrayList(); - for (Container innerC : c.getContainerRowCol().values()) { - innerC.setName(innerC.getName()); - innerC.setWidth(10*innerC.computeSize().getWidth()); - innerC.setHeight(10*innerC.computeSize().getHeight()); - innerC.setLeft(10*innerC.getP().getX()); - innerC.setTop(10*innerC.getP().getY()); - - if (innerC.getElementRowCol() != null) { - List innerContainerEList = new ArrayList(); - for (Element ele : innerC.getElementRowCol().values()) { - ele.setWidth(10*ele.computeSize().getWidth()); - ele.setHeight(10*ele.computeSize().getHeight()); - ele.setLeft(10*ele.getP().getX()); - ele.setTop(10*ele.getP().getY()-10); - ele.setImgFileName(pathToImg+ele.getImgFileName()); - if (ele.getBorderType().equals("V")) - ele.setBorderType("dashed"); - else - ele.setBorderType("solid"); - - innerContainerEList.add(ele); - } - innerC.setElementList(innerContainerEList); - } - innerContainerList.add(innerC); - } - c.setInnerCList(innerContainerList); - } - - if (c.getElementRowCol() != null) { - List elementList = new ArrayList(); - for (Element e : c.getElementRowCol().values()) { - e.setWidth(10*e.computeSize().getWidth()); - e.setHeight(10*e.computeSize().getHeight()); - e.setLeft(10*e.getP().getX()); - e.setTop(10*e.getP().getY()-10); - e.setImgFileName(pathToImg+e.getImgFileName()); - - if (e.getBorderType().equals("V")) - e.setBorderType("dashed"); - else - e.setBorderType("solid"); - - if (e.getName().equals("ue1") || e.getName().equals("ue2") || e.getName().equals("ue3") - || e.getName().equals("ue4") || e.getName().equals("ue5") || e.getName().equals("ue6")) - e.setBgColor("white"); - elementList.add(e); - } - c.setElementList(elementList); - } - containerList.add(c); - } - d.setContainerList(containerList); - domainList.add(d); - - } - domainMap.put("domainList", domainList); - - List collapsedDomains = new ArrayList(); - - //nline - for (Domain collapsed : layout.getCollapsedDomainsNewList()) { - collapsed.setWidth(10*collapsed.computeSize().getWidth()); - collapsed.setHeight(10*collapsed.computeSize().getHeight()); - collapsed.setLeft(10*collapsed.getP().getX()); - collapsed.setTop(10*collapsed.getP().getY()); - //nline - collapsed.setNewXafterColl(10*collapsed.getNewXafterColl()); - collapsed.setYafterColl(10*collapsed.getYafterColl()); - collapsedDomains.add(collapsed); - } - - domainMap.put("collapsedDomainList", collapsedDomains); - - Representer representer = new Representer(); - representer.addClassTag(Domain.class, Tag.MAP); - - - Yaml yaml = new Yaml(representer); - String output = yaml.dump(domainMap); - - return output; - -} - - - - public static HashMap toscaElementsMap = new HashMap(); - public static HashMap elementMap = new HashMap(); - public static HashMap miscElementMap = new HashMap(); - public static HashMap outercontainers = new HashMap(); - public static HashMap innercontainers = new HashMap(); - public static HashMap domainMap = new HashMap(); - - - static String filePath = - SystemProperties.getProperty("element_map_file_path") ; - static String callFlowBusinessYml = "call_flow_sip_digest.yml"; - static String networkToscaYml = null;//"NetworkMap_topology_composition.yml"; - static String networkLayoutYml = null;// "network_map_layout.yml"; - - - @SuppressWarnings({ "unchecked", "unused" }) - public String main1(String args[]) throws Exception{ - - - if(args != null && args.length > 0 ) { - - if( args[2] != null) { - networkToscaYml = args[2] + ".yml"; - } - - if( args[3] != null) { - networkLayoutYml = args[3] + ".yml"; - } - } - - HashMap toscaYaml = (HashMap)YamlUtils.readYamlFile(filePath, networkToscaYml); //TrinityYAMLHelper.getToscaYaml(); - HashMap networkMapLayoutYaml = (HashMap)YamlUtils.readYamlFile(filePath, networkLayoutYml); //TrinityYAMLHelper.getNetworkMapLayoutYaml(); - - toscaElementsMap = new HashMap(); - elementMap = new HashMap(); - domainMap = new HashMap(); - outercontainers = new HashMap(); - innercontainers = new HashMap(); - miscElementMap = new HashMap(); - - if(toscaYaml != null){ - for(String key : toscaYaml.keySet()){ - if("topology_template".equalsIgnoreCase(key) && toscaYaml.get(key) instanceof HashMap){ - HashMap toscaTopologyDetails = (HashMap) toscaYaml.get(key); - - for(String detailsKey: toscaTopologyDetails.keySet()){ - - if("node_templates".equalsIgnoreCase(detailsKey) && toscaTopologyDetails.get(detailsKey) instanceof HashMap){ - - toscaElementsMap = (HashMap) toscaTopologyDetails.get(detailsKey); - - for(String toscaElementKey: toscaElementsMap.keySet()){ - } - - } - } - } - - } - } - - if(networkMapLayoutYaml != null){ - if(networkMapLayoutYaml.containsKey("toscaNetworkMapElementStyleList") && networkMapLayoutYaml.get("toscaNetworkMapElementStyleList") instanceof ArrayList){ - - ArrayList elementlist = (ArrayList)networkMapLayoutYaml.get("toscaNetworkMapElementStyleList"); - String elementName; - String elementID; - String imgPath; - String row; - String column; - String mapKey; - int i=0; - - if(elementlist != null){ - for(Object eachElement: elementlist){ - if(eachElement != null && eachElement instanceof HashMap){ - HashMap elementDetails = (HashMap) eachElement; - if(elementDetails != null){ - elementName = "NA"+i; - elementID = "NA"+i; - imgPath = "NA"+i; - row = "0"; - column = "0"; - for(String detailsKey: elementDetails.keySet()){ - if ("tosca_id".equalsIgnoreCase(detailsKey)) elementName = elementDetails.get(detailsKey).toString(); - if ("id".equalsIgnoreCase(detailsKey)) { - elementID = String.valueOf(elementDetails.get(detailsKey)); - } - if ("row".equalsIgnoreCase(detailsKey)) { - row = String.valueOf(elementDetails.get(detailsKey)); - } - if ("column".equalsIgnoreCase(detailsKey)) { - column = String.valueOf(elementDetails.get(detailsKey)); - } - if ("icon".equalsIgnoreCase(detailsKey)) imgPath = elementDetails.get(detailsKey).toString(); - } - - if(elementMap.containsKey(elementName.concat("/").concat(row).concat(column))){ - if(elementMap.containsKey(elementName.concat("/").concat(String.valueOf(i)).concat(String.valueOf(i)))){ - mapKey = elementName; - } else mapKey = elementName.concat("/").concat(String.valueOf(i)).concat(String.valueOf(i)); - - } else mapKey = elementName.concat("/").concat(row).concat(column); - - elementMap.put(mapKey, fetchElementObject(elementID,elementName,imgPath)); - } - } - i++; - } - } - - for(String elementkey : elementMap.keySet()){ - Element c = (Element) elementMap.get(elementkey); - } - - if(!elementMap.isEmpty()){ - miscElementMap = new HashMap(elementMap); - } - } - - - if(networkMapLayoutYaml.containsKey("containerStyleList") && networkMapLayoutYaml.get("containerStyleList") instanceof ArrayList){ - - ArrayList containerstylelist = (ArrayList)networkMapLayoutYaml.get("containerStyleList"); - String containerName; - String containerID; - String domain; - String row; - String column; - String mapKey; - int i=0; - - if(containerstylelist != null){ - //Inner Containers - for(Object eachContainer: containerstylelist){ - if(eachContainer != null && eachContainer instanceof HashMap){ - HashMap containerDetails = (HashMap) eachContainer; - if(containerDetails != null){ - containerName = "NA"+i; - containerID = "NA"+i; - domain = "NA"+i; - row = "0"; - column = "0"; - - for(String detailsKey: containerDetails.keySet()){ - if ("logical_group_name".equalsIgnoreCase(detailsKey)) containerName = containerDetails.get(detailsKey).toString(); - if ("id".equalsIgnoreCase(detailsKey)) { - containerID = String.valueOf(containerDetails.get(detailsKey)); - } - if("domain".equalsIgnoreCase(detailsKey)){ - domain = containerDetails.get(detailsKey).toString(); - } - if ("row".equalsIgnoreCase(detailsKey)) { - row = String.valueOf(containerDetails.get(detailsKey)); - } - if ("column".equalsIgnoreCase(detailsKey)) { - column = String.valueOf(containerDetails.get(detailsKey)); - } - } - if(containerName.contains("/")){ - - if(innercontainers.containsKey((domain +":"+ containerName).concat("/").concat(row).concat(column))){ - if(elementMap.containsKey((domain +":"+ containerName).concat("/").concat(String.valueOf(i)).concat(String.valueOf(i)))){ - mapKey = (domain +":"+ containerName); - } else mapKey = (domain +":"+ containerName).concat("/").concat(String.valueOf(i)).concat(String.valueOf(i)); - - } else mapKey = (domain +":"+ containerName).concat("/").concat(row).concat(column); - - innercontainers.put(mapKey, fetchContainerObject(containerID,containerName.substring(containerName.indexOf("/")+1),true,containerName,domain)); - } - } - } - i++; - } - - //OuterContainers - i=0; - for(Object eachContainer: containerstylelist){ - if(eachContainer != null && eachContainer instanceof HashMap){ - HashMap containerDetails = (HashMap) eachContainer; - if(containerDetails != null){ - containerName = "NA"+i; - containerID = "NA"+i; - domain = "NA"+i; - row = "0"; - column = "0"; - - for(String detailsKey: containerDetails.keySet()){ - if ("logical_group_name".equalsIgnoreCase(detailsKey)) containerName = containerDetails.get(detailsKey).toString(); - if ("id".equalsIgnoreCase(detailsKey)) { - containerID = String.valueOf(containerDetails.get(detailsKey)); - } - if("domain".equalsIgnoreCase(detailsKey)){ - domain = containerDetails.get(detailsKey).toString(); - } - if ("row".equalsIgnoreCase(detailsKey)) { - row = String.valueOf(containerDetails.get(detailsKey)); - } - if ("column".equalsIgnoreCase(detailsKey)) { - column = String.valueOf(containerDetails.get(detailsKey)); - } - } - if(!containerName.contains("/")){ - if(outercontainers.containsKey((domain +":"+ containerName).concat("/").concat(row).concat(column))){ - if(outercontainers.containsKey((domain +":"+ containerName).concat("/").concat(String.valueOf(i)).concat(String.valueOf(i)))){ - mapKey = (domain +":"+ containerName); - } else mapKey = (domain +":"+ containerName).concat("/").concat(String.valueOf(i)).concat(String.valueOf(i)); - - } else mapKey = (domain +":"+ containerName).concat("/").concat(row).concat(column); - outercontainers.put(mapKey, fetchContainerObject(containerID,containerName,false,containerName,domain)); - } - - } - } - i++; - } - } - - for(String innerContainerkey : innercontainers.keySet()){ - Container c = (Container) innercontainers.get(innerContainerkey); - } - - for(String outerContainerkey : outercontainers.keySet()){ - Container c = (Container) outercontainers.get(outerContainerkey); - } - - } - - if(networkMapLayoutYaml.containsKey("domainList") && networkMapLayoutYaml.get("domainList") instanceof ArrayList){ - - ArrayList domainlist = (ArrayList)networkMapLayoutYaml.get("domainList"); - String domainName; - String domainID; - String row; - String column; - String mapKey; - int i=0; - - if(domainlist != null){ - - Double leftPosition = 7d; - HashMap domainStagingMap = new HashMap(); - - for(Object eachDomain: domainlist){ - if(eachDomain != null && eachDomain instanceof HashMap){ - HashMap domainDetails = (HashMap) eachDomain; - if(domainDetails != null){ - domainName = "NA"+i; - domainID = "NA"+i; - row = "0"; - column = "0"; - for(String detailsKey: domainDetails.keySet()){ - if ("name".equalsIgnoreCase(detailsKey)) domainName = domainDetails.get(detailsKey).toString(); - if ("id".equalsIgnoreCase(detailsKey)) { - domainID = String.valueOf(domainDetails.get(detailsKey)); - } - if ("row".equalsIgnoreCase(detailsKey)) { - row = String.valueOf(domainDetails.get(detailsKey)); - } - if ("column".equalsIgnoreCase(detailsKey)) { - column = String.valueOf(domainDetails.get(detailsKey)); - } - } - - if(domainStagingMap.containsKey(row.concat(column))){ - mapKey = domainName; - } else mapKey = row.concat(column); - - domainStagingMap.put(mapKey, domainID+"%"+domainName); - } - } - i++; - } - - if(domainStagingMap != null && !domainStagingMap.isEmpty()){ - for(String domainsKey: new TreeSet(domainStagingMap.keySet())){ - String value = domainStagingMap.get(domainsKey); - if(value.contains("%")){ - domainMap.put(domainsKey, fetchDomainObject(value.substring(0,value.indexOf("%")),value.substring(value.indexOf("%")+1))); - } - } - } - } - - for(String domainkey : domainMap.keySet()){ - Domain c = (Domain) domainMap.get(domainkey); - } - - } - - - } - - Layout dynamicLayout = new Layout(domainMap, 2, 10, 1, 5); - - dynamicLayout.computeDomainPositionsModified(); - Map resultDomain2= dynamicLayout.domainRowCol; - - for (String key : resultDomain2.keySet()) { - if (resultDomain2.get(key).getP() !=null) { - - } - } - - ElementMapService cm2 = new ElementMapService(); - try { - - if(args != null && args.length > 0 ) { - - if( args[0] != null) { - String collapsedDomains[] = args[0].split(","); - for(String collapsedDomain : collapsedDomains) - dynamicLayout.collapseDomainNew(collapsedDomain); - } - - if( args[1] != null) { - String expandedDomains[] = args[1].split(","); - for(String expandedDomain : expandedDomains) - dynamicLayout.uncollapseDomainNew1(expandedDomain); - } - - return cm2.convertToYAML(dynamicLayout); - - } - }catch (Exception e) { - - e.printStackTrace(); - } - - - return ""; - - - } - - private static int computeRows(Set keys){ - int i = 0; - if(keys!= null && !keys.isEmpty()){ - for(String s: keys){ - String r = s.substring(0, 1); - if(StringUtils.isNumeric(r)){ - int j = Integer.parseInt(r); - if(i<= j){ - i=j; - } - - } - } - - return i+1; - } - - return 1; - } - - private static int computeColumns(Set keys){ - int i = 0; - if(keys!= null && !keys.isEmpty()){ - for(String s: keys){ - String r = s.substring(1, 2); - if(StringUtils.isNumeric(r)){ - int j = Integer.parseInt(r); - if(i<= j){ - i=j; - } - - } - } - - return i+1; - } - - return 1; - } - - private static Container fetchContainerObject(String id, String name, boolean isInner, String logicalGroupName, String domain){ - Map containerElementsMap = new HashMap(); - - containerElementsMap = fetchElementsMapForContainer(name, isInner, logicalGroupName, domain); - int rows = 1; - int columns = 1; - - if(isInner){ - - if(containerElementsMap != null && !containerElementsMap.isEmpty()){ - rows = computeRows(containerElementsMap.keySet()); - columns = computeColumns(containerElementsMap.keySet()); - } - - Container thisContainer = new Container(id, name, rows, columns, 1, 4, 8, 12, 1, 2); - thisContainer.setElements(containerElementsMap); - - return thisContainer; - } else { - Map innerContainersMap = fetchInnerContainersMapForOuter(name, isInner, logicalGroupName,domain); - - if(innerContainersMap != null && !innerContainersMap.isEmpty()){ - if(containerElementsMap != null && !containerElementsMap.isEmpty()){ - Set keys = new HashSet(innerContainersMap.keySet()); - keys.addAll(containerElementsMap.keySet()); - rows = computeRows(keys); - columns = computeColumns(keys); - } else { - rows = computeRows(innerContainersMap.keySet()); - columns = computeColumns(innerContainersMap.keySet()); - } - } else if(containerElementsMap != null && !containerElementsMap.isEmpty()){ - rows = computeRows(containerElementsMap.keySet()); - columns = computeColumns(containerElementsMap.keySet()); - } - - Container thisContainer = new Container(id, name, rows, columns,2 , 6, 2, 5, 0, 0); - thisContainer.setElements(containerElementsMap); - thisContainer.setInnerContainer(innerContainersMap); - - - return thisContainer; - } - - } - - private static Domain fetchDomainObject(String id, String name){ - HashMap domainContainersMap = fetchContainersForDomain(name); - - int rows = 1; - int columns = 1; - if(domainContainersMap != null && !domainContainersMap.isEmpty()){ - rows = computeRows(domainContainersMap.keySet()); - columns = computeColumns(domainContainersMap.keySet()); - } - - double domainWidth = 11; - Domain thisDomain; - - if(domainMap != null && !domainMap.isEmpty()){ - int domainsCountSoFar = domainMap.size(); - switch(domainsCountSoFar){ - case 1: {domainWidth = 12.1; break;} - case 2: {domainWidth = 13.3; break;} - case 3: {domainWidth = 14.5; break;} - case 4: {domainWidth = 15.6; break;} - default: {domainWidth = 11; break;} - } - - for(String domainsKey: new TreeSet(domainMap.keySet())){ - Domain eachDomain = domainMap.get(domainsKey); - domainWidth+= eachDomain.computeSize().getWidth(); - } - thisDomain = new Domain(id, name, 2, 2, domainWidth, 10, 3, rows, columns); - } else { - - thisDomain = new Domain(id, name, 2, 1, 11, 10, 3, rows, columns); - } - - thisDomain.setContainers(domainContainersMap); - - thisDomain.computeConatinerPositions(); - if(domainContainersMap!= null && !domainContainersMap.isEmpty()){ - for(Container thisContainer : domainContainersMap.values()){ - thisContainer.computeSize(); - thisContainer.computeElementPositions(); - Map resultElementMap = thisContainer.elementRowCol; - for (String key : resultElementMap.keySet()) { - if(resultElementMap.get(key) == null || resultElementMap.get(key).getP() == null) { - } - - } - - HashMap innerContainersMap = (HashMap) thisContainer.getContainerRowCol(); - if(innerContainersMap != null && !innerContainersMap.isEmpty()){ - for(Container thisInnerContainer : innerContainersMap.values()){ - thisInnerContainer.computeElementPositions(); - } - } - } - } - - return thisDomain; - } - - private static HashMap fetchContainersForDomain(String domain){ - HashMap domainContainersMap = new HashMap(); - - domainContainersMap = fetchFromOuterContainers(domain); - - return domainContainersMap; - - } - - @SuppressWarnings("unchecked") - private static Element fetchElementObject(String id, String name, String imgPath){ - String bgColor = "bgColor"; - String logical_group; - String display_longname; - String display_shortname; - String description; - String primary_function; - String key_interfaces; - String location; - String vendor; - String vendor_shortname; - String enclosingContainer; - String borderType; - String network_function; - - if(toscaElementsMap.containsKey(name)){ - - if(toscaElementsMap.get(name) != null && toscaElementsMap.get(name) instanceof HashMap){ - HashMap toscaElementDetails = (HashMap) toscaElementsMap.get(name); - - for(String detailsKey: toscaElementDetails.keySet()){ - if("properties".equalsIgnoreCase(detailsKey) && toscaElementDetails.get(detailsKey) instanceof HashMap){ - HashMap elementDetails = (HashMap) toscaElementDetails.get(detailsKey); - - if(elementDetails != null){ - logical_group = elementDetails.get("logical_group") == null? "" : elementDetails.get("logical_group").toString(); - display_longname = elementDetails.get("display_longname") == null? "" : elementDetails.get("display_longname").toString(); - display_shortname = elementDetails.get("display_shortname") == null? "" : elementDetails.get("display_shortname").toString(); - description = elementDetails.get("description") == null? "" : elementDetails.get("description").toString(); - primary_function = elementDetails.get("primary_function") == null? "" : elementDetails.get("primary_function").toString(); - key_interfaces = elementDetails.get("key_interfaces") == null? "" : elementDetails.get("key_interfaces").toString(); - location = elementDetails.get("location") == null? "" : elementDetails.get("location").toString(); - vendor = elementDetails.get("vendor") == null? "" : elementDetails.get("vendor").toString(); - vendor_shortname = elementDetails.get("vendor_shortname") == null? "" : elementDetails.get("vendor_shortname").toString(); - enclosingContainer = logical_group.replace("/", "-"); - network_function = elementDetails.get("network_function"); - borderType = elementDetails.get("network_function") == null? "P" : elementDetails.get("network_function").toString().toUpperCase(); - bgColor = elementDetails.get("background_color") == null? "bgColor" : elementDetails.get("background_color").toString(); - - ElementDetails details = new ElementDetails(logical_group,display_longname,description,primary_function, network_function, - key_interfaces,location,vendor,vendor_shortname,enclosingContainer); - - return new Element(name, display_shortname, imgPath, bgColor,borderType, details); - } - - } - } - - } - - } else { - return new Element(id,name); - } - - return new Element(id,name); - } - - @SuppressWarnings("unchecked") - private static String fetchDomainNameOfElement(String name){ - if(toscaElementsMap.containsKey(name)){ - - if(toscaElementsMap.get(name) != null && toscaElementsMap.get(name) instanceof HashMap){ - HashMap toscaElementDetails = (HashMap) toscaElementsMap.get(name); - - for(String detailsKey: toscaElementDetails.keySet()){ - if("properties".equalsIgnoreCase(detailsKey) && toscaElementDetails.get(detailsKey) instanceof HashMap){ - HashMap elementDetails = (HashMap) toscaElementDetails.get(detailsKey); - - if(elementDetails != null){ - return elementDetails.get("domain") == null? "" : elementDetails.get("domain").toString(); - } - - } - } - - } - - } else { - return ""; - } - - return ""; - } - - private static HashMap fetchInnerContainersMapForOuter(String name, boolean isInner, String logicalGroupName, String domain){ - return fetchInnerContainersMap(name,logicalGroupName,domain); - } - - private static HashMap fetchElementsMapForContainer(String name, boolean isInner, String logicalGroupName, String domain){ - return fetchElementsMap(logicalGroupName,domain); - } - - private static HashMap fetchInnerContainersMap(String name, String logicalGroupName, String domain){ - HashMap containersMap = new HashMap(); - String rowColumnKey = ""; - int count = 0; - - if(innercontainers!=null && !innercontainers.isEmpty()){ - for(String key : innercontainers.keySet()){ - - - Container eachContainer = innercontainers.get(key); - - if(key.toUpperCase().contains((domain+":"+name).toUpperCase())){ - if(key.contains("/")){ - rowColumnKey = key.substring(key.lastIndexOf("/")+1); - } - - if(rowColumnKey.isEmpty() || containersMap.containsKey(rowColumnKey)){ - count=0; - while(count<=9){ - if(containersMap.containsKey(String.valueOf(count).concat(String.valueOf(count)))){ - count++; - } else - { - rowColumnKey = String.valueOf(count).concat(String.valueOf(count)); - break; - } - } - - - } - - containersMap.put(rowColumnKey,eachContainer); - } - - - } - } - return containersMap.isEmpty()?null:containersMap; - - } - - private static HashMap fetchFromOuterContainers(String domain){ - HashMap thisContainersMap = new HashMap(); - String rowColumnKey = ""; - int count = 0; - - if(outercontainers!=null && !outercontainers.isEmpty()){ - for(String key : outercontainers.keySet()){ - Container eachContainer = outercontainers.get(key); - - if(key.toUpperCase().contains((domain+":").toUpperCase())){ - if(key.contains("/")){ - rowColumnKey = key.substring(key.lastIndexOf("/")+1); - } - - if(rowColumnKey.isEmpty() || thisContainersMap.containsKey(rowColumnKey)){ - count=0; - while(count<=9){ - if(thisContainersMap.containsKey(String.valueOf(count).concat(String.valueOf(count)))){ - count++; - } else - { - rowColumnKey = String.valueOf(count).concat(String.valueOf(count)); - break; - } - } - - - } - - thisContainersMap.put(rowColumnKey,eachContainer); - } - } - - } - - //Misc Elements Containers - - if(miscElementMap!=null && !miscElementMap.isEmpty()){ - for(String key : miscElementMap.keySet()){ - Element eachElement = miscElementMap.get(key); - String elementName = eachElement.getName(); - String domainName = fetchDomainNameOfElement(elementName); - - if(domain.equalsIgnoreCase(domainName)){ - Container eachContainer = new Container(domainName+":"+elementName, elementName, 1, 1, 3, 6, 2, 5, 0, 0); - count=0; - while(count<=9){ - if(thisContainersMap.containsKey(String.valueOf(count).concat(String.valueOf(count)))){ - count++; - } else - { - rowColumnKey = String.valueOf(count).concat(String.valueOf(count)); - break; - } - } - - thisContainersMap.put(rowColumnKey,eachContainer); - } - - - } - - } - - - return thisContainersMap.isEmpty()?null:thisContainersMap; - } - - - - @SuppressWarnings("unused") - private static HashMap addOuterContainersForMiscElements(String domain){ - HashMap containerElementsMap = new HashMap(); - if(miscElementMap!=null && !miscElementMap.isEmpty()){ - for(String key : miscElementMap.keySet()){ - Element eachElement = miscElementMap.get(key); - String elementName = eachElement.getName(); - String domainName = fetchDomainNameOfElement(elementName); - - if(domain.equalsIgnoreCase(domainName)){ - Container newContainer = new Container(domainName+":"+elementName, elementName, 1, 1, 3, 6, 2, 5, 0, 0); - containerElementsMap.put(domainName+":"+elementName, newContainer); - } - - - } - - } - return containerElementsMap.isEmpty()? null:containerElementsMap; - } - - private static HashMap fetchElementsMap(String logicalGroupName, String domain){ - HashMap innerElementMap = new HashMap(); - String rowColumnKey = ""; - int count = 0; - - if(elementMap!=null && !elementMap.isEmpty()){ - for(String key : elementMap.keySet()){ - Element eachElement = elementMap.get(key); - - String elementName = eachElement.getId(); - String elementLogicalGroup = eachElement.details == null ? "" : eachElement.details.logical_group; - if(elementLogicalGroup.equalsIgnoreCase(logicalGroupName) && domain.equalsIgnoreCase(fetchDomainNameOfElement(elementName))){ - if(key.contains("/")){ - rowColumnKey = key.substring(key.indexOf("/")+1); - } - - if(rowColumnKey.isEmpty() || innerElementMap.containsKey(rowColumnKey)){ - count=0; - while(count<=9){ - if(innerElementMap.containsKey(String.valueOf(count).concat(String.valueOf(count)))){ - count++; - } else - { - rowColumnKey = String.valueOf(count).concat(String.valueOf(count)); - break; - } - } - - - } - - innerElementMap.put(rowColumnKey,eachElement); - miscElementMap.remove(key); - } - - } - } - - return innerElementMap.isEmpty()?null:innerElementMap; - } - - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/FnMenuServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/FnMenuServiceImpl.java deleted file mode 100644 index b17be180..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/FnMenuServiceImpl.java +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.openecomp.portalsdk.core.domain.Menu; -import org.openecomp.portalsdk.core.domain.MenuData; -import org.openecomp.portalsdk.core.domain.RoleFunction; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * Description: this java class is an implementation of services for Admin to add/edit/delete menu items from FN_MENU - */ - -@Service("fnMenuService") -@Transactional -public class FnMenuServiceImpl implements FnMenuService{ - - @Autowired - private DataAccessService dataAccessService; - - @SuppressWarnings("unchecked") - public List getFnMenuItems() { - return getDataAccessService().getList(MenuData.class, null, "1", null); - - } - - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - - @Override - public void saveFnMenuData(MenuData domainFnMenu) { - // TODO Auto-generated method stub - getDataAccessService().saveDomainObject(domainFnMenu, null); - - } - - @SuppressWarnings("unchecked") - @Override - public List getParentId(String label) { - // TODO Auto-generated method stub - Map params = new HashMap(); - params.put("paramLabel", label); - return getDataAccessService().executeNamedQuery("IdForLabelList", params, null); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public List getParentList() { - // TODO Auto-generated method stub - - return getDataAccessService().executeNamedQuery("parentList", null, null); - - } - - @SuppressWarnings("unchecked") - @Override - public List getFunctionCDList() { - // TODO Auto-generated method stub - - return getDataAccessService().executeNamedQuery("functionCDlist", null, null); - - } - - @Override - public void removeMenuItem(MenuData domainFnMenu) { - getDataAccessService().deleteDomainObject(domainFnMenu, null); - } - - @Override - public void removeMenuItem(Menu domainFnMenu) { - getDataAccessService().deleteDomainObject(domainFnMenu, null); - } - - public MenuData getMenuItemRow(Long id) { - return (MenuData)getDataAccessService().getDomainObject(MenuData.class, id, null); - } - - @Override - public Menu getMenuItem(Long id) { - return (Menu)getDataAccessService().getDomainObject(Menu.class, id, null); - } - - @Override - public void saveFnMenu(Menu domainFnMenu) { - // TODO Auto-generated method stub - getDataAccessService().saveDomainObject(domainFnMenu, null); - - } - @Override - public Map> setMenuDataStructure(List> childItemList, List parentList, Set menuResult) throws Exception{ - for(MenuData menu: menuResult){ - MenuData parentData = new MenuData(); - parentData.setLabel(menu.getLabel()); - parentData.setAction(menu.getAction()); - parentData.setImageSrc(menu.getImageSrc()); - parentList.add(parentData); - List tempList = new ArrayList(); - for(Object o:menu.getChildMenus()){ - MenuData m = (MenuData)o; - MenuData data = new MenuData(); - data.setLabel(m.getLabel()); - data.setAction(m.getAction()); - data.setImageSrc(m.getImageSrc()); - tempList.add(data); - } - childItemList.add(tempList); - } - return null; - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LdapServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LdapServiceImpl.java deleted file mode 100644 index d1176c1c..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LdapServiceImpl.java +++ /dev/null @@ -1,269 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.DirContext; -import javax.naming.directory.SearchControls; - -import org.openecomp.portalsdk.core.command.support.SearchResult; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.domain.support.DomainVo; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.support.FusionService; -import org.openecomp.portalsdk.core.service.support.ServiceLocator; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("ldapService") -@Transactional -public class LdapServiceImpl extends FusionService implements LdapService { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(LdapServiceImpl.class); - @Autowired - private ServiceLocator serviceLocator; - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public SearchResult searchPost(DomainVo searchCriteria, String sortBy1, String sortBy2, String sortBy3, - int pageNo, int dataSize, int userId) throws Exception { - - // initialize the directory context to access POST - DirContext dirContext = serviceLocator.getDirContext(SystemProperties.getProperty(SystemProperties.POST_INITIAL_CONTEXT_FACTORY), - SystemProperties.getProperty(SystemProperties.POST_PROVIDER_URL), - SystemProperties.getProperty(SystemProperties.POST_SECURITY_PRINCIPAL)); - - SearchResult searchResult = new SearchResult(); - - try { - - String[] postAttributes = {"nickname","givenName","initials","sn","employeeNumber","mail","telephoneNumber", - "departmentNumber","a1","street","roomNumber","l","st","postalCode","zip4","physicalDeliveryOfficeName","bc", - "friendlyCountryName","bd","bdname","bu","buname","jtname","mgrid","a2","compcode","compdesc", - "costcenter","silo","b2"}; - - SearchControls searchControls = new SearchControls(); - searchControls.setTimeLimit(5000); - searchControls.setReturningAttributes(postAttributes); - - StringBuffer filterClause = new StringBuffer("(&(objectClass=*)"); - - User user = (User)searchCriteria; - - if(Utilities.nvl(user.getFirstName()).length() > 0) { - filterClause.append("(givenName=").append(user.getFirstName()).append("*)"); - } - if(Utilities.nvl(user.getLastName()).length() > 0) { - filterClause.append("(sn=").append(user.getLastName()).append("*)"); - } - if(Utilities.nvl(user.getHrid()).length() > 0) { - filterClause.append("(employeeNumber=").append(user.getHrid()).append("*)"); - } - if(Utilities.nvl(user.getOrgManagerUserId()).length() > 0) { - filterClause.append("(mgrid=").append(user.getOrgManagerUserId()).append("*)"); - } - if(Utilities.nvl(user.getOrgCode()).length() > 0) { - filterClause.append("(departmentNumber=").append(user.getOrgCode()).append("*)"); - } - if(Utilities.nvl(user.getEmail()).length() > 0) { - filterClause.append("(mail=").append(user.getEmail()).append("*)"); - } - if(Utilities.nvl(user.getOrgUserId()).length() > 0) { - filterClause.append("(a1=").append(user.getOrgUserId()).append("*)"); - } - filterClause.append("(c3=N)"); // this has been added to filter CP09 entries on the LDAP server that are duplicates of existing individuals - filterClause.append(")"); - - List list = new ArrayList(); - if (!filterClause.toString().equals("(&(objectClass=*))")) { - NamingEnumeration e = dirContext.search(SystemProperties.getProperty(SystemProperties.POST_PROVIDER_URL) + "/" + - SystemProperties.getProperty(SystemProperties.POST_SECURITY_PRINCIPAL), - filterClause.toString(), - searchControls); - - list = processResults(e); - } - - Collections.sort(list); - - searchResult = new SearchResult(list); - searchResult.setPageNo(pageNo); - if(dataSize >= 0) { - searchResult.setDataSize(dataSize); - } - else { - searchResult.setDataSize(list.size()); - } // else - - } - catch(NamingException ne) { - logger.error(EELFLoggerDelegate.errorLogger,ne.getMessage()); - } - finally { - dirContext.close(); - } - - return searchResult; - } - - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private ArrayList processResults(NamingEnumeration e) throws NamingException { - ArrayList results = new ArrayList(); - int count = 0; - - while (e.hasMore()) { - javax.naming.directory.SearchResult searchResult = (javax.naming.directory.SearchResult)e.next(); - results.add(processAttributes(searchResult.getAttributes())); - count++; - - if(count > Integer.parseInt(SystemProperties.getProperty(SystemProperties.POST_MAX_RESULT_SIZE))) { - break; - } - - } - - return results; - } - - - @SuppressWarnings("rawtypes") - private DomainVo processAttributes(Attributes resultAttributes) throws NamingException { - User user = new User(); - - try { - if (resultAttributes == null) { - System.out.println("This result has no attributes"); - } else { - for (NamingEnumeration e = resultAttributes.getAll(); e.hasMore();) { //why the nested loop? - Attribute attribute = (Attribute)e.next(); - for (NamingEnumeration ie = attribute.getAll(); ie.hasMore();) { - if (attribute.getID().equalsIgnoreCase("nickname")) { - user.setFirstName((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("initials")) { - user.setMiddleInitial((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("sn")) { - user.setLastName((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("employeeNumber")) { - user.setHrid((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("mail")) { - user.setEmail((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("telephoneNumber")) { - user.setPhone((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("departmentNumber")) { - user.setOrgCode((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("a1")) { - user.setOrgUserId((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("street")) { - user.setAddress1((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("roomNumber")) { - user.setAddress2((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("l")) { - user.setCity((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("st")) { - user.setState((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("postalCode")) { - user.setZipCode((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("zip4")) { - user.setZipCodeSuffix((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("physicalDeliveryOfficeName")) { - user.setLocationClli((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("bc")) { - user.setBusinessCountryCode((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("friendlyCountryName")) { - user.setBusinessCountryName((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("bd")) { - user.setDepartment((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("bdname")) { - user.setDepartmentName((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("jtname")) { - user.setJobTitle((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("mgrid")) { - user.setOrgManagerUserId((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("a2")) { - user.setCommandChain((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("compcode")) { - user.setCompanyCode((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("compdesc")) { - user.setCompany((String) ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("bu")) { - user.setBusinessUnit((String)ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("buname")) { - user.setBusinessUnitName((String)ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("silo")) { - user.setSiloStatus((String)ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("costcenter")) { - user.setCostCenter((String)ie.next()); - } - else if (attribute.getID().equalsIgnoreCase("b2")) { - user.setFinancialLocCode((String)ie.next()); - } - else { //we don't care about returned attribute, let's move on - ie.next(); - } - - } - } - } - } catch (NamingException e) { - logger.error(EELFLoggerDelegate.errorLogger, "An error occurred while processing the following user from POST with an ORGUSERID of " + user.getOrgUserId() + e.getMessage()); - } finally { - - } - return user; - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LoginService.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LoginService.java deleted file mode 100644 index 113833bf..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LoginService.java +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - - -import java.util.HashMap; - -import org.openecomp.portalsdk.core.command.LoginBean; - - -public interface LoginService { - - // validate user exists in the system - @SuppressWarnings("rawtypes") - LoginBean findUser(LoginBean bean, String menuPropertiesFilename, HashMap additionalParams) throws Exception; - - @SuppressWarnings("rawtypes") - LoginBean findUser(LoginBean bean, String menuPropertiesFilename, HashMap additionalParams, boolean matchPassword) throws Exception; -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LoginServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LoginServiceImpl.java deleted file mode 100644 index 7da427ba..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/LoginServiceImpl.java +++ /dev/null @@ -1,190 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.openecomp.portalsdk.core.command.LoginBean; -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.menu.MenuBuilder; -import org.openecomp.portalsdk.core.service.support.FusionService; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.AppUtils; -import org.openecomp.portalsdk.core.web.support.UserUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("loginService") -@Transactional -public class LoginServiceImpl extends FusionService implements LoginService { - - @SuppressWarnings("unused") - private MenuBuilder menuBuilder; - - @Autowired - private DataAccessService dataAccessService; - - - @SuppressWarnings("rawtypes") - public LoginBean findUser(LoginBean bean, String menuPropertiesFilename, HashMap additionalParams ) throws Exception { - return findUser(bean, menuPropertiesFilename, additionalParams, true); - } - - @SuppressWarnings("rawtypes") - public LoginBean findUser(LoginBean bean, String menuPropertiesFilename, HashMap additionalParams, boolean matchPassword) throws Exception { - User user = null; - User userCopy = null; - - if (bean.getUserid() != null && bean.getUserid() != null) { - user = (User)findUser(bean); - } - else { - if (matchPassword) - user = (User)findUser(bean.getLoginId(), bean.getLoginPwd()); - else - user = (User)findUserWithoutPwd(bean.getLoginId()); - } - - if (user != null) { - - // raise an error if the application is locked and the user does not have system administrator privileges - if (AppUtils.isApplicationLocked() && !UserUtils.hasRole(user, SystemProperties.getProperty(SystemProperties.SYS_ADMIN_ROLE_ID))) { - bean.setLoginErrorMessage(SystemProperties.MESSAGE_KEY_LOGIN_ERROR_APPLICATION_LOCKED); - } - - // raise an error if the user is inactive - if (!user.getActive()) { - bean.setLoginErrorMessage(SystemProperties.MESSAGE_KEY_LOGIN_ERROR_USER_INACTIVE); - } - - if (!userHasActiveRoles(user)) { - bean.setLoginErrorMessage(SystemProperties.MESSAGE_KEY_LOGIN_ERROR_USER_INACTIVE); - } - // only login the user if no errors have occurred - if (bean.getLoginErrorMessage() == null) { - - // this will be a snapshot of the user's information as retrieved from the database - userCopy = (User)user.clone(); - - // update the last logged in date for the user - user.setLastLoginDate(new Date()); - getDataAccessService().saveDomainObject(user, additionalParams); - - // update the audit log of the user - //Check for the client device type and set log attributes appropriately - - // save the above changes to the User and their audit trail - - // create the application menu based on the user's privileges - Set appMenu = getMenuBuilder().getMenu(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_SET_NAME),dataAccessService); - bean.setMenu(appMenu != null?appMenu:new HashSet()); - Set businessDirectMenu = getMenuBuilder().getMenu(SystemProperties.getProperty(SystemProperties.BUSINESS_DIRECT_MENU_SET_NAME),dataAccessService); - bean.setBusinessDirectMenu(businessDirectMenu != null?businessDirectMenu:new HashSet()); - - bean.setUser(userCopy); - } - - } - - return bean; - } - - @SuppressWarnings("rawtypes") - private boolean userHasActiveRoles(User user) { - boolean hasActiveRole = false; - Iterator roles = user.getRoles().iterator(); - while (roles.hasNext()) { - Role role = (Role)roles.next(); - if (role.getActive()) { - hasActiveRole = true; - break; - } - } - return hasActiveRole; - } - - - @SuppressWarnings("rawtypes") - public User findUser(String loginId, String password) { - List list = null; - - StringBuffer criteria = new StringBuffer(); - criteria.append(" where login_id = '").append(loginId).append("'") - .append(" and login_pwd = '").append(password).append("'"); - - list = getDataAccessService().getList(User.class, criteria.toString(), null, null); - - return (list == null || list.size() == 0) ? null : (User)list.get(0); - } - - @SuppressWarnings("rawtypes") - private User findUserWithoutPwd(String loginId) { - List list = null; - - StringBuffer criteria = new StringBuffer(); - criteria.append(" where login_id = '").append(loginId).append("'"); - - list = getDataAccessService().getList(User.class, criteria.toString(), null, null); - - return (list == null || list.size() == 0) ? null : (User)list.get(0); - } - - - @SuppressWarnings("rawtypes") - public User findUser(LoginBean bean) { - List list = null; - - StringBuffer criteria = new StringBuffer(); - criteria.append(" where org_user_id = '").append(bean.getUserid()).append("'"); - - list = getDataAccessService().getList(User.class, criteria.toString(), null, null); - - return (list == null || list.size() == 0) ? null : (User)list.get(0); - } - - - public MenuBuilder getMenuBuilder() { - return new MenuBuilder(); - } - - - public void setMenuBuilder(MenuBuilder menuBuilder) { - this.menuBuilder = menuBuilder; - } - - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsServiceImpl.java deleted file mode 100644 index 726d8973..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostDroolsServiceImpl.java +++ /dev/null @@ -1,179 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.io.File; -import java.io.IOException; -import java.nio.file.DirectoryIteratorException; -import java.nio.file.DirectoryStream; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.kie.api.io.ResourceType; -import org.kie.internal.KnowledgeBase; -import org.kie.internal.KnowledgeBaseFactory; -import org.kie.internal.builder.KnowledgeBuilder; -import org.kie.internal.builder.KnowledgeBuilderFactory; -import org.kie.internal.definition.KnowledgePackage; -import org.kie.internal.io.ResourceFactory; -import org.kie.internal.runtime.StatefulKnowledgeSession; -import org.openecomp.portalsdk.core.command.PostDroolsBean; -import org.openecomp.portalsdk.core.drools.DroolsRuleService; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.fasterxml.jackson.databind.ObjectMapper; - - -@Service("postDroolsService") -@Transactional -public class PostDroolsServiceImpl implements PostDroolsService{ - - static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PostDroolsServiceImpl.class); - - @Override - public String execute(String droolsFile, String className, String selectedRules) { - logger.info(EELFLoggerDelegate.applicationLogger, "Executing Drools..."); - String resultsString = executeDemoRules(droolsFile, className, selectedRules); - return resultsString; - } - - - public List fetchDroolBeans() { - - List beanList = new ArrayList(); - Path path = FileSystems.getDefault().getPath(SystemProperties.getProperty(SystemProperties.FILES_PATH)); - try (DirectoryStream stream = Files.newDirectoryStream(path,"*.{drl}")) { - for (Path entry: stream) { - - PostDroolsBean postDroolsBean = new PostDroolsBean(); - String fileName = entry.getName(entry.getNameCount()-1).toString(); - postDroolsBean.setDroolsFile(fileName);//sample populated - postDroolsBean.setClassName(retrieveClass(fileName)); - //postDroolsBean.setSelectedRules("[\"NJ\",\"NY\",\"KY\"]"); - beanList.add(postDroolsBean); - } - } catch (DirectoryIteratorException ex) { - logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage()); - } catch (IOException e) { - logger.error(EELFLoggerDelegate.errorLogger, e.getMessage()); - } - return beanList; - } - - @Override - public String retrieveClass(String fileName) { - String resultsString = ""; - try { - // load up the knowledge base - final KnowledgeBuilder kbuilder = loadKBuilder(fileName); - final Collection pkgs = kbuilder.getKnowledgePackages(); - return pkgs.iterator().next().getFactTypes().iterator().next().getFactClass().getName(); - - } catch (Throwable t) { - logger.error(EELFLoggerDelegate.errorLogger, t.getMessage()); - } - - return resultsString; - } - - protected static KnowledgeBuilder loadKBuilder(String fileName) { - final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); - - // this will parse and compile in one step - kbuilder.add(ResourceFactory.newFileResource(SystemProperties.getProperty(SystemProperties.FILES_PATH) + File.separator + fileName), - ResourceType.DRL); - - if (kbuilder.hasErrors()) { - - logger.error(EELFLoggerDelegate.errorLogger, kbuilder.getErrors().toString()); - - throw new RuntimeException("Unable to compile \".drl\"."); - - } - return kbuilder; - } - - - @SuppressWarnings({ "deprecation", "unchecked" }) - public static String executeDemoRules(String fileName, String className, String ruleValue) { - String resultsString = ""; - try { - // load up the knowledge base - // KieServices ks = KieServices.Factory.get(); - // KieContainer kContainer = ks.getKieClasspathContainer(); - // KieSession kSession = kContainer.newKieSession("ksession-rules"); - - final KnowledgeBuilder kbuilder = loadKBuilder(fileName); - - // get the compiled packages (which are serializable) - - final Collection pkgs = kbuilder.getKnowledgePackages(); - - // add the packages to a knowledgebase (deploy the knowledge - // packages). - - final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); - - kbase.addKnowledgePackages(pkgs); - - final StatefulKnowledgeSession kSession = kbase.newStatefulKnowledgeSession(); - - ObjectMapper mapper = new ObjectMapper(); - if(ruleValue == null || ruleValue.equals("")) { - resultsString = "Please enter valid rule"; - return resultsString; - } - List selectedRules = mapper.readValue(ruleValue, List.class); - List ruleResponse = new ArrayList(); - - for(String rule : selectedRules){ - Class clazz = (Class) Class.forName(className); - DroolsRuleService droolsIntroduction =clazz.newInstance(); - droolsIntroduction.init(rule); - kSession.insert(droolsIntroduction); - kSession.fireAllRules(); - ruleResponse.add(droolsIntroduction.getResultsString()); - } - - resultsString = mapper.writeValueAsString(ruleResponse); - -// kSession.insert(new DroolsRuleService("KY")); -// kSession.fireAllRules(); -// -// kSession.setGlobal("age", "25"); -// kSession.insert(new DroolsRuleService("NY")); -// kSession.fireAllRules(); - } catch (Throwable t) { - logger.error(EELFLoggerDelegate.errorLogger, t.getMessage()); - } - - return resultsString; - } - - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostSearchService.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostSearchService.java deleted file mode 100644 index 55c9db3f..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostSearchService.java +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.command.PostSearchBean; - -public interface PostSearchService { - - void process(HttpServletRequest request, PostSearchBean postSearch); - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostSearchServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostSearchServiceImpl.java deleted file mode 100644 index 2ecedbea..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/PostSearchServiceImpl.java +++ /dev/null @@ -1,203 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.FusionObject.Parameters; -import org.openecomp.portalsdk.core.command.PostSearchBean; -import org.openecomp.portalsdk.core.domain.Lookup; -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.openecomp.portalsdk.core.web.support.FeedbackMessage; -import org.openecomp.portalsdk.core.web.support.MessagesList; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("postSearchService") -@Transactional -public class PostSearchServiceImpl implements PostSearchService{ - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PostSearchServiceImpl.class); - - @Autowired - private DataAccessService dataAccessService; - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void process(HttpServletRequest request, PostSearchBean postSearch) { - HashMap additionalParams = new HashMap(); - additionalParams.put(Parameters.PARAM_HTTP_REQUEST, request); - - if (postSearch.getSelected() != null) { - //sort the selected users for quick validation - - Arrays.sort(postSearch.getSelected()); - System.out.println("list - " + postSearch.getPostOrgUserId().length); - // import the users that have been selected - for(int i=0; i < postSearch.getPostOrgUserId().length; i++){ - if (Arrays.binarySearch(postSearch.getSelected(), postSearch.getPostOrgUserId()[i]) >= 0) { - logger.info(EELFLoggerDelegate.debugLogger, "Adding ORGUSERID - " + postSearch.getPostOrgUserId()[i]); - logger.info(EELFLoggerDelegate.auditLogger, "Import new user from webphone " + postSearch.getPostOrgUserId()[i]); - - User user = new User(); - user.setLastName(postSearch.getPostLastName()[i]); - user.setFirstName(postSearch.getPostFirstName()[i]); - - if (postSearch.getPostHrid() != null && postSearch.getPostHrid().length > 0) { - user.setHrid(postSearch.getPostHrid()[i]); - } - - if (postSearch.getPostPhone() != null && postSearch.getPostPhone().length > 0) { - user.setPhone(postSearch.getPostPhone()[i]); - } - - if (postSearch.getPostEmail() != null && postSearch.getPostEmail().length > 0) { - user.setEmail(postSearch.getPostEmail()[i]); - } - - if (postSearch.getPostOrgUserId() != null && postSearch.getPostOrgUserId().length > 0) { - user.setOrgUserId(postSearch.getPostOrgUserId()[i]); - user.setLoginId(postSearch.getPostOrgUserId()[i]); - } - - if (postSearch.getPostAddress1() != null && postSearch.getPostAddress1().length > 0) { - user.setAddress1(postSearch.getPostAddress1()[i]); - } - - if (postSearch.getPostAddress2() != null && postSearch.getPostAddress2().length > 0) { - user.setAddress2(postSearch.getPostAddress2()[i]); - } - - if (postSearch.getPostCity() != null && postSearch.getPostCity().length > 0) { - user.setCity(postSearch.getPostCity()[i]); - } - - if (postSearch.getPostState() != null && postSearch.getPostState().length > 0) { - user.setState(postSearch.getPostState()[i]); - } - - if (postSearch.getPostZipCode() != null && postSearch.getPostZipCode().length > 0) { - user.setZipCode(postSearch.getPostZipCode()[i]); - } - - if (postSearch.getPostLocationClli() != null && postSearch.getPostLocationClli().length > 0) { - user.setLocationClli(postSearch.getPostLocationClli()[i]); - } - - if (postSearch.getPostBusinessCountryCode() != null && postSearch.getPostBusinessCountryCode().length > 0) { - user.setBusinessCountryCode(postSearch.getPostBusinessCountryCode()[i]); - } - - if (postSearch.getPostBusinessCountryName() != null && postSearch.getPostBusinessCountryName().length > 0) { - - // find the country cd for the indicated country - List countries = dataAccessService.getLookupList("fn_lu_country", "country_cd", "country", "country = '" - + postSearch.getPostBusinessCountryName()[i] + "'", null, null); - - if (countries!=null&&countries.size() == 1) { - Lookup country = (Lookup)countries.get(0); - user.setCountry(country.getValue()); - } - else { - logger.info(EELFLoggerDelegate.debugLogger, "No countries or more than one country was found matching the country returned from WEBPHONE. " + - "Therefore, no country was set for this user."); - } - - } - - if (postSearch.getPostDepartment() != null && postSearch.getPostDepartment().length > 0) { - user.setDepartment(postSearch.getPostDepartment()[i]); - } - - if (postSearch.getPostDepartmentName() != null && postSearch.getPostDepartmentName().length > 0) { - user.setDepartmentName(postSearch.getPostDepartmentName()[i]); - } - - if (postSearch.getPostBusinessUnit() != null && postSearch.getPostBusinessUnit().length > 0) { - user.setBusinessUnit(postSearch.getPostBusinessUnit()[i]); - } - - if (postSearch.getPostBusinessUnitName() != null && postSearch.getPostBusinessUnitName().length > 0) { - user.setBusinessUnitName(postSearch.getPostBusinessUnitName()[i]); - } - - if (postSearch.getPostJobTitle() != null && postSearch.getPostJobTitle().length > 0) { - user.setJobTitle(postSearch.getPostJobTitle()[i]); - } - - if (postSearch.getPostOrgManagerUserId() != null && postSearch.getPostOrgManagerUserId().length > 0) { - user.setOrgManagerUserId(postSearch.getPostOrgManagerUserId()[i]); - } - - if (postSearch.getPostCommandChain() != null && postSearch.getPostCommandChain().length > 0) { - user.setCommandChain(postSearch.getPostCommandChain()[i]); - } - - if (postSearch.getPostCompanyCode() != null && postSearch.getPostCompanyCode().length > 0) { - user.setCompanyCode(postSearch.getPostCompanyCode()[i]); - } - - if (postSearch.getPostCompany() != null && postSearch.getPostCompany().length > 0) { - user.setCompany(postSearch.getPostCompany()[i]); - } - - if (postSearch.getPostCostCenter() != null && postSearch.getPostCostCenter().length > 0) { - user.setCostCenter(postSearch.getPostCostCenter()[i]); - } - - if (postSearch.getPostSiloStatus() != null && postSearch.getPostSiloStatus().length > 0) { - user.setSiloStatus(postSearch.getPostSiloStatus()[i]); - } - - if (postSearch.getPostFinancialLocCode() != null && postSearch.getPostFinancialLocCode().length > 0) { - user.setFinancialLocCode(postSearch.getPostFinancialLocCode()[i]); - } - - user.setActive(true); - - try { - dataAccessService.saveDomainObject(user, additionalParams); - - Role role = (Role)dataAccessService.getDomainObject(Role.class,Long.valueOf(SystemProperties.getProperty(SystemProperties.POST_DEFAULT_ROLE_ID)), null); - user.addRole(role); - } - catch (Exception e) { - MessagesList messages = new MessagesList(); - messages.addExceptionMessage(new FeedbackMessage("An error occurred while attempting to import " + user.getFirstName() + " " - + user.getLastName() + ": " + e.getMessage(), FeedbackMessage.MESSAGE_TYPE_ERROR)); - - } - } - } - - } - - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ProfileServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ProfileServiceImpl.java deleted file mode 100644 index 3927d727..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/ProfileServiceImpl.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.List; - -import org.openecomp.portalsdk.core.dao.ProfileDao; -import org.openecomp.portalsdk.core.domain.Profile; -import org.openecomp.portalsdk.core.domain.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("profileService") -@Transactional -public class ProfileServiceImpl implements ProfileService{ - - @Autowired - private ProfileDao profileDao; - - @Autowired - private DataAccessService dataAccessService; - - @SuppressWarnings("unchecked") - public List findAll() { - return getDataAccessService().getList(Profile.class, null); - } - - public User getUser(String userId){ - return (User) getDataAccessService().getDomainObject(User.class, Long.parseLong(userId), null); - } - - public void saveUser(User user){ - - getDataAccessService().saveDomainObject(user, null); - } - - - public Profile getProfile(int id) { - return profileDao.getProfile(id); - } - - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceImpl.java deleted file mode 100644 index e71e0c58..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceImpl.java +++ /dev/null @@ -1,171 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -import javax.sql.DataSource; - -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.domain.RoleFunction; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("roleService") -@Transactional -public class RoleServiceImpl implements RoleService{ - - @Autowired - private DataAccessService dataAccessService; - - DataSource dataSource; - - public DataSource getDataSource() { - return dataSource; - } - - - @Autowired - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - - @SuppressWarnings("unchecked") - public List getRoleFunctions() { - //List msgDB = getDataAccessService().getList(Profile.class, null); - return getDataAccessService().getList(RoleFunction.class, null); - } - - @SuppressWarnings("unchecked") - public List getAvailableChildRoles(Long roleId) { - List availableChildRoles = (List)getDataAccessService().getList(Role.class,null); - if(roleId==null || roleId==0){ - return availableChildRoles; - } - - Role currentRole = (Role)getDataAccessService().getDomainObject(Role.class,roleId,null); - Set allParentRoles = new TreeSet(); - allParentRoles = getAllParentRolesAsList(currentRole, allParentRoles); - - - Iterator availableChildRolesIterator = availableChildRoles.iterator(); - while (availableChildRolesIterator.hasNext()) { - Role role = availableChildRolesIterator.next(); - if(!role.getActive() || allParentRoles.contains(role) || role.getId().equals(roleId)){ - availableChildRolesIterator.remove(); - } - } - return availableChildRoles; - } - - @SuppressWarnings("unchecked") - private Set getAllParentRolesAsList(Role role, Set allParentRoles) { - Set parentRoles = role.getParentRoles(); - allParentRoles.addAll(parentRoles); - Iterator parentRolesIterator = parentRoles.iterator(); - while (parentRolesIterator.hasNext()) { - getAllParentRolesAsList(parentRolesIterator.next(),allParentRoles); - } - return allParentRoles; - } - - public RoleFunction getRoleFunction(String code) { - return (RoleFunction)getDataAccessService().getDomainObject(RoleFunction.class, code, null); - } - - public void saveRoleFunction(RoleFunction domainRoleFunction) { - getDataAccessService().saveDomainObject(domainRoleFunction, null); - } - - public void deleteRoleFunction(RoleFunction domainRoleFunction) { - getDataAccessService().deleteDomainObject(domainRoleFunction, null); - } - - public Role getRole(Long id) { - return (Role)getDataAccessService().getDomainObject(Role.class, id, null); - } - - public void saveRole(Role domainRole) { - getDataAccessService().saveDomainObject(domainRole, null); - } - - public void deleteRole(Role domainRole) { - getDataAccessService().deleteDomainObject(domainRole, null); - } - - @SuppressWarnings("unchecked") - public List getAvailableRoles() { - return getDataAccessService().getList(Role.class, null); - } - - @SuppressWarnings("unchecked") - @Override - public List getActiveRoles() { - String filter = " where active_yn = 'Y' "; - return getDataAccessService().getList(Role.class, filter, null,null); - } - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - @Override - public void deleteDependcyRoleRecord(Long id) { - - Connection conn = null; - Statement stmt = null; - - try { - conn = getDataSource().getConnection(); - stmt = conn.createStatement(); - String sql = "delete from fn_user_role where role_id = '" + id + "'"; - stmt.executeUpdate(sql); - stmt.close(); - conn.close(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (stmt != null) - stmt.close(); - } catch (SQLException se2) {} - try { - if (conn != null) - conn.close(); - } catch (SQLException se) { se.printStackTrace();} - } - - } - - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceNonSpringImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceNonSpringImpl.java deleted file mode 100644 index bd6796c1..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/RoleServiceNonSpringImpl.java +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; -/*package org.openecomp.portalsdk.core.service; - -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.domain.RoleFunction; - -@Service("roleService") -@Transactional -public class RoleServiceNonSpringImpl implements RoleService{ - - @Autowired - private DataAccessService dataAccessService; - - @SuppressWarnings("unchecked") - public List getRoleFunctions() { - //List msgDB = getDataAccessService().getList(Profile.class, null); - return getDataAccessService().getList(RoleFunction.class, null); - } - - @SuppressWarnings("unchecked") - public List getAvailableChildRoles(Long roleId) { - List availableChildRoles = (List)getDataAccessService().getList(Role.class,null); - if(roleId==null || roleId==0){ - return availableChildRoles; - } - - Role currentRole = (Role)getDataAccessService().getDomainObject(Role.class,roleId,null); - Set allParentRoles = new TreeSet(); - allParentRoles = getAllParentRolesAsList(currentRole, allParentRoles); - - - Iterator availableChildRolesIterator = availableChildRoles.iterator(); - while (availableChildRolesIterator.hasNext()) { - Role role = availableChildRolesIterator.next(); - if(!role.getActive() || allParentRoles.contains(role) || role.getId().equals(roleId)){ - availableChildRolesIterator.remove(); - } - } - return availableChildRoles; - } - - @SuppressWarnings("unchecked") - private Set getAllParentRolesAsList(Role role, Set allParentRoles) { - Set parentRoles = role.getParentRoles(); - allParentRoles.addAll(parentRoles); - Iterator parentRolesIterator = parentRoles.iterator(); - while (parentRolesIterator.hasNext()) { - getAllParentRolesAsList(parentRolesIterator.next(),allParentRoles); - } - return allParentRoles; - } - - public RoleFunction getRoleFunction(String code) { - return (RoleFunction)getDataAccessService().getDomainObject(RoleFunction.class, code, null); - } - - public void saveRoleFunction(RoleFunction domainRoleFunction) { - getDataAccessService().saveDomainObject(domainRoleFunction, null); - } - - public void deleteRoleFunction(RoleFunction domainRoleFunction) { - getDataAccessService().deleteDomainObject(domainRoleFunction, null); - } - - public Role getRole(Long id) { - return (Role)getDataAccessService().getDomainObject(Role.class, id, null); - } - - public void saveRole(Role domainRole) { - getDataAccessService().saveDomainObject(domainRole, null); - } - - public void deleteRole(Role domainRole) { - getDataAccessService().deleteDomainObject(domainRole, null); - } - - @SuppressWarnings("unchecked") - public List getAvailableRoles() { - return getDataAccessService().getList(Role.class, null); - } - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - - -} -*/ diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/UserProfileService.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/UserProfileService.java deleted file mode 100644 index 0cf3986b..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/UserProfileService.java +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.List; - -import org.openecomp.portalsdk.core.domain.User; - - -public interface UserProfileService { - List findAll(); - User getUser(String id); - User getUserByLoginId(String loginId); - void saveUser(User user); - public List findAllUserWithOnOffline(String originOrgUserId); - List findAllActive(); - List searchPost(User user, String sortBy1, String sortBy2, String sortBy3, int pageNo, int newDataSize, - int intValue); -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/UserProfileServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/UserProfileServiceImpl.java deleted file mode 100644 index e0899917..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/UserProfileServiceImpl.java +++ /dev/null @@ -1,210 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.SortedSet; - -import org.hibernate.criterion.Criterion; -import org.hibernate.criterion.Restrictions; -import org.json.JSONArray; -import org.json.JSONObject; -import org.openecomp.portalsdk.core.FusionObject.Utilities; -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.domain.support.CollaborateList; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("userProfileService") -@Transactional -public class UserProfileServiceImpl implements UserProfileService{ - - - @Autowired - private DataAccessService dataAccessService; - - @SuppressWarnings("unchecked") - public List findAll() { - return getDataAccessService().getList(User.class, null); - } - - public User getUser(String userId){ - return (User) getDataAccessService().getDomainObject(User.class, Long.parseLong(userId), null); - } - - @SuppressWarnings("unchecked") - public User getUserByLoginId(String loginId){ - User user=null; - List restrictionsList = new ArrayList(); - Criterion criterion1= Restrictions.eq("loginId",loginId); - restrictionsList.add(criterion1); - List users = (List) getDataAccessService().getList(User.class,null, restrictionsList, null); - if(users!=null && users.size()==1) - user = users.get(0); - return user; - } - - public void saveUser(User user){ - - getDataAccessService().saveDomainObject(user, null); - } - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - @SuppressWarnings("unchecked") - public List findAllUserWithOnOffline(String originOrgUserId) { - HashSet onlineUser = CollaborateList.getInstance().getAllUserName(); - List users = getDataAccessService().getList(User.class, null); - for(User u:users){ - if(onlineUser.contains(u.getOrgUserId())) - u.setOnline(true); - if(u.getOrgUserId()!=null){ - if(originOrgUserId.compareTo(u.getOrgUserId()) > 0) { - u.setChatId(originOrgUserId + "-" + u.getOrgUserId()); - } else u.setChatId(u.getOrgUserId() + "-" + originOrgUserId ); - } - } - return users; - - } - - @SuppressWarnings("unchecked") - public List findAllActive() { - List users = getDataAccessService().getList(User.class, null); - Iterator itr = users.iterator(); - while(itr.hasNext()){ - User u = (User) itr.next(); - if(!u.getActive()) - itr.remove();//if not active remove user from list - else { - SortedSet roles = u.getRoles(); - Iterator itrRoles = roles.iterator(); - while(itrRoles.hasNext()){ - Role role = (Role) itrRoles.next(); - if(!role.getActive()) - u.removeRole(role.getId());//if not active remove role from list - } - } - } - return users; - } - - - @Override - public List searchPost(User user, String sortBy1, String sortBy2, String sortBy3, int pageNo, - int newDataSize, int intValue) { - - List users=new ArrayList(); - List filterdUsers=new ArrayList(); - BufferedReader in = null; - - try{ - String url = SystemProperties.getProperty(SystemProperties.AUTH_USER_SERVER); - URL obj = new URL(url); - - HttpURLConnection con = (HttpURLConnection) obj.openConnection(); - - // optional default is GET - con.setRequestMethod("GET"); - con.setConnectTimeout(3000); - con.setReadTimeout(8000); - - StringBuffer response = new StringBuffer(); - - - - in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); - String inputLine; - while ((inputLine = in.readLine()) != null) - response.append(inputLine); - - JSONObject jObject = new JSONObject(response.toString()); // json - JSONArray jsonUsers = jObject.getJSONArray("response"); // get data object - for (int i = 0; i < jsonUsers.length(); i++) { - JSONObject eachObject = jsonUsers.getJSONObject(i); - User eachUser = new User(); - eachUser.setOrgUserId(eachObject.get("id").toString());// getString("id")); - eachUser.setFirstName(eachObject.get("givenName").toString()); - eachUser.setLastName(eachObject.get("familyName").toString()); - eachUser.setEmail(eachObject.get("email").toString()); - - users.add(eachUser); - } - - for(int i = 0 ; i < users.size(); i ++){ - - if(Utilities.nvl(user.getFirstName()).length() > 0){ - if(!user.getFirstName().equalsIgnoreCase(users.get(i).getFirstName())){ - continue; - } - } - if(Utilities.nvl(user.getLastName()).length() > 0){ - if(!user.getLastName().equalsIgnoreCase(users.get(i).getLastName())){ - continue; - } - } - if(Utilities.nvl(user.getOrgUserId()).length() > 0){ - if(!user.getOrgUserId().equalsIgnoreCase(users.get(i).getOrgUserId())){ - continue; - } - } - if(Utilities.nvl(user.getEmail()).length() > 0){ - if(!user.getEmail().equalsIgnoreCase(users.get(i).getEmail())){ - continue; - } - } - - filterdUsers.add(users.get(i)); - - } - - }catch (Exception e){ - - }finally{ - try { - in.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - return filterdUsers; - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallServiceImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallServiceImpl.java deleted file mode 100644 index 3e1a1a40..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/WebServiceCallServiceImpl.java +++ /dev/null @@ -1,189 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service; - -import java.util.List; - -import org.openecomp.portalsdk.core.domain.App; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.util.CipherUtil; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("webServiceCallService") -@Transactional -public class WebServiceCallServiceImpl implements WebServiceCallService{ - - @Autowired - private DataAccessService dataAccessService; - - @Autowired - AppService appService; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(WebServiceCallServiceImpl.class); - - /** - * Verify REST Credential - * @return true if the credential is accepted; else false. - */ - @Override - public boolean verifyRESTCredential(String secretKey, String requestAppName, String requestPassword)throws Exception { - App app = appService.getDefaultApp(); - if (app!=null) { - String encriptedPwdDB = app.getAppPassword(); - String appUserName = app.getUsername(); - String decreptedPwd = CipherUtil.decrypt(encriptedPwdDB, secretKey==null?SystemProperties.getProperty(SystemProperties.Decryption_Key):secretKey); - if(decreptedPwd.equals(requestPassword) && appUserName.equals(requestAppName)) { - return true; - } - } - return false; - } - - /** - * Getting App information from FN_APP table - * @return App domain object, or null if not found. - */ - public App findApp(){ - List list = null; - StringBuffer criteria = new StringBuffer(); - criteria.append(" where id = 1"); - list = getDataAccessService().getList(App.class, criteria.toString(), null, null); - return (list == null || list.size() == 0) ? null : (App) list.get(0); - } - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - /*/ - @Override - public String get(String restURL, String restPath) { - String appUserName = ""; - String appUebKey = ""; - String decreptedPwd = ""; - String appName = ""; - String inputLine = ""; - String serviceName = ""; - String loginId = ""; - StringBuffer jsonResponse = new StringBuffer(); - - StopWatch stopWatch = new StopWatch("WebServiceCallServiceImpl.get"); - stopWatch.start(); - try { - logger.info(EELFLoggerDelegate.metricsLogger, "WebServiceCallServiceImpl.get (" + restPath + ") operation is started."); - logger.debug(EELFLoggerDelegate.debugLogger, "WebServiceCallServiceImpl.get (" + restPath + ") operation is started."); - loginId = MDC.get("LoginId"); - appUebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); - App app = appService.getDefaultApp(); - if (app!=null) { - appName = app.getName(); - appUserName = app.getUsername(); - try{ - decreptedPwd = CipherUtil.decrypt(app.getAppPassword(), SystemProperties.getProperty(SystemProperties.Decryption_Key)); - } catch(Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred in WebServiceCallServiceImpl.get while decrypting the password. Details: " + e.getMessage()); - } - } else { - logger.warn(EELFLoggerDelegate.errorLogger, "Unable to locate the app information from the database."); - appName = SystemProperties.SERVICE_NAME; - } - - //Create the connection object - URL obj = new URL(restURL + restPath); - HttpURLConnection con = (HttpURLConnection) obj.openConnection(); - con.setRequestMethod("GET"); - con.setConnectTimeout(3000); - con.setReadTimeout(8000); - - //add request header - con.setRequestProperty("username", appUserName); - con.setRequestProperty("password", decreptedPwd); - con.setRequestProperty("uebkey", appUebKey); - con.setRequestProperty(SystemProperties.LOGIN_ID, loginId); - con.setRequestProperty(SystemProperties.USERAGENT_NAME, appName); - con.setRequestProperty(SystemProperties.ECOMP_REQUEST_ID, MDC.get(MDC_KEY_REQUEST_ID)); - - //set MDC context for outgoing audit logging - serviceName = String.format("%s:%s.%s", appName, SystemProperties.ECOMP_PORTAL_BE, restPath); - MDC.put(Configuration.MDC_SERVICE_NAME, serviceName); - MDC.put(Configuration.MDC_REMOTE_HOST, restURL); - MDC.put(SystemProperties.MDC_APPNAME, appName); - MDC.put(SystemProperties.MDC_REST_PATH, restPath); - MDC.put(SystemProperties.MDC_REST_METHOD, "GET"); - - int responseCode = con.getResponseCode(); - logger.info(EELFLoggerDelegate.errorLogger, "Received the response code '" + responseCode + "' while getting the '" + restPath + "' for user: " + loginId); - - BufferedReader in = new BufferedReader( - new InputStreamReader(con.getInputStream())); - - while ((inputLine = in.readLine()) != null) { - jsonResponse.append(inputLine); - } - in.close(); - - logSecurityMessage(RESULT_ENUM.SUCCESS); - logger.debug(EELFLoggerDelegate.debugLogger, restPath + " response: " + jsonResponse.toString()); - logger.debug(EELFLoggerDelegate.debugLogger, "WebServiceCallServiceImpl.get (" + restPath + ") operation is started."); - } catch(UrlAccessRestrictedException e) { - logger.error(EELFLoggerDelegate.errorLogger, "Authentication exception occurred in WebServiceCallServiceImpl.get (" + restPath + "). Details: " + e.getMessage()); - logSecurityMessage(RESULT_ENUM.FAILURE); - } catch(Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred in WebServiceCallServiceImpl.get (" + restPath + "). Details: " + e.getMessage()); - logSecurityMessage(RESULT_ENUM.FAILURE); - } finally { - if (stopWatch.isRunning()) stopWatch.stop(); - MDC.put(SystemProperties.MDC_TIMER, stopWatch.getTotalTimeMillis() + "ms"); - logger.info(EELFLoggerDelegate.metricsLogger, "WebServiceCallServiceImpl.get (" + restPath + ") operation is completed."); - - //clear the temporary MDC context values - MDC.remove(SystemProperties.MDC_TIMER); - MDC.remove(SystemProperties.MDC_REST_METHOD); - MDC.remove(SystemProperties.MDC_REST_PATH); - MDC.remove(SystemProperties.MDC_APPNAME); - MDC.remove(Configuration.MDC_REMOTE_HOST); - MDC.remove(Configuration.MDC_SERVICE_NAME); - } - - return jsonResponse.toString(); - } - - //Handles all the outgoing rest/ueb messages. - public void logSecurityMessage(RESULT_ENUM isSuccess) { - String additionalInfo = ""; - String protocol = "HTTP"; - String loginId = MDC.get("LoginId"); - additionalInfo = String.format("Rest API=%s, Rest Method=%s, App-Name=%s, Request-URL=%s", - MDC.get(SystemProperties.MDC_REST_PATH), MDC.get(SystemProperties.MDC_REST_METHOD), - MDC.get(SystemProperties.MDC_APPNAME), MDC.get(Configuration.MDC_REMOTE_HOST)); - - logger.info(EELFLoggerDelegate.auditLogger, AuditLogFormatter.getInstance().createMessage( - protocol, SecurityEventTypeEnum.OUTGOING_REST_MESSAGE.name(), loginId, SystemProperties.SERVICE_NAME, - isSuccess.name(), additionalInfo)); - } - /**/ -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocatorImpl.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocatorImpl.java deleted file mode 100644 index e7437835..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/service/support/ServiceLocatorImpl.java +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.service.support; - -import java.util.Properties; - -import javax.naming.Context; -import javax.naming.NamingException; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; -import javax.naming.ldap.InitialLdapContext; - -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.springframework.stereotype.Service; - -/** - * This class implements the J2EE service locator pattern. It provides lookup - * facilities for various services. Currenttly LDAP (pre-v3) is supported - */ -@Service("serviceLocator") -public class ServiceLocatorImpl implements ServiceLocator { - - private Context context; // JNDI context (not currently in use) - private Context rootContext; // Java env root context (not currently in use) - private DirContext dirContext; // LDAP DIR context - private InitialLdapContext ldapContext; // LDAP context LDAPv3-style (not currently in use) - - - // cannot directly instantiate - public ServiceLocatorImpl() {} - - // Get an LDAP directory context - public DirContext getDirContext(String initialContextFactory, String providerUrl, String securityPrincipal) { - - if (dirContext == null) { - - Properties properties = new Properties(); - properties.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory); - properties.put(Context.PROVIDER_URL, providerUrl); - properties.put(Context.SECURITY_PRINCIPAL, securityPrincipal); - - try { - dirContext = new InitialDirContext(properties); - } - catch (NamingException ne) { - logger.error(EELFLoggerDelegate.errorLogger, "An error has occurred while creating an Initial Directory Context: " + ne.getMessage()); - logger.error(EELFLoggerDelegate.errorLogger, "Explanation: " + ne.getExplanation()); - } - } - - return dirContext; - } - - /** Logger for this class and subclasses */ - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ServiceLocatorImpl.class); - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/CipherUtil.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/CipherUtil.java deleted file mode 100644 index 0eec9295..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/CipherUtil.java +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.util; - -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.binary.Base64; - -public class CipherUtil { - - private final static String key = "AGLDdG4D04BKm2IxIWEr8o==!"; - - /** - * @param plainText - * @param secretKey - * @return encrypted version of plain text. - * @throws Exception - */ - public static String encrypt(String plainText, String secretKey) throws Exception{ - byte[] rawKey; - String encryptedString; - SecretKeySpec sKeySpec; - byte[] encryptText = plainText.getBytes("UTF-8"); - Cipher cipher; - rawKey = Base64.decodeBase64(secretKey); - sKeySpec = new SecretKeySpec(rawKey, "AES"); - cipher = Cipher.getInstance("AES"); - cipher.init(Cipher.ENCRYPT_MODE, sKeySpec); - encryptedString = Base64.encodeBase64String(cipher.doFinal(encryptText)); - - return encryptedString; - } - - /** - * - * @param plainText - * @return Encrypted Text - * @throws Exception - */ - public static String encrypt(String plainText) throws Exception - { - return CipherUtil.encrypt(plainText,key); - } - - /** - * @param encryptedText - * @param secretKey - * @return plain text version of encrypted text - * @throws Exception - */ - public static String decrypt(String encryptedText, String secretKey) throws Exception { - Cipher cipher; - String encryptedString; - byte[] encryptText = null; - byte[] rawKey; - SecretKeySpec sKeySpec; - - rawKey = Base64.decodeBase64(secretKey); - sKeySpec = new SecretKeySpec(rawKey, "AES"); - encryptText = Base64.decodeBase64(encryptedText.getBytes("UTF-8")); - cipher = Cipher.getInstance("AES"); - cipher.init(Cipher.DECRYPT_MODE, sKeySpec); - encryptedString = new String(cipher.doFinal(encryptText)); - - return encryptedString; - } - - /** - * @param encryptedText - * @return Decrypted Text - * @throws Exception - */ - public static String decrypt(String encryptedText) throws Exception - { - return CipherUtil.decrypt(encryptedText,key); - } - - - public static void main(String[] args) throws Exception { - - String password = "Welcome123"; - String encrypted; - String decrypted; - - if (args.length != 2) { - System.out.println("Default password testing... "); - System.out.println("Plain password: " + password); - encrypted = encrypt(password); - System.out.println("Encrypted password: " + encrypted); - decrypted = decrypt(encrypted); - System.out.println("Decrypted password: " + decrypted); - } else { - String whatToDo = args[0]; - if (whatToDo.equalsIgnoreCase("d")) { - encrypted = args[1]; - System.out.println("Encrypted Text: " + encrypted); - decrypted = decrypt(encrypted); - System.out.println("Decrypted Text: " + decrypted); - } else { - decrypted = args[1]; - System.out.println("Plain Text: " + decrypted); - encrypted = encrypt(decrypted); - System.out.println("Encrypted Text" + encrypted); - } - } - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/EncDecUtilTest.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/EncDecUtilTest.java deleted file mode 100644 index 46a24533..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/EncDecUtilTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.util; -import java.security.AlgorithmParameters; -import java.security.SecureRandom; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.PBEKeySpec; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.binary.Base64; - -public class EncDecUtilTest { - - private static final String password = "test"; - private static final String salt = "r n�HN~��|f��X�" ; - private static int pswdIterations = 65536 ; - private static int keySize = 256; - private byte[] ivBytes; - - public String encrypt(String plainText) throws Exception { - - //get salt - //salt = generateSalt(); - byte[] saltBytes = salt.getBytes("UTF-8"); - - // Derive the key - SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); - PBEKeySpec spec = new PBEKeySpec( - password.toCharArray(), - saltBytes, - pswdIterations, - keySize - ); - - SecretKey secretKey = factory.generateSecret(spec); - SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); - - //encrypt the message - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.ENCRYPT_MODE, secret); - AlgorithmParameters params = cipher.getParameters(); - ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV(); - byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8")); - return new Base64().encodeAsString(encryptedTextBytes); - } - - @SuppressWarnings("static-access") - public String decrypt(String encryptedText) throws Exception { - - byte[] saltBytes = salt.getBytes("UTF-8"); - byte[] encryptedTextBytes = new Base64().decodeBase64(encryptedText); - - // Derive the key - SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); - PBEKeySpec spec = new PBEKeySpec( - password.toCharArray(), - saltBytes, - pswdIterations, - keySize - ); - - SecretKey secretKey = factory.generateSecret(spec); - SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); - - // Decrypt the message - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes)); - - - byte[] decryptedTextBytes = null; - try { - decryptedTextBytes = cipher.doFinal(encryptedTextBytes); - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - } catch (BadPaddingException e) { - e.printStackTrace(); - } - - return new String(decryptedTextBytes); - } - - public String generateSalt() { - SecureRandom random = new SecureRandom(); - byte bytes[] = new byte[20]; - random.nextBytes(bytes); - String s = new String(bytes); - return s; - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/EncTest.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/EncTest.java deleted file mode 100644 index 865731db..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/EncTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.util; - -public class EncTest { - - - public static void main(String[] args) { - String secretKey = "AGLDdG4D04BKm2IxIWEr8o=="; - String value1= "AppPassword!1"; - try { - String encryptedValue1= CipherUtil.encrypt(value1, secretKey); - System.out.println(encryptedValue1); - String decryptedValue1 = CipherUtil.decrypt(encryptedValue1, secretKey); - System.out.println(decryptedValue1); - } catch (Exception e) { - // Invalid key would throw an exception. - e.printStackTrace(); - } - - } -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/SystemProperties.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/SystemProperties.java deleted file mode 100644 index 8bc6d7a1..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/SystemProperties.java +++ /dev/null @@ -1,279 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.util; - -import javax.servlet.ServletContext; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; - -/** - * SystemProperties contains a list of constants used throughout portions of the - * application. Populated by Spring from multiple configuration files. - * - * Should be used like this: - * - *
        - * 
        - * @Autowired
        - * SystemProperties systemProperties;
        - * 
        - */ -@Configuration -@PropertySource(value = { "${container.classpath:}/WEB-INF/conf/system.properties", - "${container.classpath:}/WEB-INF/fusion/conf/fusion.properties", - "${container.classpath:}/WEB-INF/conf/sql.properties" }) -public class SystemProperties { - - private static Environment environment; - - public SystemProperties() { - } - - protected Environment getEnvironment() { - return environment; - } - - @Autowired - public void setEnvironment(Environment environment) { - SystemProperties.environment = environment; - } - - public ServletContext getServletContext() { - return servletContext; - } - - public void setServletContext(ServletContext servletContext) { - this.servletContext = servletContext; - } - - - public static boolean containsProperty(String key) { - return environment.containsProperty(key); - } - - public static String getProperty(String key) { - if (environment!=null) { - return environment.getRequiredProperty(key); - } else { - return ""; - } - } - - // method created to get around JSTL 1.0 limitation of not being able to - // access a static method of a bean - public String getApplicationName() { - return getProperty(APPLICATION_NAME); - } - - public String getAppDisplayName() { - return getProperty(APP_DISPLAY_NAME); - } - - private ServletContext servletContext; - - // keys used to reference values in the system properties file - public static final String DOMAIN_CLASS_LOCATION = "domain_class_location"; - public static final String DEFAULT_ERROR_MESSAGE = "default_error_message"; - - public static final String AUTHENTICATION_MECHANISM = "authentication_mechanism"; - - public static final String APPLICATION_NAME = "application_name"; - public static final String HIBERNATE_CONFIG_FILE_PATH = "hibernate_config_file_path"; - public static final String APPLICATION_USER_ID = "application_user_id"; - - public static final String POST_INITIAL_CONTEXT_FACTORY = "post_initial_context_factory"; - public static final String POST_PROVIDER_URL = "post_provider_url"; - public static final String POST_SECURITY_PRINCIPAL = "post_security_principal"; - public static final String POST_MAX_RESULT_SIZE = "post_max_result_size"; - public static final String POST_DEFAULT_ROLE_ID = "post_default_role_id"; - - public static final String FILES_PATH = "files_path"; - public static final String TEMP_PATH = "temp_path"; - - public static final String NUM_UPLOAD_FILES = "num_upload_files"; - - public static final String SYS_ADMIN_ROLE_ID = "sys_admin_role_id"; - - public static final String SYS_ADMIN_ROLE_FUNCTION_DELETE_FROM_UI = "sys_admin_role_function_delete_from_ui"; - public static final String USER_NAME = "user_name"; - public static final String FIRST_NAME = "first_name"; - public static final String LAST_NAME = "last_name"; - public static final String APP_DISPLAY_NAME = "app_display_name"; - // Application base URL is a proper prefix of the on-boarding URL - public static final String APP_BASE_URL = "app_base_url"; - - public static final String MENU_PROPERTIES_FILE_LOCATION = "menu_properties_file_location"; - public static final String MENU_QUERY_NAME = "menu_query_name"; - public static final String APPLICATION_MENU_SET_NAME = "application_menu_set_name"; - public static final String APPLICATION_MENU_ATTRIBUTE_NAME = "application_menu_attribute_name"; - public static final String APPLICATION_MENU_PROPERTIES_NAME = "application_menu_properties_name"; - public static final String BUSINESS_DIRECT_MENU_SET_NAME = "business_direct_menu_set_name"; - public static final String BUSINESS_DIRECT_MENU_ATTRIBUTE_NAME = "business_direct_menu_attribute_name"; - public static final String BUSINESS_DIRECT_MENU_PROPERTIES_NAME = "business_direct_menu_properties_name"; - public static final String RAPTOR_CONFIG_FILE_PATH = "raptor_config_file_path"; - public static final String HOMEPAGE_DATA_CALLBACK_CLASS = "homepage_data_callback_class"; - public static final String ERROR_EMAIL_DISTRIBUTION = "error_email_distribution"; - public static final String ERROR_EMAIL_SOURCE_ADDRESS = "error_email_source_address"; - public static final String ERROR_EMAIL_SUBJECT_LINE = "error_email_subject_line"; - public static final String PROFILE_SEARCH_REPORT_ID = "profile_search_report_id"; - public static final String CALLABLE_PROFILE_SEARCH_REPORT_ID = "callable_profile_search_report_id"; - public static final String CLUSTERED = "clustered"; - - public static final String USER_ATTRIBUTE_NAME = "user_attribute_name"; - public static final String ROLES_ATTRIBUTE_NAME = "roles_attribute_name"; - public static final String ROLE_FUNCTIONS_ATTRIBUTE_NAME = "role_functions_attribute_name"; - public static final String CLIENT_DEVICE_ATTRIBUTE_NAME = "client_device_attribute_name"; - public static final String CLIENT_DEVICE_EMULATION = "client_device_emulation"; - public static final String CLIENT_DEVICE_TYPE_TO_EMULATE = "client_device_type_to_emulate"; - // File generation - Document - public static final String TEMPLATES_PATH = "templates_path"; - public static final String DOCUMENT_XML_ENCODING = "document_xml_encoding"; - - // Transaction - public static final String ROUTING_DATASOURCE_KEY = "routing_datasource_key"; - - // Document Library keys - public static final String DOCLIB_ADMIN_ROLE_ID = "doclib_admin_role_id"; - public static final String DOCLIB_USER_ROLE_ID = "doclib_user_role_id"; - - public static final String SYSTEM_PROPERTIES_FILENAME = "system.properties"; - public static final String FUSION_PROPERTIES_FILENAME = "fusion.properties"; - public static final String SUCCESS_TASKS_PROPERTIES_FILENAME = "success_tasks.properties"; - - // login error message keys - public static final String MESSAGE_KEY_LOGIN_ERROR_COOKIE_EMPTY = "login.error.hrid.empty"; - public static final String MESSAGE_KEY_LOGIN_ERROR_HEADER_EMPTY = "login.error.header.empty"; - public static final String MESSAGE_KEY_LOGIN_ERROR_USER_INACTIVE = "login.error.user.inactive"; - public static final String MESSAGE_KEY_LOGIN_ERROR_USER_NOT_FOUND = "login.error.hrid.not-found"; - public static final String MESSAGE_KEY_LOGIN_ERROR_APPLICATION_LOCKED = "login.error.application.locked"; - public static final String MESSAGE_KEY_AUTOLOGIN_NONE = "webphone.autoimport.nouser"; - public static final String MESSAGE_KEY_AUTOLOGIN_MULTIPLE = "webphone.autoimport.multiple"; - - // Application Mobile capability - public static final String MOBILE_ENABLE = "mobile_enable"; - - public static final String DATABASE_TIME_ZONE = "db.time_zone"; - - public static final String AUTO_USER_IMPORT_ENABLE = "auto_user_import_enable"; - public static final String AUTO_USER_IMPORT_ROLE = "auto_user_import_role"; - - public static final String ITRACKER_EMAIL_SOURCE_ADDRESS = "itracker_email_source_address"; - public static final String ITRACKER_EMAIL_DISTRIBUTION = "itracker_email_distribution"; - public static final String ITRACKER_SYSTEM_USER = "itracker_system_user_id"; - - public static final String MAIL_SERVER_HOST = "mail_server_host"; - public static final String MAIL_SERVER_PORT = "mail_server_port"; - - // Routing Data Source keys - public static final String ROUTING_DATASOURCE_KEY_NON_XA = "NON-XA"; - public static final String ROUTING_DATASOURCE_KEY_XA = "XA"; - public static final String QUARTZ_JOB_ENABLED = "quartz_job_enable"; - public static final String WORKFLOW_EMAIL_SENDER = "workflow_email_sender"; - public static final String DROOLS_GUVNOR_HOME = "drools.guvnor.home"; - - // Hibernate Config - public static final String HB_DIALECT = "hb.dialect"; - public static final String HB_SHOW_SQL = "hb.show_sql"; - // DataSource - public static final String DB_DRIVER = "db.driver"; - public static final String DB_CONNECTIONURL = "db.connectionURL"; - public static final String DB_USERNAME = "db.userName"; - public static final String DB_PASSWOR = "db.password"; - public static final String DB_MIN_POOL_SIZE = "db.min_pool_size"; - public static final String DB_MAX_POOL_SIZE = "db.max_pool_size"; - public static final String IDLE_CONNECTION_TEST_PERIOD = "hb.idle_connection_test_period"; - - public static final String MYLOGINS_FEED_CRON = "mylogins_feed_cron"; - public static final String SESSIONTIMEOUT_FEED_CRON = "sessiontimeout_feed_cron"; - public static final String LOG_CRON = "log_cron"; - - public static final String DB_ENCRYPT_FLAG = "db.encrypt_flag"; - - // Decryption Key - public static final String Decryption_Key = "decryption_key"; - - // Logging/Audit Fields - public static final String MDC_APPNAME = "AppName"; - public static final String MDC_REST_PATH = "RestPath"; - public static final String MDC_REST_METHOD = "RestMethod"; - public static final String INSTANCE_UUID = "instance_uuid"; - public static final String MDC_CLASS_NAME = "ClassName"; - public static final String MDC_LOGIN_ID = "LoginId"; - public static final String MDC_TIMER = "Timer"; - public static final String SDK_NAME = "ECOMP_SDK"; - public static final String ECOMP_REQUEST_ID = "X-ECOMP-RequestID"; - public static final String PARTNER_NAME = "PartnerName"; - public static final String FULL_URL = "Full-URL"; - public static final String AUDITLOG_BEGIN_TIMESTAMP = "AuditLogBeginTimestamp"; - public static final String AUDITLOG_END_TIMESTAMP = "AuditLogEndTimestamp"; - public static final String METRICSLOG_BEGIN_TIMESTAMP = "MetricsLogBeginTimestamp"; - public static final String METRICSLOG_END_TIMESTAMP = "MetricsLogEndTimestamp"; - public static final String CLIENT_IP_ADDRESS = "ClientIPAddress"; - public static final String STATUS_CODE = "StatusCode"; - public static final String RESPONSE_CODE = "ResponseCode"; - public static final String TARGET_ENTITY = "TargetEntity"; //Component or sub component name - public static final String TARGET_SERVICE_NAME = "TargetServiceName"; //API or operation name - - // Logging Compliance - public static final String DOUBLE_WHITESPACE_SEPARATOR = " "; - public static final String SINGLE_WHITESPACE_SEPARATOR = " "; - public static final String SINGLE_QUOTE = "'"; - public static final String NA = "N/A"; - public static final String UNKNOWN = "Unknown"; - public static final String SECURITY_LOG_TEMPLATE = "Protocol:{0} Security-Event-Type:{1} Login-ID:{2} {3}"; - public static final String ECOMP_PORTAL_BE = "ECOMP_PORTAL_BE"; - public static final String PROTOCOL = "PROTOCOL"; - public static final String SECURIRY_EVENT_TYPE = "SECURIRY_EVENT_TYPE"; - public static final String LOGIN_ID = "LOGIN_ID"; - public static final String ACCESSING_CLIENT = "ACCESSING_CLIENT"; - public static final String RESULT_STR = "RESULT"; - public static final String ECOMP_PORTAL_FE = "ECOMP_PORTAL_FE"; - public static final String ADDITIONAL_INFO = "ADDITIONAL_INFO"; - public static final String INTERFACE_NAME = "INTERFACE_NAME"; - public static final String USERAGENT_NAME = "user-agent"; - - // Protocols - public static final String HTTP = "HTTP"; - public static final String HTTPS = "HTTPS"; - public static final String SSO_VALUE = "sso"; - - public enum RESULT_ENUM { - SUCCESS, FAILURE - } - - public enum SecurityEventTypeEnum { - FE_LOGIN_ATTEMPT, FE_LOGOUT, SSO_LOGIN_ATTEMPT_PHASE_1, SSO_LOGIN_ATTEMPT_PHASE_2, SSO_LOGOUT, LDAP_PHONEBOOK_USER_SEARCH, INCOMING_REST_MESSAGE, OUTGOING_REST_MESSAGE, REST_AUTHORIZATION_CREDENTIALS_MODIFIED, ECOMP_PORTAL_USER_MODIFIED, ECOMP_PORTAL_USER_ADDED, ECOMP_PORTAL_USER_REMOVED, ECOMP_PORTAL_WIDGET, INCOMING_UEB_MESSAGE, ECOMP_PORTAL_HEALTHCHECK - } - - // Menu - public static final String CONTACT_US_LINK = "contact_us_link"; - - //Left Menu - public static final String LEFT_MENU_PARENT = "parentList"; - public static final String LEFT_MENU_CHILDREND = "childItemList"; - - // URL of the portal site that provides the shared-context REST service - public static final String ECOMP_SHARED_CONTEXT_REST_URL = "ecomp_shared_context_rest_url"; - - public static final String AUTH_USER_SERVER = "authenticate_user_server"; -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/YamlUtils.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/YamlUtils.java deleted file mode 100644 index 58bcb252..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/util/YamlUtils.java +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.util; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Map; - -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.representer.Representer; - -public class YamlUtils { - - static Yaml yaml; - - static { - - Representer representer = new Representer(); - yaml = new Yaml(representer); - - } - - public static void writeYamlFile(String filePath, String fileName, - Map model) throws IOException { - FileWriter writer = new FileWriter(filePath + File.separator + fileName); - yaml.dump(model, writer); - writer.close(); - } - - public static String returnYaml( - Map model) throws IOException { - - return yaml.dump(model); - - } - - @SuppressWarnings("unchecked") - public static Map readYamlFile( - String filePath, String fileName) throws FileNotFoundException, - IOException { - FileReader reader = new FileReader(filePath + File.separator + fileName); - - Map callFlowBs = (Map)yaml.load(reader); - reader.close(); - return callFlowBs; - } - - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/AppUtils.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/AppUtils.java deleted file mode 100644 index 170d87cb..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/AppUtils.java +++ /dev/null @@ -1,195 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.web.support; - -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.sql.DataSource; - -import org.hibernate.Session; -import org.openecomp.portalsdk.core.exception.SessionExpiredException; -import org.openecomp.portalsdk.core.objectcache.AbstractCacheManager; -import org.openecomp.portalsdk.core.service.DataAccessService; -import org.springframework.beans.factory.annotation.Autowired; - - -public class AppUtils { - - private static DataAccessService dataAccessService; - - private static AbstractCacheManager cacheManager; - - private static boolean applicationLocked; - - private static Hashtable feedback = new Hashtable(); - - private static DataSource datasource; - - public static DataSource getDatasource() { - return datasource; - } - - @Autowired - public void setDatasource(DataSource datasource) { - AppUtils.datasource = datasource; - } - - public AppUtils() { - } - - public static HttpSession getSession(HttpServletRequest request) { - HttpSession session = null; - if (request != null) { - session = request.getSession(false); - if (session == null) { - throw new SessionExpiredException(); - } - } else { - throw new SessionExpiredException(); - } - return session; - } - - public static List getLookupList(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy) { - return getLookupList(dbTable, dbValueCol, dbLabelCol, dbFilter, dbOrderBy, null); - } // getLookupList - - public static List getLookupList(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy, Session session) { - String cacheKey = dbTable + "|" + dbValueCol + "|" + dbLabelCol + "|" + dbFilter + "|" + dbOrderBy; - List list = getLookupListFromCache(cacheKey); - if (list == null) { - list = getDataAccessService().getLookupList(dbTable, dbValueCol, dbLabelCol, dbFilter, dbOrderBy, null); - if (list != null) { - addLookupListToCache(cacheKey, list); - } - } // if - return list; - } // getLookupList - - private static List getLookupListFromCache(String key) { - return (List)getObjectFromCache(key); - } // getLookupListFromCache - - public static Object getObjectFromCache(String key) { - if (isCacheManagerAvailable()) { - return getCacheManager().getObject(key); - } else { - return null; - } - } // getObjectFromCache - - private static void addLookupListToCache(String key, List list) { - addObjectToCache(key, list); - } // addLookupListToCache - - public static void addObjectToCache(String key, Object o) { - if (isCacheManagerAvailable()) { - getCacheManager().putObject(key, o); - } - } // addObjectToCache - - @Autowired - public void setCacheManager(AbstractCacheManager cacheManager) { - this.cacheManager = cacheManager; - } - - public static AbstractCacheManager getCacheManager() { - return cacheManager; - } - - public static boolean isCacheManagerAvailable() { - return (getCacheManager() != null); - } - - public void setFeedback(Hashtable feedback) { - this.feedback = feedback; - } - - public static boolean isApplicationLocked() { - return applicationLocked; - } - - public static DataAccessService getDataAccessService() { - return dataAccessService; - } - - @Autowired - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - public static void setApplicationLocked(boolean locked) { - applicationLocked = locked; - } - - public static String getLookupValueByLabel(String label, String dbTable, String dbValueCol, String dbLabelCol) { - if (label == null || label.equals("")) { - return ""; - } - - List lstResult = getLookupListNoCache(dbTable, dbValueCol, dbLabelCol, dbLabelCol + "='" + label.replaceAll("'", "''") + "'", ""); - if (lstResult == null) { - return ""; - } - if (lstResult.size() > 0) { - return ((org.openecomp.portalsdk.core.domain.Lookup)lstResult.toArray()[0]).getValue(); - } else { - return ""; - } - } - - public static String getLookupValueByLabel(String label, List lookupList) { - Iterator i = null; - - if (label == null || label.equalsIgnoreCase("")) { - return ""; - } - - if (lookupList == null || lookupList.size() == 0) { - return ""; - } - - i = lookupList.iterator(); - while (i.hasNext()) { - org.openecomp.portalsdk.core.domain.Lookup lookup = (org.openecomp.portalsdk.core.domain.Lookup)i.next(); - - if (lookup.getLabel().equals(label)) { - return lookup.getValue(); - } - } - - return ""; -} - public static List getLookupListNoCache(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy) { - return getLookupListNoCache(dbTable, dbValueCol, dbLabelCol, dbFilter, dbOrderBy, null); - } // getLookupListNoCache - - - public static List getLookupListNoCache(String dbTable, String dbValueCol, String dbLabelCol, String dbFilter, String dbOrderBy, Session session) { - return getDataAccessService().getLookupList(dbTable, dbValueCol, dbLabelCol, dbFilter, dbOrderBy, null); - } // getLookupListNoCache - - - -} // AppUtils diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/MessagesList.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/MessagesList.java deleted file mode 100644 index 9ab956d0..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/MessagesList.java +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.web.support; - -import java.util.ArrayList; -import java.util.List; - -public class MessagesList { - - private boolean successMessageDisplayed = true; - private boolean includeCauseInCustomExceptions = false; - - private List successMessages; - private List exceptionMessages; - - public MessagesList() { - setExceptionMessages(new ArrayList()); - setSuccessMessages(new ArrayList()); - } - - public MessagesList(boolean displaySuccess) { - this(); - setSuccessMessageDisplayed(displaySuccess); - } - - public List getExceptionMessages() { - return exceptionMessages; - } - - public List getSuccessMessages() { - return successMessages; - } - - public boolean isSuccessMessageDisplayed() { - return successMessageDisplayed; - } - - public boolean isIncludeCauseInCustomExceptions() { - return includeCauseInCustomExceptions; - } - - - public void setExceptionMessages(List exceptionMessages) { - this.exceptionMessages = exceptionMessages; - } - - public void setSuccessMessages(List successMessages) { - this.successMessages = successMessages; - } - - public void setSuccessMessageDisplayed(boolean successMessageDisplayed) { - this.successMessageDisplayed = successMessageDisplayed; - } - - public void setIncludeCauseInCustomExceptions(boolean includeCauseInCustomExceptions) { - this.includeCauseInCustomExceptions = includeCauseInCustomExceptions; - } - - - public void addSuccessMessage(FeedbackMessage message) { - getSuccessMessages().add(message); - } - - public void addExceptionMessage(FeedbackMessage message) { - getExceptionMessages().add(message); - } - - public boolean hasExceptionMessages() { - return!getExceptionMessages().isEmpty(); - } - - public boolean hasSuccessMessages() { - return!getSuccessMessages().isEmpty(); - } - -} diff --git a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/UserUtils.java b/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/UserUtils.java deleted file mode 100644 index 7f974574..00000000 --- a/ecomp-sdk/quantum/src/main/java/org/openecomp/portalsdk/core/web/support/UserUtils.java +++ /dev/null @@ -1,373 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.web.support; - -import java.io.PrintWriter; -import java.io.Serializable; -import java.io.StringWriter; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.UUID; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.openecomp.portalsdk.core.FusionObject; -import org.openecomp.portalsdk.core.domain.Role; -import org.openecomp.portalsdk.core.domain.RoleFunction; -import org.openecomp.portalsdk.core.domain.UrlsAccessible; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.exception.SessionExpiredException; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.menu.MenuBuilder; -import org.openecomp.portalsdk.core.restful.domain.EcompRole; -import org.openecomp.portalsdk.core.restful.domain.EcompUser; -import org.openecomp.portalsdk.core.service.DataAccessService; -import org.openecomp.portalsdk.core.util.CipherUtil; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; - -@SuppressWarnings("rawtypes") -public class UserUtils implements Serializable, FusionObject { - - /** - * - */ - private static final long serialVersionUID = 1L; - private static final String USER_ID = "UserId"; - - static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(UserUtils.class); - - public static final String KEY_USER_ROLES_CACHE = "userRoles"; - - public static final String WJ_HEADER_USER_NAME = "iv-user"; - public static final String WJ_HEADER_USER_GROUP = "iv-groups"; - - private static DataAccessService dataAccessService; - - public static void setUserSession(HttpServletRequest request, User user, Set applicationMenuData, Set businessDirectMenuData, String loginMethod) { - HttpSession session = request.getSession(true); - - UserUtils.clearUserSession(request); // let's clear the current user session to avoid any conflicts during the set - - session.setAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME), user); - - getRoleFunctions(request); - - // truncate the role (and therefore the role function) data to save memory in the session - user.setRoles(null); - session.setAttribute(SystemProperties.getProperty(SystemProperties.USER_NAME), user.getFullName()); - session.setAttribute(SystemProperties.FIRST_NAME, user.getFirstName()); - session.setAttribute(SystemProperties.LAST_NAME, user.getLastName()); - String displayName = ""; - if (SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME) != null) - displayName = SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME); - session.setAttribute(SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME), displayName); - - session.setAttribute(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_ATTRIBUTE_NAME), MenuBuilder.filterMenu(applicationMenuData, request)); - session.setAttribute(SystemProperties.getProperty(SystemProperties.BUSINESS_DIRECT_MENU_ATTRIBUTE_NAME), MenuBuilder.filterMenu(businessDirectMenuData, request)); - } - - public static void clearUserSession(HttpServletRequest request) { - HttpSession session = AppUtils.getSession(request); - - if (session == null) { - throw new SessionExpiredException(); - } - - // removes all stored attributes from the current user's session - session.removeAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME)); - session.removeAttribute(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_ATTRIBUTE_NAME)); - session.removeAttribute(SystemProperties.getProperty(SystemProperties.BUSINESS_DIRECT_MENU_ATTRIBUTE_NAME)); - session.removeAttribute(SystemProperties.getProperty(SystemProperties.ROLES_ATTRIBUTE_NAME)); - session.removeAttribute(SystemProperties.getProperty(SystemProperties.ROLE_FUNCTIONS_ATTRIBUTE_NAME)); - } - - @SuppressWarnings("unchecked") - public static Set getRoleFunctions(HttpServletRequest request) { - HashSet roleFunctions = null; - - HttpSession session = request.getSession(); - roleFunctions = (HashSet)session.getAttribute(SystemProperties.getProperty(SystemProperties.ROLE_FUNCTIONS_ATTRIBUTE_NAME)); - - if (roleFunctions == null) { - HashMap roles = getRoles(request); - roleFunctions = new HashSet(); - - Iterator i = roles.keySet().iterator(); - - while (i.hasNext()) { - Long roleKey = (Long)i.next(); - Role role = (Role)roles.get(roleKey); - - Iterator j = role.getRoleFunctions().iterator(); - - while (j.hasNext()) { - RoleFunction function = (RoleFunction) j.next(); - roleFunctions.add(function.getCode()); - } - } - - session.setAttribute(SystemProperties.getProperty(SystemProperties.ROLE_FUNCTIONS_ATTRIBUTE_NAME), roleFunctions); - } - - return roleFunctions; - } - - public static HashMap getRoles(HttpServletRequest request) { - HashMap roles = null; - - //HttpSession session = request.getSession(); - HttpSession session = AppUtils.getSession(request); - roles = (HashMap)session.getAttribute(SystemProperties.getProperty(SystemProperties.ROLES_ATTRIBUTE_NAME)); - - // if roles are not already cached, let's grab them from the user session - if (roles == null) { - User user = getUserSession(request); - - // get all user roles (including the tree of child roles) - roles = getAllUserRoles(user); - - session.setAttribute(SystemProperties.getProperty(SystemProperties.ROLES_ATTRIBUTE_NAME), getAllUserRoles(user)); - } - - return roles; - } - - public static User getUserSession(HttpServletRequest request) { - HttpSession session = AppUtils.getSession(request); - - if (session == null) { - throw new SessionExpiredException(); - } - - return (User)session.getAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME)); - } - - @SuppressWarnings("unchecked") - public static HashMap getAllUserRoles(User user) { - HashMap roles = new HashMap(); - Iterator i = user.getRoles().iterator(); - - while (i.hasNext()) { - Role role = (Role)i.next(); - - if (role.getActive()) { - roles.put(role.getId(), role); - - // let's take a recursive trip down the tree to add all child roles - addChildRoles(role, roles); - } - } - - return roles; - } - - @SuppressWarnings("unchecked") - private static void addChildRoles(Role role, HashMap roles) { - Set childRoles = role.getChildRoles(); - - if (childRoles != null && childRoles.size() > 0) { - Iterator j = childRoles.iterator(); - while (j.hasNext()) { - Role childRole = (Role)j.next(); - - if (childRole.getActive()) { - roles.put(childRole.getId(), childRole); - - addChildRoles(childRole, roles); - } - } - } - - } - - @SuppressWarnings("unchecked") - public static boolean isUrlAccessible(HttpServletRequest request, String currentUrl) { - boolean isAccessible = false; - - Map params = new HashMap(); - params.put("current_url", currentUrl); - - List list = getDataAccessService().executeNamedQuery("restrictedUrls", params, null); - - // loop through the list of restricted URL's - if (list != null && list.size() > 0) { - for (int i=0; i < list.size(); i++) { - - UrlsAccessible urlFunctions = (UrlsAccessible) list.get(i); - String functionCd = (String)urlFunctions.getFunctionCd(); - - if (UserUtils.isAccessible(request, functionCd)) { - isAccessible = true; - } - } - return isAccessible; - } - - return true; - } - - public static boolean hasRole(HttpServletRequest request, String roleKey) { - return getRoles(request).keySet().contains(new Long(roleKey)); - } - - - public static boolean hasRole(User user, String roleKey) { - return getAllUserRoles(user).keySet().contains(new Long(roleKey)); - } - - public static boolean isAccessible(HttpServletRequest request, String functionKey) { - return getRoleFunctions(request).contains(functionKey); - } - - public static DataAccessService getDataAccessService() { - return dataAccessService; - } - - @Autowired - public void setDataAccessService(DataAccessService dataAccessService) { - UserUtils.dataAccessService = dataAccessService; - } - - public static int getUserId(HttpServletRequest request) { - return getUserIdAsLong(request).intValue(); - } - - public static Long getUserIdAsLong(HttpServletRequest request) { - Long userId = new Long(SystemProperties.getProperty(SystemProperties.APPLICATION_USER_ID)); - - if (request != null) { - if (getUserSession(request) != null) { - userId = getUserSession(request).getId(); - } - } - - return userId; - } - - - private static final Object stackTraceLock = new Object(); - public static String getStackTrace(Throwable t) { - synchronized(stackTraceLock) { - StringWriter sw = new StringWriter (); - PrintWriter pw = new PrintWriter (sw); - t.printStackTrace (pw); - return sw.toString (); - } - } - - public static String getFullURL(HttpServletRequest request) { - if (request!=null) { - StringBuffer requestURL = request.getRequestURL(); - String queryString = request.getQueryString(); - - if (queryString == null) { - return requestURL.toString(); - } else { - return requestURL.append('?').append(queryString).toString(); - } - } - - return ""; - } - - public static String getRequestId(HttpServletRequest request) { - Enumeration headerNames = request.getHeaderNames(); - - String requestId = ""; - try { - while (headerNames.hasMoreElements()) { - String headerName = (String) headerNames.nextElement(); - logger.info(EELFLoggerDelegate.debugLogger, "One header is " + headerName + " : " + request.getHeader(headerName)); - if (headerName.equalsIgnoreCase(SystemProperties.ECOMP_REQUEST_ID)) { - requestId = request.getHeader(headerName); - break; - } - } - } catch (Exception e) { - logger.error(EELFLoggerDelegate.debugLogger, "HEADER!!!! Exception : " + UserUtils.getStackTrace(e)); - } - - return (requestId.isEmpty() ? UUID.randomUUID().toString() : requestId); - } - - - public static EcompUser convertToEcompUser (User user){ - EcompUser userJson = new EcompUser(); - - - userJson.setEmail(user.getEmail()); - userJson.setFirstName(user.getFirstName()); - userJson.setHrid(user.getHrid()); - userJson.setJobTitle(user.getJobTitle()); - userJson.setLastName(user.getLastName()); - userJson.setLoginId(user.getLoginId()); - userJson.setOrgManagerUserId(user.getOrgManagerUserId()); - userJson.setMiddleInitial(user.getMiddleInitial()); - userJson.setOrgCode(user.getOrgCode()); - userJson.setOrgId(user.getOrgId()); - userJson.setPhone(user.getPhone()); - userJson.setOrgUserId(user.getOrgUserId()); - - - Set ecompRoles = new TreeSet(); - - for(Role role : user.getRoles()){ - ecompRoles.add(convertToEcompRole(role)); - } - - userJson.setRoles(ecompRoles); - - return userJson; - } - - public static EcompRole convertToEcompRole(Role role){ - - EcompRole ecompRole = new EcompRole(); - ecompRole.setId(role.getId()); - ecompRole.setName(role.getName()); - - return ecompRole; - } - - public static String getUserIdFromCookie(HttpServletRequest request) throws Exception { - String userId = ""; - Cookie[] cookies = request.getCookies(); - Cookie userIdcookie = null; - if (cookies != null) - for (Cookie cookie : cookies) - if (cookie.getName().equals(USER_ID)) - userIdcookie = cookie; - if(userIdcookie!=null){ - userId = CipherUtil.decrypt(userIdcookie.getValue(), - SystemProperties.getProperty(SystemProperties.Decryption_Key)); - } - return userId; - - } -} diff --git a/ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/MockApplicationContextTestSuite.java b/ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/MockApplicationContextTestSuite.java deleted file mode 100644 index 0f918f6b..00000000 --- a/ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/MockApplicationContextTestSuite.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.openecomp.portalsdk.core; - -import java.io.IOException; - -import org.junit.Before; -import org.junit.runner.RunWith; -import org.openecomp.portalsdk.core.conf.AppConfig; -import org.openecomp.portalsdk.core.objectcache.AbstractCacheManager; -import org.openecomp.portalsdk.core.util.CacheManager; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.AnnotationConfigWebContextLoader; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; - - -/** - * - * - * - * In order to write a unit test, - * 1. inherit this class - See SanityTest.java - * 2. place the "war" folder on your test class's classpath - * 3. run the test with the following VM argument; This is important because when starting the application from Container, the System Properties file (SystemProperties.java) can have the direct path - * but, when running from the Mock Junit container, the path should be prefixed with "classpath" to enable the mock container to search for the file in the classpath - * -Dcontainer.classpath="classpath:" - * - */ - -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -@ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, classes = {MockAppConfig.class}) -@ActiveProfiles(value="test") -public class MockApplicationContextTestSuite { - - @Autowired - public WebApplicationContext wac; - - private MockMvc mockMvc; - - @Before - public void setup() { - if(mockMvc == null) { - this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); - - } - } - - public Object getBean(String name) { - return this.wac.getBean(name); - } - - - public MockMvc getMockMvc() { - return mockMvc; - } - - public void setMockMvc(MockMvc mockMvc) { - this.mockMvc = mockMvc; - } - - public WebApplicationContext getWebApplicationContext() { - return wac; - } - - - - -} - - - @Configuration - @ComponentScan(basePackages = "org.openecomp", - excludeFilters = { - - } - ) - @Profile("test") - class MockAppConfig extends AppConfig { - - @Bean - public SystemProperties systemProperties(){ - return new MockSystemProperties(); - } - - @Bean - public AbstractCacheManager cacheManager() { - return new CacheManager() { - - public void configure() throws IOException { - - } - }; - } - - protected String[] tileDefinitions() { - return new String[] {"classpath:/WEB-INF/fusion/defs/definitions.xml", "classpath:/WEB-INF/defs/definitions.xml"}; - } - - @Override - public void addInterceptors(InterceptorRegistry registry) { - //registry.addInterceptor(new SessionTimeoutInterceptor()).excludePathPatterns(getExcludeUrlPathsForSessionTimeout()); - //registry.addInterceptor(resourceInterceptor()); - } - - public static class MockSystemProperties extends SystemProperties { - - public MockSystemProperties() { - } - - } - - } - - - - diff --git a/ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/MockHibernateMappingLocations.java b/ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/MockHibernateMappingLocations.java deleted file mode 100644 index a7de5159..00000000 --- a/ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/MockHibernateMappingLocations.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.openecomp.portalsdk.core; - - - -import org.openecomp.portalsdk.core.conf.HibernateMappingLocatable; -import org.springframework.context.annotation.Profile; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.stereotype.Component; - -@Component -@Profile("test") -public class MockHibernateMappingLocations implements HibernateMappingLocatable{ - - public Resource[] getMappingLocations() { - return new Resource[]{new ClassPathResource("WEB-INF/fusion/orm/Fusion.hbm.xml"), new ClassPathResource("WEB-INF/fusion/orm/Workflow.hbm.xml")}; - } - - -} diff --git a/ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/controller/sessionmgt/PortalCommunicationTest.java b/ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/controller/sessionmgt/PortalCommunicationTest.java deleted file mode 100644 index 3e14becb..00000000 --- a/ecomp-sdk/quantum/src/test/java/org/openecomp/portalsdk/core/controller/sessionmgt/PortalCommunicationTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.openecomp.portalsdk.core.controller.sessionmgt; -/*package org.openecomp.portalsdk.core.controller.sessionmgt; - -import org.junit.Assert; -import org.junit.Test; -import org.springframework.mock.web.MockHttpSession; -import org.springframework.test.web.servlet.ResultActions; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - -import org.openecomp.portalsdk.core.MockApplicationContextTestSuite; -import org.openecomp.portalsdk.core.service.sessionmgt.CoreTimeoutHandler; - -public class PortalCommunicationTest extends MockApplicationContextTestSuite{ - - - @Test - public void testGetTimeoutSessions() throws Exception { - - MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/api/sessionTimeOuts"); - MockHttpSession httpSession = new MockHttpSession(this.wac.getServletContext(),"1234"); - CoreTimeoutHandler.sessionCreated("12", "1234", httpSession); - - ResultActions ra = this.getMockMvc().perform(requestBuilder); - - System.out.println(" %%%%%%%%%%%%%%%%%%%%%%%%% " + ra.andReturn().getResponse().getContentAsString()); - System.out.println(" %%%%%%%%%%%%%%%%%%%%%%%%% " + "{\"12\":{\"jSessionId\":\"1234\",\"sessionTimOutMilliSec\":"); - - Assert.assertTrue(ra.andReturn().getResponse().getContentAsString().startsWith("{\"12\":{\"jSessionId\":\"1234\",\"sessionTimOutMilliSec\":")); - - } - - @Test - public void testUpdateTimeoutSessions() throws Exception { - - // pre condition - MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/api/sessionTimeOuts"); - MockHttpSession httpSession = new MockHttpSession(this.wac.getServletContext(),"1234"); - CoreTimeoutHandler.sessionCreated("12", "1234", httpSession); - ResultActions ra = this.getMockMvc().perform(requestBuilder); - - String responseSessMapStr = ra.andReturn().getResponse().getContentAsString(); - - - // test - requestBuilder = MockMvcRequestBuilders.post("/api/updateSessionTimeOuts"); - requestBuilder.param("sessionMap", responseSessMapStr); - ra = this.getMockMvc().perform(requestBuilder); - - - } - - - -} -*/ \ No newline at end of file diff --git a/ecomp-sdk/sdk-analytics/.gitignore b/ecomp-sdk/sdk-analytics/.gitignore deleted file mode 100644 index d4111ffd..00000000 --- a/ecomp-sdk/sdk-analytics/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/.settings/ -/target/ diff --git a/ecomp-sdk/sdk-analytics/README.md b/ecomp-sdk/sdk-analytics/README.md deleted file mode 100644 index e7a5d130..00000000 --- a/ecomp-sdk/sdk-analytics/README.md +++ /dev/null @@ -1,8 +0,0 @@ -ECOMP Portal SDK Analytics -========================== - -This is the Maven project for the ECOMP Portal SDK Analytics, -which is distributed as ecompSDK-analytics-nnn.jar. This library -requires Hibernate and Spring, and provides features including -charts, maps and reports. - diff --git a/ecomp-sdk/sdk-analytics/pom.xml b/ecomp-sdk/sdk-analytics/pom.xml deleted file mode 100644 index 5209c94f..00000000 --- a/ecomp-sdk/sdk-analytics/pom.xml +++ /dev/null @@ -1,160 +0,0 @@ - - 4.0.0 - - - org.openecomp.ecompsdkos - ecompSDK-project - 1.1.0-SNAPSHOT - - - ecompSDK-analytics - Ecomp Portal SDK Analytics - Provides reporting features for SDK applications - jar - - - - - - - - - org.openecomp.ecompsdkos - ecompSDK-core - ${project.version} - - - - com.fasterxml.jackson.core - jackson-annotations - 2.6.3 - - - com.fasterxml.jackson.core - jackson-core - 2.6.3 - - - com.fasterxml.jackson.core - jackson-databind - 2.6.3 - - - - - commons-codec - commons-codec - 1.10 - - - commons-lang - commons-lang - 2.6 - - - javax.servlet - javax.servlet-api - 3.1.0 - - - - com.lowagie - itext - 2.0.8 - - - - org.slf4j - jcl-over-slf4j - 1.7.12 - - - org.springframework - spring-core - ${springframework.version} - - - commons-logging - commons-logging - - - - - org.springframework - spring-orm - ${springframework.version} - - - org.springframework - spring-web - ${springframework.version} - - - org.springframework - spring-webmvc - ${springframework.version} - - - - org.apache.poi - poi - 3.5-FINAL - - - commons-logging - commons-logging - - - log4j - log4j - - - - - org.apache.poi - poi-ooxml - 3.5-FINAL - - - commons-logging - commons-logging - - - log4j - log4j - - - - - org.apache.poi - poi-scratchpad - 3.5-FINAL - - - commons-logging - commons-logging - - - log4j - log4j - - - - - org.apache.poi - poi-contrib - 3.5-FINAL - - - commons-logging - commons-logging - - - log4j - log4j - - - - - - diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/AntBuild.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/AntBuild.java deleted file mode 100644 index eeb2b605..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/AntBuild.java +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics; - -import java.io.IOException; -import java.net.URL; -import java.util.Iterator; -import java.util.Map; -import java.util.jar.Attributes; -import java.util.jar.Manifest; - -/** - * This class is used to get version and Build information when - * user run "java -jar raptor_classes.jar" command. - */ -public class AntBuild { - - public static String buildNum = ""; - - public static void main(String[] args) { - System.out.println("Jar (raptor_classes.jar) Information: "); - readManifest(); - } - - public static void readManifest() { - try { - Class clazz = AntBuild.class; - String classContainer = clazz.getProtectionDomain().getCodeSource().getLocation().toString(); - URL manifestUrl = new URL("jar:" + classContainer + "!/META-INF/MANIFEST.MF"); - Manifest manifest = new Manifest(manifestUrl.openStream()); - - //JarFile jar = new JarFile("../lib/raptor_classes.jar"); - //Manifest manifest = jar.getManifest(); - - Attributes attribs = manifest.getMainAttributes(); - Iterator it = attribs.entrySet().iterator(); - while(it.hasNext()) { - Map.Entry entry = (Map.Entry) it.next(); - Attributes.Name attributeName = (Attributes.Name) entry.getKey(); - String attributeValue = (String) entry.getValue(); - if (attributeName.toString().equals("Created-By")) - System.out.println("Java HotSpot(TM) Client VM " + " : " + attributeValue); - else if (attributeName.toString().equals("Java-Version")) - System.out.println("Java Version " + " : " + attributeValue); - else if (attributeName.toString().equals("Java-Runtime-Version")) - System.out.println("Java Runtime Version " + " : " + attributeValue); - else if (attributeName.toString().equals("Ant-Version")) - System.out.println(attributeName.toString() + " : " + attributeValue); - else { - if(attributeName.toString().startsWith("Raptor")) { - if (attributeName.toString().startsWith("Raptor-Build-Version")) - buildNum = attributeValue; - System.out.println(attributeName.toString() + " : " + attributeValue); - } - } - } - - } catch (IOException e) { - System.err.println("Cannot read jar-file manifest: " - + e.getMessage()); - } - } - - public static String getBuildNum() { - if (buildNum.length()>0) - return buildNum; - else { - readManifest(); - return buildNum; - } - } -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/config/ConfigLoader.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/config/ConfigLoader.java deleted file mode 100644 index 826d7a29..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/config/ConfigLoader.java +++ /dev/null @@ -1,196 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.config; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.util.Properties; - -import javax.servlet.ServletContext; - -import org.openecomp.portalsdk.analytics.controller.Action; -import org.openecomp.portalsdk.analytics.controller.ActionMapping; -import org.openecomp.portalsdk.analytics.util.Log; - -public class ConfigLoader { - // public static final String RAPTOR_ACTION_MAP = - // "raptor_action_map.properties"; - - private static final String P_FILE_EXTENSION = ".properties"; - - public static final String RAPTOR_PROPERTIES = "raptor"; - - public static final String SQL_PROPERTIES = "sql"; - - public static final String APP_PROPERTIES = "raptor_app"; - - public static final String DB_PROPERTIES = "raptor_db"; - - private static String configFilesPath = "/WEB-INF/conf/"; - - public static final String RAPTOR_PDF_PROPERTIES = "raptor_pdf"; - - // private static String internalFilesPath = - // are not supposed to be modified by the user; may be unavailable in some - // cases - so defaults are expected - - private static String raptorActionMapString = - "report.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_run.jsp \n" - + "mobile.report.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |mobile_report_run.jsp \n" - + "report.dashrep1.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDashRep1 |report_run_dashrep1.jsp \n" - + "report.dashrep2.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDashRep2 |report_run_dashrep2.jsp \n" - + "report.dashrep3.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDashRep3 |report_run_dashrep3.jsp \n" - + "report.dashrep4.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDashRep4 |report_run_dashrep4.jsp \n" - + "report.download |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_xls.jsp \n" - + "report.download.excel2007 |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_xlsx.jsp \n" - + "report.download.page |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_page_xls.jsp \n" - + "report.csv.download |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_csv.jsp \n" - + "report.text.download |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_txt.jsp \n" - + "report.search |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearch |report_search.jsp \n" - + "report.search.execute |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearchExecute |report_search \n" - + "report.search.user |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearchUser |report_search.jsp \n" - + "report.search.public |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearchPublic |report_search.jsp \n" - + "report.search.favorite |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportSearchFavorites |report_search.jsp \n" - + "report.wizard |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportWizard |report_wizard \n" - + "report.create |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportCreate |report_wizard \n" - + "report.import |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_import \n" - + "report.import.save |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportImportSave |report_wizard \n" - + "report.copy |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportCopy |report_wizard \n" - + "report.copy.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportCopy |raptor_wizard_container.jsp \n" - + "report.edit |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportEdit |report_wizard \n" - + "report.delete |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDelete |report_search \n" - + "report.popup.field |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportFormFieldPopup |popup_field.jsp \n" - + "report.popup.map |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportValuesMapDefPopup |popup_map.jsp \n" - + "report.popup.drilldown.table |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_drill_down_table.jsp \n" - + "report.popup.drilldown.report|org.openecomp.portalsdk.analytics.controller.ActionHandler|reportDrillDownToReportDefPopup|popup_drill_down_report \n" - + "report.popup.import.semaphore|org.openecomp.portalsdk.analytics.controller.ActionHandler|importSemaphorePopup |popup_import_semaphore \n" - + "report.popup.semaphore |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_semaphore \n" - + "report.popup.semaphore.save |org.openecomp.portalsdk.analytics.controller.ActionHandler|saveSemaphorePopup |popup_semaphore \n" - + "report.popup.filter.col |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_filter_col.jsp \n" - + "report.popup.filter.data |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportFilterDataPopup |popup_filter_data.jsp \n" - + "report.popup.sql |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportShowSQLPopup |popup_sql \n " - + "report.run.popup |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_run_popup.jsp \n" - + "report.popup.test.cond |org.openecomp.portalsdk.analytics.controller.ActionHandler|testSchedCondPopup |popup_sql \n" - + "report.popup.testrun.sql |org.openecomp.portalsdk.analytics.controller.ActionHandler|testRunSQLPopup |popup_testrun_sql \n" - + "report.test.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |test_run_sql \n" - + "report.field.testrun.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |test_field_run_sql \n" - + "report.field.default.testrun.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |default_field_run_sql \n" - + "report.field.date.start.testrun.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |date_start_field_run_sql \n" - + "report.field.date.end.testrun.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |date_end_field_run_sql \n" - + "report.popup.table.cols |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_table_cols \n" - + "refresh.cache |org.openecomp.portalsdk.analytics.controller.ActionHandler|refreshCache |message.jsp \n" - + "report.message |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |message.jsp \n" - + "report.download.pdf |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_pdf.jsp \n" - + "report.popup.pdfconfig |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_pdf_config.jsp \n" - + "download.all |org.openecomp.portalsdk.analytics.controller.ActionHandler|downloadAll |close.jsp \n" - + "download.all.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |popup_download_flat_file.jsp \n" - + "download.data.file |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |download_data_file.jsp \n" - + "popup.calendar |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |gtm_calendar.jsp \n" - + "report.folderlist |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |folder_report_list.jsp \n" - + "report.folderlist_iframe |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |folder_report_list_iframe.jsp \n" - + "report.childDropDown |org.openecomp.portalsdk.analytics.controller.ActionHandler|getChildDropDown |raptor_childdropdown.jsp \n" - + "report.create.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_create_container.jsp \n" - + "report.search.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_container.jsp \n" - + "report.search.execute.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_execute_container.jsp \n" - + "report.search.user.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_user_container.jsp \n" - + "report.search.public.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_public_container.jsp \n" - + "report.search.favorite.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_search_favorite_container.jsp \n" - + "report.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_run_container.jsp \n" - + "report.formfields.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|formFieldRun |report_run_container.jsp \n" - + "report.run.jsp |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_run.jsp \n" - + "report.schedule.multiple |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |wizard_schedule_multiple.jsp \n" - + "report.schedule.submit |org.openecomp.portalsdk.analytics.controller.ActionHandler|processSchedule |wizard_schedule_only.jsp \n" - + "report.schedule.report.submit |org.openecomp.portalsdk.analytics.controller.ActionHandler|processScheduleReportList |wizard_schedule_only.jsp \n" - + "report.schedule.report.submit_wmenu |org.openecomp.portalsdk.analytics.controller.ActionHandler|processScheduleReportList |wizard_schedule_only_from_search.jsp \n" - + "report.schedule_only |org.openecomp.portalsdk.analytics.controller.ActionHandler|processSchedule |wizard_schedule_only \n" - + "report.schedule_only_from_search |org.openecomp.portalsdk.analytics.controller.ActionHandler|processSchedule |wizard_schedule_only_from_search.jsp \n" - + "report.schedule_delete |org.openecomp.portalsdk.analytics.controller.ActionHandler|processScheduleDelete |report_run_container.jsp \n" - + "report.schedule.submit_from_search |org.openecomp.portalsdk.analytics.controller.ActionHandler|processSchedule |wizard_schedule_only_from_search.jsp \n" - + "report.dashboard.detail |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |dashboard_report_run_detail.jsp \n" - + "report.csv.download.direct |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_csv.jsp \n" - + "report.csv.download.direct |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportRun |report_download_csv.jsp \n" - + "report.download.csv.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_csv \n" - + "report.download.excel2007.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_xlsx.jsp \n" - + "report.download.excel.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_xls.jsp \n" - + "report.download.pdf.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_pdf.jsp \n" - + "report.download.page.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_download_page_xls.jsp \n" - + "report.data.remove.session |org.openecomp.portalsdk.analytics.controller.ActionHandler|removeReportDataFromSession |report_run_container.jsp \n" - + "report.dashboard.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_dashboard_run_container.jsp \n" - + "chart.force.cluster |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |force_cluster.jsp \n" - + "chart.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportChartRun |report_run_container.jsp \n" - + "chart.json |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportChartRun |report_run_container.jsp \n" - + "chart.data.json |org.openecomp.portalsdk.analytics.controller.ActionHandler|reportChartDataRun |report_run_container.jsp \n" - + "quicklinks.json |org.openecomp.portalsdk.analytics.controller.ActionHandler|getQuickLinksJSON |report_run_container.jsp \n" - + "embed.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_embed_run_container.zul \n" - + "schedule.edit |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |wizard_adhoc_schedule.zul \n" - + "chart.annotations.run |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |plugin_chart_annotation.jsp \n" - + "chart.annotations.exec |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |chart_annotations.jsp \n" - + "chart.mini |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |chart_minified.jsp \n" - + "report.olap.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_olap_run_container.jsp \n" - + "report.hive.run.container |org.openecomp.portalsdk.analytics.controller.ActionHandler|gotoJsp |report_hive_run_container.jsp \n" - - ; - - private ConfigLoader() { - } - - public static void setConfigFilesPath(String path) { - configFilesPath = path; - } // setConfigFilesPath - - public static Properties getProperties(ServletContext servletContext, String propertiesFile) - throws IOException { - return getProperties(servletContext, propertiesFile, null); - } // getProperties - - public static Properties getProperties(ServletContext servletContext, - String propertiesFile, String systemTypeExtension) throws IOException { - Properties p = new Properties(); - p.load(servletContext.getResourceAsStream(configFilesPath + propertiesFile - + ((systemTypeExtension == null) ? "" : "_" + systemTypeExtension) - + P_FILE_EXTENSION)); - return p; - } // getProperties - - public static ActionMapping loadRaptorActionMapping(ServletContext servletContext) - throws IOException { - ActionMapping actionMapping = new ActionMapping(); - - String pLine = null; - // BufferedReader pFile = new BufferedReader(new - // InputStreamReader(servletContext.getResourceAsStream(internalFilesPath+RAPTOR_ACTION_MAP))); - BufferedReader pFile = new BufferedReader(new StringReader(raptorActionMapString)); - while ((pLine = pFile.readLine()) != null) - if (pLine.trim().length() > 0) - try { - actionMapping.addAction(Action.parse(pLine)); - } catch (Exception e) { - Log - .write("[ConfigLoader.loadRaptorActionMapping] Error - unable to parse action [" - + pLine + "]"); - } - pFile.close(); - - return actionMapping; - } // loadRaptorActionMapping - -} // ConfigLoader - diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Action.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Action.java deleted file mode 100644 index 3d14dcbf..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Action.java +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import java.util.StringTokenizer; - -public class Action extends org.openecomp.portalsdk.analytics.RaptorObject { - private String action = null; - - private String controllerClass = null; - - private String controllerMethod = null; - - private String jspName = null; - - private Action() { - } - - public Action(String action, String controllerClass, String controllerMethod, - String jspName) { - setAction(action); - setControllerClass(controllerClass); - setControllerMethod(controllerMethod); - setJspName(jspName); - } // Action - - public static Action parse(String configFileEntry) { - Action a = new Action(); - - StringTokenizer st = new StringTokenizer(configFileEntry, "| \t", false); - // if(st.hasMoreTokens()) - a.setAction(st.nextToken()); - a.setControllerClass(st.nextToken()); - a.setControllerMethod(st.nextToken()); - a.setJspName(st.nextToken()); - - return a; - } // parse - - public String getAction() { - return action; - } - - public String getControllerClass() { - return controllerClass; - } - - public String getControllerMethod() { - return controllerMethod; - } - - public String getJspName() { - return jspName; - } - - private void setAction(String action) { - this.action = action; - } - - private void setControllerClass(String controllerClass) { - this.controllerClass = controllerClass; - } - - private void setControllerMethod(String controllerMethod) { - this.controllerMethod = controllerMethod; - } - - private void setJspName(String jspName) { - this.jspName = jspName; - } - -} // Action diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionHandler.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionHandler.java deleted file mode 100644 index e0cd8d2f..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionHandler.java +++ /dev/null @@ -1,2417 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -/* =========================================================================================== - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) - * Raptor : This tool is used to generate different kinds of reports with lot of utilities - * =========================================================================================== - * - * ------------------------------------------------------------------------------------------- - * ActionHandler.java - This class is used to call actions related to reports. - * ------------------------------------------------------------------------------------------- - * - * - * - * Changes - * ------- - * 31-Aug-2009 : Version 8.5.1 (Sundar);
        • reportFormFieldPopup iterates form field collections.
        - * 18-Aug-2009 : Version 8.5.1 (Sundar);
        • request Object is passed to prevent caching user/roles - Datamining/Hosting.
        - * 13-Aug-2009 : Version 8.5 (Sundar);
        • reportFormFieldPopup is changed to have effect on textfield with popup.
        - * 06-Aug-2009 : Version 9.0 (Sundar);
        • reportFormFieldPopupB is changed.
        - * 29-Jul-2009 : Version 8.4 (Sundar);
        • Previously report data for dashboard stored only page level data. This has been changed to show all the data up to the maximum specified.
        - * 27-Jul-2009 : Version 8.4 (Sundar);
        • Bug due to not showing back button after child report in drilldown is navigated more than - * one page is resolved.
        - * 14-Jul-2009 : Version 8.4 (Sundar);
        • Dashboard reports can now be generated excel as separate sheets or group together in PDF. - * They can also be scheduled.
        - * - */ -package org.openecomp.portalsdk.analytics.controller; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.Writer; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; -import java.util.Vector; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.RaptorRuntimeException; -import org.openecomp.portalsdk.analytics.error.RaptorSchedularException; -import org.openecomp.portalsdk.analytics.error.ReportSQLException; -import org.openecomp.portalsdk.analytics.error.UserDefinedException; -import org.openecomp.portalsdk.analytics.error.ValidationException; -import org.openecomp.portalsdk.analytics.model.DataCache; -import org.openecomp.portalsdk.analytics.model.ReportHandler; -import org.openecomp.portalsdk.analytics.model.ReportLoader; -import org.openecomp.portalsdk.analytics.model.SearchHandler; -import org.openecomp.portalsdk.analytics.model.base.IdNameColLookup; -import org.openecomp.portalsdk.analytics.model.base.IdNameList; -import org.openecomp.portalsdk.analytics.model.base.IdNameSql; -import org.openecomp.portalsdk.analytics.model.base.ReportSecurity; -import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; -import org.openecomp.portalsdk.analytics.model.definition.ReportSchedule; -import org.openecomp.portalsdk.analytics.model.runtime.ChartWebRuntime; -import org.openecomp.portalsdk.analytics.model.runtime.ErrorJSONRuntime; -import org.openecomp.portalsdk.analytics.model.runtime.FormField; -import org.openecomp.portalsdk.analytics.model.runtime.FormatProcessor; -import org.openecomp.portalsdk.analytics.model.runtime.ReportFormFields; -import org.openecomp.portalsdk.analytics.model.runtime.ReportJSONRuntime; -import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; -import org.openecomp.portalsdk.analytics.model.runtime.VisualManager; -import org.openecomp.portalsdk.analytics.model.search.ReportSearchResultJSON; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.ConnectionUtils; -import org.openecomp.portalsdk.analytics.system.DbUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.system.fusion.domain.QuickLink; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.analytics.view.DataRow; -import org.openecomp.portalsdk.analytics.view.DataValue; -import org.openecomp.portalsdk.analytics.view.ReportData; -import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; -import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - -public class ActionHandler extends org.openecomp.portalsdk.analytics.RaptorObject { - - //private static Log debugLogger = LogFactory.getLog(ActionHandler.class.getName()); - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ActionHandler.class); - - private void preserveReportRuntimeAsBackup(HttpServletRequest request) { - HttpSession session = request.getSession(); - ArrayList repAl = null; - - if(session.getAttribute(AppConstants.DRILLDOWN_REPORTS_LIST)!=null) - repAl = ((ArrayList)session.getAttribute(AppConstants.DRILLDOWN_REPORTS_LIST)); - int index = Integer.parseInt(nvl((String) session.getAttribute(AppConstants.DRILLDOWN_INDEX), "0")); - int form_index = Integer.parseInt(nvl((String) session.getAttribute(AppConstants.FORM_DRILLDOWN_INDEX), "0")); - int flag = 0; - if(repAl ==null || repAl.size() <= 0) { - //session.setAttribute(AppConstants.SI_BACKUP_FOR_REP_ID, ((ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID()); - //session.setAttribute(AppConstants.SI_REPORT_RUN_BACKUP, request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)); - repAl = new ArrayList(); - repAl.add((ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)); - - } else { - if(Globals.getMaxDrillDownLevel() < repAl.size()) { - repAl.remove(0); - if(index > 0) index--; - } else if(index < repAl.size()) - repAl.remove(index); - repAl.add(index, (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)); - } - index = index + 1; - // needed to differentiate form and report index to store form parameters for ZK - form_index = form_index + 1; - session.setAttribute(AppConstants.FORM_DRILLDOWN_INDEX, Integer.toString(form_index)); - session.setAttribute(AppConstants.DRILLDOWN_INDEX, Integer.toString(index)); - request.getSession().setAttribute(AppConstants.DRILLDOWN_REPORTS_LIST, repAl); - } // preserveReportRuntimeAsBackup - - private void clearReportRuntimeBackup(HttpServletRequest request) { -// debugLogger.debug("in Action Handler clear is been called."); - HttpSession session = request.getSession(); - session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); - session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); - request.removeAttribute(AppConstants.DRILLDOWN_INDEX); - request.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); - Enumeration enum1 = session.getAttributeNames(); - String attributeName = ""; - while(enum1.hasMoreElements()) { - attributeName = enum1.nextElement(); - if(attributeName.startsWith("parent_")) { - session.removeAttribute(attributeName); - } - } - //request.getSession().removeAttribute(AppConstants.SI_REPORT_RUN_BACKUP); - //request.getSession().removeAttribute(AppConstants.SI_BACKUP_FOR_REP_ID); - } // clearReportRuntimeBackup - - private boolean isDashboardInDrillDownList(HttpServletRequest request) throws RaptorException { - ArrayList aL = (ArrayList) request.getSession().getAttribute( - AppConstants.DRILLDOWN_REPORTS_LIST); - ReportRuntime rr = null; - if(aL ==null || aL.size() <= 0) { - return false; - } else { - for (int i =0; i0 ? --index : 0; - form_index = form_index>0 ? --form_index : 0; - request.setAttribute(AppConstants.DRILLDOWN_INDEX, Integer.toString(index)); - session.setAttribute(AppConstants.DRILLDOWN_INDEX, Integer.toString(index)); - request.setAttribute(AppConstants.FORM_DRILLDOWN_INDEX, Integer.toString(form_index)); - session.setAttribute(AppConstants.FORM_DRILLDOWN_INDEX, Integer.toString(form_index)); - - rr = (ReportRuntime)aL.get(index); - request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); - //clearReportRuntimeBackup(request); - //} - return rr; - } // getReportRuntimeFromBackup - - public String reportRun(HttpServletRequest request, String nextPage) { - String action = nvl(request.getParameter(AppConstants.RI_ACTION), request.getParameter("action")); - ReportRuntime rr = null; - String userId = null; - String formFields = ""; - ReportData rd = null; - boolean isEmailAttachment = false; - boolean fromDashboard = AppUtils.getRequestFlag(request,"fromDashboard"); - request.getSession().setAttribute("login_id", AppUtils.getUserBackdoorLoginId(request)); - - boolean rDisplayContent = AppUtils.getRequestFlag(request, - AppConstants.RI_DISPLAY_CONTENT) - || AppUtils.getRequestFlag(request, "noFormFields"); - - try { - //if "refresh=Y" is in request parameter, session variables are removed. - if(AppUtils.getRequestFlag(request, AppConstants.RI_REFRESH)) { - removeVariablesFromSession(request); - } - - - long currentTime = System.currentTimeMillis(); - request.setAttribute("triggeredStartTime", new Long(currentTime)); - String actionKey = nvl(request.getParameter(AppConstants.RI_ACTION), request.getParameter("action")); - String pdfAttachmentKey = AppUtils.getRequestNvlValue(request, "pdfAttachmentKey"); - String parent = ""; - int parentFlag = 0; - if(!nvl(request.getParameter("parent"), "").equals("N")) parent = nvl(request.getParameter("parent"), ""); - if(parent.startsWith("parent_")) parentFlag = 1; - - if (pdfAttachmentKey.length()<=0) { - if(actionKey.equals("report.download.page") || actionKey.equals("report.download") || actionKey.equals("report.download.pdf") || actionKey.equals("report.download.excel2007") || actionKey.equals("report.csv.download") || actionKey.equals("report.text.download")) { - if(parentFlag == 1) rr = (ReportRuntime) request.getSession().getAttribute(parent+"_rr"); - if(rr==null) - rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); //changing session to request - if(!(rr!=null && fromDashboard)) { - userId = AppUtils.getUserID(request); - boolean isFromReportLog = AppUtils.getRequestFlag(request, "fromReportLog"); - int downloadLimit = 0; - if(rr!=null) - downloadLimit = (rr.getMaxRowsInExcelDownload()>0)?rr.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); - if(actionKey.equals("report.csv.download")) - downloadLimit = Globals.getCSVDownloadLimit(); - - if(rr!=null && rr.getReportType().equals(AppConstants.RT_LINEAR)) { - String sql_whole = rr.getReportDataSQL(userId, downloadLimit, request); - request.setAttribute(AppConstants.RI_REPORT_SQL_WHOLE, sql_whole); - } else if(rr!=null && rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { - rd = rr.loadReportData(-1, userId, downloadLimit,request, false); /* TODO: should be changed to true */ - request.getSession().setAttribute(AppConstants.RI_REPORT_DATA, rd); - } - if(!isFromReportLog) { - if(pdfAttachmentKey!=null && pdfAttachmentKey.length()>0) { - if(actionKey.equals("report.download")) { - rr.logReportExecutionTime(userId, "",AppConstants.RLA_SCHEDULED_DOWNLOAD_EXCEL, formFields); - } else if (actionKey.equals("report.download.pdf")) { - rr.logReportExecutionTime(userId, "",AppConstants.RLA_SCHEDULED_DOWNLOAD_PDF, formFields); - } else if (actionKey.equals("report.download.excel2007")) { - rr.logReportExecutionTime(userId, "",AppConstants.RLA_SCHEDULED_DOWNLOAD_EXCELX, formFields); - } - } else { - if(actionKey.equals("report.download") ) { - rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_EXCEL, formFields); - } else if (actionKey.equals("report.download.pdf")) { - rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_PDF, formFields); - } else if (actionKey.equals("report.csv.download")) { - rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_CSV, formFields); - } else if (actionKey.equals("report.text.download")) { - rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_TEXT, formFields); - } else if (actionKey.equals("report.download.page")) { - rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_PAGE_EXCEL, formFields); - } else if (actionKey.equals("report.download.excel2007")) { - rr.logReportExecutionTime(userId, "",AppConstants.RLA_DOWNLOAD_EXCELX, formFields); - } - } - } - return nextPage; - } - - } - }// pdfAttachmentKey - String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); - rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); //changing session to request - - String reportIDFromSession = (rr!=null)?rr.getReportID():""; - logger.debug(EELFLoggerDelegate.debugLogger, ("in Action Handler ********** " + reportID + " " + reportIDFromSession + " "+ actionKey)); -// ReportRuntime rr = (ReportRuntime) request.getAttribute(AppConstants.SI_REPORT_RUNTIME); - logger.debug(EELFLoggerDelegate.debugLogger, ("^^^^^^^^^^^^^^report ID from session " + ((rr!=null)?rr.getReportID():"no report id in session"))); - // if(rr!=null && !(rr.getReportID().equals(reportID))) { -// rr = null; -// request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, null); -// } - - ReportHandler rh1 = new ReportHandler(); - ReportRuntime rr1 = null; - - //debugLogger.debug("Report ID B4 rr1 in ActionHandler " - // + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); - - - //try { - boolean isGoBackAction = AppUtils.getRequestFlag(request, AppConstants.RI_GO_BACK); - - if (AppUtils.getRequestFlag(request, AppConstants.RI_SHOW_BACK_BTN) && !isGoBackAction) { - // debugLogger.debug("Preserving report"); - if(!reportID.equals(reportIDFromSession)) - preserveReportRuntimeAsBackup(request); - } - - if(reportID !=null) - rr1 = rh1.loadReportRuntime(request, reportID, true, 1); - //} catch(Exception e) { - - // } -// debugLogger.debug("Report ID After rr1 in ActionHandler " -// + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); - if(rr1!=null && rr1.getReportType().equals(AppConstants.RT_DASHBOARD)) { - int DASH=7; - int requestFlag = DASH; - ReportHandler rh = new ReportHandler(); - // Added below statement to add parent dashboard report id in session. - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REP_ID, reportID); - //rr = null; - // get dashboard HTML from report runtime. getListOfReportsFromDashBoardHTML - String strHTML = rr1.getDashboardLayoutHTML(); - - //System.out.println("StrHTML " + strHTML); - // call getListOfReportsFromDashBoardHTML returns HashMap - - TreeMap treeMap = getListOfReportsFromDashBoardHTML(strHTML); - //System.out.println("Size " + hashMap.size()); - Set set = treeMap.entrySet(); - String value = ""; - - HashMap reportsRuntimeMap = new HashMap(); - HashMap reportDataMap = new HashMap(); - HashMap reportChartDataMap = new HashMap(); - // displayTypeMap differentiates whether report need to be displayed as data or chart - HashMap reportDisplayTypeMap = new HashMap(); - - userId = null; - userId = AppUtils.getUserID(request); - int pageNo = -1; - //int downloadLimit = (rr1.getMaxRowsInExcelDownload()>0)?rr1.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); - int downloadLimit = 0; - int rep_idx = 0; - int widthFlag = 0; - int heightFlag = 0; - ReportRuntime rrDashboardReports = null; - Integer intObj = null; - ReportRuntime similiarReportRuntime = null; - rd = null; - DataSet ds = null; - String reportIDFromMap = null; - int record = 0; - boolean buildReportdata = true; - - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - record++; - Map.Entry entry = (Entry) iter.next(); - //System.out.println("Key "+ entry.getKey()); - //System.out.println("Value "+ entry.getValue()); - reportIDFromMap = entry.getValue().toString().substring(1); - // The below line is used to optimize, so that if there is already same report id it wouldn't go through the whole process - similiarReportRuntime = getSimiliarReportRuntime(reportsRuntimeMap, reportIDFromMap); - if(similiarReportRuntime != null ) { - rrDashboardReports = (ReportRuntime) getSimiliarReportRuntime(reportsRuntimeMap, reportIDFromMap).clone(); - intObj = getKey(reportsRuntimeMap,reportIDFromMap); - } else { - rrDashboardReports = rh.loadReportRuntime(request, reportIDFromMap, true, requestFlag); - } - if(entry.getValue().toString().toLowerCase().startsWith("c")) { - rrDashboardReports.setDisplayMode(ReportRuntime.DISPLAY_CHART_ONLY); - } else { - rrDashboardReports.setDisplayMode(ReportRuntime.DISPLAY_DATA_ONLY); - } - - downloadLimit = (rrDashboardReports.getMaxRowsInExcelDownload()>0)?rrDashboardReports.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); - if (new Integer(nvl(rrDashboardReports.getDataContainerWidth(),"100")).intValue() >100) widthFlag = 1; - if (new Integer(nvl(rrDashboardReports.getDataContainerHeight(),"100")).intValue() >100) heightFlag = 1; - - if(record == 1) { - if(rrDashboardReports.getReportFormFields()!=null && rrDashboardReports.getReportFormFields().size()>0) { - buildReportdata = false; - if(rDisplayContent) buildReportdata = true; - } - } - - if(buildReportdata) { - if(similiarReportRuntime != null ) { - rd = (ReportData) reportDataMap.get(intObj); - ds = (DataSet) reportChartDataMap.get(intObj); - } else { - if (!rrDashboardReports.getReportType().equals(AppConstants.RT_HIVE)) - rd = rrDashboardReports.loadReportData(pageNo, userId, downloadLimit,request, false /*download*/); - else - rd = rrDashboardReports.loadHiveLinearReportData(rrDashboardReports.getReportSQL(), userId, 2,request); - ds = rrDashboardReports.loadChartData(userId,request); - } - } - - - long totalTime = System.currentTimeMillis() - currentTime; - formFields = AppUtils.getRequestNvlValue(request, "formFields"); - if(buildReportdata) { - rrDashboardReports.logReportRun(userId, String.valueOf(totalTime),formFields); - rrDashboardReports.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_EXECUTION_TIME, formFields); - } - - /*reportsRuntimeMap.put(new Integer(entry.getKey().toString()), rrDashboardReports); - reportDataMap.put(new Integer(entry.getKey().toString()), rd); - reportChartDataMap.put(new Integer(entry.getKey().toString()), ds); - reportDisplayTypeMap.put(new Integer(entry.getKey().toString()), entry.getValue().toString().substring(0,1));*/ - - reportsRuntimeMap.put(new Integer(entry.getKey().toString())+"_"+rrDashboardReports.getReportID(), rrDashboardReports); - reportDisplayTypeMap.put(new Integer(entry.getKey().toString())+"_"+rrDashboardReports.getReportID(), entry.getValue().toString().substring(0,1)); - if(buildReportdata) { - reportDataMap.put(new Integer(entry.getKey().toString())+"_"+rrDashboardReports.getReportID(), rd); - reportChartDataMap.put(new Integer(entry.getKey().toString())+"_"+rrDashboardReports.getReportID(), ds); - } - - } - - /*if(widthFlag ==1) request.getSession().setAttribute("extendedWidth", "Y"); - else request.getSession().removeAttribute("extendedWidth"); - if(heightFlag ==1) request.getSession().setAttribute("extendedHeight", "Y"); - else request.getSession().removeAttribute("extendedHeight"); - */ - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP, new TreeMap(reportsRuntimeMap)); - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP, new TreeMap(reportDisplayTypeMap)); - if(buildReportdata) { - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP, new TreeMap(reportDataMap)); - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP, new TreeMap(reportChartDataMap)); - } -// debugLogger.debug("I am inside this if " + rr1.getReportType() + " "+rr1.getReportID()); - request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr1); //changing session to request - //request.setAttribute(AppConstants.SI_REPORT_RUNTIME, rr1); - if((String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!= null || rr1.getReportType().equals(AppConstants.RT_DASHBOARD)) { - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME, rr1); - } - - return "raptor/report_dashboard_run_container.jsp"; - } else { - fromDashboard = AppUtils.getRequestFlag(request,"fromDashboard"); - if(isDashboardInDrillDownList(request)) fromDashboard= true; - - if(!fromDashboard) { - request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); - request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); - request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP); - request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); - request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_REP_ID); - request.getSession().removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME); - request.getSession().removeAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP); - request.getSession().removeAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP); - } - //String pdfAttachmentKey = AppUtils.getRequestValue(request, "pdfAttachmentKey"); - String report_email_sent_log_id = AppUtils.getRequestValue(request, "log_id"); - logger.debug(EELFLoggerDelegate.debugLogger, ("Email PDF" + pdfAttachmentKey+" "+ report_email_sent_log_id)); - - //email pdf attachment specific - if(nvl(pdfAttachmentKey).length()>0 && report_email_sent_log_id !=null) - isEmailAttachment = true; - if(isEmailAttachment) { - /* String query = "Select user_id, rep_id from CR_REPORT_EMAIL_SENT_LOG" + - " where rownum = 1" + - " and gen_key='"+pdfAttachmentKey.trim()+"'" + - " and log_id ="+report_email_sent_log_id.trim() + - " and (sysdate - sent_date) < 1 ";*/ - - - String query = Globals.getDownloadAllEmailSent(); - query = query.replace("[pdfAttachmentKey.trim()]", pdfAttachmentKey.trim()); - query = query.replace("[report_email_sent_log_id.trim()]", report_email_sent_log_id.trim()); - - DataSet ds = DbUtils.executeQuery(query, 1); - if(!ds.isEmpty()) { - userId = ds.getString(0,"user_id"); - reportID = ds.getString(0, "rep_id"); - request.setAttribute("schedule_email_userId", userId); - } else { - request.setAttribute("message", "This link has expired, please login and regenerate the report"); - return "raptor/message.jsp"; - } - } else userId = AppUtils.getUserID(request); -// debugLogger.debug("Report ID b4 showbutton in ActionHandler " -// + ( request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)!=null?((ReportRuntime)request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME)).getReportID():"Not in session")); -// debugLogger.debug("Report ID " + reportID + " " + reportIDFromSession); - - // Scheduling Dashoard report - if(reportID !=null && nvl(pdfAttachmentKey).length()>0) - rr = rh1.loadReportRuntime(request, reportID, true, 1); - if(rr!=null && rr.getReportType().equals(AppConstants.RT_DASHBOARD) && nvl(pdfAttachmentKey).length()>0) { - int DASH=7; - int requestFlag = DASH; - ReportHandler rh = new ReportHandler(); - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REP_ID, reportID); - //rr = null; - // get dashboard HTML from report runtime. getListOfReportsFromDashBoardHTML - String strHTML = rr.getDashboardLayoutHTML(); - //System.out.println("StrHTML " + strHTML); - // call getListOfReportsFromDashBoardHTML returns HashMap - - TreeMap treeMap = getListOfReportsFromDashBoardHTML(strHTML); - //System.out.println("Size " + hashMap.size()); - Set set = treeMap.entrySet(); - String value = ""; - - HashMap reportsRuntimeMap = new HashMap(); - HashMap reportDataMap = new HashMap(); - HashMap reportChartDataMap = new HashMap(); - HashMap reportDisplayTypeMap = new HashMap(); - - userId = null; - userId = AppUtils.getUserID(request); - int pageNo = -1; - int downloadLimit = 0; - int rep_idx = 0; - int widthFlag = 0; - int heightFlag = 0; - ReportRuntime rrDashboardReports = null; - Integer intObj = null; - ReportRuntime similiarReportRuntime = null; - rd = null; - DataSet ds = null; - String reportIDFromMap = null; - int record = 0; - boolean buildReportdata = true; - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - record++; - Map.Entry entry = (Entry) iter.next(); - - reportIDFromMap = entry.getValue().toString().substring(1); - similiarReportRuntime = getSimiliarReportRuntime(reportsRuntimeMap, reportIDFromMap); - if(similiarReportRuntime != null ) { - rrDashboardReports = getSimiliarReportRuntime(reportsRuntimeMap, reportIDFromMap); - intObj = getKey(reportsRuntimeMap,reportIDFromMap); - } else { - rrDashboardReports = rh.loadReportRuntime(request, reportIDFromMap, true, requestFlag); - } - - downloadLimit = (rrDashboardReports.getMaxRowsInExcelDownload()>0)?rrDashboardReports.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); - - if (new Integer(nvl(rrDashboardReports.getDataContainerWidth(),"100")).intValue() >100) widthFlag = 1; - if (new Integer(nvl(rrDashboardReports.getDataContainerHeight(),"100")).intValue() >100) heightFlag = 1; - if(record == 1) { - if(rrDashboardReports.getReportFormFields()!=null && rrDashboardReports.getReportFormFields().size()>0) { - buildReportdata = false; - if(rDisplayContent) buildReportdata = true; - } - } - if(buildReportdata) { - if(similiarReportRuntime != null ) { - rd = (ReportData) reportDataMap.get(intObj); - ds = (DataSet) reportChartDataMap.get(intObj); - } else { - - if (!rrDashboardReports.getReportType().equals(AppConstants.RT_HIVE)) - rd = rrDashboardReports.loadReportData(pageNo, userId, downloadLimit,request, false /*download*/); - else - rd = rrDashboardReports.loadHiveLinearReportData(rrDashboardReports.getReportSQL(), userId, 2,request); - ds = rrDashboardReports.loadChartData(userId,request); - } - } - - - - long totalTime = System.currentTimeMillis() - currentTime; - formFields = AppUtils.getRequestNvlValue(request, "formFields"); - - rrDashboardReports.logReportRun(userId, String.valueOf(totalTime),formFields); - rrDashboardReports.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_EXECUTION_TIME, formFields); - - reportsRuntimeMap.put(new Integer(entry.getKey().toString()), rrDashboardReports); - reportDisplayTypeMap.put(new Integer(entry.getKey().toString()), entry.getValue().toString().substring(0,1)); - if(buildReportdata) { - reportDataMap.put(new Integer(entry.getKey().toString()), rd); - reportChartDataMap.put(new Integer(entry.getKey().toString()), ds); - //reportDisplayTypeMap.put(new Integer(entry.getKey().toString()), entry.getValue().toString().substring(0,1)); - } - } - - /*if(widthFlag ==1) request.getSession().setAttribute("extendedWidth", "Y"); - else request.getSession().removeAttribute("extendedWidth"); - if(heightFlag ==1) request.getSession().setAttribute("extendedHeight", "Y"); - else request.getSession().removeAttribute("extendedHeight"); - */ - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP, new TreeMap(reportsRuntimeMap)); - request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); //changing session to request - if(buildReportdata) { - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP, new TreeMap(reportDisplayTypeMap)); - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP, new TreeMap(reportDataMap)); - request.getSession().setAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP, new TreeMap(reportChartDataMap)); - } - //request.setAttribute(AppConstants.SI_REPORT_RUNTIME, rr1); - //return nextPage; - } else { - - // Ends - - -// debugLogger.debug("Action Handler *****************" + new java.util.Date()+ " " + isGoBackAction); - ReportHandler rh = new ReportHandler(); - //rr = null; // COMMENT THIS LINE - boolean resetParams = AppUtils.getRequestFlag(request, - AppConstants.RI_RESET_PARAMS); - boolean resetAction = AppUtils.getRequestFlag(request, - AppConstants.RI_RESET_ACTION); - boolean refresh = false; - if (resetAction) { - rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); - resetParams=true; - refresh = true; - if(rr!=null) { - rr.setParamValues(request, resetParams,refresh); - request.getSession().removeAttribute(AppConstants.RI_REPORT_DATA); - rr.resetVisualSettings(); - } - return nextPage; - } - - /*if (isGoBackAction) { -// debugLogger.debug("Report back in action handler " + ((ReportRuntime) request.getSession().getAttribute( -// AppConstants.SI_REPORT_RUN_BACKUP))!=null?((ReportRuntime) request.getSession().getAttribute( -// AppConstants.SI_REPORT_RUN_BACKUP)).getReportID():((ReportRuntime) request.getSession().getAttribute( -// AppConstants.SI_REPORT_RUN_BACKUP))); - rr = null; - rr = getReportRuntimeFromBackup(request); - if (rr == null) - throw new Exception("[ActionHandler.reportRun] Report backup not found"); - reportID = rr.getReportID(); - } else {*/ - - logger.debug(EELFLoggerDelegate.debugLogger, ("Ocurring during Schedule ")); - //TODO differentiate Schedule with other actions -// if(isEmailAttachment) { -// -// } else { -// -// } - rr = rh.loadReportRuntime(request, reportID); - //setParamValues called for Drilldown to display formfield - //rr.setParamValues(request, false,true); - - //} // else - - ArrayList aL = (ArrayList)request.getSession().getAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); - ReportRuntime aLR = null; - if(aL != null) { -// for (int i = 1; i < aL.size(); i++) { -// aLR = (ReportRuntime) aL.get(i); -// if (!aLR.getReportID().equals(reportID)) { -// request.setAttribute(AppConstants.RI_SHOW_BACK_BTN, "Y"); -// } -// } -// if(reportID.equals(reportIDFromSession)) { - aLR = (ReportRuntime) aL.get(0); - if (aLR!=null && !aLR.getReportID().equals(reportID)) { - request.setAttribute(AppConstants.RI_SHOW_BACK_BTN, "Y"); - } -// } - } - - if(rDisplayContent) - rr.setDisplayFlags(true, true); - - if (rr.getDisplayContent()) { - int pageNo = 0; - if (isGoBackAction) - pageNo = rr.getCachedPageNo(); - else { - try { - pageNo = Integer.parseInt(AppUtils.getRequestNvlValue(request, AppConstants.RI_NEXT_PAGE)); - } catch (Exception e) { - } - - String vAction = AppUtils.getRequestNvlValue(request, - AppConstants.RI_VISUAL_ACTION); - String vCoId = AppUtils.getRequestNvlValue(request, - AppConstants.RI_DETAIL_ID); - if (vAction.equals(AppConstants.VA_HIDE)) - rr.hideColVisual(vCoId); - else if (vAction.equals(AppConstants.VA_SHOW)) - rr.showColVisual(vCoId); - else if (vAction.equals(AppConstants.VA_SORT)) { - rr.sortColVisual(vCoId); - pageNo = 0; - } // else - } // else - - int downloadLimit = (rr.getMaxRowsInExcelDownload()>0)?rr.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); - if(isEmailAttachment) { - String limit = nvl(request.getParameter("download_limit"),"1000"); - downloadLimit = Integer.parseInt(limit); - } - //if (action.startsWith("mobile")) rr.setPageSize(5); - long reportTime = System.currentTimeMillis(); - if (!rr.getReportType().equals(AppConstants.RT_HIVE)) - rd = rr.loadReportData(pageNo, userId, downloadLimit,request,false /*download*/); - else - rd = rr.loadHiveLinearReportData(rr.getReportSQL(), userId, 2,request); - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] ------->Time Taken for the loading report data --- " + (System.currentTimeMillis() - reportTime))); - ReportData rd_whole = null; - boolean hideReportMap = rr.isDisplayOptionHideMap()||AppUtils.getRequestNvlValue(request, "noMap").equals("Y"); -/* if (Globals.getMapAllowedYN().equals("Y") && !hideReportMap && rr.getReportMap()!=null){ - rd_whole = rr.loadReportData(-1, userId, downloadLimit,request); - } -*/ - request.getSession().setAttribute(AppConstants.RI_REPORT_DATA, rd); - //if (Globals.getMapAllowedYN().equals("Y") && !hideReportMap && (rr.getReportMap()!=null && rr.getReportMap().getLatColumn()!=null && rr.getReportMap().getLongColumn()!=null)) { - if(rr!=null && rr.getReportType().equals(AppConstants.RT_LINEAR)) { - String sql_whole = rr.getReportDataSQL(userId, downloadLimit, request); - request.setAttribute(AppConstants.RI_REPORT_SQL_WHOLE, sql_whole); - } else if(rr.getReportType().equals(AppConstants.RT_HIVE)) { - String sql_whole = rr.getReportSQL(); - request.setAttribute(AppConstants.RI_REPORT_SQL_WHOLE, sql_whole); - } - //} - //request.setAttribute(AppConstants.RI_REPORT_DATA_WHOLE, rd_whole); - // if(rr.getReportDataSize() > Globals.getFlatFileLowerLimit() && rr.getReportDataSize() <= Globals.getFlatFileUpperLimit() ) { - // rr.setFlatFileName(rh.saveFlatFile(request, rd, rr - // .getParamNameValuePairs(), rr.getReportName(), rr.getReportDescr())); - // } - //if(actionKey!=null && actionKey.equals("report.download")) { -// rr.setExcelPageFileName(rh.saveAsExcelFile(request, rd, rr -// .getParamNameValuePairs(), rr.getReportName(), rr.getReportDescr())); - //} - if (!rr.getReportType().equals(AppConstants.RT_HIVE)) { - long currentChartTime = System.currentTimeMillis(); - DataSet chartDS = rr.loadChartData(userId,request); - if(chartDS != null) - request.getSession().setAttribute(AppConstants.RI_CHART_DATA, rr.loadChartData(userId,request)); - else - request.getSession().removeAttribute(AppConstants.RI_CHART_DATA); - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] ------->Time Taken for the loading chart data --- " + (System.currentTimeMillis() - currentChartTime))); - } - -/* if((String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) { - request.getSession().setAttribute("FirstDashReport", rr); - } -*/ - } - request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rr); //changing session to request - request.getSession().setAttribute(AppConstants.RI_REPORT_DATA, rd); - } // else - long totalTime = System.currentTimeMillis() - currentTime; - formFields = AppUtils.getRequestNvlValue(request, "formFields"); - request.setAttribute(AppConstants.RLA_EXECUTION_TIME, "" + totalTime); - - - boolean isFromReportLog = AppUtils.getRequestFlag(request, "fromReportLog"); - if(!isFromReportLog) { - if(pdfAttachmentKey!=null && pdfAttachmentKey.length()>0) { - if(actionKey.equals("report.download")) { - rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_SCHEDULED_DOWNLOAD_EXCEL, formFields); - } else if (actionKey.equals("report.download.pdf")) { - rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_SCHEDULED_DOWNLOAD_PDF, formFields); - } - } else { - if(actionKey.equals("report.download") ) { - rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_DOWNLOAD_EXCEL, formFields); - } else if (actionKey.equals("report.download.pdf")) { - rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_DOWNLOAD_PDF, formFields); - } else if (actionKey.equals("report.csv.download")) { - rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_DOWNLOAD_CSV, formFields); - } else if (actionKey.equals("report.text.download")) { - rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_DOWNLOAD_TEXT, formFields); - } else { - - //rr.logReportRun(userId, String.valueOf(totalTime),formFields); - if(rd!=null && !action.equals("report.run.container")) - rr.logReportExecutionTime(userId, String.valueOf(totalTime),AppConstants.RLA_EXECUTION_TIME, formFields); - } - } - } else { - rr.logReportExecutionTimeFromLogList(userId, String.valueOf(totalTime),formFields); - } - -/* if((String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) { - reportID = (String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID); - ReportRuntime rrDash = rh1.loadReportRuntime(request, reportID, true, 1); - request.getSession().setAttribute(AppConstants.SI_REPORT_RUNTIME, rrDash); - } -*/ - if(rr.isDrillDownURLInPopupPresent()) { - request.getSession().setAttribute("parent_"+rr.getReportID()+"_rr", rr); - request.getSession().setAttribute("parent_"+rr.getReportID()+"_rd", rd); - } - - if(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { - return "raptor/report_crosstab_run_container.jsp"; - } else if (rr.getReportType().equals(AppConstants.RT_HIVE) && !isEmailAttachment) { - return "raptor/report_hive_run_container.jsp"; - } - } // else - - boolean isEmbedded = false; - Object temp = request.getSession().getAttribute("isEmbedded"); - if(temp!=null){ - isEmbedded = (boolean)temp; - } - if(isEmbedded && !action.equals("chart.run")){ - HashMap embeddedReportsRuntimeMap = null; - HashMap embeddedReportsDataMap = null; - if(request.getSession().getAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP)!= null){ - embeddedReportsRuntimeMap = (HashMap)request.getSession().getAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP); - } else { - embeddedReportsRuntimeMap = new HashMap(); - } - if(request.getSession().getAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP)!= null){ - embeddedReportsDataMap = (HashMap)request.getSession().getAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP); - } else { - embeddedReportsDataMap = new HashMap(); - } - embeddedReportsRuntimeMap.put(rr.getReportID(), rr); - embeddedReportsDataMap.put(rr.getReportID(), rd); - - - request.getSession().setAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP, embeddedReportsRuntimeMap); - request.getSession().setAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP, embeddedReportsDataMap); - - } - - ReportJSONRuntime reportJSONRuntime = rr.createReportJSONRuntime(request, rd); - ObjectMapper mapper = new ObjectMapper(); - //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); - //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - String jsonInString = ""; - try { - jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(reportJSONRuntime); - } catch (Exception ex) { - ex.printStackTrace(); - - } - return jsonInString; - } catch (RaptorException e) { - try { - e.printStackTrace(); - - if(rr!=null) { // when user tries report they don't have access this should not throw exception that's why this if is added. - if(isEmailAttachment) - rr.logReportExecutionTime(userId, "", "Scheduled: " + AppConstants.RLA_ERROR, formFields); - else - rr.logReportExecutionTime(userId, "", "On Demand: " + AppConstants.RLA_ERROR, formFields); - } - - ErrorJSONRuntime errorJSONRuntime = new ErrorJSONRuntime(); - errorJSONRuntime.setErrormessage(e.getMessage()); - errorJSONRuntime.setStacktrace(getStackTrace(e)); - ObjectMapper mapper = new ObjectMapper(); - //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); - //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - String jsonInString = ""; - try { - jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(errorJSONRuntime); - } catch (Exception ex) { - ex.printStackTrace(); - - } - return jsonInString; - - } catch (RaptorException ex) { - nextPage = (new ErrorHandler()).processFatalError(request, ex); - ErrorJSONRuntime errorJSONRuntime = new ErrorJSONRuntime(); - errorJSONRuntime.setErrormessage(ex.getMessage()); - errorJSONRuntime.setStacktrace(getStackTrace(ex)); - ObjectMapper mapper = new ObjectMapper(); - //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); - //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - String jsonInString = ""; - try { - jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(errorJSONRuntime); - } catch (Exception ex1) { - ex1.printStackTrace(); - } - return jsonInString; - } - //nextPage = (new ErrorHandler()).processFatalError(request, e); - } catch (Throwable t) { - t.printStackTrace(); - ErrorJSONRuntime errorJSONRuntime = new ErrorJSONRuntime(); - errorJSONRuntime.setErrormessage(t.toString()); - errorJSONRuntime.setStacktrace(getStackTrace(t)); - ObjectMapper mapper = new ObjectMapper(); - //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); - //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - String jsonInString = ""; - try { - jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(errorJSONRuntime); - } catch (Exception ex) { - ex.printStackTrace(); - - } - return jsonInString; - - } - //return nextPage; - } // reportRun - - public static String getStackTrace(Throwable aThrowable) { - Writer result = new StringWriter(); - PrintWriter printWriter = new PrintWriter(result); - aThrowable.printStackTrace(printWriter); - return result.toString(); - } - - /** - * The below method is used to optimize, so that if there is already same report id in hashMap it wouldn't go through the whole process again. - **/ - private ReportRuntime getSimiliarReportRuntime(HashMap reportsRuntimeMap, String reportID) { - Set set = reportsRuntimeMap.entrySet(); - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - if (((ReportRuntime) entry.getValue()).getReportID().equals(reportID)) { - return (ReportRuntime) entry.getValue(); - } - } - return null; - } - - private Integer getKey(HashMap reportsRuntimeMap, String reportID) { - Set set = reportsRuntimeMap.entrySet(); - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - if (((ReportRuntime) entry.getValue()).getReportID().equals(reportID)) { - return new Integer(((String) entry.getKey()).substring(2)); - } - } - return null; - } - - public String reportSearch(HttpServletRequest request, String nextPage) { - return reportSearchExecute(request, nextPage); - } // reportSearch - - public String reportSearchUser(HttpServletRequest request, String nextPage) { - removeVariablesFromSession(request); - request.setAttribute(AppConstants.RI_USER_REPORTS, "Y"); - return reportSearchExecute(request, nextPage); - } // reportSearchUser - - public String reportSearchPublic(HttpServletRequest request, String nextPage) { - removeVariablesFromSession(request); - request.setAttribute(AppConstants.RI_PUBLIC_REPORTS, "Y"); - return reportSearchExecute(request, nextPage); - } // reportSearchPublic - - public String reportSearchFavorites(HttpServletRequest request, String nextPage) { - removeVariablesFromSession(request); - request.setAttribute(AppConstants.RI_FAVORITE_REPORTS, "Y"); - return reportSearchExecute(request, nextPage); - } // reportSearchFavorites - - public String reportSearchExecute(HttpServletRequest request, String nextPage) { - removeVariablesFromSession(request); - try { - SearchHandler sh = new SearchHandler(); - ReportSearchResultJSON sr = sh.loadReportSearchResult(request); - return sr.getJSONString(); - //request.setAttribute(AppConstants.RI_SEARCH_RESULT, sr); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // reportSearchExecute - - public String reportChartRun(HttpServletRequest request, String nextPage) { - ChartWebRuntime cwr = new ChartWebRuntime(); - return cwr.generateChart(request, false); //no data - } // reportSearchExecute - - public String reportChartDataRun(HttpServletRequest request, String nextPage) { - ChartWebRuntime cwr = new ChartWebRuntime(); - return cwr.generateChart(request); //data - } // reportSearchExecute - - - // public String reportRunExecute(HttpServletRequest request, String nextPage) { -// try { -// ReportRunHandler rh = new ReportRunHandler(); -// ReportRunResultJSON sr = rh.loadReportRunResult(request); -// return sr.getJSONString(); -// //request.setAttribute(AppConstants.RI_SEARCH_RESULT, sr); -// } catch (RaptorException e) { -// nextPage = (new ErrorHandler()).processFatalError(request, e); -// } -// -// return nextPage; -// } - - public String getQuickLinksJSON(HttpServletRequest request, String nextPage) { - String jsonInString = null; - try { - ArrayList quickLinks = ReportLoader.getQuickLinksJSON(request, request.getParameter("quick_links_menu_id"),true); - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(quickLinks); - - } catch (Exception e) { - e.printStackTrace(); - } - return jsonInString; - } - - public String processScheduleReportList(HttpServletRequest request, String nextPage) { - String reportID = ""; - reportID = AppUtils.getRequestNvlValue(request, "schedule_reports"); - if (nvl(reportID).length()<=0) - reportID = AppUtils.getRequestNvlValue(request, AppConstants.RI_REPORT_ID); - // Added for form field chaining in schedule tab so that setParamValues() is called - request.setAttribute(AppConstants.SCHEDULE_ACTION, "Y"); - - try { - boolean isAdmin = AppUtils.isAdminUser(request); - boolean check = ReportLoader.doesUserCanScheduleReport(request, null); - - logger.debug(EELFLoggerDelegate.debugLogger, ("^^^^^^^^^^^^^Check " + check + " Admin "+ isAdmin)); - - if(check || isAdmin) { - if(reportID.length()>0) { - ReportHandler rh = new ReportHandler(); - ReportDefinition rdef = rh.loadReportDefinition(request, reportID); - request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); - ReportSchedule reportSchedule = null; - if(rdef!=null) { - reportSchedule = new ReportSchedule(reportID, AppUtils.getUserID(request), false, request); - } - request.getSession().setAttribute(AppConstants.SI_REPORT_SCHEDULE, reportSchedule); - } - } else { - //String message = "You have reached your schedule limit. Please visit this page again after removing your old schedules in \"My Schedule\" section."; - String message = "You have reached the scheduled report limit for your Login ID. Please remove any old schedule requests in the \"My Scheduled Reports\" screen before attempting to schedule any additional reports."; - nextPage = (new ErrorHandler()).processFatalError(request, new RaptorSchedularException(message)); - } - - } catch(Exception ex) { ex.printStackTrace();} - return nextPage; - } - - public String processSchedule(HttpServletRequest request, String nextPage) { - - // Added for form field chaining in schedule tab so that setParamValues() is called - - request.setAttribute(AppConstants.SCHEDULE_ACTION, "Y"); - if(request.getSession().getAttribute(AppConstants.SI_REPORT_SCHEDULE)!=null && (!AppUtils.getRequestNvlValue(request, AppConstants.RI_ACTION).equals("report.schedule_only_from_search"))) { - String action = nvl(request.getParameter(AppConstants.RI_WIZARD_ACTION), - AppConstants.WA_BACK); - String scheduleID = ""; - scheduleID = AppUtils.getRequestValue(request, AppConstants.RI_SCHEDULE_ID); - ReportSchedule reportSchedule = null; - - if( nvl(scheduleID).length() <= 0) { - reportSchedule = (ReportSchedule) request.getSession().getAttribute(AppConstants.SI_REPORT_SCHEDULE); - scheduleID = reportSchedule.getScheduleID(); - } - - String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); - try { - boolean isAdmin = AppUtils.isAdminUser(request); - boolean check = ReportLoader.doesUserCanScheduleReport(request, scheduleID); - if(!isAdmin && !check) { - String message = "You have reached the scheduled report limit for your Login ID. Please remove any old schedule requests in the My Scheduled Reports screen before attempting to schedule any additional reports."; - nextPage = (new ErrorHandler()).processFatalError(request, new RaptorSchedularException(message)); - return nextPage; - } - - } catch (Exception ex) { ex.printStackTrace();} - if(reportSchedule == null) reportSchedule = new ReportSchedule(reportID, scheduleID, AppUtils.getUserID(request), request); - String formFields = ""; - formFields = reportSchedule.getFormFields(); - formFields = (formFields.length()>1)?formFields.substring(1):formFields; - String formFieldsArr[] = formFields.split("&"); - String sessionParams[] = Globals.getSessionParamsForScheduling().split(","); - - for (int i=0; i1)?formFields.substring(1):formFields; - String formFieldsArr[] = formFields.split("&"); - String sessionParams[] = Globals.getSessionParamsForScheduling().split(","); - - for (int i=0; i 0) - ws.performGoToStep(goToStep); - else - ws.performAction(action, rdef); - } catch (ValidationException ve) { - (new ErrorHandler()).processError(request, ve); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } catch (Throwable t) { - t.printStackTrace(); - } - - return nextPage; - } // reportWizard - - public String refreshCache ( HttpServletRequest request, String nextPage ) { - //DataCache.refreshReportTableSources(); - removeVariablesFromSession(request); - DataCache.refreshAll(); - Globals.getAppUtils().resetUserCache(); - request.setAttribute("message", "Cache Refreshed"); - return nextPage; - } - public String reportCreate(HttpServletRequest request, String nextPage) { - try { - removeVariablesFromSession(request); - ReportDefinition rdef = ReportDefinition.createBlank(request); - - request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); - // request.setAttribute(AppConstants.RI_CUR_STEP, - // AppConstants.WS_DEFINITION); - DataCache.refreshReportTableSources(); - request.getSession().removeAttribute("remoteDB"); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // reportCreate - - public String reportImportSave(HttpServletRequest request, String nextPage) { - try { - String reportXML = nvl(AppUtils.getRequestValue(request, "reportXML")).trim(); - - ReportHandler rh = new ReportHandler(); - ReportDefinition rdef = rh.createReportDefinition(request, "-1", reportXML); - rdef.updateReportDefType(); - rdef.generateWizardSequence(request); - rdef.setReportName("Import: " + rdef.getReportName()); - rdef.clearAllDrillDowns(); - - request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); - } catch (RaptorException e) { - request.setAttribute("error_extra_msg", "Unable to parse XML. Nested error: "); - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // reportImportSave - - private String reportLoad(HttpServletRequest request, String nextPage, boolean asCopy) { - try { - String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); - - ReportHandler rh = new ReportHandler(); - ReportDefinition rdef = rh.loadReportDefinition(request, reportID); - if (asCopy) - rdef.setAsCopy(request); - else - rdef.checkUserWriteAccess(request); - - rdef.getWizardSequence().performGoToStep(AppConstants.WS_DEFINITION); - request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); - // request.setAttribute(AppConstants.RI_CUR_STEP, - // AppConstants.WS_DEFINITION); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // reportLoad - - public String reportCopy(HttpServletRequest request, String nextPage) { - return reportLoad(request, nextPage, true); - } // reportCopy - - public String reportEdit(HttpServletRequest request, String nextPage) { - return reportLoad(request, nextPage, false); - } // reportEdit - - public String reportDelete(HttpServletRequest request, String nextPage) { - try { - String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); - try { - int i = Integer.parseInt(reportID); - } catch(NumberFormatException ex) { - throw new UserDefinedException("Not a valid report id"); - } - String userID = AppUtils.getUserID(request); - - (new ReportSecurity(reportID)).checkUserDeleteAccess(request); - - ReportLoader.deleteReportRecord(reportID); - - return "deleted:true"; - //nextPage = reportSearchExecute(request, nextPage); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - //return nextPage; - return "deleted:false"; - } // reportDelete - - private String generateSearchString(HttpServletRequest request) { - String searchString = AppUtils.getRequestNvlValue(request, AppConstants.RI_SEARCH_STRING); - boolean containFlag = AppUtils.getRequestFlag(request, AppConstants.RI_CONTAIN_FLAG); - return (searchString.length() > 0) ? ((containFlag ? "%" : "") + searchString + "%"):""; - } // generateSearchString - - public String reportFormFieldPopup(HttpServletRequest request, String nextPage) { - try { - ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( - AppConstants.SI_REPORT_RUNTIME); - - FormField ff = rr.getFormField(request.getParameter(AppConstants.RI_FIELD_NAME)); - ReportFormFields rff = rr.getReportFormFields(); - - int idx = 0; - FormField ff1 = null; - Map fieldNameMap = new HashMap(); - int countOfFields = 0 ; - String userId = AppUtils.getUserID(request); - IdNameList lookup = ff.getLookupList(); - String oldSQL = lookup.getOldSql(); - - if(AppUtils.getRequestFlag(request, AppConstants.RI_TEXTFIELD_POP)) { - for(rff.resetNext(); rff.hasNext(); idx++) { - ff1 = rff.getNext(); - fieldNameMap.put(ff1.getFieldName(), ff1.getFieldDisplayName()); - countOfFields++; - } - - - //List formParameter = new ArrayList(); - String formField = ""; - HashMap valuesMap = new HashMap(); - for(int i = 0 ; i < rff.size(); i++) { - formField = ((FormField)rff.getFormField(i)).getFieldName(); - if(request.getParameterValues(formField) != null && request.getParameterValues(formField).length > 1 ) { - String[] vals = (String[]) request.getParameterValues(formField); - String value = ""; - StringBuffer valueBuf = new StringBuffer(); - for(int ii = 0 ; ii < vals.length; ii++) { - if(ii == 0) valueBuf.append("("); - valueBuf.append(vals[ii]); - if(ii == vals.length-1) valueBuf.append(")"); - else valueBuf.append(","); - } - value = valueBuf.toString(); - valuesMap.put(fieldNameMap.get(formField), value); - } else if(request.getParameter(formField) != null) { - valuesMap.put(fieldNameMap.get(formField), request.getParameter(formField)); - } - } - if(countOfFields != 0) { - IdNameSql lu = (IdNameSql) lookup; - String SQL = (oldSQL==null)?lu.getSql():oldSQL; - oldSQL = SQL; - Set set = valuesMap.entrySet(); - String value = ""; - StringBuffer valueBuf = new StringBuffer(); - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - if(entry.getValue() instanceof String[]) { - String[] vals = (String[]) entry.getValue(); - for(int i = 0 ; i < vals.length; i++) { - if(i == 0) valueBuf.append("("); - valueBuf.append(vals[i]); - if(i == vals.length-1) valueBuf.append(")"); - else valueBuf.append(","); - } - value = valueBuf.toString(); - } else { - value = (String) entry.getValue(); - } - // added so empty string would be treated as null value if not given in single quotes. - if(value==null || value.trim().length()<=0) value="NULL"; - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", Utils.oracleSafe(value)); - } - if(request.getParameter(ff.getFieldName())!=null) { - lookup = new IdNameSql(-1,SQL,null); - lookup.setOldSql(oldSQL); - } - else { - lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); - lookup.setOldSql(oldSQL); - } - //lookup.loadData("0"); - } - if(lookup instanceof IdNameSql) ((IdNameSql)lookup).setDataSizeUsedinPopup(-3); // -3 indicates to run the count sql for pagination. - } - if(lookup instanceof IdNameSql) { - ((IdNameSql)lookup).loadUserData(request.getParameter(AppConstants.RI_NEXT_PAGE), - nvl(generateSearchString(request),"%"), rr.getDBInfo(),userId); - } - - int dataSizeForPopUp = 0; - if(lookup instanceof IdNameSql) { - dataSizeForPopUp = ((IdNameSql)lookup).getDataSizeUsedinPopup(); - } else - dataSizeForPopUp = lookup.getDataSize(); - - ff.setLookupList(lookup); - request.setAttribute("lookupList", lookup); - if(dataSizeForPopUp >= 0) - request.getSession().setAttribute(AppConstants.SI_DATA_SIZE_FOR_TEXTFIELD_POPUP, ""+dataSizeForPopUp); - } catch (RaptorException e) { - e.printStackTrace(); - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - return nextPage; - } // reportFormFieldPopup - - public String reportValuesMapDefPopup(HttpServletRequest request, String nextPage) { - try { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String colName = AppUtils.getRequestNvlValue(request, "colName"); - String colType = nvl(AppUtils.getRequestValue(request, "colType"), - AppConstants.CT_CHAR); - String displayName = AppUtils.getRequestNvlValue(request, "displayName"); - String displayFormat = AppUtils.getRequestNvlValue(request, "displayFormat"); - String tableId = AppUtils.getRequestNvlValue(request, "tableId"); - String dbInfo = rdef.getDBInfo(); - if (Utils.isNull(dbInfo)) { - dbInfo = (String) request.getSession().getAttribute("remoteDB"); - } - /*String query = "SELECT x FROM (SELECT DISTINCT " - + (colType.equals(AppConstants.CT_DATE) ? ("TO_CHAR(" + colName + ", '" - + nvl(displayFormat, AppConstants.DEFAULT_DATE_FORMAT) + "')") - : colName) + " x FROM " - + rdef.getTableById(tableId).getTableName() + " WHERE " + colName - + " IS NOT NULL ORDER BY 1) xx WHERE ROWNUM <= " - + Globals.getDefaultPageSize();*/ - - - String q1 = Globals.getReportValuesMapDefA(); - - String q2 = Globals.getReportValuesMapDefB(); - q2 = q2.replace("[colName]", colName); - q2 = q2.replace("[nvl(displayFormat, AppConstants.DEFAULT_DATE_FORMAT)]", nvl(displayFormat, AppConstants.DEFAULT_DATE_FORMAT)); - - String q3 = Globals.getReportValuesMapDefC(); - q3 = q3.replace("[colName]", colName); - - String q4 = Globals.getReportValuesMapDefD(); - q4 = q4.replace("[rdef.getTableById(tableId).getTableName()]", rdef.getTableById(tableId).getTableName()); - q4 = q4.replace("[colName]", colName); - q4 = q4.replace("[Globals.getDefaultPageSize()]", String.valueOf(Globals.getDefaultPageSize())); - - String query = q1 + (colType.equals(AppConstants.CT_DATE) ? q2 : q3) + q4; - - DataSet ds = ConnectionUtils.getDataSet(query, dbInfo); - request.setAttribute(AppConstants.RI_DATA_SET, ds); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // reportValuesMapDefPopup - - public String reportDrillDownToReportDefPopup(HttpServletRequest request, String nextPage) { - try { - // ReportDefinition rdef = (ReportDefinition) - // request.getSession().getAttribute(AppConstants.SI_REPORT_DEFINITION); - String ddReportID = AppUtils - .getRequestNvlValue(request, AppConstants.RI_REPORT_ID); - ReportRuntime ddRr = (new ReportHandler()).loadReportRuntime(request, ddReportID, - false); - if (ddRr != null) - request.setAttribute(AppConstants.RI_FORM_FIELDS, ddRr.getReportFormFields()); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // reportDrillDownToReportDefPopup - - public String reportFilterDataPopup(HttpServletRequest request, String nextPage) { - try { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String colId = AppUtils.getRequestNvlValue(request, AppConstants.RI_COLUMN_ID); - IdNameColLookup lookup = null; - String dbInfo = rdef.getDBInfo(); - if (Utils.isNull(dbInfo)) { - dbInfo = (String) request.getSession().getAttribute("remoteDB"); - } - if (!AppUtils.getRequestFlag(request, AppConstants.RI_RESET_PARAMS)) - lookup = (IdNameColLookup) request.getSession().getAttribute( - AppConstants.SI_COLUMN_LOOKUP); - if (lookup == null || (!colId.equals(lookup.getColId()))) { - DataColumnType dct = rdef.getColumnById(colId); - lookup = new IdNameColLookup(colId, rdef.getTableById(dct.getTableId()) - .getTableName(), dct.getColName(), rdef.getSelectExpr(dct), dct - .getColName() - + (dct.getColType().equals(AppConstants.CT_DATE) ? " DESC" : "")); - request.getSession().setAttribute(AppConstants.SI_COLUMN_LOOKUP, lookup); - } // if - - lookup.loadData(nvl(request.getParameter(AppConstants.RI_NEXT_PAGE), "0"), - generateSearchString(request), dbInfo); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // reportFilterDataPopup - - public String reportShowSQLPopup(HttpServletRequest request, String nextPage) { - try { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - String reportSQL = rdef.generateSQL(AppUtils.getUserID(request),request); - - String[] sqlClause = { "SELECT ", "FROM ", "WHERE ", "GROUP BY ", "HAVING ", - "ORDER BY " }; - - int idxNext = 0; - StringBuffer sb = new StringBuffer(); - while (idxNext < sqlClause.length) { - sb.append(""); - if (idxNext > 0) - sb.append("    "); - sb.append(sqlClause[idxNext]); - sb.append("
        \n"); - - int clauseStartPos = reportSQL.indexOf(sqlClause[idxNext]) - + sqlClause[idxNext].length(); - do - idxNext++; - while ((idxNext < sqlClause.length) - && (reportSQL.indexOf(sqlClause[idxNext]) < 0)); - - String clauseContent = null; - if (idxNext < sqlClause.length) - clauseContent = reportSQL.substring(clauseStartPos, reportSQL - .indexOf(sqlClause[idxNext]) - 1); - else - clauseContent = reportSQL.substring(clauseStartPos); - - while (clauseContent.length() > 0) { - int braketCount = 0; - StringBuffer nextToken = new StringBuffer(); - for (int i = 0; i < clauseContent.length(); i++) { - char ch = clauseContent.charAt(i); - nextToken.append(ch); - if (ch == '(') - braketCount++; - else if (ch == ')') - braketCount--; - else if (ch == ',') - if (braketCount == 0) - break; - } // for %> - - sb.append("        "); - sb.append(nextToken.toString()); - sb.append("
        \n"); - - if (nextToken.length() < clauseContent.length()) - clauseContent = clauseContent.substring(nextToken.length() + 1); - else - clauseContent = ""; - } // while - } // while - - request.setAttribute(AppConstants.RI_FORMATTED_SQL, sb.toString()); - request.setAttribute(AppConstants.RI_PAGE_TITLE, "Generated SQL"); - request.setAttribute(AppConstants.RI_PAGE_SUBTITLE, "Generated SQL for report " - + rdef.getReportName()); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // reportShowSQLPopup - - public String testSchedCondPopup(HttpServletRequest request, String nextPage) { - try { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String sql = AppUtils.getRequestNvlValue(request, AppConstants.RI_FORMATTED_SQL); - - request.setAttribute("msg_align", " align=center"); - request.setAttribute(AppConstants.RI_PAGE_TITLE, "Test Scheduler Condition"); - // request.setAttribute(AppConstants.RI_PAGE_SUBTITLE, ...); - //String query = "SELECT 1 FROM DUAL WHERE EXISTS (" + sql + ")"; - - String query = Globals.getTestSchedCondPopup(); - query = query.replace("[sql]", sql); - - DataSet ds = null; - String remoteDb = request.getParameter("remoteDbPrefix"); - String remoteDbPrefix = (remoteDb != null && !remoteDb.equalsIgnoreCase("null")) ? remoteDb - : rdef.getDBInfo(); - ds = ConnectionUtils.getDataSet(sql, remoteDbPrefix); - // if ( (remoteDbPrefix!=null) && - // (!remoteDbPrefix.equals(AppConstants.DB_LOCAL))) { - // Globals.getRDbUtils().setDBPrefix(remoteDbPrefix); - // ds = RemDbUtils.executeQuery(query); - // } - // else - // ds = DbUtils.executeQuery(query); - if (ds.getRowCount() == 0) - request - .setAttribute(AppConstants.RI_FORMATTED_SQL, - "
        Condition NOT satisfied - email notification will NOT be send.

        "); - else - request - .setAttribute(AppConstants.RI_FORMATTED_SQL, - "
        Condition satisfied - email notification will be send.

        "); - } catch (Exception e) { - // nextPage = (new ErrorHandler()).processFatalError(request, e); - request.setAttribute(AppConstants.RI_FORMATTED_SQL, "
        SQL ERROR " - + e.getMessage() + "
        Email notification will NOT be send.

        "); - } - - return nextPage; - } // testSchedCondPopup - - public String testRunSQLPopup(HttpServletRequest request, String nextPage) { - String sql = AppUtils.getRequestNvlValue(request, AppConstants.RI_FORMATTED_SQL); - if(nvl(sql).length()<=0) { - sql = AppUtils.getRequestNvlValue(request, "reportSQL"); - } - - - boolean chkFormFieldSQL = AppUtils.getRequestNvlValue(request, - AppConstants.RI_CHK_FIELD_SQL).equals("Y"); - try { - if (!sql.trim().toUpperCase().startsWith("SELECT")) - throw new UserDefinedException( - "Invalid statement - the SQL must start with the keyword SELECT"); - - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - if (!chkFormFieldSQL) { - if (rdef.getFormFieldList() != null) - for (Iterator iter = rdef.getFormFieldList().getFormField().iterator(); iter - .hasNext();) { - FormFieldType fft = (FormFieldType) iter.next(); - String fieldId = fft.getFieldId(); - String fieldDisplay = rdef.getFormFieldDisplayName(fft); - /* - * if(paramValues.isParameterMultiValue(fieldId)) - * generatedSQL = Utils.replaceInString(generatedSQL, - * fieldDisplay, nvl(formatListValue((String) - * paramValues.get(fieldId), null, false, false, null), - * "NULL")); else - */ - sql = Utils.replaceInString(sql, fieldDisplay, "NULL"); - } // for - } // if - DataSet ds = null; - String remoteDb = request.getParameter("remoteDbPrefix"); - String remoteDbPrefix = (remoteDb != null && !remoteDb.equalsIgnoreCase("null")) ? remoteDb - : rdef.getDBInfo(); - String userId = AppUtils.getUserID(request); - sql = Utils.replaceInString(sql, "[LOGGED_USERID]", userId); - String[] reqParameters = Globals.getRequestParams().split(","); - String[] sessionParameters = Globals.getSessionParams().split(","); - javax.servlet.http.HttpSession session = request.getSession(); - logger.debug(EELFLoggerDelegate.debugLogger, ("B4 testRunSQL " + sql)); - if(request != null ) { - for (int i = 0; i < reqParameters.length; i++) { - if(!reqParameters[i].startsWith("ff")) - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); - else - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); - } - } - if(session != null ) { - for (int i = 0; i < sessionParameters.length; i++) { - //if(!sessionParameters[i].startsWith("ff")) - //sql = Utils.replaceInString(sql, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i].toUpperCase()) ); - //else { - logger.debug(EELFLoggerDelegate.debugLogger, (" Session " + " sessionParameters[i] " + sessionParameters[i] + " " + (String)session.getAttribute(sessionParameters[i]))); - sql = Utils.replaceInString(sql, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); - //} - } - } - logger.debug(EELFLoggerDelegate.debugLogger, ("After testRunSQL " + sql)); - - ds = ConnectionUtils.getDataSet(sql, remoteDbPrefix, true); - // if ( (remoteDbPrefix!=null) && - // (!remoteDbPrefix.equals(AppConstants.DB_LOCAL))) { - // Globals.getRDbUtils().setDBPrefix(remoteDbPrefix); - // ds = RemDbUtils.executeQuery(sql, - // Globals.getDefaultPageSize()+1); - // } - // else - // ds = DbUtils.executeQuery(sql, Globals.getDefaultPageSize()+1); - if (chkFormFieldSQL && ds.getRowCount() > 0) { - String id = ds.getString(0, "id"); - String name = ds.getString(0, "name"); - } // if - - request.setAttribute(AppConstants.RI_DATA_SET, ds); - } catch (RaptorException e) { - request.setAttribute(AppConstants.RI_EXCEPTION, e); - } - - return nextPage; - } // testRunSQLPopup - - public String importSemaphorePopup(HttpServletRequest request, String nextPage) { - try { - (new WizardProcessor()).processImportSemaphorePopup(request); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // importSemaphorePopup - - public String saveSemaphorePopup(HttpServletRequest request, String nextPage) { - try { - (new WizardProcessor()).processSemaphorePopup(request); - } catch (RaptorException e) { - nextPage = (new ErrorHandler()).processFatalError(request, e); - } - - return nextPage; - } // saveSemaphorePopup - - public String gotoJsp(HttpServletRequest request, String nextPage) { - return nextPage; - } // gotoJsp - - public String downloadAll(HttpServletRequest request, String nextPage) throws InterruptedException, IOException, Exception { - String emailId = null; - String pdfAttachmentKey = AppUtils.getRequestValue(request, "pdfAttachmentKey"); - boolean isFromSchedule = nvl(pdfAttachmentKey).length()>0; - if(!isFromSchedule) - emailId = AppUtils.getUserEmail(request); - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); - SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd"); - java.util.Date currDate = new java.util.Date(); - String timestamp = sdf.format(currDate); - String dateStr = sdf1.format(currDate); - - String userId = null; - if(!isFromSchedule) - userId = AppUtils.getUserID(request); - else - userId = AppUtils.getRequestValue(request, "user_id"); - Runtime runtime = Runtime.getRuntime(); - ReportRuntime rr = null; - if(!isFromSchedule) { - rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); - if(rr!=null) AppUtils.getUserEmail(request); - } - String scheduleId = ""; - - if(isFromSchedule) { - String reportID = null; - String report_email_sent_log_id = AppUtils.getRequestValue(request, "log_id"); - /*String query = "Select user_id, rep_id from CR_REPORT_EMAIL_SENT_LOG" + - " where rownum = 1" + - " and gen_key='"+pdfAttachmentKey.trim()+"'" + - " and log_id ="+report_email_sent_log_id.trim() + - " and (sysdate - sent_date) < 1 ";*/ - - String query = Globals.getDownloadAllEmailSent(); - query = query.replace("[pdfAttachmentKey.trim()]", pdfAttachmentKey.trim()); - query = query.replace("[report_email_sent_log_id.trim()]", report_email_sent_log_id.trim()); - - DataSet ds = DbUtils.executeQuery(query, 1); - if(!ds.isEmpty()) { - userId = ds.getString(0,"user_id"); - reportID = ds.getString(0, "rep_id"); - request.setAttribute("schedule_email_userId", userId); - } else { - request.setAttribute("message", "This link has expired, please login and regenerate the report"); - return "raptor/message.jsp"; - } - - ReportHandler rh1 = new ReportHandler(); - - if(reportID !=null && nvl(pdfAttachmentKey).length()>0) { - rr = rh1.loadReportRuntime(request, reportID, true, 1); - rr.loadReportData(-1, userId, 1000 ,request, false /*download*/); - } - - String d_sql = Globals.getDownloadAllGenKey(); - d_sql = d_sql.replace("[pdfAttachmentKey]", pdfAttachmentKey); - - //ds = DbUtils.executeQuery("select schedule_id from cr_report_email_sent_log u where U.GEN_KEY = '"+ pdfAttachmentKey + "'"); - - ds = DbUtils.executeQuery(d_sql); - for (int i = 0; i < ds.getRowCount(); i++) { - scheduleId = ds.getString(i,0); - } - } - logger.debug(EELFLoggerDelegate.debugLogger, ("SQL2:\n"+ rr.getCachedSQL())); - String fileName = rr.getReportID()+"_"+userId+"_"+timestamp; - boolean flag = false; - logger.debug(EELFLoggerDelegate.debugLogger, (""+Utils.isDownloadFileExists(rr.getReportID()+"_"+userId+"_"+dateStr))); - // if(Utils.isDownloadFileExists(rr.getReportID()+"_"+userId+"_"+dateStr)) { - // flag = true; - // } - - if(flag){ - String strFileName = Utils.getLatestDownloadableFile(rr.getReportID()+"_"+userId+"_"+dateStr); - //debugLogger.debug("File Name " + strFileName); - StringBuffer messageBuffer = new StringBuffer(""); - messageBuffer.append("Download data file using the following link
        "); - messageBuffer.append("click here.

        "); - request.setAttribute("message", messageBuffer.toString()); - } - else if(!flag) { - String whole_fileName = (Globals.getShellScriptDir() +AppConstants.SHELL_QUERY_DIR+ fileName+AppConstants.FT_SQL); - String whole_columnsfileName = (Globals.getShellScriptDir() +AppConstants.SHELL_QUERY_DIR+ fileName+AppConstants.FT_COLUMNS); - - logger.debug(EELFLoggerDelegate.debugLogger, ("FILENAME "+whole_fileName)); - - List l = rr.getAllColumns(); - StringBuffer allColumnsBuffer = new StringBuffer(); - DataColumnType dct = null; - - for (Iterator iter = l.iterator(); iter.hasNext();) { - dct = (DataColumnType) iter.next(); - allColumnsBuffer.append(dct.getDisplayName()); - if(iter.hasNext()) - allColumnsBuffer.append("|"); - } - try { - PrintWriter xmlOut = new PrintWriter(new BufferedWriter(new FileWriter(new File(whole_columnsfileName)))); - xmlOut.println(allColumnsBuffer.toString()); - xmlOut.flush(); - xmlOut.close(); - } catch (IOException e) {e.printStackTrace();} - try { - PrintWriter xmlOut = new PrintWriter(new BufferedWriter(new FileWriter(new File(whole_fileName)))); - logger.debug(EELFLoggerDelegate.debugLogger, ("**************************")); - logger.debug(EELFLoggerDelegate.debugLogger, (rr.getWholeSQL())); - logger.debug(EELFLoggerDelegate.debugLogger, ("************************")); - logger.debug(EELFLoggerDelegate.debugLogger, ("************************")); - logger.debug(EELFLoggerDelegate.debugLogger, (rr.parseReportSQL(rr.getWholeSQL()))); - xmlOut.println(rr.parseReportSQL(rr.getWholeSQL())); - //xmlOut.println("******************"); - //xmlOut.println(rr.getWholeSQL()); - xmlOut.flush(); - xmlOut.close(); - } catch (IOException e) {e.printStackTrace();} - - StringBuffer command = new StringBuffer(Globals.getShellScriptDir() + AppConstants.SHELL_SCRIPTS_DIR); - if(nvl(emailId).length()>0) { - command.append(AppConstants.SHELL_SCRIPT_NAME + " " + (fileName+AppConstants.FT_SQL)); - command.append(" "+emailId); - } - else if (nvl(scheduleId).length()>0) { - command.append(AppConstants.SCHEDULE_SHELL_SCRIPT_NAME + " " + (fileName+AppConstants.FT_SQL)); - command.append(" " + scheduleId); - } - logger.debug(EELFLoggerDelegate.debugLogger, ("Command " + command)); - Process downloadProcess = runtime.exec(command.toString()); - logger.debug(EELFLoggerDelegate.debugLogger, ("Command Executed ")); - //Connection connection = DbUtils.getConnection(); - Enumeration enum1 = rr.getParamKeys(); - String value = "", key = ""; - String paramStr = ""; - StringBuffer paramBuffer = new StringBuffer(); - if(enum1!=null) { - for (; enum1.hasMoreElements();) { - key = (String) enum1.nextElement(); - value = rr.getParamValue(key); - paramBuffer.append(key+":"+value+" "); - } - paramStr = paramBuffer.toString(); - } - - StringBuffer retrieveUserEmailQry = null; - ArrayList userEmailList = new ArrayList(); - if(nvl(scheduleId).length()>0) { - /*retrieveUserEmailQry = new StringBuffer(); - retrieveUserEmailQry.append(" SELECT "); - retrieveUserEmailQry.append(" au.user_id "); - retrieveUserEmailQry.append(" FROM "); - retrieveUserEmailQry.append(" (SELECT rs.schedule_id, rs.rep_id FROM cr_report_schedule rs WHERE rs.enabled_yn='Y' AND rs.run_date IS NOT NULL "); - retrieveUserEmailQry.append(" AND rs.schedule_id = " + scheduleId + " ) x, cr_report r, app_user au "); - retrieveUserEmailQry.append(" WHERE "); - retrieveUserEmailQry.append("x.rep_id = r.rep_id "); - retrieveUserEmailQry.append(" AND au.user_id IN (SELECT rsu.user_id FROM cr_report_schedule_users rsu WHERE rsu.schedule_id = x.schedule_id and rsu.schedule_id = " + scheduleId ); - retrieveUserEmailQry.append(" UNION "); - retrieveUserEmailQry.append(" SELECT ur.user_id FROM fn_user_role ur "); - retrieveUserEmailQry.append(" WHERE ur.role_id IN "); - retrieveUserEmailQry.append(" (SELECT rsu2.role_id FROM cr_report_schedule_users rsu2 "); - retrieveUserEmailQry.append(" WHERE rsu2.schedule_id = x.schedule_id and "); - retrieveUserEmailQry.append(" rsu2.schedule_id = "+ scheduleId + ")) ");*/ - - String r_sql = Globals.getDownloadAllRetrieve(); - r_sql = r_sql.replace("[scheduleId]", scheduleId); - - // DataSet ds = DbUtils.executeQuery(retrieveUserEmailQry.toString()); - DataSet ds = DbUtils.executeQuery(r_sql); - - for (int i = 0; i < ds.getRowCount(); i++) { - userEmailList.add(ds.getString(i, 0)); - } - - } - // String insertQry = "insert into cr_report_dwnld_log (user_id,rep_id,file_name,dwnld_start_time,filter_params) values (?,?,?,?,?)"; - String insertQry = Globals.getDownloadAllInsert(); - - - Connection connection = null; - PreparedStatement pst = null; - try { - connection = DbUtils.getConnection(); - pst = connection.prepareStatement(insertQry); - if(nvl(emailId).length()>0){ - pst.setInt(1, Integer.parseInt(userId)); - pst.setInt(2, Integer.parseInt(rr.getReportID())); - pst.setString(3, fileName+AppConstants.FT_ZIP); - pst.setTimestamp(4,new java.sql.Timestamp(currDate.getTime())); - pst.setString(5,paramStr); - pst.execute(); - connection.commit(); - } else { - for (int i = 0; i < userEmailList.size(); i++) { - pst.setInt(1, Integer.parseInt((String)userEmailList.get(i))); - pst.setInt(2, Integer.parseInt(rr.getReportID())); - pst.setString(3, fileName+AppConstants.FT_ZIP); - pst.setTimestamp(4,new java.sql.Timestamp(currDate.getTime())); - pst.setString(5,paramStr); - pst.execute(); - connection.commit(); - } - } - pst.close(); - connection.close(); - logger.debug(EELFLoggerDelegate.debugLogger, ("Data inserted")); - } catch (SQLException ex) { - throw new RaptorException(ex); - } catch (ReportSQLException ex) { - throw new RaptorException(ex); - } catch (Exception ex) { - throw new RaptorException (ex); - } finally { - try { - if(connection!=null) - connection.close(); - if(pst!=null) - pst.close(); - } catch (SQLException ex) { - throw new RaptorException(ex); - } - } - //DbUtils.commitTransaction(connection); - //DbUtils.clearConnection(connection); - - - -// debugLogger.debug("|"+downloadProcess.toString() + "|"); -// if (downloadProcess == null) -// throw new Exception("unable to create a process for command:" + -// command); -// int retCode= 1; -// try { -// retCode= downloadProcess.waitFor(); -// } catch (InterruptedException e){ -// e.printStackTrace(); -// } -// debugLogger.debug("retCode " + retCode); -// Process child = rtime.exec("/bin/bash"); -// BufferedWriter outCommand = new BufferedWriter(new -// OutputStreamWriter(child.getOutputStream())); -// outCommand.write(Globals.getShellScriptName()); -// outCommand.flush(); -// int retCode = child.waitFor(); -// debugLogger.debug("RetCode " + retCode); - //request.setAttribute("message", "Shell Script is running in the background. You'll get an email once it is done"); - } - - return nextPage; - } - public String getChildDropDown(HttpServletRequest request, String nextPage) throws RaptorRuntimeException { - - if(request.getParameter("firstTime") != null) { return nextPage; } - - /*ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( - AppConstants.SI_REPORT_RUNTIME); - - String c_master = request.getParameter("c_master"); - java.util.HashMap valuesMap = Globals.getRequestParamtersMap(request); - request.setAttribute("c_master", c_master); - - int idx = 0; - ReportFormFields rff = rr.getReportFormFields(); - FormField ff = null; - for(rff.resetNext(); rff.hasNext(); idx++) { - ff = rff.getNext(); - - - if(ff.getDependsOn() != null && ff.getDependsOn().trim() != "") - { - String val = request.getParameter(ff.getFieldName()); - request.setAttribute(ff.getFieldName(), ff.getHtml(val, valuesMap, rr)); - } - - } - */ - return nextPage; - - } - - private void removeVariablesFromSession(HttpServletRequest request) { - HttpSession session = request.getSession(); - session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); - session.removeAttribute(AppConstants.DRILLDOWN_INDEX); - session.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); - session.removeAttribute(AppConstants.SI_BACKUP_FOR_REP_ID); - session.removeAttribute(AppConstants.SI_COLUMN_LOOKUP); - session.removeAttribute(AppConstants.SI_DASHBOARD_REP_ID); - session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); - session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME); - session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); - session.removeAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP); - session.removeAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); - session.removeAttribute(AppConstants.SI_DATA_SIZE_FOR_TEXTFIELD_POPUP); - session.removeAttribute(AppConstants.SI_MAP); - session.removeAttribute(AppConstants.SI_MAP_OBJECT); - session.removeAttribute(AppConstants.SI_REPORT_DEFINITION); - session.removeAttribute(AppConstants.SI_REPORT_RUNTIME); - session.removeAttribute(AppConstants.SI_REPORT_RUN_BACKUP); - session.removeAttribute(AppConstants.SI_REPORT_SCHEDULE); - session.removeAttribute(AppConstants.RI_REPORT_DATA); - session.removeAttribute(AppConstants.RI_CHART_DATA); - session.removeAttribute(AppConstants.SI_FORMFIELD_INFO); - session.removeAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); - session.removeAttribute(AppConstants.EMBEDDED_REPORTRUNTIME_MAP); - session.removeAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP); - Enumeration enum1 = session.getAttributeNames(); - String attributeName = ""; - while(enum1.hasMoreElements()) { - attributeName = enum1.nextElement(); - if(attributeName.startsWith("parent_")) { - session.removeAttribute(attributeName); - } - } - } - - - private TreeMap getListOfReportsFromDashBoardHTML(String htmlString) { - //String sourcestring = "
        [Report#123][Report#124]
        [Report#125][Report#126]
        "; - String sourcestring = htmlString; - //Pattern re = Pattern.compile("([a-z]+)\\[([a-z]+)([=<>]+)([a-z]+)\\]",Pattern.CASE_INSENSITIVE); - //Pattern re = Pattern.compile("\\[([R][e][p][o][r][t][#])[(*)]\\]"); - Pattern re = Pattern.compile("\\[(.*?)\\]"); //\\[(.*?)\\] - Matcher m = re.matcher(sourcestring); - HashMap hashReports = new HashMap(); - int mIdx = 0; - while (m.find()){ - for( int groupIdx = 0; groupIdx < m.groupCount(); groupIdx++ ){ - String str = m.group(groupIdx); - //System.out.println(str); - hashReports.put(new String(Integer.toString(mIdx+1)), (str.substring(1).toLowerCase().startsWith("chart")?"c":"d") + str.substring(str.indexOf("#")+1, str.length()-1)); - } - mIdx++; - } - // Sorting HashMap based on Keys - /*List mapKeys = new ArrayList(hashReports.keySet()); - List mapValues = new ArrayList(hashReports.values()); - hashReports.clear(); - hashReports = null; - hashReports = new HashMap(); - - TreeSet sortedSet = new TreeSet(mapKeys); - Object[] sortedArray = sortedSet.toArray(); - int size = sortedArray.length; - for (int i=0; i iter = reportCols.iterator(); iter.hasNext();) { - - DataColumnType dc = (DataColumnType) iter.next(); - if (colNames.length() > 0) - colNames.append(", "); - colNames.append(dc.getColId()); - if (dc.isVisible()) { - //TODO: Drilldown URL - //sql = reportRuntime.parseReportSQLForDrillDownParams(sql, dc, request); - } - } - - DataSet ds = null; - // try { - String dbInfo = reportRuntime.getDBInfo(); - if(maxRows == 1) - sql += " limit "+ maxRows; - System.out.println("SQL getReportData()- " + sql); - ds = ConnectionUtils.getDataSet(sql, dbInfo); - int totalRows = 0; - /*if (reportRuntime.getReportDataSize() < 0) {*/ - //String countSQL = "SELECT count(*) FROM (" + sql + ") x"; - String dbType = ""; - - if (dbInfo!=null && (!dbInfo.equals(AppConstants.DB_LOCAL))) { - try { - org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); - dbType = remDbInfo.getDBType(dbInfo); - } catch (Exception ex) { - throw new RaptorException(ex); - } - } - - totalRows = ds.getRowCount(); - /*}*/ - ReportData rd = new ReportData(0, true); - - if(totalRows > 0) { - // Already defined changed for modifying request parameters - //List reportCols = getAllColumns(); - Vector visibleCols = new Vector(reportCols.size()); - Vector formatProcessors = new Vector(reportCols.size()); - - // ColumnHeaderRow chr = new ColumnHeaderRow(); - // rd.reportColumnHeaderRows.addColumnHeaderRow(chr); - // chr.setRowHeight("30"); - int count =0 ; - - /* ADDED */ - ReportFormFields rff = reportRuntime.getReportFormFields(); - ReportFormFields childReportFormFields = null; - String fieldDisplayName = ""; - String fieldValue = ""; - - for (int c = 0; c < reportCols.size(); c++) { - if(reportCols.get(c)!=null) { - DataColumnType dct = (DataColumnType) reportCols.get(c); - if(nvl(dct.getDependsOnFormField()).length()>0 && nvl(dct.getDependsOnFormField()).indexOf("[")!=-1) { - for(int i = 0 ; i < rff.size(); i++) { - fieldDisplayName = "["+((FormField)rff.getFormField(i)).getFieldDisplayName()+"]"; - fieldValue = ""; - //if(dct.getOriginalDisplayName()==null) dct.setOriginalDisplayName(dct.getDisplayName()); - if (dct.getDependsOnFormField().equals(fieldDisplayName)) { - fieldValue = nvl(request.getParameter(((FormField)rff.getFormField(i)).getFieldName())); - - if (fieldValue.length()>0) { - if(!fieldValue.toUpperCase().equals("Y")) - dct.setDisplayName(fieldValue); - if(!dct.isVisible()) - dct.setVisible(true); - } else { - dct.setVisible(false); - } - } - } - } - } - } - - /* ADDED */ - String displayName = ""; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - - DataColumnType dc = (DataColumnType) iter.next(); - - formatProcessors.add(count,new FormatProcessor( - reportRuntime.getSemaphoreById(dc.getSemaphoreId()), dc.getColType(), dc - .getColFormat(), reportRuntime.getReportDefType().equals( - AppConstants.RD_SQL_BASED))); - - /* TODO: Add Drilldown URL */ - if (nvl(dc.getDrillDownURL()).length() > 0) { - childReportFormFields = reportRuntime.getChildReportFormFields(request,dc.getDrillDownURL()); - } - if (dc.isVisible()) { - visibleCols.add(count,dc); - //if(dc.getColId().startsWith("group")) { - for (int d = 0; d < reportCols.size(); d++) { - if(reportCols.get(d)!=null) { - DataColumnType dct1 = (DataColumnType) reportCols.get(d); - if(dct1.getColId().equals(dc.getColId()+"_name") && ds.getRowCount()>0) { - displayName = ds.getString(0,dct1.getColId()); - dc.setDisplayName(displayName); - } - } - } - //} - - VisualManager visualManager = reportRuntime.getVisualManager(); - rd.createColumn(dc.getColId(), dc.getDisplayName(), dc.getDisplayWidthInPxls(),dc.getDisplayHeaderAlignment(), - visualManager.isColumnVisible(dc.getColId()), visualManager - .getSortByColId().equals(dc.getColId()) ? visualManager - .getSortByAscDesc() : null, true, dc.getLevel()!=null?dc.getLevel():0, dc.getStart()!=null?dc.getStart():0, dc.getColspan()!=null?dc.getColspan():0, dc.isIsSortable()!=null?dc.isIsSortable():false); - // chr.addColumnHeader(new ColumnHeader(dc.getDisplayName(), - // (dc.getDisplayWidth()>100)?"10%":(""+dc.getDisplayWidth()+"%"))); - } // if - else { - visibleCols.add(count,null); - rd.createColumn(dc.getColId(), AppConstants.HIDDEN, dc.getDisplayWidthInPxls(), dc.getDisplayHeaderAlignment(), - false, null,false,dc.getLevel()!=null?dc.getLevel():0, dc.getStart()!=null?dc.getStart():0, dc.getColspan()!=null?dc.getColspan():0, dc.isIsSortable()!=null?dc.isIsSortable():false); -// formatProcessors.add(count,null); - } - count++; - } // for - - // Utils._assert(chr.size()==ds.getColumnCount(), - // "[ReportRuntime.loadLinearReportData] The number of visible columns - // does not match the number of data columns"); - //TODO: This should be optimized to accept -1 for flat file download - if(maxRows > totalRows) maxRows = totalRows; - ArrayList reportDataList = new ArrayList(); - for (int r = 0; r < maxRows; r++) { - DataRow dr = new DataRow(); - rd.reportDataRows.addDataRow(dr); - - for (int c = 0; c < reportCols.size(); c++) { - if(reportCols.get(c)!=null) { - DataColumnType dct = (DataColumnType) reportCols.get(c); - //Modified since ds is null. - DataValue dv = new DataValue(); - - if(ds.getRowCount()>0){ - if(ds.getColumnIndex(dct.getColId())!= -1) { - dr.addDataValue(dv); - dv.setDisplayValue(ds.getString(r, dct.getColId())); - } else { - continue; - } - - } else { - dv.setDisplayValue(""); - } - dv.setColName(dct.getColName()); - dv.setColId(dct.getColId()); - dv.setNowrap(nvl(dct.getNowrap(),"null").equals("false")?"null":nvl(dct.getNowrap(),"null")); - - //Add Drilldown URL to dv - if (nvl(dct.getDrillDownURL()).length() > 0) { - - if(dv.getDisplayValue().length() > 0) { - dv.setDrillDownURL(reportRuntime.parseDrillDownURL(r, /* c, */ds, dct, request, childReportFormFields)); - dv.setDrillDowninPoPUp(dct.isDrillinPoPUp()!=null?dct.isDrillinPoPUp():false); - } - - if (dv.getDisplayValue().length() == 0) { - //dv.setDisplayValue("[NULL]"); - dv.setDisplayValue(""); - } - } // if - - StringBuffer indentation = new StringBuffer(""); - if(dct.getIndentation()!=null && dct.getIndentation()>0) { - for (int indent=0; indent< dct.getIndentation(); indent++) { - indentation.append("\t"); - } - dv.setNowrap("true"); - } - dv.setIndentation(indentation.toString()); - - if(dct.isVisible()) { - - dv.setVisible(true); - dv.setAlignment(dct.getDisplayAlignment()); - dv.setDisplayTotal(dct.getDisplayTotal()); - dv.setDisplayName(dct.getDisplayName()); - -// if (nvl(dct.getDrillDownURL()).length() > 0) { - -// if(dv.getDisplayValue().length() > 0) { - //TODO: Below Drilldown URL -// dv.setDrillDownURL(reportRuntime.parseDrillDownURL(r, /* c, */ds, dct,request, childReportFormFields)); -// dv.setDrillDowninPoPUp(dct.isDrillinPoPUp()); -// } -// -// if (dv.getDisplayValue().length() == 0) { -// //dv.setDisplayValue("[NULL]"); -// dv.setDisplayValue(""); -// } -// } // if - - } else { - dv.setVisible(false); - dv.setHidden(true); - } - //System.out.println("in Linear report b4" + dr.getFormatId() + dr.getBgColorHtml() + dv.getDisplayValue()); - - if(dr.getFormatId()!=null) - ((FormatProcessor) formatProcessors.get(c)).setHtmlFormatters(dv, dr, true); - else - ((FormatProcessor) formatProcessors.get(c)).setHtmlFormatters(dv, dr, false); - - //System.out.println("in Linear report After" + dr.getFormatId() + dr.getBgColorHtml() + dv.getDisplayValue()); - } // if reportCols - } // for - reportDataList.add(dr); - } // for - - rd.setReportDataList(reportDataList); - //Only if rownumber options is needed - //rd.addRowNumbers(pageNo, getPageSize()); - DataRow colDataTotalsLinear = null; - if (colDataTotalsLinear == null) - colDataTotalsLinear = reportRuntime.generateColumnDataTotalsLinear(new ArrayList(reportCols), AppUtils.getUserID(request), - reportRuntime.getDbInfo(),request); - - if(colDataTotalsLinear!=null) - rd.setColumnDataTotalsLinear(colDataTotalsLinear, "Total"); - // Please note the below function doesn't set the visibility for dv since this is set in this function. - Sundar - rd.applyVisibility(); - } - return rd; - } // loadLinearReportData - - public String formFieldRun(HttpServletRequest request, String nextPage) { - ReportRuntime rr = null; - rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); - if(rr!=null) { - ReportJSONRuntime reportJSONRuntime = rr.createFormFieldJSONRuntime(request); - ObjectMapper mapper = new ObjectMapper(); - //mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); - //mapper.setVisibilityChecker(mapper.getVisibilityChecker().with(JsonAutoDetect.Visibility.NONE)); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - String jsonInString = ""; - try { - jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(reportJSONRuntime); - } catch (Exception ex) { - ex.printStackTrace(); - - } - return jsonInString; - } - - return ""; - } - -} // ActionHandler diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionMapping.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionMapping.java deleted file mode 100644 index 93fff254..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ActionMapping.java +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import java.util.HashMap; - -public class ActionMapping extends HashMap { - - public void addAction(Action action) { - put(action.getAction(), action); - } // addAction - - public Action getAction(String actionKey) { - return (Action) get(actionKey); - } // getAction - -} // ActionMapping diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Controller.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Controller.java deleted file mode 100644 index b2be8510..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/Controller.java +++ /dev/null @@ -1,124 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.RaptorRuntimeException; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -public class Controller extends org.openecomp.portalsdk.analytics.RaptorObject { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(Controller.class); - public Controller() { - } - - public String processRequest(HttpServletRequest request) { - String actionKey = nvl(request.getParameter(AppConstants.RI_ACTION), "report.run"); - - return processRequest(actionKey, request); - } // processRequest - - public String processRequest(String actionKey, HttpServletRequest request) { - Action action = null; - try { - action = Globals.getRaptorActionMapping().getAction(actionKey); - if (action == null) - throw new RaptorRuntimeException("Action not found"); - } catch (RaptorException e) { - logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey - + "]. RaptorException: " + e.getMessage())); -// if (actionKey.equals("system_upgrade")) // System override - - return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( - "[Controller.processRequest]Invalid raptor action [" + actionKey - + "]. Exception: " + e.getMessage())); - } - - try { - Class[] paramTypes = new Class[2]; - paramTypes[0] = Class.forName("javax.servlet.http.HttpServletRequest"); - paramTypes[1] = Class.forName("java.lang.String"); - - Class handlerClass = Class.forName(action.getControllerClass()); - Object handler = handlerClass.newInstance(); - Method handlerMethod = handlerClass.getMethod(action.getControllerMethod(), - paramTypes); - - Object[] paramValues = new Object[2]; - paramValues[0] = request; - paramValues[1] = action.getJspName(); - - return (String) handlerMethod.invoke(handler, paramValues); - } catch (ClassNotFoundException e) { - logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey - + "]. ClassNotFoundException: " + e.getMessage())); - return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( - "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " - + e.getMessage())); - } catch (IllegalAccessException e) { - logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey - + "]. IllegalAccessException: " + e.getMessage())); - return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( - "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " - + e.getMessage())); - }catch (InstantiationException e) { - logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey - + "]. InstantiationException: " + e.getMessage())); - return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( - "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " - + e.getMessage())); - }catch (NoSuchMethodException e) { - logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey - + "]. NoSuchMethodException: " + e.getMessage())); - return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( - "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " - + e.getMessage())); - }catch (InvocationTargetException e) { - logger.debug(EELFLoggerDelegate.debugLogger, ("[Controller.processRequest]Invalid raptor action [" + actionKey - + "]. InvocationTargetException: " + e.getMessage())); - return (new ErrorHandler()).processFatalError(request, new RaptorRuntimeException( - "[Controller.processRequest] Unable to instantiate and invoke action handler. Exception: " - + e.getMessage())); - } - } // processRequest - - public void handleRequest(HttpServletRequest request, HttpServletResponse response, - ServletContext servletContext) throws Exception { - String actionKey = nvl(request.getParameter(AppConstants.RI_ACTION), request.getParameter("action")); - - handleRequest(actionKey, request, response, servletContext); - } // handleRequest - - public void handleRequest(String actionKey, HttpServletRequest request, - HttpServletResponse response, ServletContext servletContext) throws Exception { - servletContext.getRequestDispatcher("/" + processRequest(actionKey, request)).forward( - request, response); - } // handleRequest - -} // Controller diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ErrorHandler.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ErrorHandler.java deleted file mode 100644 index bca56955..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/ErrorHandler.java +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import java.util.ArrayList; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.ReportSQLException; -import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; -import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.core.logging.format.AlarmSeverityEnum; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -public class ErrorHandler extends org.openecomp.portalsdk.analytics.RaptorObject { - - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ErrorHandler.class); - - public ErrorHandler() { - } - - public void processError(HttpServletRequest request, String errorMsg) { - //Log.write(errorMsg, 2); - logger.error(EELFLoggerDelegate.debugLogger, (errorMsg)); - ArrayList error_list = (ArrayList) request.getAttribute(AppConstants.RI_ERROR_LIST); - if (error_list == null) - error_list = new ArrayList(1); - error_list.add(errorMsg); - request.setAttribute(AppConstants.RI_ERROR_LIST, error_list); - } // processError - - public void processError(HttpServletRequest request, RaptorException e) { - processError(request, "Exception: " + e.getMessage()); - } // processError - - private String getSessionLog(HttpServletRequest request) { - String[] sessionVariablesToLog = Globals.getLogVariablesInSession().split(","); - StringBuffer sessionLogStrBuf = new StringBuffer("\n"); - sessionLogStrBuf.append("***** ADDITIONAL INFORMATION ******"); - HttpSession session = request.getSession(); - ReportRuntime rr = (ReportRuntime) session.getAttribute(AppConstants.SI_REPORT_RUNTIME); - ReportDefinition rdef = (ReportDefinition) session.getAttribute(AppConstants.SI_REPORT_DEFINITION); - if(rr!=null) { - sessionLogStrBuf.append("\nWHILE RUNNING"); - sessionLogStrBuf.append("\nReport Id="+rr.getReportID()+";\t"); - sessionLogStrBuf.append("Report Name="+rr.getReportName()+";\t\n"); - } else if (rdef != null) { - sessionLogStrBuf.append("\nWHILE CREATING/UPDATING"); - sessionLogStrBuf.append("\nReport Id="+rdef.getReportID()+";\t"); - sessionLogStrBuf.append("Report Name="+rdef.getReportName()+";\t\n"); - } - for (int i = 0; i < sessionVariablesToLog.length; i++) { - if(session.getAttribute(sessionVariablesToLog[i])!=null) - sessionLogStrBuf.append(sessionVariablesToLog[i]+"="+(String)session.getAttribute(sessionVariablesToLog[i])+";\t"); - } - sessionLogStrBuf.append("\n***********************************"); - sessionLogStrBuf.append("\n"); - return sessionLogStrBuf.toString(); - } - public String processFatalError(HttpServletRequest request, RaptorException e) { - //Log.write("Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage()), 1); - logger.error(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage())+" "+ getSessionLog(request) + e.getMessage()),AlarmSeverityEnum.MAJOR); - if (e instanceof ReportSQLException) { - String errorSQL = ((ReportSQLException) e).getReportSQL(); - if (nvl(errorSQL).length() > 0) - request.setAttribute("c_error_sql", errorSQL); - } // if - AppUtils.processErrorNotification(request, e); - - request.setAttribute(AppConstants.RI_EXCEPTION, e); - return AppUtils.getErrorPage(); - } // processFatalError - - public String processFatalErrorWMenu(HttpServletRequest request, RaptorException e) { - //Log.write("Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage()), 1); - logger.error(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] Fatal error [" + e.getClass().getName() + "]: " + nvl(e.getMessage())+" "+ getSessionLog(request) + e.getMessage()),AlarmSeverityEnum.MAJOR); - if (e instanceof ReportSQLException) { - String errorSQL = ((ReportSQLException) e).getReportSQL(); - if (nvl(errorSQL).length() > 0) - request.setAttribute("c_error_sql", errorSQL); - } // if - AppUtils.processErrorNotification(request, e); - - request.setAttribute(AppConstants.RI_EXCEPTION, e); - return AppUtils.getErrorPageWMenu(); - } // processFatalError - -} // ErrorHandler - diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardProcessor.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardProcessor.java deleted file mode 100644 index a9204db1..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardProcessor.java +++ /dev/null @@ -1,2354 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.ValidationException; -import org.openecomp.portalsdk.analytics.model.ReportHandler; -import org.openecomp.portalsdk.analytics.model.ReportLoader; -import org.openecomp.portalsdk.analytics.model.base.IdNameValue; -import org.openecomp.portalsdk.analytics.model.base.OrderBySeqComparator; -import org.openecomp.portalsdk.analytics.model.base.OrderSeqComparator; -import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; -import org.openecomp.portalsdk.analytics.model.definition.ReportSchedule; -import org.openecomp.portalsdk.analytics.model.runtime.FormField; -import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.DbUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.XSSFilter; -import org.openecomp.portalsdk.analytics.xmlobj.ChartDrillFormfield; -import org.openecomp.portalsdk.analytics.xmlobj.ColFilterType; -import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; -import org.openecomp.portalsdk.analytics.xmlobj.DataSourceType; -import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; -import org.openecomp.portalsdk.analytics.xmlobj.FormatType; -import org.openecomp.portalsdk.analytics.xmlobj.JavascriptItemType; -import org.openecomp.portalsdk.analytics.xmlobj.Marker; -import org.openecomp.portalsdk.analytics.xmlobj.ObjectFactory; -import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreType; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -/**
        - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting)
        - *
        - * - * --------------------------------------------------------------------------------------------------
        - * WizardProcessor.java - This class is used to process the user input provided in the wizard.
        - * It is called in creation as well as updation process. It builds report xml via JAXB using user
        - * input. This is vital one, to store meta information of each report
        - * ---------------------------------------------------------------------------------------------------
        - * - * - * Change Log

        - * - * 31-Aug-2009 : Version 8.5.1 (Sundar);
        • For Time Series multi series property is exposed.
        - * 28-Aug-2009 : Version 8.5.1 (Sundar);
        • If user login id is null, it would display user name when user is added for schedule.
        - * 18-Aug-2009 : Version 8.5.1 (Sundar);
        • request Object is passed to prevent caching user/roles - Datamining/Hosting.
        - * 12-Aug-2009 : Version 8.5 (Sundar);
        • For Line Charts too options are captured and rendering is customized.
        - * 29-Jul-2009 : Version 8.4 (Sundar);
        • Maximum Excel Download size would be persisted if changed.
        - * 14-Jul-2009 : Version 8.4 (Sundar);
        • Schedule feature is added to Dashboard Reports.
        - * 29-Jun-2009 : Version 8.4 (Sundar);
        • Options for Compare to Previous year Chart are processed.
        • - *
        • In the Bar chart Last Occuring Series/Category can be plotted as Bar or Line Renderer.
        • - *
        - * 22-Jun-2009 : Version 8.4 (Sundar);
        • processChart method is modified to accommodate creating - * Bar Charts, Time Difference Charts and adding generic chart options.
        - * - */ - -public class WizardProcessor extends org.openecomp.portalsdk.analytics.RaptorObject { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(WizardProcessor.class); - - public WizardProcessor() { - } - - private String adjustDataType(String oracleDataType) { - return oracleDataType.equals("VARCHAR2") ? AppConstants.CT_CHAR : oracleDataType; - // Probably should be expanded to convert any CHAR or VARCHAR type to - // CT_CHAR, number type to CT_NUMBER and date to CT_DATE - } // adjustDataType - - public void persistReportDefinition(HttpServletRequest request, ReportDefinition rdef) - throws RaptorException { - ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute( - AppConstants.SI_REPORT_RUNTIME); - if (rr != null && rr.getReportID().equals(rdef.getReportID())) - request.getSession().removeAttribute(AppConstants.SI_REPORT_RUNTIME); - rdef.persistReport(request); - } // persistReportDefinition - - public void processWizardStep(HttpServletRequest request) throws Exception { - String action = nvl(request.getParameter(AppConstants.RI_WIZARD_ACTION), - AppConstants.WA_BACK); - - String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); - ReportDefinition rdef = (new ReportHandler()).loadReportDefinition(request, reportID); - request.getSession().setAttribute(AppConstants.SI_REPORT_DEFINITION, rdef); - - String curStep = rdef.getWizardSequence().getCurrentStep(); - String curSubStep = rdef.getWizardSequence().getCurrentSubStep(); - if (AppUtils.getRequestNvlValue(request, "showDashboardOptions").length()<=0) - request.setAttribute("showDashboardOptions", "F"); - logger.debug(EELFLoggerDelegate.debugLogger, ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^curStep " + curStep + " " + curSubStep + " " + action)); - boolean reportUpdated = false; - if (!action.equals(AppConstants.WA_BACK)) { - if (curStep.equals(AppConstants.WS_DEFINITION)) { - reportUpdated = processDefinition(request); - } else if (curStep.equals(AppConstants.WS_SQL)) { - if (action.equals(AppConstants.WA_VALIDATE)) - reportUpdated = processValidateSQL(request); - } else if (curStep.equals(AppConstants.WS_TABLES)) { - if (curSubStep.equals(AppConstants.WSS_ADD)) - reportUpdated = processTableAdd(request); - else if (curSubStep.equals(AppConstants.WSS_EDIT)) - reportUpdated = processTableEdit(request); - else if (action.equals(AppConstants.WA_DELETE)) - reportUpdated = processTableDelete(request); - } else if (curStep.equals(AppConstants.WS_COLUMNS)) { - if (curSubStep.equals(AppConstants.WSS_ADD) - || curSubStep.equals(AppConstants.WSS_EDIT) || action.equals(AppConstants.WA_SAVE) || action.equals(AppConstants.WA_NEXT)) { - reportUpdated = processColumnAddEdit(request, curSubStep - .equals(AppConstants.WSS_EDIT) || curSubStep - .equals(AppConstants.WA_MODIFY)); - //reportUpdated = processColumnAddEdit(request, true); - } - else if (curSubStep.equals(AppConstants.WSS_ADD_MULTI)) - reportUpdated = processColumnAddMulti(request); - else if (curSubStep.equals(AppConstants.WSS_ORDER_ALL)) - reportUpdated = processColumnOrderAll(request); - else if (action.equals(AppConstants.WA_DELETE)) - reportUpdated = processColumnDelete(request); - else if (action.equals(AppConstants.WA_MOVE_UP)) - reportUpdated = processColumnMoveUp(request); - else if (action.equals(AppConstants.WA_MOVE_DOWN)) - reportUpdated = processColumnMoveDown(request); - } else if (curStep.equals(AppConstants.WS_FORM_FIELDS)) { - if (curSubStep.equals(AppConstants.WSS_ADD) - || curSubStep.equals(AppConstants.WSS_EDIT)) - reportUpdated = processFormFieldAddEdit(request, curSubStep - .equals(AppConstants.WSS_EDIT), action); - else if (action.equals(AppConstants.WA_DELETE)) - reportUpdated = processFormFieldDelete(request); - else if (action.equals(AppConstants.WA_MOVE_UP)) - reportUpdated = processFormFieldMoveUp(request); - else if (action.equals(AppConstants.WA_MOVE_DOWN)) - reportUpdated = processFormFieldMoveDown(request); - else if (action.equals(AppConstants.WSS_ADD_BLANK)) - reportUpdated = processFormFieldBlank(request); - else if (action.equals(AppConstants.WSS_INFO_BAR)) - reportUpdated = processFormFieldInfoBar(request); - } else if (curStep.equals(AppConstants.WS_FILTERS)) { - if (curSubStep.equals(AppConstants.WSS_ADD) - || curSubStep.equals(AppConstants.WSS_EDIT)) - reportUpdated = processFilterAddEdit(request, curSubStep - .equals(AppConstants.WSS_EDIT)); - else if (action.equals(AppConstants.WA_DELETE)) - reportUpdated = processFilterDelete(request); - } else if (curStep.equals(AppConstants.WS_SORTING)) { - if (curSubStep.equals(AppConstants.WSS_ADD) - || curSubStep.equals(AppConstants.WSS_EDIT)) - reportUpdated = processSortAddEdit(request, curSubStep - .equals(AppConstants.WSS_EDIT)); - else if (curSubStep.equals(AppConstants.WSS_ORDER_ALL)) - reportUpdated = processSortOrderAll(request); - else if (action.equals(AppConstants.WA_DELETE)) - reportUpdated = processSortDelete(request); - else if (action.equals(AppConstants.WA_MOVE_UP)) - reportUpdated = processSortMoveUp(request); - else if (action.equals(AppConstants.WA_MOVE_DOWN)) - reportUpdated = processSortMoveDown(request); - } else if (curStep.equals(AppConstants.WS_JAVASCRIPT)) { - if (action.equals(AppConstants.WSS_ADD)) - reportUpdated = processAddJavascriptElement(request); - else if (action.equals(AppConstants.WA_SAVE)) - reportUpdated = processSaveJavascriptElement(request); - else if (action.equals(AppConstants.WA_DELETE)) - reportUpdated = processDeleteJavascriptElement(request); - else - reportUpdated = processJavascript(request); - } else if (curStep.equals(AppConstants.WS_CHART)) { - reportUpdated = processChart(request, action); - } else if (curStep.equals(AppConstants.WS_USER_ACCESS)) { - reportUpdated = processUserAccess(request, action); - } else if (curStep.equals(AppConstants.WS_REPORT_LOG)) { - if (action.equals(AppConstants.WA_DELETE_USER)) - reportUpdated = processClearLog(request); - } else if (curStep.equals(AppConstants.WS_SCHEDULE)) { - reportUpdated = processSchedule(request, action); - } else if(curStep.equals(AppConstants.WS_DATA_FORECASTING)) { - reportUpdated = processForecasting(request, action); - } - /****For Report Maps - Start*****/ - else if (curStep.equals(AppConstants.WS_MAP)) { - reportUpdated = processMap(request, action); - } - /****For Report Maps - End*****/ - - // else - } - if (reportUpdated) - persistReportDefinition(request, rdef); - } // processWizardStep - - public void processImportSemaphorePopup(HttpServletRequest request) throws RaptorException { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String importReportId = AppUtils - .getRequestNvlValue(request, AppConstants.RI_REPORT_ID); - ReportRuntime rr = (new ReportHandler()).loadReportRuntime(request, importReportId, - false); - - ArrayList importedList = new ArrayList(); - if (rr.getSemaphoreList() != null) - for (Iterator iter = rr.getSemaphoreList().getSemaphore().iterator(); iter - .hasNext();) { - SemaphoreType sem = rdef.addSemaphore(new ObjectFactory(), - (SemaphoreType) iter.next()); - importedList - .add(new IdNameValue(sem.getSemaphoreId(), sem.getSemaphoreName())); - } // for - - if (importedList.size() > 0) { - request.setAttribute(AppConstants.RI_DATA_SET, importedList); - persistReportDefinition(request, rdef); - } // if - } // processImportSemaphorePopup - - public void processSemaphorePopup(HttpServletRequest request) throws RaptorException { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String semaphoreId = AppUtils.getRequestNvlValue(request, "semaphoreId"); - String semaphoreName = AppUtils.getRequestNvlValue(request, "semaphoreName"); - String semaphoreType = AppUtils.getRequestNvlValue(request, "semaphoreType"); - - SemaphoreType semaphore = rdef.getSemaphoreById(semaphoreId); - if (semaphore == null) { - semaphore = rdef.addSemaphoreType(new ObjectFactory(), semaphoreName, - semaphoreType, null); - semaphoreId = semaphore.getSemaphoreId(); - request.setAttribute("semaphoreId", semaphoreId); - } else { - rdef.deleteSemaphore(semaphore); - semaphore.setSemaphoreName(semaphoreName); - semaphore.setSemaphoreType(semaphoreType); - - rdef.setSemaphore(semaphore); - } - - String[] formatId = request.getParameterValues("formatId"); - String[] lessThanValue = request.getParameterValues("lessThanValue"); - String[] expression = request.getParameterValues("expression"); - String[] bold = request.getParameterValues("bold"); - String[] italic = request.getParameterValues("italic"); - String[] underline = request.getParameterValues("underline"); - String[] bgColor = request.getParameterValues("bgColor"); - String[] fontColor = request.getParameterValues("fontColor"); - String[] fontFace = request.getParameterValues("fontFace"); - String[] fontSize = request.getParameterValues("fontSize"); - //String[] anyFmt = request.getParameterValues("anyFmt"); - - // String[] alignment = request.getParameterValues("alignment"); - - for (int i = 0; i < lessThanValue.length; i++) - if (i == 0 || nvl(lessThanValue[i]).length() > 0) { - FormatType fmt = null; - if (i == 0 || nvl(formatId[i]).length() > 0) - fmt = rdef.getSemaphoreFormatById(semaphore, nvl(formatId[i])); - if (fmt == null) - fmt = rdef.addEmptyFormatType(new ObjectFactory(), semaphore); - - fmt.setLessThanValue(nvl(lessThanValue[i])); - fmt.setExpression(nvl(expression[i])); - fmt.setBold(bold[i].equals("Y")); - fmt.setItalic(italic[i].equals("Y")); - fmt.setUnderline(underline[i].equals("Y")); - fmt.setBgColor(bgColor[i]); - fmt.setFontColor(fontColor[i]); - fmt.setFontFace(fontFace[i]); - fmt.setFontSize(fontSize[i]); - //fmt.setAnyFmt((anyFmt[i]!=null)?anyFmt[i].startsWith("Y"):false); - // fmt.setAlignment(alignment[i]); - } else if (nvl(formatId[i]).length() > 0) - rdef.deleteFormatType(semaphore, formatId[i]); - - persistReportDefinition(request, rdef); - } // processSemaphorePopup - - private boolean processDefinition(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String reportName = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportName")); - String reportDescr = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportDescr")); - String folderId = AppUtils.getRequestNvlValue(request, "folder_id"); - boolean isAllowSchedule = (AppUtils.getRequestNvlValue(request, "allowSchedule").length()<=0?"N":AppUtils.getRequestNvlValue(request, "allowSchedule")).startsWith("Y"); - boolean isColumnGroup = (AppUtils.getRequestNvlValue(request, "multiGroupColumn").length()<=0?"N":AppUtils.getRequestNvlValue(request, "multiGroupColumn")).startsWith("Y"); - boolean isTopDown = (AppUtils.getRequestNvlValue(request, "topDown").length()<=0?"N":AppUtils.getRequestNvlValue(request, "topDown")).startsWith("Y"); - boolean isSizedByContent= (AppUtils.getRequestNvlValue(request, "sizedByContent").length()<=0?"N":AppUtils.getRequestNvlValue(request, "sizedByContent")).startsWith("Y"); - boolean reportsInNewWindow = false; - boolean hideFormFieldAfterRun = false; - - /*recurrance in schedule tab - Start*/ - String isOneTimeScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isOneTimeScheduleAllowed"),"N"); - String isHourlyScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isHourlyScheduleAllowed"),"N"); - String isDailyScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isDailyScheduleAllowed"),"N"); - String isDailyMFScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isDailyMFScheduleAllowed"),"N"); - String isWeeklyScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isWeeklyScheduleAllowed"),"N"); - String isMonthlyScheduleAllowed = nvl(AppUtils.getRequestValue(request, "isMonthlyScheduleAllowed"),"N"); - //System.out.println("//////////// + isOneTimeScheduleAllowed : " + isOneTimeScheduleAllowed); - /*recurrance in schedule tab - End*/ - - - if (reportDescr.length() > 1000) - reportDescr = reportDescr.substring(0, 1000); - boolean reportUpdated; - - String reportType = AppUtils.getRequestNvlValue(request, "reportType"); - - - - //rdef.setReportName(reportName); - //rdef.setReportDescr(reportDescr); - //rdef.setReportType(reportType); - rdef.setFolderId(folderId); -// debugLogger.debug("setting folder ID = " + folderId); - if(reportType.equals(AppConstants.RT_DASHBOARD)) { - rdef.setReportName(reportName); - rdef.setReportDescr(reportDescr); - rdef.setReportType(reportType); - String dashboardLayoutHTML = AppUtils.getRequestNvlValue(request, "dashboardLayoutHTML"); - rdef.setDashboardLayoutHTML(dashboardLayoutHTML); - String dataContainerHeight = nvl(AppUtils.getRequestValue(request, "heightContainer"), "auto"); - String dataContainerWidth = nvl(AppUtils.getRequestValue(request, "widthContainer"), "auto"); - rdef.setDataContainerHeight(dataContainerHeight); - rdef.setDataContainerWidth(dataContainerWidth); - rdef.setAllowSchedule(isAllowSchedule?"Y":"N"); - - - /* - String numDashCols = AppUtils.getRequestNvlValue(request, "numDashCols"); - String reports1 = AppUtils.getRequestNvlValue(request, "reports1"); - String reports2 = AppUtils.getRequestNvlValue(request, "reports2"); - String reports3 = AppUtils.getRequestNvlValue(request, "reports3"); - String reports4 = AppUtils.getRequestNvlValue(request, "reports4"); - String repBgColor1 = AppUtils.getRequestNvlValue(request, "repBgColor1"); - String repBgColor2 = AppUtils.getRequestNvlValue(request, "repBgColor2"); - String repBgColor3 = AppUtils.getRequestNvlValue(request, "repBgColor3"); - String repBgColor4 = AppUtils.getRequestNvlValue(request, "repBgColor4"); - - //List reports = rdef.getDashBoardReports(); - rdef.setNumDashCols(numDashCols); - DashboardReports reportsList = new DashboardReportsImpl(); - - String reports[] = new String[]{reports1, reports2, reports3, reports4}; - String repBgColors[] = new String[]{repBgColor1, repBgColor2, repBgColor3, repBgColor4}; - for (int i = 0; i < reports.length; i++) { - Reports report = new ReportsImpl(); - report.setReportId(reports[i]); - report.setBgcolor(repBgColors[i]); - reportsList.getReportsList().add(report); - } - - - - rdef.setDashBoardReports(reportsList); - */ - reportUpdated = true; - -// reportUpdated = (!(reportName.equals(nvl(rdef.getReportName())) -// && reportDescr.equals(nvl(rdef.getReportDescr())) -// && reportType.equals(nvl(rdef.getReportType())) -// && numDashCols.equals(nvl(rdef.getNumDashCols())))); -//// && rdef.getR - - if (rdef.getWizardSequence() instanceof WizardSequence) - rdef.generateWizardSequence(request); - - } else { - - if (AppUtils.getRequestNvlValue(request, "reportType").equals(AppConstants.RT_CROSSTAB) || rdef.getReportType().equals(AppConstants.RT_CROSSTAB)) { - - String widthNo = AppUtils.getRequestNvlValue(request, "widthNo"); - if(nvl(widthNo).endsWith("px")) - rdef.setWidthNoColumn(widthNo); - else - rdef.setWidthNoColumn(widthNo+"px"); - } - - String dataGridAlign = AppUtils.getRequestNvlValue(request, "dataGridAlign"); - if(nvl(dataGridAlign).length()>0) { - rdef.setDataGridAlign(dataGridAlign); - } else { - rdef.setDataGridAlign("left"); - } - - String pdfImgLogo = AppUtils.getRequestNvlValue(request, "pdfImg"); - if(nvl(pdfImgLogo).length()>0) - rdef.setPdfImg(pdfImgLogo); - else - rdef.setPdfImg(null); - String emptyMessage = AppUtils.getRequestNvlValue(request, "emptyMessage"); - if(nvl(emptyMessage).length()>0) - rdef.setEmptyMessage(emptyMessage); - else - rdef.setEmptyMessage(""); - String formHelp = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "formHelp")); - //String rDashboardType = nvl(AppUtils.getRequestValue(request, "showDashboardOptions"), "N"); - //rdef.setDashboardType(rDashboardType.equals("Y")); - int excelDownloadSize = 500; - try { - excelDownloadSize = Integer.parseInt(AppUtils.getRequestValue(request, "excelDownloadSize")); - } catch (NumberFormatException ex) {} - if(AppUtils.getRequestNvlValue(request, "excelDownloadSize").length()>0) - rdef.setMaxRowsInExcelDownload(Integer.parseInt(AppUtils.getRequestValue(request, "excelDownloadSize"))); - if(AppUtils.getRequestNvlValue(request, "reportInNewWindow").length()>0) - reportsInNewWindow = AppUtils.getRequestNvlValue(request,"reportInNewWindow").equals("Y"); - if(AppUtils.getRequestNvlValue(request, "hideFormFieldsAfterRun").length()>0) - hideFormFieldAfterRun = AppUtils.getRequestNvlValue(request,"hideFormFieldsAfterRun").equals("Y"); - - - if(AppUtils.getRequestNvlValue(request, "displayFolderTree").length()>0) - rdef.setDisplayFolderTree(AppUtils.getRequestNvlValue(request,"displayFolderTree").equals("Y")); - else - rdef.setDisplayFolderTree(false); - String dataSource = AppUtils.getRequestNvlValue(request, "dataSource"); - String dbType = Globals.getDBType(); - String schemaSql = Globals.getRemoteDbSchemaSqlWithWhereClause(); - schemaSql = schemaSql.replace("[schema_id]", dataSource); - DataSet ds = null; - try { - ds = DbUtils.executeQuery(schemaSql); - - String prefix = "", desc = ""; - - for (int i = 0; i < ds.getRowCount(); i++) { - dbType = ds.getItem(i, 2); - } - } - catch (Exception e) {} - - int pageSize = Globals.getDefaultPageSize(); - try { - pageSize = Integer.parseInt(AppUtils.getRequestValue(request, "pageSize")); - } catch (NumberFormatException e) { - } - String rApproved = nvl(AppUtils.getRequestValue(request, "menuApproved"), "N"); - String menuID = ""; - String[] menuIDs = request.getParameterValues("menuID"); - if (menuIDs != null) - for (int i = 0; i < menuIDs.length; i++) - menuID += (menuID.length() == 0 ? "" : "|") + menuIDs[i]; - -// boolean additionalFieldsShown = AppUtils.getRequestNvlValue(request, -// "additionalFieldsShown").equals("Y"); - boolean rRCSDisabled = AppUtils.getRequestNvlValue(request, "runtimeColSortDisabled").equals("Y"); - String reportDefType = AppUtils.getRequestNvlValue(request, "reportDefType"); - String dataContainerHeight = nvl(AppUtils.getRequestValue(request, "heightContainer"), "auto"); - String dataContainerWidth = nvl(AppUtils.getRequestValue(request, "widthContainer"), "auto"); - - String displayOptions = nvl(AppUtils.getRequestValue(request, "hideForm"), "N") - + nvl(AppUtils.getRequestValue(request, "hideChart"), "N") - + nvl(AppUtils.getRequestValue(request, "hideData"), "N") - + nvl(AppUtils.getRequestValue(request, "hideBtns"), "N") - + nvl(AppUtils.getRequestValue(request, "hideMap"), "N") - + nvl(AppUtils.getRequestValue(request, "hideExcelIcons"), "N") - + nvl(AppUtils.getRequestValue(request, "hidePDFIcons"), "N"); -/* StringBuffer dashboardOptions = new StringBuffer(""); - dashboardOptions.append((nvl(AppUtils.getRequestValue(request, "hide"),"chart").equals("chart"))?"Y":"N"); - dashboardOptions.append((nvl(AppUtils.getRequestValue(request, "hide"),"").equals("data"))?"Y":"N"); - dashboardOptions.append((nvl(AppUtils.getRequestValue(request, "hideBtns"),"").equals("Y"))?"Y":"N");*/ - - String numFormCols = nvl(AppUtils.getRequestValue(request, "numFormCols"), "1"); - String reportTitle = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportTitle")); - String reportSubTitle = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportSubTitle")); - String reportHeader = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportHeader")); - String reportFooter = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportFooter")); - - int frozenColumns = 0; - try { - frozenColumns = Integer.parseInt(AppUtils.getRequestValue(request, "frozenColumns")); - } catch (NumberFormatException ex) { - - } - -/* reportUpdated = (!(reportName.equals(nvl(rdef.getReportName())))) - && (!(reportDescr.equals(nvl(rdef.getReportDescr())))) - && (!(formHelp.equals(nvl(rdef.getFormHelpText())))) - && (!(reportType.equals(nvl(rdef.getReportType())))) - && (pageSize != rdef.getPageSize()) && - // rPublic.equals(rdef.isPublic()?"Y":"N")&& - (!(menuID.equals(nvl(rdef.getMenuID())))) - && (!(rApproved.equals(rdef.isMenuApproved()))) && (additionalFieldsShown ? ((!(rRCSDisabled - .equals(rdef.isRuntimeColSortDisabled()))) - && (!(displayOptions.equals(nvl(rdef.getDisplayOptions())))) - && (!(dashboardOptions.equals(nvl(rdef.getDashboardOptions())))) - && (!(numFormCols.equals(nvl(rdef.getNumFormCols())))) - && (!(reportTitle.equals(nvl(rdef.getReportTitle())))) - && (!(reportSubTitle.equals(nvl(rdef.getReportSubTitle())))) - && (!(reportHeader.equals(nvl(rdef.getReportHeader())))) && (!(reportFooter - .equals(nvl(rdef.getReportFooter()))))&& (reportsInNewWindow != rdef.isReportInNewWindow())):true); -*/ -/* reportUpdated = rRCSDisabled ==(rdef.isRuntimeColSortDisabled() - && displayOptions.equals(nvl(rdef.getDisplayOptions())) - //&& dashboardOptions.equals(nvl(rdef.getDashboardOptions())) - && numFormCols.equals(nvl(rdef.getNumFormCols())) - && reportTitle.equals(nvl(rdef.getReportTitle())) - && reportSubTitle.equals(nvl(rdef.getReportSubTitle())) - && reportHeader.equals(nvl(rdef.getReportHeader())) - && reportsInNewWindow == rdef.isReportInNewWindow() - && reportFooter.equals(nvl(rdef.getReportFooter()))) - ;*/ - - - /*reportUpdated = (!(reportName.equals(nvl(rdef.getReportName())) - && reportDescr.equals(nvl(rdef.getReportDescr())) - && formHelp.equals(nvl(rdef.getFormHelpText())) - && reportType.equals(nvl(rdef.getReportType())) - && (pageSize == rdef.getPageSize()) - && excelDownloadSize == rdef.getMaxRowsInExcelDownload() - && reportsInNewWindow == rdef.isReportInNewWindow() - && displayOptions.equals(rdef.getDisplayOptions()) - && dataContainerHeight.equals(rdef.getDataContainerHeight()) - && dataContainerWidth.equals(rdef.getDataContainerWidth()) - && (isAllowSchedule ==(rdef.isAllowSchedule())) - // rPublic.equals(rdef.isPublic()?"Y":"N")&& - && menuID.equals(nvl(rdef.getMenuID())) - && rApproved.equals(rdef.isMenuApproved() ? "Y" : "N") && (rRCSDisabled - == ((rdef.isRuntimeColSortDisabled()) - && displayOptions.equals(nvl(rdef.getDisplayOptions())) - //&& dashboardOptions.equals(nvl(rdef.getDashboardOptions())) - && numFormCols.equals(nvl(rdef.getNumFormCols())) - && reportTitle.equals(nvl(rdef.getReportTitle())) - && reportSubTitle.equals(nvl(rdef.getReportSubTitle())) - && isOneTimeScheduleAllowed.equals(nvl(rdef.getIsOneTimeScheduleAllowed())) - && isHourlyScheduleAllowed.equals(nvl(rdef.getIsHourlyScheduleAllowed())) - && isDailyScheduleAllowed.equals(nvl(rdef.getIsDailyScheduleAllowed())) - && isDailyMFScheduleAllowed.equals(nvl(rdef.getIsDailyMFScheduleAllowed())) - && isWeeklyScheduleAllowed.equals(nvl(rdef.getIsWeeklyScheduleAllowed())) - && isMonthlyScheduleAllowed.equals(nvl(rdef.getIsMonthlyScheduleAllowed())) - && reportHeader.equals(nvl(rdef.getReportHeader())) && reportFooter - .equals(nvl(rdef.getReportFooter())))) - )); */ - rdef.setReportName(reportName); - rdef.setReportDescr(reportDescr); - rdef.setFormHelpText(formHelp); - rdef.setReportType(reportType); - rdef.setPageSize(pageSize); - rdef.setDBInfo(dataSource); - rdef.setDBType(dbType); - rdef.setDisplayOptions(displayOptions); - rdef.setDataContainerHeight(dataContainerHeight); - rdef.setDataContainerWidth(dataContainerWidth); - rdef.setAllowSchedule(isAllowSchedule?"Y":"N"); - rdef.setMultiGroupColumn(isColumnGroup?"Y":"N"); - rdef.setTopDown(isTopDown?"Y":"N"); - rdef.setSizedByContent(isSizedByContent?"Y":"N"); - // rdef.setPublic(rPublic.equals("Y")); - rdef.setMenuID(menuID); - rdef.setMenuApproved(rApproved.equals("Y")); - if (reportDefType.length() > 0) - rdef.setReportDefType(reportDefType); -/* if(rdef.isDashboardType()) { - rdef.setDashboardOptions(dashboardOptions.toString()); - }*/ - rdef.setHideFormFieldAfterRun(hideFormFieldAfterRun); - rdef.setReportInNewWindow(reportsInNewWindow); - rdef.setRuntimeColSortDisabled(rRCSDisabled); - rdef.setNumFormCols(numFormCols); - rdef.setReportTitle(reportTitle); - rdef.setReportSubTitle(reportSubTitle); - rdef.setReportHeader(reportHeader); - rdef.setReportFooter(reportFooter); - rdef.setIsOneTimeScheduleAllowed(isOneTimeScheduleAllowed); - rdef.setIsHourlyScheduleAllowed(isHourlyScheduleAllowed); - rdef.setIsDailyScheduleAllowed(isDailyScheduleAllowed); - rdef.setIsDailyMFScheduleAllowed(isDailyMFScheduleAllowed); - rdef.setIsWeeklyScheduleAllowed(isWeeklyScheduleAllowed); - rdef.setIsMonthlyScheduleAllowed(isMonthlyScheduleAllowed); - rdef.setFrozenColumns(frozenColumns); - - } // if - - if (rdef.getWizardSequence() instanceof WizardSequence) - rdef.generateWizardSequence(request); - - - /* - * if(formHelp.length()>255) formHelp = formHelp.substring(0, 255); - */ - - - // String rPublic = nvl(AppUtils.getRequestValue(request, "public"), - // "N"); - // String menuID = AppUtils.getRequestNvlValue(request, "menuID"); - -// boolean dashboardOptionsShown = AppUtils.getRequestNvlValue(request, -// "dashboardOptionsShown").equals("Y"); - - reportUpdated = true; - - if (rdef.getReportID().equals("-1")) - // Always need to persist new report - in case it is a copy - reportUpdated = true; - - return reportUpdated; - } // processDefinition - - private boolean processTableAdd(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String tableName = AppUtils.getRequestNvlValue(request, "tableName").toUpperCase(); - String tableId = rdef.getUniqueTableId(tableName); - - String joinTableExpr = null; - String joinTableId = null; - - DataSourceType joinTable = - rdef.getTableById(AppUtils.getRequestValue(request, "joinTableName")); - if (joinTable != null) { - String joinTableName = joinTable.getTableName(); - joinTableId = joinTable.getTableId(); - - String joinExpr = AppUtils.getRequestNvlValue(request, "joinExpr").toUpperCase(); - - joinTableExpr = joinExpr.replaceAll("\\["+tableName+"\\]", tableId); - joinTableExpr = joinTableExpr.replaceAll("\\["+joinTableName+"\\]", joinTableId); -// debugLogger.debug("joinExpr : "+joinExpr+"\njoinTableExpr : "+ joinTableExpr); - } - - rdef.addDataSourceType(new ObjectFactory(), tableId, tableName, AppUtils - .getRequestNvlValue(request, "tablePK"), AppUtils.getRequestNvlValue(request, - "displayName"), joinTableId, joinTableExpr, null); - - rdef.setOuterJoin(rdef.getTableById(tableId), AppUtils.getRequestNvlValue(request, - "outerJoin")); - rdef.resetCache(true); - - return true; - } // processTableAdd - - private boolean processTableEdit(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - DataSourceType dst = rdef.getTableById(AppUtils.getRequestNvlValue(request, - AppConstants.RI_DETAIL_ID)); - - String displayName = XSSFilter.filterRequest(AppUtils.getRequestNvlValue(request, "displayName")); - String outerJoin = AppUtils.getRequestNvlValue(request, "outerJoin"); - - String tableName = AppUtils.getRequestNvlValue(request, "tableName").toUpperCase(); - String joinTableId = AppUtils.getRequestNvlValue(request, "joinTableName"); - - String joinExpr = AppUtils.getRequestNvlValue(request, "joinExpr").toUpperCase(); - - String joinTableExpr = null; - if(joinExpr.length()!=0){ - joinTableExpr = joinExpr.replaceAll("\\["+tableName+"\\]", rdef.getTableByDBName(tableName).getTableId()); - joinTableExpr = joinTableExpr.replaceAll("\\["+rdef.getTableById(joinTableId).getTableName().toUpperCase()+"\\]", joinTableId); - dst.setRefDefinition(joinTableExpr); - } - boolean reportUpdated = (!displayName.equals(nvl(dst.getDisplayName())) || - !outerJoin.equals(rdef.getOuterJoinType(dst)) || - !(joinExpr.length()==0)); - - dst.setDisplayName(displayName); - rdef.setOuterJoin(dst, outerJoin); - if (reportUpdated) - rdef.resetCache(true); - - return true; // reportUpdated; - } // processTableEdit - - - private boolean processTableDelete(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef.deleteDataSourceType(AppUtils.getRequestNvlValue(request, - AppConstants.RI_DETAIL_ID)); - return true; - } // processTableDelete - - private boolean processColumnAddEdit(HttpServletRequest request, boolean isEdit) - throws Exception { - if(!isEdit) { - return true; - } - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - DataColumnType currColumn = null; - - String tableId = null; - String colName = null; - String dataType = null; - if (isEdit) { - currColumn = rdef.getColumnById(AppUtils.getRequestNvlValue(request, - AppConstants.RI_DETAIL_ID)); - - if(currColumn!=null) { - tableId = currColumn.getTableId(); - colName = currColumn.getDbColName(); // currColumn.getColName(); - dataType = currColumn.getDbColType(); - } - } else { - String colData = AppUtils.getRequestNvlValue(request, "columnDetails"); - if(nvl(colData).length()>0) { - tableId = colData.substring(0, colData.indexOf('|')); - colName = colData.substring(tableId.length() + 1, - colData.indexOf('|', tableId.length() + 1)).toUpperCase(); - dataType = colData.substring(tableId.length() + colName.length() + 2); - } - } // else - - String exprFormula = AppUtils.getRequestNvlValue(request, "exprFormula"); - - String colNameValue = null; - if (exprFormula.length() > 0) - if (exprFormula.equals("_exprText_")) - colNameValue = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestValue(request, "exprText")); - else if (exprFormula.equals("COUNT(*)")) - colNameValue = exprFormula; - else - colNameValue = exprFormula + " " + colName + ")"; - else - colNameValue = colName; - - int displayWidth = -1; - try { - displayWidth = Integer.parseInt(AppUtils.getRequestValue(request, "displayWidth")); - } catch (NumberFormatException e) { - } - - String sColId = isEdit ? currColumn.getColId() : (nvl(colName).length()>0?rdef.getUniqueColumnId(colName):null); - String drillDownParams = AppUtils.getRequestValue(request, "drillDownParams"); - if (drillDownParams != null) { - // Replacing references to [this] with [col_id] - while (drillDownParams.indexOf("[this]") >= 0) { - int startIdx = drillDownParams.indexOf("[this]"); - StringBuffer sb = new StringBuffer(); - - if (startIdx > 0) - sb.append(drillDownParams.substring(0, startIdx)); - sb.append("[" + sColId + "]"); - if (startIdx + 6 < drillDownParams.length() - 1) - sb.append(drillDownParams.substring(startIdx + 5)); - drillDownParams = sb.toString(); - } // while - } // if - - String crossTabValue = null; - boolean isVisible = AppUtils.getRequestFlag(request, "visible"); - boolean isSortable = AppUtils.getRequestFlag(request, "sortable"); - String nowrap = AppUtils.getRequestNvlValue(request, "nowrap"); - int indentation = 0; - try { - indentation = Integer.parseInt(AppUtils.getRequestNvlValue(request, "indentation")); - }catch (NumberFormatException e) { - } - String dependsOnFormField = AppUtils.getRequestNvlValue(request, "dependsOnFormField"); - boolean isGroupBreak = AppUtils.getRequestFlag(request, "groupBreak"); - String groupByPosStr = AppUtils.nvls(AppUtils.getRequestValue(request, "groupByPos"), "0"); - int groupByPos = Integer.parseInt(groupByPosStr); - currColumn.setGroupByPos(groupByPos); - - if(groupByPos > 0) { - String subTotalCustomText = AppUtils.nvls(AppUtils.getRequestValue(request, "subTotalCustomText"), "Sub Total"); - currColumn.setSubTotalCustomText(subTotalCustomText); - - boolean hideRepeatedKey = AppUtils.getRequestFlag(request, "hideRepeatedKeys"); - currColumn.setHideRepeatedKey(hideRepeatedKey); - } - - String displayTotal = AppUtils.getRequestNvlValue(request, "displayTotal"); - String widthInPxls = AppUtils.getRequestNvlValue(request, "widthInPxls"); - - if (rdef.getReportType().equals(AppConstants.RT_CROSSTAB)) { - - - - crossTabValue = AppUtils.getRequestValue(request, "crossTabValue"); - isVisible = nvl(crossTabValue).equals(AppConstants.CV_ROW) - || nvl(crossTabValue).equals(AppConstants.CV_COLUMN) - || nvl(crossTabValue).equals(AppConstants.CV_VALUE); - isGroupBreak = nvl(crossTabValue).equals(AppConstants.CV_ROW) - || nvl(crossTabValue).equals(AppConstants.CV_COLUMN); - - if (nvl(crossTabValue).equals(AppConstants.CV_VALUE)) - displayTotal += "|" - + AppUtils.getRequestNvlValue(request, "displayTotalPerRow"); - else - displayTotal = ""; - } // if - - String displayName = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "displayName")); - String colType = AppUtils.getRequestNvlValue(request, "colType"); - String displayFormat = AppUtils.getRequestNvlValue(request, "displayFormat"); - - //HYPERLINK - if(colType.equals(AppConstants.CT_HYPERLINK)) { - String hyperlinkURL = AppUtils.getRequestValue(request, "hyperlinkURL"); - currColumn.setHyperlinkURL(hyperlinkURL); - String anchor = AppUtils.getRequestValue(request, "anchor"); - currColumn.setHyperlinkType(anchor); - if(anchor.equals("IMAGE")) { - String actionImg = AppUtils.getRequestValue(request, "actionImg"); - currColumn.setActionImg(actionImg); - } - } - - - - String displayAlign = AppUtils.getRequestValue(request, "displayAlign"); - String displayHeaderAlign = AppUtils.getRequestValue(request, "displayHeaderAlign"); - String drillDownURL = AppUtils.getRequestValue(request, "drillDownURL"); - String drillDownSuppress = AppUtils.getRequestValue(request, "drillDownSuppress"); - boolean drillDownPopUp = AppUtils.getRequestFlag (request, "drillDownPopUp"); - String semaphoreId = AppUtils.getRequestNvlValue(request, "semaphore"); - String semaphoreType = AppUtils.getRequestNvlValue(request, "semaphoreTypeHidden"); - - String levelStr = AppUtils.getRequestNvlValue(request, "multiGroupColLevel"); - String startColGroup = AppUtils.getRequestNvlValue(request, "startMultiGroup"); - String colGroupColSpan = AppUtils.getRequestNvlValue(request, "colspan"); - int level = 0; - try { - level = Integer.parseInt(levelStr); - }catch (NumberFormatException ex) { - level = 0; - } - int startColGroupInt = 0; - int colGroupColSpanInt = 0; - if(level > 0) { - try { - //startColGroupInt = Integer.parseInt(startColGroup); - colGroupColSpanInt = Integer.parseInt(colGroupColSpan); - } catch (NumberFormatException ex) { - - } - } - currColumn.setLevel(level); - if(level > 0) { - currColumn.setStart(startColGroupInt); - currColumn.setColspan(colGroupColSpanInt); - } - - String targetColumnId = (semaphoreType.indexOf("|")!= -1 ? semaphoreType.substring(semaphoreType.indexOf("|")+1):""); - DataColumnType targetColumn = rdef.getColumnById(targetColumnId); - - SemaphoreType semaphore = rdef.getSemaphoreById(semaphoreId); - rdef.deleteSemaphore(semaphore); - if(nvl(semaphoreType).length() > 0 && semaphoreType.indexOf("|")!=-1) - semaphore.setSemaphoreType(semaphoreType.substring(0,semaphoreType.indexOf("|"))); - if(semaphore!=null) { - semaphore.setComment(currColumn.getColId()); - if(nvl(semaphoreType).length() > 0) - semaphore.setTarget(targetColumnId.length()>0? targetColumnId: ""); - rdef.setSemaphore(semaphore); - } - - - if (isEdit) { - if(nvl(widthInPxls).length()>0) { - if(nvl(widthInPxls).endsWith("px")) - currColumn.setDisplayWidthInPxls(widthInPxls); - else - currColumn.setDisplayWidthInPxls(widthInPxls+"px"); - } else { - currColumn.setDisplayWidthInPxls(""); - } - - currColumn.setCrossTabValue(crossTabValue); - currColumn.setDependsOnFormField(dependsOnFormField); - currColumn.setDisplayName(displayName); - //currColumn.setOriginalDisplayName(displayName); - - if (displayWidth > 0) - currColumn.setDisplayWidth(displayWidth); - currColumn.setDisplayAlignment(displayAlign); - currColumn.setDisplayHeaderAlignment(displayHeaderAlign); - currColumn.setDrillDownURL(drillDownURL); - currColumn.setDrillDownParams(drillDownParams); - currColumn.setDrillDownType(drillDownSuppress); - currColumn.setDrillinPoPUp(drillDownPopUp); - //indentation - currColumn.setIndentation(indentation); - if(drillDownPopUp) { - rdef.setDrillDownURLInPopupPresent(true); - } - /*if(targetColumn!=null) { - currColumn.setSemaphoreId(null); - targetColumn.setSemaphoreId(semaphoreId); - } else */ - currColumn.setSemaphoreId(semaphoreId); - currColumn.setGroupBreak(isGroupBreak); - logger.debug(EELFLoggerDelegate.debugLogger, (" ------------ Display Total ---------- "+ displayTotal)); - currColumn.setDisplayTotal(displayTotal); - //if (currColumn.getDrillDownURL() == null || currColumn.getDrillDownURL().length() == 0) - currColumn.setVisible(isVisible); - currColumn.setIsSortable(isSortable); - currColumn.setNowrap(nowrap); - //else - // currColumn.setVisible(true); - if (rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) { - if(colType!=null) - currColumn.setColType(colType); - displayFormat = AppUtils.getRequestValue(request, "colDataFormat"); - if (displayFormat != null){ - currColumn.setColFormat(displayFormat); - } - if(colType!=null && colType.equals(AppConstants.CT_DATE)) { - boolean enhancedPagination = AppUtils.getRequestFlag(request, "enhancedPagination"); - currColumn.setEnhancedPagination(enhancedPagination); - } - } - if (!rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) { - currColumn.setColName(colNameValue); - if (displayFormat != null) - currColumn.setColFormat(displayFormat); - //currColumn.setVisible(isVisible); - currColumn.setCalculated(exprFormula.length() > 0); - - rdef.adjustColumnType(currColumn); - } // if - - rdef.resetCache(true); - } else - currColumn = rdef.addDataColumnType(new ObjectFactory(), sColId, tableId, colName, - crossTabValue, colNameValue, displayName, displayWidth, displayAlign, rdef - .getAllColumns().size() + 1, isVisible, - (exprFormula.length() > 0), adjustDataType(dataType), displayFormat, - isGroupBreak, -1, null, displayTotal, null, -1, drillDownSuppress, - drillDownURL, drillDownParams, semaphoreId, null); - - if (rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) - rdef.setColumnNoParseDateFlag(currColumn, AppUtils.getRequestFlag(request, - "no_parse_date")); - if(nvl(displayName).length()>0) - return true; - else - return false; - } // processColumnAddEdit - - private boolean processColumnAddMulti(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - List reportCols = rdef.getAllColumns(); - int nCol = reportCols.size() + 1; - - String[] addColumn = request.getParameterValues("addColumn"); - String[] tableId = request.getParameterValues("tableId"); - String[] columnName = request.getParameterValues("columnName"); - String[] columnType = request.getParameterValues("columnType"); - String[] displayName = request.getParameterValues("displayName"); - - for (int i = 0; i < addColumn.length; i++) - if (addColumn[i].equals("Y")) { - int j = 2; - String uniqueDisplayName = displayName[i]; - boolean isUnique = true; - do { - isUnique = true; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) - if (uniqueDisplayName.equals(((DataColumnType) iter.next()) - .getDisplayName())) { - isUnique = false; - uniqueDisplayName = displayName[i] + (j++); - break; - } // if - } while (!isUnique); - - rdef - .addDataColumnType( - new ObjectFactory(), - rdef.getUniqueColumnId(columnName[i]), - tableId[i], - columnName[i], - null, - columnName[i], - uniqueDisplayName, - 10, - "Left", - nCol++, - true, - false, - adjustDataType(columnType[i]), - (columnType[i].equals(AppConstants.CT_DATE) ? AppConstants.DEFAULT_DATE_FORMAT - : null), false, -1, null, null, null, -1, null, null, - null, null, null); - } // if - - return true; - } // processColumnAddMulti - - private boolean processColumnOrderAll(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String[] colId = request.getParameterValues("colId"); - String[] colOrder = request.getParameterValues("colOrder"); - - boolean reportUpdated = false; - for (int i = 0; i < colId.length; i++) { - DataColumnType dct = rdef.getColumnById(nvl(colId[i])); - if (dct == null) - continue; - - int iColOrder = 0; - try { - iColOrder = Integer.parseInt(colOrder[i]); - } catch (NumberFormatException e) { - } - - if (iColOrder > 0) { - dct.setOrderSeq(iColOrder); - reportUpdated = true; - } // if - } // for - - if (reportUpdated) { - List reportCols = rdef.getAllColumns(); - Collections.sort(reportCols, new OrderSeqComparator()); - - int iOrder = 1; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - dct.setOrderSeq(iOrder++); - } // for - - rdef.resetCache(false); - } // if - - return reportUpdated; - } // processColumnOrderAll - - private boolean processColumnDelete(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef.deleteDataColumnType(AppUtils.getRequestNvlValue(request, - AppConstants.RI_DETAIL_ID)); - return true; - } // processColumnDelete - - private boolean processColumnMoveUp(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef.shiftColumnOrderUp(AppUtils - .getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - return true; - } // processColumnMoveUp - - private boolean processColumnMoveDown(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef.shiftColumnOrderDown(AppUtils.getRequestNvlValue(request, - AppConstants.RI_DETAIL_ID)); - return true; - } // processColumnMoveDown - - private boolean processFormFieldAddEdit(HttpServletRequest request, boolean isEdit, - String action) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String fieldName = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "fieldName")); - String multiSelectSize = "0"; - String colId = AppUtils.getRequestNvlValue(request, "fieldColId"); - if (rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) { - String displayFormat = AppUtils.getRequestNvlValue(request, "displayFormat"); - if (displayFormat.length() > 0) - colId += "|" + displayFormat; - } // if - String fieldType = AppUtils.getRequestNvlValue(request, "fieldType"); - String validation = AppUtils.getRequestNvlValue(request, "validation"); - String mandatory = nvl(AppUtils.getRequestValue(request, "mandatory"), "N"); - String defaultValue = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "defaultValue")); - String fieldHelp = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "fieldHelp")); - String fieldSQL = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "fieldSQL")); - String fieldDefaultSQL = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "fieldDefaultSQL")); - String visible = nvl(AppUtils.getRequestValue(request, "visible"),"Y"); - String dependsOn = nvl(AppUtils.getRequestValue(request, "dependsOn"),""); - String rangeStartDate = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "rangeStartDate")); - String rangeEndDate = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "rangeEndDate")); - String rangeStartDateSQL = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "rangeStartDateSQL")); - String rangeEndDateSQL = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "rangeEndDateSQL")); - boolean isGroupFormField = AppUtils.getRequestFlag(request,"isGroupFormField"); - - Calendar start = null; - Calendar end = null; - if (AppUtils.nvl(rangeStartDate).length()>0){ - SimpleDateFormat dtf = new SimpleDateFormat("MM/dd/yyyy"); - start = Calendar.getInstance(); - start.setTime(dtf.parse(rangeStartDate)); - } - if (AppUtils.nvl(rangeEndDate).length()>0){ - SimpleDateFormat dtf = new SimpleDateFormat("MM/dd/yyyy"); - end = Calendar.getInstance(); - end.setTime(dtf.parse(rangeEndDate)); - }/* - * if(fieldHelp.length()>255) fieldHelp = fieldHelp.substring(0, 255); - */ - - boolean reportUpdated = false; - - FormFieldType currField = null; - if (isEdit) { - String fieldId = AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID); - - currField = rdef.getFormFieldById(fieldId); - if (currField != null && nvl(fieldName).length()>0) { - reportUpdated = (!(fieldName.equals(nvl(currField.getFieldName())) - && colId.equals(nvl(currField.getColId())) - && fieldType.equals(nvl(currField.getFieldType())) - && validation.equals(nvl(currField.getValidationType())) - && mandatory.equals(nvl(currField.getMandatory(), "N")) - && defaultValue.equals(nvl(currField.getDefaultValue())) - && fieldSQL.equals(nvl(currField.getFieldSQL())) - && fieldDefaultSQL.equals(nvl(currField.getFieldDefaultSQL())) - && dependsOn.equals(nvl(currField.getDependsOn(), "N")) - && (start == null || (start != null && currField.getRangeStartDate() == null) || (start.equals(currField.getRangeStartDate()))) - && (end == null || (end != null && currField.getRangeEndDate() == null) || (end.equals(currField.getRangeEndDate()))) - && rangeStartDateSQL.equals(nvl(currField.getRangeStartDateSQL())) - && rangeEndDateSQL.equals(nvl(currField.getRangeEndDateSQL())) - && visible.equals(nvl(currField.getVisible(), "Y")) - && isGroupFormField == currField.isGroupFormField() - && fieldHelp.equals(nvl(currField.getComment())))); - - rdef.replaceFormFieldReferences("[" + currField.getFieldName() + "]", "[" - + fieldName + "]"); - - currField.setFieldName(fieldName); - currField.setColId(colId); - currField.setFieldType(fieldType); - currField.setValidationType(validation); - currField.setMandatory(mandatory); - currField.setDefaultValue(defaultValue); - currField.setFieldSQL(fieldSQL); - currField.setFieldDefaultSQL(fieldDefaultSQL); - currField.setComment(fieldHelp); - currField.setVisible(visible); - currField.setDependsOn(dependsOn); - try { - if(start!=null) { - currField.setRangeStartDate(DatatypeFactory.newInstance() - .newXMLGregorianCalendar(start.YEAR, start.MONTH, start.DAY_OF_WEEK, start.HOUR, start.MINUTE, start.SECOND, start.MILLISECOND, start.ZONE_OFFSET)); - } else { - currField.setRangeStartDate(null); - } - if(end!=null) { - currField.setRangeEndDate(DatatypeFactory.newInstance() - .newXMLGregorianCalendar(end.YEAR, end.MONTH, end.DAY_OF_WEEK, end.HOUR, end.MINUTE, end.SECOND, end.MILLISECOND, end.ZONE_OFFSET)); - } else { - currField.setRangeEndDate(null); - } - /*currField.setRangeEndDate(DatatypeFactory.newInstance() - .newXMLGregorianCalendar(end));*/ - } catch (DatatypeConfigurationException ex) { - - } - - currField.setRangeStartDateSQL(rangeStartDateSQL); - currField.setRangeEndDateSQL(rangeEndDateSQL); - currField.setGroupFormField(isGroupFormField); - if(fieldType.equals(FormField.FFT_LIST_MULTI)) { - multiSelectSize = AppUtils.getRequestNvlValue(request, "multiSelectListSize"); - currField.setMultiSelectListSize(multiSelectSize); - } - - - } // if - } else { - reportUpdated = true; - - currField = rdef.addFormFieldType(new ObjectFactory(), fieldName, colId, - fieldType, validation, mandatory, defaultValue, fieldSQL, fieldHelp, start, end, rangeStartDateSQL, rangeEndDateSQL); - - request.setAttribute(AppConstants.RI_DETAIL_ID, currField.getFieldId()); - } // else - - if (action.equals(AppConstants.WA_ADD_USER)) { - reportUpdated = true; - rdef.addFormFieldPredefinedValue(new ObjectFactory(), currField, XSSFilter.filterRequestOnlyScript(AppUtils - .getRequestNvlValue(request, "newPredefinedValue"))); - } else if (action.equals(AppConstants.WA_DELETE_USER)) { - reportUpdated = true; - rdef.deleteFormFieldPredefinedValue(currField, AppUtils.getRequestNvlValue( - request, "delPredefinedValue")); - } - - return reportUpdated; - } // processFormFieldAddEdit - - private boolean processFormFieldDelete(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String fieldId = AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID); - rdef.deleteFormField(fieldId); - - return true; - } // processFormFieldDelete - - private boolean processFormFieldMoveUp(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef.shiftFormFieldUp(AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - return true; - } // processFormFieldMoveUp - - private boolean processFormFieldMoveDown(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef.shiftFormFieldDown(AppUtils - .getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - return true; - } // processFormFieldMoveDown - - private boolean processFormFieldBlank(HttpServletRequest request) throws Exception { - boolean reportUpdated = false; - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - reportUpdated = true; - rdef.addFormFieldBlank(new ObjectFactory()); - return true; - } // processFormFieldMoveDown - - //processFormFieldInfoBar - private boolean processFormFieldInfoBar(HttpServletRequest request) throws Exception { - boolean reportUpdated = false; - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - reportUpdated = true; - rdef.addCustomizedTextForParameters(XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "blueBarField"))); - return true; - } // processFormFieldMoveDown - - - private boolean processForecasting(HttpServletRequest request, String action) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - if(rdef.getDataminingOptions()==null) - rdef.addDataminingOptions(new ObjectFactory()); - - String classifiers = AppUtils.getRequestNvlValue(request, "classifiers"); - rdef.setClassifier(classifiers); - String dateAttrColId = AppUtils.getRequestNvlValue(request, "timeAttribute"); - String timeFormat = AppUtils.getRequestNvlValue(request, "timeFormat"); - if(timeFormat.equals("Default")) timeFormat = "yyyy-MM-dd HH:mm:ss"; - String forecastingPeriod = AppUtils.getRequestNvlValue(request, "forecastingPeriod"); - - String[] forecastCols = request.getParameterValues("forecastCol"); - List reportCols = rdef.getAllColumns(); - DataColumnType dct = null; - Iterator iter = null; - - - - if(dateAttrColId != null) { - for(iter=reportCols.iterator(); iter.hasNext(); ) { - dct = (DataColumnType) iter.next(); - if(dct.getColId().equals(dateAttrColId)) { - dct.setDataMiningCol(AppConstants.DM_DATE_ATTR); - if(timeFormat!=null) rdef.setForecastingTimeFormat(timeFormat); - break; - } - } - } - - if(forecastCols != null) { - for (int i = 0; i < forecastCols.length; i++) { - for(iter=reportCols.iterator(); iter.hasNext(); ) { - dct = (DataColumnType) iter.next(); - if(dct.getColId().equals(forecastCols[i])) { - dct.setDataMiningCol(AppConstants.DM_FORECASTING_ATTR); - } - } - } - rdef.setForecastingPeriod(forecastingPeriod); - } - boolean reportUpdated = true; - - return reportUpdated; - } // processForecasting - - - private boolean processFilterAddEdit(HttpServletRequest request, boolean isEdit) - throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String colId = AppUtils.getRequestNvlValue(request, "filterColId"); - String filterExpr = AppUtils.getRequestNvlValue(request, "filterExpr"); - String argType = (filterExpr.equals("IS NULL") || filterExpr.equals("IS NOT NULL")) ? null - : AppUtils.getRequestNvlValue(request, "argType"); - String argValue = (filterExpr.equals("IS NULL") || filterExpr.equals("IS NOT NULL")) ? null - : AppUtils.getRequestNvlValue(request, "argValue"); - - if (nvl(argType).equals(AppConstants.AT_COLUMN)) { - List reportCols = rdef.getAllColumns(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - if (argValue.equals("[" + dct.getDisplayName() + "]")) { - argValue = dct.getColId(); - break; - } - } // for - } // if - - if (nvl(argType).equals(AppConstants.AT_VALUE) - && (!nvl(argValue).equals(AppConstants.FILTER_MAX_VALUE)) - && (!nvl(argValue).equals(AppConstants.FILTER_MIN_VALUE))) { - // Validating the value by type - DataColumnType currColumn = rdef.getColumnById(colId); - String currColType = currColumn.getColType(); - - try { - String s_sql = Globals.getProcessFilterAddEdit(); - s_sql = s_sql.replace("[argValue]", argValue); - /*DataSet ds = DbUtils.executeQuery("SELECT " - + (currColType.equals(AppConstants.CT_NUMBER) ? ("TO_NUMBER('" - + argValue + "')") - : (currColType.equals(AppConstants.CT_DATE) ? ("TO_DATE('" - + argValue - + "', '" - + nvl(currColumn.getColFormat(), - AppConstants.DEFAULT_DATE_FORMAT) + "')") - : ("'" + argValue + "'"))) + " FROM dual");*/ - - DataSet ds = DbUtils.executeQuery("SELECT " - + (currColType.equals(AppConstants.CT_NUMBER) ? ("TO_NUMBER('" - + argValue + "')") - : (currColType.equals(AppConstants.CT_DATE) ? ("TO_DATE('" - + argValue - + "', '" - + nvl(currColumn.getColFormat(), - AppConstants.DEFAULT_DATE_FORMAT) + "')") - : s_sql))); - } catch (Exception e) { - throw new ValidationException( - "" - + (currColType.equals(AppConstants.CT_NUMBER) ? "Invalid number" - : (currColType.equals(AppConstants.CT_DATE) ? ("Invalid date
        Expected date format " + nvl( - currColumn.getColFormat(), - AppConstants.DEFAULT_DATE_FORMAT)) - : "Invalid value
        Possible reason: use of single quotes")) - + "
        Value: " + argValue); - } - } // if - - if (isEdit) { - int filterPos = -1; - try { - filterPos = Integer.parseInt(AppUtils.getRequestValue(request, "filterPos")); - } catch (NumberFormatException e) { - } - - ColFilterType currFilter = rdef.getFilterById(colId, filterPos); - if (currFilter != null) { - currFilter.setJoinCondition(AppUtils.getRequestValue(request, "filterJoin")); - currFilter.setOpenBrackets(AppUtils.getRequestValue(request, "openBrackets")); - currFilter.setExpression(filterExpr); - // if(argType!=null) - currFilter.setArgType(argType); - // if(argValue!=null) - currFilter.setArgValue(argValue); - currFilter - .setCloseBrackets(AppUtils.getRequestValue(request, "closeBrackets")); - } // if - - rdef.resetCache(true); - } else { - rdef.addColFilterType(new ObjectFactory(), colId, AppUtils.getRequestValue( - request, "filterJoin"), AppUtils.getRequestValue(request, "openBrackets"), - filterExpr, argType, argValue, AppUtils.getRequestValue(request, - "closeBrackets"), null); - } // else - - return true; - } // processFilterAddEdit - - private boolean processFilterDelete(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String filterId = AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID); - String colId = filterId.substring(0, filterId.indexOf('|')); - int filterPos = -1; - try { - filterPos = Integer.parseInt(filterId.substring(colId.length() + 1)); - } catch (NumberFormatException e) { - } - - rdef.removeColumnFilter(colId, filterPos); - - return true; - } // processFilterDelete - - private boolean processSortAddEdit(HttpServletRequest request, boolean isEdit) - throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String sortAscDesc = AppUtils.getRequestNvlValue(request, "sortAscDesc"); - if (isEdit) { - DataColumnType currColumn = rdef.getColumnById(AppUtils.getRequestNvlValue( - request, AppConstants.RI_DETAIL_ID)); - if (currColumn != null) - currColumn.setOrderByAscDesc(sortAscDesc); - rdef.resetCache(true); - } else - rdef.addColumnSort(AppUtils.getRequestNvlValue(request, "sortColId"), sortAscDesc, - rdef.getNumSortColumns() + 1); - - return true; - } // processSortAddEdit - - private boolean processSortOrderAll(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String[] colId = request.getParameterValues("colId"); - String[] sortOrder = request.getParameterValues("sortOrder"); - String[] sortAscDesc = request.getParameterValues("sortAscDesc"); - - boolean reportUpdated = false; - for (int i = 0; i < colId.length; i++) { - DataColumnType dct = rdef.getColumnById(nvl(colId[i])); - if (dct == null) - continue; - - int iSortOrder = 0; - try { - iSortOrder = Integer.parseInt(sortOrder[i]); - } catch (NumberFormatException e) { - } - - if (iSortOrder > 0) { - if (dct.getOrderBySeq() > 0) { - // Update sort - if (dct.getOrderBySeq() != iSortOrder) { - dct.setOrderBySeq(iSortOrder); - reportUpdated = true; - } // if - if (!nvl(dct.getOrderByAscDesc()).equals(nvl(sortAscDesc[i]))) { - dct.setOrderByAscDesc(sortAscDesc[i]); - reportUpdated = true; - } // if - } else { - // Add sort - dct.setOrderBySeq(iSortOrder); - dct.setOrderByAscDesc(sortAscDesc[i]); - reportUpdated = true; - } // else - } else { - if (dct.getOrderBySeq() > 0) { - // Remove sort - dct.setOrderBySeq(0); - dct.setOrderByAscDesc(null); - reportUpdated = true; - } // if - } // else - } // for - - if (reportUpdated) { - List reportCols = rdef.getAllColumns(); - Collections.sort(reportCols, new OrderBySeqComparator()); - int iOrder = 1; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - if (dct.getOrderBySeq() > 0) - dct.setOrderBySeq(iOrder++); - } // for - Collections.sort(reportCols, new OrderSeqComparator()); - - rdef.resetCache(true); - } // if - - return reportUpdated; - } // processSortOrderAll - - private boolean processSortDelete(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef.removeColumnSort(AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - return true; - } // processSortDelete - - private boolean processSortMoveUp(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef - .shiftColumnSortUp(AppUtils.getRequestNvlValue(request, - AppConstants.RI_DETAIL_ID)); - return true; - } // processSortMoveUp - - private boolean processSortMoveDown(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef.shiftColumnSortDown(AppUtils.getRequestNvlValue(request, - AppConstants.RI_DETAIL_ID)); - return true; - } // processSortMoveDown - - private boolean processJavascript (HttpServletRequest request) throws Exception { - processSaveJavascriptElement(request); - return true; - } - - private boolean processSaveJavascriptElement (HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - rdef.setJavascriptElement(AppUtils.getRequestNvlValue(request, AppConstants.RI_JAVASCRIPT)); - String id = AppUtils.getRequestNvlValue(request, AppConstants.RI_JAVASCRIPT_ITEM_ID); - String fieldId = AppUtils.getRequestNvlValue(request, "javascriptFormField-"+id); - if( nvl(fieldId).length()>0 && !(fieldId.startsWith("-1"))) { - - String callableJavascriptText = AppUtils.getRequestNvlValue(request, "callText-"+id); - - logger.debug(EELFLoggerDelegate.debugLogger, ("FieldId " + fieldId + " Call Text " + callableJavascriptText+ " id " + id)); - JavascriptItemType javaScriptType = null; - if(id.length()>0 && id.startsWith("-1")) { - javaScriptType = rdef.addJavascriptType(new ObjectFactory(), id); - javaScriptType.setFieldId(fieldId); - if(!fieldId.equals("os1") || !fieldId.equals("ol1")) - javaScriptType.setId(rdef.getNextIdForJavaScriptElement(new ObjectFactory(), fieldId)); - else { - if(fieldId.equals("os1")) - javaScriptType.setId("os1|1"); - else - javaScriptType.setId("ol1|1"); - } - javaScriptType.setCallText(callableJavascriptText); - } else { - javaScriptType = rdef.addJavascriptType(new ObjectFactory(), id); - javaScriptType.setCallText(callableJavascriptText); - } - } - return true; - } - private boolean processAddJavascriptElement (HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - JavascriptItemType javaScriptType = rdef.addJavascriptType(new ObjectFactory(), ""); - javaScriptType.setId(""); - javaScriptType.setFieldId(""); - javaScriptType.setCallText(""); - - return true; - } - - private boolean processDeleteJavascriptElement (HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - String id = AppUtils.getRequestNvlValue(request, AppConstants.RI_JAVASCRIPT_ITEM_ID); - if(rdef.deleteJavascriptType(id)) - return true; - else - return false; - } - - private boolean processChart(HttpServletRequest request, String action) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - int valueColsCount = rdef.getChartValueColumnsList(AppConstants.CHART_ALL_COLUMNS, null).size(); - - String chartType = AppUtils.getRequestNvlValue(request, "chartType"); - String chartTypeFixed = AppUtils.getRequestValue(request, "chartTypeFixed"); - String legendColId = AppUtils.getRequestNvlValue(request, "legendCol"); - // String valueColId = AppUtils.getRequestNvlValue(request, "valueCol"); - String leftAxisLabel = AppUtils.getRequestValue(request, "leftAxisLabel"); - String rightAxisLabel = AppUtils.getRequestValue(request, "rightAxisLabel"); - String chartWidth = XSSFilter.filterRequest(AppUtils.getRequestNvlValue(request, "chartWidth")); - String chartHeight = XSSFilter.filterRequest(AppUtils.getRequestNvlValue(request, "chartHeight")); - String chartMultiseries = AppUtils.getRequestNvlValue(request, "multiSeries"); - String lastSeriesALineChart = AppUtils.getRequestNvlValue(request, "lastSeriesALineChart"); - String lastSeriesABarChart = AppUtils.getRequestNvlValue(request, "lastSeriesABarChart"); - String overLayItemLabel = "N"; - String chartDisplay = null; - - String multiplePieOrder = null; - String multiplePieLabelDisplay = null; - - String chartOrientation = null; - String secondaryChartRenderer = null; - - String linearRegression = null; - - boolean multiplePieOrderInRunPage = false; - boolean multiplePieLabelDisplayInRunPage = false; - - boolean chartOrientationInRunPage = false; - boolean secondaryChartRendererInRunPage = false; - - boolean chartDisplayInRunPage = false; - - String intervalFromdate = null; - String intervalTodate = null; - String intervalLabel = null; - boolean displayIntervalInputInRunPage = false; - boolean animate = false; - - animate = AppUtils.getRequestNvlValue(request, "animatedOption").equals("animate"); - if(Globals.showAnimatedChartOption()) - rdef.setChartAnimate(animate); - - - String removeColId = ""; - if (action.equals(AppConstants.WA_DELETE_USER)) { - removeColId = AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID); - if(valueColsCount == 2 && !rdef.hasSeriesColumn()) { - rdef.setChartLeftAxisLabel(null); - rdef.setChartRightAxisLabel(null); - - if(chartType.equals(AppConstants.GT_TIME_SERIES) || chartType.equals(AppConstants.GT_PIE_MULTIPLE)) { - chartMultiseries = "N"; - } - } - } - - if(rdef.getChartAdditionalOptions()==null) - rdef.addChartAdditionalOptions(new ObjectFactory()); - - if(rdef.getChartDrillOptions()==null) - rdef.addChartDrillOptions(new ObjectFactory()); - - //clearing already added - if(rdef.getChartDrillOptions().getTargetFormfield()!=null) - rdef.getChartDrillOptions().getTargetFormfield().removeAll(rdef.getChartDrillOptions().getTargetFormfield()); - - - if(chartType.equals(AppConstants.GT_PIE_MULTIPLE)) { - multiplePieOrder = AppUtils.getRequestNvlValue(request, "multiplePieOrder"); - multiplePieLabelDisplay = AppUtils.getRequestNvlValue(request, "multiplePieLabelDisplay"); - chartDisplay = AppUtils.getRequestNvlValue(request, "chartDisplay"); - //if(AppUtils.getRequestNvlValue(request, "multiplePieOrderInRunPage").length()>0) - multiplePieOrderInRunPage = AppUtils.getRequestNvlValue(request,"multiplePieOrderInRunPage").equals("Y"); - //if(AppUtils.getRequestNvlValue(request, "multiplePieLabelDisplayInRunPage").length()>0) - multiplePieLabelDisplayInRunPage = AppUtils.getRequestNvlValue(request,"multiplePieLabelDisplayInRunPage").equals("Y"); - //if(AppUtils.getRequestNvlValue(request, "chartDisplayInRunPage").length()>0) - chartDisplayInRunPage = AppUtils.getRequestNvlValue(request,"chartDisplayInRunPage").equals("Y"); - if(rdef.getChartAdditionalOptions()!=null) { - rdef.setChartMultiplePieOrder(multiplePieOrder+(multiplePieOrderInRunPage?"|Y":"")); - rdef.setChartMultiplePieLabelDisplay(multiplePieLabelDisplay+(multiplePieLabelDisplayInRunPage?"|Y":"")); - rdef.setChartDisplay(chartDisplay+(chartDisplayInRunPage?"|Y":"")); - } - - } - - if(chartType.equals(AppConstants.GT_REGRESSION)) { - linearRegression = AppUtils.getRequestNvlValue(request, "regressionType"); - rdef.setLinearRegressionColor(AppUtils.getRequestNvlValue(request, "valueLinearRegressionColor")); - rdef.setExponentialRegressionColor(AppUtils.getRequestNvlValue(request, "valueExponentialRegressionColor")); - rdef.setCustomizedRegressionPoint(AppUtils.getRequestNvlValue(request, "regressionPointCustomization")); - - if(nvl(linearRegression).length()>0) - rdef.setLinearRegression(linearRegression); - else - rdef.setLinearRegression("Y"); - } - - if(chartType.equals(AppConstants.GT_BAR_3D)) { - chartOrientation = AppUtils.getRequestNvlValue(request, "chartOrientation"); - secondaryChartRenderer = AppUtils.getRequestNvlValue(request, "secondaryChartRenderer"); - chartDisplay = AppUtils.getRequestNvlValue(request, "chartDisplay"); - //if(AppUtils.getRequestNvlValue(request, "chartOrientationInRunPage").length()>0) - chartOrientationInRunPage = AppUtils.getRequestNvlValue(request,"chartOrientationInRunPage").equals("Y"); - //if(AppUtils.getRequestNvlValue(request, "secondaryChartRendererInRunPage").length()>0) - secondaryChartRendererInRunPage = AppUtils.getRequestNvlValue(request,"secondaryChartRendererInRunPage").equals("Y"); - //if(AppUtils.getRequestNvlValue(request, "chartDisplayInRunPage").length()>0) - chartDisplayInRunPage = AppUtils.getRequestNvlValue(request,"chartDisplayInRunPage").equals("Y"); - rdef.setChartOrientation(chartOrientation+(chartOrientationInRunPage?"|Y":"")); - rdef.setSecondaryChartRenderer(secondaryChartRenderer+(secondaryChartRendererInRunPage?"|Y":"")); - rdef.setChartDisplay(chartDisplay+(chartDisplayInRunPage?"|Y":"")); - rdef.setLastSeriesALineChart(nvl(lastSeriesALineChart, "N")); - } - - if(chartType.equals(AppConstants.GT_LINE)) { - chartOrientation = AppUtils.getRequestNvlValue(request, "chartOrientation"); - secondaryChartRenderer = AppUtils.getRequestNvlValue(request, "secondaryChartRenderer"); - chartDisplay = AppUtils.getRequestNvlValue(request, "chartDisplay"); - //if(AppUtils.getRequestNvlValue(request, "chartOrientationInRunPage").length()>0) - chartOrientationInRunPage = AppUtils.getRequestNvlValue(request,"chartOrientationInRunPage").equals("Y"); - //if(AppUtils.getRequestNvlValue(request, "secondaryChartRendererInRunPage").length()>0) - secondaryChartRendererInRunPage = AppUtils.getRequestNvlValue(request,"secondaryChartRendererInRunPage").equals("Y"); - //if(AppUtils.getRequestNvlValue(request, "chartDisplayInRunPage").length()>0) - chartDisplayInRunPage = AppUtils.getRequestNvlValue(request,"chartDisplayInRunPage").equals("Y"); - rdef.setChartOrientation(chartOrientation+(chartOrientationInRunPage?"|Y":"")); - rdef.setSecondaryChartRenderer(secondaryChartRenderer+(secondaryChartRendererInRunPage?"|Y":"")); - rdef.setChartDisplay(chartDisplay+(chartDisplayInRunPage?"|Y":"")); - rdef.setLastSeriesABarChart(nvl(lastSeriesABarChart, "N")); - } - if(chartType.equals(AppConstants.GT_TIME_DIFFERENCE_CHART)) { - intervalFromdate = AppUtils.getRequestNvlValue(request, "intervalFromDate"); - intervalTodate = AppUtils.getRequestNvlValue(request, "intervalToDate"); - intervalLabel = AppUtils.getRequestNvlValue(request, "intervalLabel"); - displayIntervalInputInRunPage = AppUtils.getRequestNvlValue(request,"intervalInputInRunPage").equals("Y"); - rdef.setIntervalFromdate(intervalFromdate+(displayIntervalInputInRunPage?"|Y":"")); - rdef.setIntervalTodate(intervalTodate+(displayIntervalInputInRunPage?"|Y":"")); - rdef.setIntervalLabel(intervalLabel); - } - if(chartType.equals(AppConstants.GT_STACKED_VERT_BAR) || chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR) || chartType.equals(AppConstants.GT_STACKED_VERT_BAR_LINES) - || chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR_LINES)) { - overLayItemLabel = AppUtils.getRequestNvlValue(request, "overlayItemValue"); - rdef.setOverlayItemValueOnStackBar(nvl(overLayItemLabel, "N")); - animate = AppUtils.getRequestNvlValue(request, "animatedOption").equals("animate"); - rdef.setChartAnimate(animate); - } - - rdef.setRangeAxisLowerLimit(AppUtils.getRequestNvlValue(request, "yAxisLowerLimit")); - rdef.setRangeAxisUpperLimit(AppUtils.getRequestNvlValue(request, "yAxisUpperLimit")); - rdef.setLegendLabelAngle(AppUtils.getRequestNvlValue(request,"labelAngle")); - rdef.setLegendPosition(AppUtils.getRequestNvlValue(request,"legendPosition")); - rdef.setMaxLabelsInDomainAxis(AppUtils.getRequestNvlValue(request,"maxLabelsInDomainAxis")); - String chartLegendDisplay = AppUtils.getRequestNvlValue(request,"hideLegend"); - boolean showLegendDisplayOptionsInRunPage = false; - showLegendDisplayOptionsInRunPage = AppUtils.getRequestNvlValue(request,"showLegendDisplayOptionsInRunPage").equals("Y"); - rdef.setChartLegendDisplay(chartLegendDisplay+(showLegendDisplayOptionsInRunPage?"|Y":"")); - rdef.setChartToolTips(AppUtils.getRequestNvlValue(request,"hideTooltips")); - rdef.setDomainAxisValuesAsString(AppUtils.getRequestNvlValue(request,"keepAsString")); - - //System.out.println("KeepAsString " + AppUtils.getRequestNvlValue(request,"keepAsString")); - //System.out.println("From ReportDef " + rdef.keepDomainAxisValueInChartAsString()); - // boolean reportUpdated = (! - // chartType.equals(nvl(rdef.getChartType()))); - rdef.setChartType(chartType); - rdef.setChartTypeFixed(nvl(chartTypeFixed, "N")); - if (nvl(leftAxisLabel).length()>0) - rdef.setChartLeftAxisLabel(leftAxisLabel); - else - rdef.setChartLeftAxisLabel(null); - if (nvl(rightAxisLabel).length()>0) - rdef.setChartRightAxisLabel(rightAxisLabel); - else - rdef.setChartRightAxisLabel(null); - rdef.setChartWidth(nvl(chartWidth, "" + Globals.getDefaultChartWidth())); - rdef.setChartHeight(nvl(chartHeight, "" + Globals.getDefaultChartHeight())); - if(chartType.equals(AppConstants.GT_TIME_SERIES) || chartType.equals(AppConstants.GT_PIE_MULTIPLE)) { - rdef.setChartMultiSeries(chartMultiseries); - } else { - rdef.setChartMultiSeries("N"); - } - - List reportCols = rdef.getAllColumns(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - - if (dct.getColId().equals(legendColId)) { - // reportUpdated = reportUpdated||(! - // nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND)); - dct.setColOnChart(AppConstants.GC_LEGEND); - } else { - // reportUpdated = - // reportUpdated||nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND); - dct.setColOnChart(null); - } - - /* - * if(dct.getColId().equals(valueColId)) { reportUpdated = - * reportUpdated||(dct.getChartSeq()<=0); dct.setChartSeq(1); } - * else { reportUpdated = reportUpdated||(dct.getChartSeq()>0); - */ - dct.setChartSeq(-1); - /* } */ - } // for - - int idx = 1; - List columns = rdef.getAllColumns(); - if(chartType.equals(AppConstants.GT_TIME_SERIES)) { - String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); - String chartGroup = AppUtils.getRequestNvlValue(request, "chartGroup"); - String yAxis = AppUtils.getRequestNvlValue(request, "yAxis"); - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType alldct = (DataColumnType) iterator.next(); - //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); - alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); - } - - String drillDownReportId = AppUtils.getRequestNvlValue(request, "drillDownReport"); - if(!drillDownReportId.equals("-1")) { - ReportRuntime ddRr = (new ReportHandler()).loadReportRuntime(request, drillDownReportId, - false); - if (ddRr != null) - request.setAttribute("CHART_FORMFIELDS", ddRr.getReportFormFields()); - - for(ddRr.getReportFormFields().resetNext(); ddRr.getReportFormFields().hasNext(); ) { - FormField ff = ddRr.getReportFormFields().getNext(); - if(!ff.getFieldType().equals(FormField.FFT_BLANK)) { - String value = AppUtils.getRequestNvlValue(request, "drillDown_"+ff.getFieldName()); - ChartDrillFormfield cdf = new ObjectFactory().createChartDrillFormfield(); - cdf.setFormfield(value); - rdef.getChartDrillOptions().getTargetFormfield().add(cdf); - } - } - } - - } else { - if(chartType.equals(AppConstants.GT_BAR_3D)) { - String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); - String chartGroup = AppUtils.getRequestNvlValue(request, "chartGroup"); - String yAxis = AppUtils.getRequestNvlValue(request, "yAxis"); - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType alldct = (DataColumnType) iterator.next(); - //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); - alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); - } - String drillDownReportId = AppUtils.getRequestNvlValue(request, "drillDownReport"); - rdef.setDrillReportIdForChart(drillDownReportId); - if(drillDownReportId.equals("-1")){ - rdef.setDrillReportIdForChart(""); - } - - if(!drillDownReportId.equals("-1")) { - ReportRuntime ddRr = (new ReportHandler()).loadReportRuntime(request, drillDownReportId, - false); - if (ddRr != null) - request.setAttribute("CHART_FORMFIELDS", ddRr.getReportFormFields()); - - for(ddRr.getReportFormFields().resetNext(); ddRr.getReportFormFields().hasNext(); ) { - FormField ff = ddRr.getReportFormFields().getNext(); - if(!ff.getFieldType().equals(FormField.FFT_BLANK)) { - String value = AppUtils.getRequestNvlValue(request, "drillDown_"+ff.getFieldName()); - ChartDrillFormfield cdf = new ObjectFactory().createChartDrillFormfield(); - cdf.setFormfield(value); - rdef.getChartDrillOptions().getTargetFormfield().add(cdf); - } - } - - String xAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownXAxisFormfield"); - String yAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownYAxisFormfield"); - String seriesAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownSeriesAxisFormfield"); - - if(!xAxisFormField.equals("-1")){ - rdef.setDrillXAxisFormField(xAxisFormField); - - if(!yAxisFormField.equals("-1")) - rdef.setDrillYAxisFormField(yAxisFormField); - if(!seriesAxisFormField.equals("-1")) - rdef.setDrillSeriesFormField(seriesAxisFormField); - } else { - rdef.setDrillXAxisFormField(""); - rdef.setDrillYAxisFormField(""); - rdef.setDrillSeriesFormField(""); - } - } - - } else if(chartType.equals(AppConstants.GT_SCATTER)) { - String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType alldct = (DataColumnType) iterator.next(); - //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); - alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); - } - - }else if(chartType.equals(AppConstants.GT_REGRESSION)) { - String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType alldct = (DataColumnType) iterator.next(); - //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); - alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); - } - }else if(chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR) || chartType.equals(AppConstants.GT_STACKED_VERT_BAR) - || chartType.equals(AppConstants.GT_STACKED_VERT_BAR_LINES) || chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR_LINES)) { - String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType alldct = (DataColumnType) iterator.next(); - //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); - alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); - } - }else if(chartType.equals(AppConstants.GT_LINE)) { - String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType alldct = (DataColumnType) iterator.next(); - //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); - alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); - } - } else if (chartType.equals(AppConstants.GT_TIME_DIFFERENCE_CHART)) { - String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType alldct = (DataColumnType) iterator.next(); - //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); - alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); - } - } else if (chartType.equals(AppConstants.GT_COMPARE_PREVYEAR_CHART)) { - String chartSeries = AppUtils.getRequestNvlValue(request, "chartSeries"); - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType alldct = (DataColumnType) iterator.next(); - //debugLogger.debug("**********In " + chartSeries + " " + alldct.getColId()); - alldct.setChartSeries((chartSeries.equals(alldct.getColId()))?true : false); - } - - } else { - if (rdef.hasSeriesColumn()) { - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType alldct = (DataColumnType) iterator.next(); - alldct.setChartSeries(false); - } - } - - String drillDownReportId = AppUtils.getRequestNvlValue(request, "drillDownReport"); - rdef.setDrillReportIdForChart(drillDownReportId); - if(drillDownReportId.equals("-1")){ - rdef.setDrillReportIdForChart(""); - } - - if(!drillDownReportId.equals("-1")) { - ReportRuntime ddRr = (new ReportHandler()).loadReportRuntime(request, drillDownReportId, - false); - if (ddRr != null) - request.setAttribute("CHART_FORMFIELDS", ddRr.getReportFormFields()); - for(ddRr.getReportFormFields().resetNext(); ddRr.getReportFormFields().hasNext(); ) { - FormField ff = ddRr.getReportFormFields().getNext(); - if(!ff.getFieldType().equals(FormField.FFT_BLANK)) { - String value = AppUtils.getRequestNvlValue(request, "drillDown_"+ff.getFieldName()); - ChartDrillFormfield cdf = new ObjectFactory().createChartDrillFormfield(); - cdf.setFormfield(value); - rdef.getChartDrillOptions().getTargetFormfield().add(cdf); - } - } - - String xAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownXAxisFormfield"); - String yAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownYAxisFormfield"); - String seriesAxisFormField = AppUtils.getRequestNvlValue(request, "drillDownSeriesAxisFormfield"); - - if(!xAxisFormField.equals("-1")){ - rdef.setDrillXAxisFormField(xAxisFormField); - - if(!yAxisFormField.equals("-1")) - rdef.setDrillYAxisFormField(yAxisFormField); - if(!seriesAxisFormField.equals("-1")) - rdef.setDrillSeriesFormField(seriesAxisFormField); - } else { - rdef.setDrillXAxisFormField(""); - rdef.setDrillYAxisFormField(""); - rdef.setDrillSeriesFormField(""); - } - } - - } - } - - for (int i = 1; i < Math.max(valueColsCount, 1) + 1; i++) { - //debugLogger.debug("********** " + chartSeries); - if(i==1) { - /* Range Axis is resetted before adding */ - for (Iterator iterator = columns.iterator(); iterator.hasNext();) { - DataColumnType dct = (DataColumnType) iterator.next(); - if(!nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND)) { - dct.setChartSeq(-1); - dct.setChartColor(null); - dct.setColOnChart(null); - dct.setCreateInNewChart(false); - dct.setChartGroup(null); - dct.setYAxis(null); - } - } - - } - String newChartColAxis = AppUtils.getRequestNvlValue(request, "newChart" + i+"Axis"); - String valueColId = AppUtils.getRequestNvlValue(request, "valueCol" + i); - String valueColColor = AppUtils.getRequestNvlValue(request, "valueCol" + i - + "Color"); - String valueColAxis = AppUtils - .getRequestNvlValue(request, "valueCol" + valueColId + "Axis"); - String chartGroup = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "chartGroup" + valueColId + "Axis")); - String yAxisGroup = ""; - yAxisGroup = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "YAxisLabel" + valueColId)); - //debugLogger.debug("^^^^^^^^^^^^^^^^^Chart Group " + chartGroup); - //if(chartType.equals(AppConstants.GT_TIME_SERIES)) { - // debugLogger.debug("**********Outer If " + chartSeries); - //} - - if (valueColId.length() > 0 && (!valueColId.equals(removeColId))) { - DataColumnType dct = rdef.getColumnById(valueColId); - dct.setChartSeq(idx++); - dct.setChartColor(valueColColor); - dct.setColOnChart(valueColAxis.equals("Y") ? "1" : "0"); - if(chartType.equals(AppConstants.GT_TIME_SERIES)) { - dct.setCreateInNewChart(newChartColAxis.equals("Y") ? true : false); - } else - dct.setCreateInNewChart(false); - - if(chartGroup!=null && chartGroup.length()>0) - dct.setChartGroup(chartGroup+"|"+valueColId); - else dct.setChartGroup(""); - if(chartType.equals(AppConstants.GT_TIME_SERIES)) - dct.setYAxis(nvl(yAxisGroup)+"|"+valueColId); - else if (chartType.equals(AppConstants.GT_BAR_3D)) - dct.setYAxis(nvl(yAxisGroup)+"|"+valueColId); - else dct.setYAxis(""); - //} - //else - //dct.setCreateInNewChart(false); - } else if (valueColId.length() > 0 && (valueColId.equals(removeColId))) {// if - DataColumnType dct = rdef.getColumnById(valueColId); - dct.setChartSeq(-1); - dct.setChartColor(null); - dct.setColOnChart(null); - dct.setCreateInNewChart(false); - dct.setChartGroup(null); - dct.setYAxis(null); - } else { // else - DataColumnType dct = rdef.getColumnById(valueColId); - dct.setChartSeq(-1); - dct.setChartColor(null); - dct.setColOnChart(null); - dct.setCreateInNewChart(false); - dct.setChartGroup(null); - dct.setYAxis(null); - } - } // for - - if (action.equals(AppConstants.WA_ADD_USER)) { - String valueColId = AppUtils.getRequestNvlValue(request, "valueColNew"); - String valueColColor = AppUtils.getRequestNvlValue(request, "valueColNewColor"); - String valueColAxis = AppUtils.getRequestNvlValue(request, "valueColNewAxis"); - - if (valueColId.length() > 0) { - DataColumnType dct = rdef.getColumnById(valueColId); - dct.setChartSeq(idx++); - dct.setChartColor(valueColColor); - dct.setColOnChart(valueColAxis.equals("Y") ? "1" : "0"); - } // if - } // for - - return true; // reportUpdated; - } // processChart - - public boolean processAdhocSchedule(HttpServletRequest request, String action) - throws Exception { - ReportSchedule reportSchedule = (ReportSchedule) request.getSession().getAttribute(AppConstants.SI_REPORT_SCHEDULE); - reportSchedule.setScheduleUserID(AppUtils.getUserID(request)); - reportSchedule.setSchedEnabled( - nvl(AppUtils.getRequestValue(request, "schedEnabled"), "N")); - reportSchedule.setStartDate( - AppUtils.getRequestNvlValue(request, "schedStartDate")); - reportSchedule.setEndDate( - AppUtils.getRequestNvlValue(request, "schedEndDate")); - reportSchedule.setEndHour(AppUtils.getRequestNvlValue(request, "schedEndHour")); - reportSchedule.setEndMin(AppUtils.getRequestNvlValue(request, "schedEndMin")); - reportSchedule.setEndAMPM(AppUtils.getRequestNvlValue(request, "schedEndAMPM")); - //schedRunDate - reportSchedule.setRunDate( - AppUtils.getRequestNvlValue(request, "schedRunDate").length()>0?AppUtils.getRequestNvlValue(request, "schedRunDate"):AppUtils.getRequestNvlValue(request, "schedStartDate")); - reportSchedule.setRunHour(AppUtils.getRequestNvlValue(request, "schedHour")); - reportSchedule.setRunMin(AppUtils.getRequestNvlValue(request, "schedMin")); - reportSchedule.setRunAMPM(AppUtils.getRequestNvlValue(request, "schedAMPM")); - reportSchedule.setRecurrence( - AppUtils.getRequestNvlValue(request, "schedRecurrence")); - reportSchedule.setConditional( - nvl(AppUtils.getRequestValue(request, "conditional"), "N")); - reportSchedule.setConditionSQL( - AppUtils.getRequestNvlValue(request, "conditionSQL")); - reportSchedule.setNotify_type( - AppUtils.getRequestNvlValue(request, "notify_type")); - reportSchedule.setDownloadLimit( - AppUtils.getRequestNvlValue(request, "downloadLimit")); - reportSchedule.setFormFields( - AppUtils.getRequestNvlValue(request, "formFields")); - reportSchedule.setAttachmentMode( - AppUtils.getRequestNvlValue(request, "sendAttachment")); - - String userId = AppUtils.getRequestNvlValue(request, "schedEmailAdd"); - String roleId = AppUtils.getRequestNvlValue(request, "schedEmailAddRole"); - int flag = 0; - if ((!(userId.length()>0 || roleId.length()>0) && (reportSchedule.getEmailToUsers().isEmpty() && reportSchedule.getEmailToRoles().isEmpty())) ) { - flag = 1; - } - - if (flag == 1 || (action.equals(AppConstants.WA_ADD_USER) || action.equals(AppConstants.WA_ADD_ROLE)) ) { - String loggedInUserId = AppUtils.getUserID(request); - if (Globals.getUseLoginIdInSchedYN().equals("Y")){ - reportSchedule.addEmailToUser(loggedInUserId, AppUtils.getUserLoginId(request)); - } else - reportSchedule.addEmailToUser(loggedInUserId, (AppUtils.getUserName(loggedInUserId).length()>0?AppUtils.getUserName(loggedInUserId):(AppUtils.getUserLoginId(loggedInUserId).length()>0?AppUtils.getUserLoginId(loggedInUserId):loggedInUserId) )); - } - if (action.equals(AppConstants.WA_ADD_USER)) { - //String userId = AppUtils.getRequestNvlValue(request, "schedEmailAdd"); - String userName = AppUtils.getUserName(userId); - if (Globals.getUseLoginIdInSchedYN().equals("Y")){ - String userLoginId = AppUtils.getUserLoginId(userId); - if (userId.length() > 0 && (userLoginId != null && userLoginId.length() > 0)) - reportSchedule.addEmailToUser(userId, userLoginId); - else { - if (userId.length() > 0 && (userName != null && userName.length() > 0) ) - reportSchedule.addEmailToUser(userId, userName); - else { - reportSchedule.addEmailToUser(userId, userId); - } - } - }else{ - if (userId.length() > 0 && (userName != null && userName.length() > 0) ) - reportSchedule.addEmailToUser(userId, userName); - else { - reportSchedule.addEmailToUser(userId, userId); - } - } - - } else if (action.equals(AppConstants.WA_DELETE_USER)) - reportSchedule.removeEmailToUser( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - else if (action.equals(AppConstants.WA_ADD_ROLE)) { - //String roleId = AppUtils.getRequestNvlValue(request, "schedEmailAddRole"); - String roleName = AppUtils.getRoleName(roleId); - if (roleId.length() > 0 && roleName != null) - reportSchedule.addEmailToRole(roleId, roleName); - } else if (action.equals(AppConstants.WA_DELETE_ROLE)) - reportSchedule.removeEmailToRole( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - request.getSession().setAttribute(AppConstants.SI_REPORT_SCHEDULE, reportSchedule); - return true; - } // processAdhocSchedule - - private boolean processSchedule(HttpServletRequest request, String action) - throws Exception { - // Added for form field chaining in schedule tab so that setParamValues() is called - request.setAttribute(AppConstants.SCHEDULE_ACTION, "Y"); - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - ReportSchedule reportSchedule = rdef.getReportSchedule(); - reportSchedule.setScheduleUserID(AppUtils.getUserID(request)); - reportSchedule.setSchedEnabled( - nvl(AppUtils.getRequestValue(request, "schedEnabled"), "N")); - reportSchedule.setStartDate( - AppUtils.getRequestNvlValue(request, "schedStartDate")); - reportSchedule.setEndDate( - AppUtils.getRequestNvlValue(request, "schedEndDate")); - reportSchedule.setEndHour(AppUtils.getRequestNvlValue(request, "schedEndHour")); - reportSchedule.setEndMin(AppUtils.getRequestNvlValue(request, "schedEndMin")); - reportSchedule.setEndAMPM(AppUtils.getRequestNvlValue(request, "schedEndAMPM")); - //schedRunDate - reportSchedule.setRunDate( - AppUtils.getRequestNvlValue(request, "schedRunDate").length()>0?AppUtils.getRequestNvlValue(request, "schedRunDate"):AppUtils.getRequestNvlValue(request, "schedStartDate")); - reportSchedule.setRunHour(AppUtils.getRequestNvlValue(request, "schedHour")); - reportSchedule.setRunMin(AppUtils.getRequestNvlValue(request, "schedMin")); - reportSchedule.setRunAMPM(AppUtils.getRequestNvlValue(request, "schedAMPM")); - reportSchedule.setRecurrence( - AppUtils.getRequestNvlValue(request, "schedRecurrence")); - reportSchedule.setConditional( - nvl(AppUtils.getRequestValue(request, "conditional"), "N")); - reportSchedule.setConditionSQL( - AppUtils.getRequestNvlValue(request, "conditionSQL")); - reportSchedule.setNotify_type( - AppUtils.getRequestNvlValue(request, "notify_type")); - reportSchedule.setDownloadLimit( - AppUtils.getRequestNvlValue(request, "downloadLimit")); - reportSchedule.setFormFields( - AppUtils.getRequestNvlValue(request, "formFields")); - reportSchedule.setAttachmentMode( - AppUtils.getRequestNvlValue(request, "sendAttachment")); - - reportSchedule.setEncryptMode( - AppUtils.getRequestNvlValue(request, "encryptMode")); - if (action.equals(AppConstants.WA_ADD_USER)) { - String userId = AppUtils.getRequestNvlValue(request, "schedEmailAdd"); - String userName = AppUtils.getUserName(userId); - if (Globals.getUseLoginIdInSchedYN().equals("Y")){ - String userLoginId = AppUtils.getUserLoginId(userId); - if (userId.length() > 0 && (userLoginId != null && userLoginId.length() > 0)) - reportSchedule.addEmailToUser(userId, userLoginId); - else { - if (userId.length() > 0 && (userName != null && userName.length() > 0) ) - reportSchedule.addEmailToUser(userId, userName); - else { - reportSchedule.addEmailToUser(userId, userId); - } - } - }else{ - if (userId.length() > 0 && (userName != null && userName.length() > 0) ) - reportSchedule.addEmailToUser(userId, userName); - else { - reportSchedule.addEmailToUser(userId, userId); - } - } - } else if (action.equals(AppConstants.WA_DELETE_USER)) - reportSchedule.removeEmailToUser( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - else if (action.equals(AppConstants.WA_ADD_ROLE)) { - String roleId = AppUtils.getRequestNvlValue(request, "schedEmailAddRole"); - String roleName = AppUtils.getRoleName(roleId); - if (roleId.length() > 0 && roleName != null) - reportSchedule.addEmailToRole(roleId, roleName); - } else if (action.equals(AppConstants.WA_DELETE_ROLE)) - reportSchedule.removeEmailToRole( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - - return true; - } // processSchedule - - private boolean processUserAccess(HttpServletRequest request, String action) - throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String ownerID = AppUtils.getRequestNvlValue(request, "reportOwner"); - String rPublic = nvl(AppUtils.getRequestValue(request, "public"), "N"); - - boolean reportUpdated = (!(ownerID.equals(nvl(rdef.getOwnerID())) && rPublic - .equals(rdef.isPublic() ? "Y" : "N"))); - - rdef.getReportSecurity().setOwnerID(ownerID); - rdef.setPublic(rPublic.equals("Y")); - - if (action.equals(AppConstants.WA_ADD_USER)) - rdef.getReportSecurity().addUserAccess( - AppUtils.getRequestNvlValue(request, "newUserId"), "Y"); - else if (action.equals(AppConstants.WA_DELETE_USER)) - rdef.getReportSecurity().removeUserAccess( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - else if (action.equals(AppConstants.WA_GRANT_USER)) - rdef.getReportSecurity().updateUserAccess( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID), "N"); - else if (action.equals(AppConstants.WA_REVOKE_USER)) - rdef.getReportSecurity().updateUserAccess( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID), "Y"); - else if (action.equals(AppConstants.WA_ADD_ROLE)) - rdef.getReportSecurity().addRoleAccess( - AppUtils.getRequestNvlValue(request, "newRoleId"), "Y"); - else if (action.equals(AppConstants.WA_DELETE_ROLE)) - rdef.getReportSecurity().removeRoleAccess( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID)); - else if (action.equals(AppConstants.WA_GRANT_ROLE)) - rdef.getReportSecurity().updateRoleAccess( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID), "N"); - else if (action.equals(AppConstants.WA_REVOKE_ROLE)) - rdef.getReportSecurity().updateRoleAccess( - AppUtils.getRequestNvlValue(request, AppConstants.RI_DETAIL_ID), "Y"); - - return reportUpdated; - } // processUserAccess - - private boolean processClearLog(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - String user_id = AppUtils.getUserID(request); - // Modified so that only the logged in user entries are erased. - Sundar - ReportLoader.clearReportLogEntries(rdef.getReportID(), user_id); - return false; - } // processClearLog - - private boolean processValidateSQL(HttpServletRequest request) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - String sql = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "reportSQL")); - request.setAttribute("sqlValidated", "N"); - rdef.parseReportSQL(sql); - request.setAttribute("sqlValidated", "Y"); - - return true; - } // processValidateSQL - - - /*****For Report Maps - Start******/ - private boolean processMap(HttpServletRequest request, String action) throws Exception { - ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute( - AppConstants.SI_REPORT_DEFINITION); - - org.openecomp.portalsdk.analytics.xmlobj.ReportMap repMap = rdef.getReportMap(); - //clearing already added - if (repMap != null){ - repMap.getMarkers().removeAll(repMap.getMarkers()); - } - String addressColumn = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "addressColumn0")); - System.out.println(" #$%#$%#$% -- address col = " + addressColumn); - String dataColumn = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "dataColumn0")); - String legendColumn = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "legendColumn")); - //String legendDisplayName = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "dataHeaderL")); - //if(nvl(legendDisplayName).length()<=0) legendDisplayName = legendColumn; - String color = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "markerColor0")); - String isMapAllowed = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "isMapAllowed")); - String useDefaultSize = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "useDefaultSize")); - String height = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "height")); - String width = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "width")); - System.out.println(" #$%#$%#$% -- useDefaultSize="+ useDefaultSize+" height = " + height+" width="+width); - - String addAddress = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "addAddress")); - String latCol = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "latColumn")); - String longCol = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "longColumn")); - String colorCol = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "colorColumn")); - if (isMapAllowed.equals("")) - isMapAllowed = "N"; - if (useDefaultSize.equals("")) - useDefaultSize = "N"; - if (repMap == null) - rdef.setReportMap(new ObjectFactory().createReportMap()); - repMap.setAddressColumn(addressColumn); - repMap.setDataColumn(dataColumn); - repMap.setIsMapAllowedYN(isMapAllowed); - repMap.setUseDefaultSize(useDefaultSize); - repMap.setMarkerColor(color); - repMap.setAddAddressInDataYN(addAddress); - repMap.setLatColumn(latCol); - repMap.setLongColumn(longCol); - repMap.setColorColumn(colorCol); - repMap.setHeight(height.trim()); - repMap.setWidth(width.trim()); - repMap.setLegendColumn(legendColumn); - //repMap.setLegendDisplayName(legendDisplayName); - - Marker m = new ObjectFactory().createMarker(); - m.setAddressColumn(addressColumn); - m.setDataColumn(dataColumn); - repMap.getMarkers().add(m); - String markerCountString = AppUtils.getRequestNvlValue(request, "markerCount"); - int markerCount = 0; - if (markerCountString != null && markerCountString.equals("") == false){ - markerCount = new Integer(markerCountString).intValue(); - } - for (int i = 1; i < markerCount; i ++){ - String additionalAddressColumn = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "addressColumn" + i)); - String additionalDataHeader = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "dataHeader" + i)); - String additionalData = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "dataColumn" + i)); - String additionalColor = XSSFilter.filterRequestOnlyScript(AppUtils.getRequestNvlValue(request, "markerColor" + i)); - if (additionalAddressColumn.equals("1") == false){ - m = new ObjectFactory().createMarker(); - m.setAddressColumn(additionalAddressColumn); - m.setDataHeader(additionalDataHeader); - m.setDataColumn(additionalData); - m.setMarkerColor(additionalColor); - repMap.getMarkers().add(m); - } - } - return true; - } // processMap - /*****For Report Maps - End******/ - - -} // WizardProcessor diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequence.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequence.java deleted file mode 100644 index 3a843873..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequence.java +++ /dev/null @@ -1,189 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import java.util.Vector; - -import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; -import org.openecomp.portalsdk.analytics.util.AppConstants; - -public class WizardSequence extends Vector { - // private String currentStep = AppConstants.WS_DEFINITION; - private int currentStepIdx = 0; - - private String currentSubStep = ""; - - private int nextElemIdx = 0; - - public void resetNext() { - resetNext(0); - } // resetNext - - public void resetNext(int toPos) { - nextElemIdx = toPos; - } // resetNext - - public boolean hasNext() { - return (nextElemIdx < size()); - } // hasNext - - public String getNext() { - return hasNext() ? getStep(nextElemIdx++) : null; - } // getNext - - // ***************************************************** - - public WizardSequence() { - add(AppConstants.WS_DEFINITION); - } // WizardSequence - - private String getStep(int index) { - return (String) get(index); - } // getStep - - private int getStepIndex(String step) { - for (int i = 0; i < size(); i++) - if (getStep(i).equals(step)) - return i; - - throw new IndexOutOfBoundsException(); - } // getStepIndex - - /* - * private String getInitialStep() { return getStep(0); } // getInitialStep - * - * private String getFinalStep() { return getStep(getStepCount()-1); } // - * getFinalStep - */ - private boolean isInitialStep(int index) { - return (index == 0); - } // isInitialStep - - /* - * private boolean isInitialStep(String step) { return - * isInitialStep(getStepIndex(step)); } // isInitialStep - */ - private boolean isFinalStep(int index) { - if (index == 0) - return false; - - return (index == (getStepCount() - 1)); - } // isFinalStep - - /* - * private boolean isFinalStep(String step) { return - * isFinalStep(getStepIndex(step)); } // isFinalStep - */ - - private int getNextStepIndex(int index) { - return (index == (getStepCount() - 1)) ? index : (index + 1); - } // getNextStep - - /* - * private String getNextStep(String step) { return - * getStep(getNextStepIndex(getStepIndex(step))); } // getNextStep - * - * private String getNextStep(String step, String subStep) { - * if(subStep.length()>0) return step; - * - * return getNextStep(step); } // getNextStep - */ - private int getPrevStepIndex(int index) { - return (index == 0) ? index : (index - 1); - } // getPrevStepIndex - - /* - * private String getPrevStep(String step) { return - * getStep(getPrevStepIndex(getStepIndex(step))); } // getPrevStep - * - * private String getPrevStep(String step, String subStep) { - * if(subStep.length()>0) return step; - * - * return getPrevStep(step); } // getPrevStep - */ - // ***************************************************** - public int getStepCount() { - return size(); - } // getStepCount - - public int getCurrentStepIndex() { - return currentStepIdx + 1; - } // getCurrentStepIndex - - public String getCurrentStep() { - return getStep(currentStepIdx); - } // getCurrentStep - - public String getCurrentSubStep() { - return currentSubStep; - } // getCurrentSubStep - - public boolean isInitialStep() { - return isInitialStep(currentStepIdx); - } // isInitialStep - - public boolean isFinalStep() { - return isFinalStep(currentStepIdx); - } // isFinalStep - - public void performAction(String action, ReportDefinition rdef) { - if (action.equals(AppConstants.WA_BACK)) - if (currentSubStep.length() > 0) - currentSubStep = ""; - else - currentStepIdx = getPrevStepIndex(currentStepIdx); - else if (action.equals(AppConstants.WA_NEXT)) { - if (currentSubStep.length() > 0) - currentSubStep = ""; - else { - currentStepIdx = getNextStepIndex(currentStepIdx); - if (rdef != null) - if (!rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED)) - if (getCurrentStep().equals(AppConstants.WS_TABLES) - && (rdef.getDataSourceList().getDataSource().size() == 0)) - currentSubStep = AppConstants.WSS_ADD; - else if (getCurrentStep().equals(AppConstants.WS_COLUMNS) - && (rdef.getAllColumns().size() == 0)) - currentSubStep = (rdef.getReportType().equals( - AppConstants.RT_CROSSTAB) ? AppConstants.WSS_ADD - : AppConstants.WSS_ADD_MULTI); - } - } else if (action.equals(AppConstants.WA_EDIT) || action.equals(AppConstants.WA_ADD) - || action.equals(AppConstants.WA_ADD_MULTI) - || action.equals(AppConstants.WA_ORDER_ALL)|| action.equals(AppConstants.WSS_ADD_BLANK) || action.equals(AppConstants.WA_MODIFY)) { - currentSubStep = action; - } - else if (currentSubStep.equals(AppConstants.WSS_ADD) - || currentSubStep.equals(AppConstants.WSS_EDIT)) - currentSubStep = AppConstants.WSS_EDIT; - else - currentSubStep = ""; - } // performAction - - public void performGoToStep(String step) { - int stepIdx = getStepIndex(step); - - if (stepIdx >= 0 && stepIdx < getStepCount()) { - currentStepIdx = stepIdx; - currentSubStep = ""; - } - } // performGoToStep - -} // WizardSequence diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceCrossTab.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceCrossTab.java deleted file mode 100644 index 2f16dcca..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceCrossTab.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; - -public class WizardSequenceCrossTab extends WizardSequence { - - public WizardSequenceCrossTab(boolean userIsAuthorizedToSeeLog) { - super(); - - add(AppConstants.WS_TABLES); - add(AppConstants.WS_COLUMNS); - add(AppConstants.WS_FORM_FIELDS); - add(AppConstants.WS_FILTERS); - add(AppConstants.WS_JAVASCRIPT); - add(AppConstants.WS_USER_ACCESS); - //add(AppConstants.WS_SCHEDULE); - if (userIsAuthorizedToSeeLog) - if (Globals.getEnableReportLog()) - add(AppConstants.WS_REPORT_LOG); - add(AppConstants.WS_RUN); - } // WizardSequenceCrossTab - -} // WizardSequenceCrossTab diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceDashboard.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceDashboard.java deleted file mode 100644 index d883e27e..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceDashboard.java +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; - -public class WizardSequenceDashboard extends WizardSequence { - - public WizardSequenceDashboard(boolean userIsAuthorizedToSeeLog) { - super(); - - add(AppConstants.WS_USER_ACCESS); - //add(AppConstants.WS_SCHEDULE); - if (userIsAuthorizedToSeeLog) - if (Globals.getEnableReportLog()) - add(AppConstants.WS_REPORT_LOG); - add(AppConstants.WS_RUN); - } // WizardSequenceDashboard - -} // WizardSequenceDashboard diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceLinear.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceLinear.java deleted file mode 100644 index 1ae4e8a6..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceLinear.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; - -public class WizardSequenceLinear extends WizardSequence { - - public WizardSequenceLinear(boolean userIsAuthorizedToSeeLog) { - super(); - - add(AppConstants.WS_TABLES); - add(AppConstants.WS_COLUMNS); - add(AppConstants.WS_FORM_FIELDS); - add(AppConstants.WS_FILTERS); - add(AppConstants.WS_SORTING); - //add(AppConstants.WS_JAVASCRIPT); - //add(AppConstants.WS_CHART); - add(AppConstants.WS_USER_ACCESS); - //add(AppConstants.WS_SCHEDULE); - if (userIsAuthorizedToSeeLog) - if (Globals.getEnableReportLog()) - add(AppConstants.WS_REPORT_LOG); - add(AppConstants.WS_RUN); - } // WizardSequenceLinear - -} // WizardSequenceLinear diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedCrossTab.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedCrossTab.java deleted file mode 100644 index 663c30c9..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedCrossTab.java +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; - -public class WizardSequenceSQLBasedCrossTab extends WizardSequence { - - public WizardSequenceSQLBasedCrossTab(boolean userIsAuthorizedToSeeLog) { - super(); - - add(AppConstants.WS_SQL); - add(AppConstants.WS_COLUMNS); - add(AppConstants.WS_FORM_FIELDS); - add(AppConstants.WS_JAVASCRIPT); - add(AppConstants.WS_USER_ACCESS); - //add(AppConstants.WS_SCHEDULE); - if (userIsAuthorizedToSeeLog) - if (Globals.getEnableReportLog()) - add(AppConstants.WS_REPORT_LOG); - add(AppConstants.WS_RUN); - } // WizardSequenceSQLBasedCrossTab - -} // WizardSequenceSQLBasedCrossTab diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedHive.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedHive.java deleted file mode 100644 index 77996380..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedHive.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; - -public class WizardSequenceSQLBasedHive extends WizardSequence { - - public WizardSequenceSQLBasedHive(boolean userIsAuthorizedToSeeLog) { - super(); - - add(AppConstants.WS_SQL); - add(AppConstants.WS_COLUMNS); - add(AppConstants.WS_FORM_FIELDS); - add(AppConstants.WS_JAVASCRIPT); - add(AppConstants.WS_CHART); - add(AppConstants.WS_USER_ACCESS); - //add(AppConstants.WS_MAP); - //add(AppConstants.WS_SCHEDULE); - if (userIsAuthorizedToSeeLog) - if (Globals.getEnableReportLog()) - add(AppConstants.WS_REPORT_LOG); - add(AppConstants.WS_RUN); - } // WizardSequenceSQLBasedHive - -} // WizardSequenceSQLBasedHive diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinear.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinear.java deleted file mode 100644 index eb90d3d6..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinear.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; - -public class WizardSequenceSQLBasedLinear extends WizardSequence { - - public WizardSequenceSQLBasedLinear(boolean userIsAuthorizedToSeeLog) { - super(); - - add(AppConstants.WS_SQL); - add(AppConstants.WS_COLUMNS); - add(AppConstants.WS_FORM_FIELDS); - //add(AppConstants.WS_JAVASCRIPT); - //if(!Globals.showAnimatedChartOnly()) - //add(AppConstants.WS_CHART); - add(AppConstants.WS_USER_ACCESS); - //add(AppConstants.WS_MAP); - //add(AppConstants.WS_SCHEDULE); - if (userIsAuthorizedToSeeLog) - if (Globals.getEnableReportLog()) - add(AppConstants.WS_REPORT_LOG); - add(AppConstants.WS_RUN); - } // WizardSequenceSQLBasedLinear - -} // WizardSequenceSQLBasedLinear diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinearDatamining.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinearDatamining.java deleted file mode 100644 index e43bf288..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/controller/WizardSequenceSQLBasedLinearDatamining.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.controller; - -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; - -public class WizardSequenceSQLBasedLinearDatamining extends WizardSequence { - - public WizardSequenceSQLBasedLinearDatamining(boolean userIsAuthorizedToSeeLog) { - super(); - - add(AppConstants.WS_SQL); - add(AppConstants.WS_COLUMNS); - add(AppConstants.WS_FORM_FIELDS); - add(AppConstants.WS_DATA_FORECASTING); - add(AppConstants.WS_JAVASCRIPT); - add(AppConstants.WS_CHART); - add(AppConstants.WS_USER_ACCESS); - //add(AppConstants.WS_SCHEDULE); - if (userIsAuthorizedToSeeLog) - if (Globals.getEnableReportLog()) - add(AppConstants.WS_REPORT_LOG); - add(AppConstants.WS_RUN); - } // WizardSequenceSQLBasedLinear - -} // WizardSequenceSQLBasedLinear diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserDefinedException.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserDefinedException.java deleted file mode 100644 index 31476bf6..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/error/UserDefinedException.java +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.error; - -/** - * This class is exclusively used to print error messages to user. - * - */ -public class UserDefinedException extends RaptorRuntimeException { - - public UserDefinedException(String message) { - super(message); - } - -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GMapProperties.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GMapProperties.java deleted file mode 100644 index 7c66f4be..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/GMapProperties.java +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.gmap.map; - -import org.openecomp.portalsdk.analytics.system.Globals; - -public class GMapProperties { - - public static String getProjectFolder() { - return Globals.getProjectFolder(); - } - - public static String getMarketShapefileFolder() { - return Globals.getMarketShapefileFolder(); - } - - public static String getTileSize() { - return Globals.getTileSize(); - } - - public static String getOutputFolder() { - return Globals.getOutputFolder(); - } - - public static String getTempFolderURL() { - return Globals.getTempFolderURL(); - } - -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/layer/SwingLayer.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/layer/SwingLayer.java deleted file mode 100644 index f5237ccf..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/map/layer/SwingLayer.java +++ /dev/null @@ -1,234 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.gmap.map.layer; - -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.Stroke; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.analytics.gmap.map.ColorProperties; -import org.openecomp.portalsdk.analytics.gmap.map.MapConstant; -import org.openecomp.portalsdk.analytics.gmap.map.NovaMap; -import org.openecomp.portalsdk.analytics.gmap.node.Node; -import org.openecomp.portalsdk.analytics.gmap.node.NodeInfo; -import org.openecomp.portalsdk.analytics.system.Globals; - - -public class SwingLayer { - private Rectangle shape; - private NovaMap map; - - public SwingLayer(NovaMap map) { - this.map = map; - } - - public boolean paintLayer(HttpServletRequest request, Graphics2D g2d, Rectangle bounds, Rectangle2D mapArea, Graphics2D g2Legend) { - return paintNodes(request, g2d, bounds, mapArea, g2Legend); - } - - protected boolean paintNodes(HttpServletRequest request, Graphics2D g2d, Rectangle bounds, Rectangle2D mapArea, Graphics2D g2Legend) { - boolean painted = false; - Node node = map.getNode(); - ColorProperties colorProperties = map.getColorProperties(); - int legendSize = 0; - if(map.isShowLegend()) - legendSize = map.getShowListSize(); - Object showListArr[] = ((HashSet)map.getShowList()).toArray(); - HashMap hashMap = node.getNodeCollection().getNodeCollection(); - Set set = hashMap.entrySet(); - int width = map.getShapeWidth(); - ArrayList visibleLabel = new ArrayList(151); - Color oldColor = g2d.getColor(); - Stroke oldStroke = g2d.getStroke(); - int textWidth = 0; - int legendLength = 0; - for (int i = 0; i < showListArr.length; i++) { - legendLength = ((String)showListArr[i]).length(); - if(legendLength > textWidth) textWidth = legendLength; - } - Point2D point = null; - for (Iterator iterator = set.iterator(); iterator.hasNext();) { - Map.Entry entry = (Map.Entry) iterator.next(); - NodeInfo nodeInfo = (NodeInfo) entry.getValue(); - - String id1 = (String) request.getAttribute("server_process_id"); - String id2 = (String) request.getSession().getAttribute("server_process_id"); - - if (!id1.equals(id2)) { - request.setAttribute("server_process_interrupted", true); - System.out.println("swing layer interrupted"); - return false; - } - //System.out.println("%%%%%%%getImage. no of T1%%%%%%" + nodeInfo.getAttribute("x_sequence")); - - - point = map.getPixelPos(nodeInfo.geoCoordinate.latitude, nodeInfo.geoCoordinate.longitude); - - if (!mapArea.contains(point.getX(), point.getY())) { - continue; - } - - painted = true; - - g2d.setColor(colorProperties.getColor(nodeInfo.getNodeType())); - - Point2D xyPoint = map.getScreenPointFromPixel(point.getX(), point.getY()); - int width2 = (colorProperties.getSize(nodeInfo.getNodeType()) * width) / 5; - - if (shape == null) { - shape = new Rectangle((int) xyPoint.getX(), (int) xyPoint.getY(), width2, width2); - } - else { - shape.setRect((int) xyPoint.getX(), (int) xyPoint.getY(), width2, width2); - } - - if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.FILLED_SQUARE)) { - g2d.fillRect((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); - } - else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.HOLLOW_SQUARE)) { - g2d.drawRect((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); - } - else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.FILLED_CIRCLE)) { - g2d.fillOval((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); - } - else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.HOLLOW_CIRCLE)) { - g2d.drawOval((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); - } - else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.FILLED_TRIANGLE)) { - int[] xPoints = {(int) shape.getX(), (int) shape.getX() - width2 / 2, (int) shape.getX() + width2 / 2}; - int[] yPoints = {(int) shape.getY() + width2 / 2, (int) shape.getY() - width2 / 2, (int) shape.getY() - width2 / 2}; - g2d.fillPolygon(xPoints, yPoints, xPoints.length); - } - else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.HOLLOW_TRIANGLE)) { - int[] xPoints = {(int) shape.getX(), (int) shape.getX() - width2 / 2, (int) shape.getX() + width2 / 2}; - int[] yPoints = {(int) shape.getY() + width2 / 2, (int) shape.getY() - width2 / 2, (int) shape.getY() - width2 / 2}; - g2d.drawPolygon(xPoints, yPoints, xPoints.length); - } - else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.FILLED_DIAMOND)) { - int[] xPoints = {(int) shape.getX() - width2 / 2, (int) shape.getX(), (int) shape.getX() + width2 / 2, (int) shape.getX()}; - int[] yPoints = {(int) shape.getY() , (int) shape.getY() - width2 / 2, (int) shape.getY(), (int) shape.getY() + width2 / 2}; - g2d.fillPolygon(xPoints, yPoints, xPoints.length); - } - else if (colorProperties.getShape(nodeInfo.getNodeType())!=null && colorProperties.getShape(nodeInfo.getNodeType()).equalsIgnoreCase(MapConstant.HOLLOW_DIAMOND)) { - int[] xPoints = {(int) shape.getX() - width2 / 2, (int) shape.getX(), (int) shape.getX() + width2 / 2, (int) shape.getX()}; - int[] yPoints = {(int) shape.getY() , (int) shape.getY() - width2 / 2, (int) shape.getY(), (int) shape.getY() + width2 / 2}; - g2d.drawPolygon(xPoints, yPoints, xPoints.length); - } else { - g2d.drawRect((int) shape.getCenterX() - width2, (int) shape.getCenterY() - width2, width2, width2); - } - - if (nodeInfo.isMoveable()) { - int fontSize = width / 2; - fontSize = fontSize > 14 ? 14 : fontSize; - fontSize = (colorProperties.getSize(nodeInfo.getNodeType()) * fontSize) / 5; - Font font = new Font("sans-serif", Font.BOLD, fontSize); - g2d.setFont(font); - g2d.setColor(Color.BLACK); - g2d.drawString("M", shape.x + width2 / 2, shape.y); - } - -// if (map.containsShowLabelList(nodeInfo.getNodeType())) { -// g2d.setColor(Color.BLACK); -// FontMetrics metrics = g2d.getFontMetrics(); -// int x = shape.x - metrics.stringWidth(nodeInfo.getID()) / 2; -// int y = shape.y + width2 * 4 / 3; -// g2d.drawString(nodeInfo.getID(), x, y); -// } - } - String legendName = ""; - int baseY = 0; - baseY = (int)(20*showListArr.length) + 20;//+5; - int baseX = 0; - if(map.isShowLegend()) { - for (int i = showListArr.length-1; i>=0; i--) { - - legendName = (String)showListArr[i]; - //for(int i = 0; i < showListArr.length; i++ ) { - if(i == showListArr.length-1){ - textWidth = (textWidth<="Legend".length())?"Legend".length():textWidth; - g2Legend.setColor(Color.WHITE); - //g2d.draw(new Rectangle2D.Double((int) bounds.getMaxX()*0.1, (int) bounds.getMaxY()*0.75*showListArr.length, (int) bounds.getMaxX()*0.75, (int) bounds.getMaxY()*0.75)); - g2Legend.fill3DRect((int)(0), (int)(0), (int) bounds.getWidth() , (int)(baseY) , true); // (int)(bounds.getMaxX()*0.9)- (int)(bounds.getMaxX()*0.25) - //if(i == 0){ - g2Legend.setColor(Color.BLACK); - g2Legend.setFont(NovaMap.HEADER_FONT); - g2Legend.drawString("Legend", (int) (10), 10); - } - int[] xPointsL = {(int) (10 - width / 2), (int) (10), (int) (10 + width/2), (int) (10)}; - int[] yPointsL = {(int) (15*i+5+20), (int) (15*i+5+20 - width / 2), (int) (15*i+5+20), (int) (15*i+5+20 + width / 2)}; - g2Legend.setColor(colorProperties.getColor( ((String)showListArr[i]).toUpperCase())); - g2Legend.fillPolygon(xPointsL, yPointsL, xPointsL.length); - g2Legend.setFont(NovaMap.TEXT_FONT); - g2Legend.setColor(Color.BLACK); - - g2Legend.drawString(legendName.substring(0, legendName.indexOf("-")), (int) (10) + width+10, (int) (15*i)+10+20); - } - } - -/* g2d.drawString("0", (int) bounds.getMaxX()/2+20 + width+10, 0); - g2d.drawString("50", (int) bounds.getMaxX()/2+20 + width+10, 50); - g2d.drawString("100", (int) bounds.getMaxX()/2+20 + width+10, 100); - g2d.drawString("200", (int) bounds.getMaxX()/2+20 + width+10, 200); - g2d.drawString("400", (int) bounds.getMaxX()/2+20 + width+10, 400); - g2d.drawString("600", (int) bounds.getMaxX()/2+20 + width+10, 600); -*/ -// g2d.setFont(NovaMap.TEXT_FONT); -// g2d.setColor(Color.BLACK); - if(nvl(map.getDataLoaded()).trim().length() > 0) { - g2d.setColor(Color.WHITE); - g2d.fill3DRect(new Double(bounds.getMinX()).intValue(), new Double(bounds.getMaxY()).intValue()-30, (int) bounds.getWidth() , (int)(30) , true); // (int)(bounds.getMaxX()*0.9)- (int)(bounds.getMaxX()*0.25) - g2d.setColor(Color.RED); - g2d.setFont(NovaMap.HEADER_FONT); - g2d.drawString(Globals.getUserDefinedMessageForMemoryLimitReached() + " "+ map.getDataLoaded()+ " were downloaded to Map.", new Double(bounds.getMinX()).intValue()+80, new Double(bounds.getMaxY()).intValue()-15); - } - - //g2d.drawString("Hello", new Double(bounds.getMinX()).intValue()+20, new Double(bounds.getMaxY()).intValue()-50); - FontMetrics metrics = g2d.getFontMetrics(); - - for (int i = 0; i < visibleLabel.size(); i++) { - String[] properties = visibleLabel.get(i).split(">>>"); - int x = Integer.parseInt(properties[1]) - metrics.stringWidth(properties[0]) / 2; - int y = Integer.parseInt(properties[2]) + Integer.parseInt(properties[3]) * 4 / 3; - g2d.drawString(properties[0], x, y); - } - - g2d.setColor(oldColor); - g2d.setStroke(oldStroke); - - return painted; - } - - private String nvl(String s) { - return (s == null) ? "" : s; - } -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/MapUtils.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/MapUtils.java deleted file mode 100644 index d938869a..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/gmap/utils/MapUtils.java +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.gmap.utils; - -import java.text.SimpleDateFormat; - - -public class MapUtils { - public static final short PLATE_CARREE_PROJECTION = 0; - public static final short WEB_MERCATOR_PROJECTION = 1; - - - - private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new java.text.SimpleDateFormat("yyyy/MM"); - - - - public static String getModifiedMarketID(String marketID) { - String modifiedMarketID = marketID.replaceAll("/", "_"); - modifiedMarketID = modifiedMarketID.replaceAll(" ", "_"); - return modifiedMarketID; - } - - /** - * increment or decrement - * @param currentYearMonth - * @param value - positive value will increment, otherwise decrement - * @return null if not valid number (must be between 2008/01 to 2010/12) - */ - - -/* public static void saveColor(HttpServletRequest request, DomainService domainService, - String type, String colorValue) { -// String userID = Integer.toString(UserUtils.getUserId(request)); -// MapColorPK colorPK = new MapColorPK(); -// MapColorVO colorVO = new MapColorVO(); -// -// colorPK.setUserID(userID); -// colorPK.setPrefID(type); -// colorVO.setMapColorPK(colorPK); -// colorVO.setColorValue(colorValue); -// -// domainService.saveDomainObject(colorVO); - } */ -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/DataCache.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/DataCache.java deleted file mode 100644 index 5bf4e003..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/DataCache.java +++ /dev/null @@ -1,524 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Vector; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.ReportSQLException; -import org.openecomp.portalsdk.analytics.model.base.IdNameValue; -import org.openecomp.portalsdk.analytics.model.definition.DBColumnInfo; -import org.openecomp.portalsdk.analytics.model.definition.TableJoin; -import org.openecomp.portalsdk.analytics.model.definition.TableSource; -import org.openecomp.portalsdk.analytics.model.runtime.LookupDBInfo; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.ConnectionUtils; -import org.openecomp.portalsdk.analytics.system.DbUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; - -public class DataCache extends org.openecomp.portalsdk.analytics.RaptorObject { - private static Vector dataViewActions = null; - - private static Vector publicReportIdNames = null; - - private static Vector privateReportIdNames = null; - - private static Vector groupReportIdNames = null; - - private static Vector reportTableSources = null; - - private static Vector reportTableJoins = null; - - private static HashMap reportTableDbColumns = new HashMap(); - - private static HashMap reportFieldDbLookups = null; - - public DataCache() { - } - - public static Vector getDataViewActions() throws RaptorException { - if (dataViewActions == null) - /* try */{ - dataViewActions = new Vector(); - - //DataSet ds = DbUtils - // .executeQuery("SELECT ts.web_view_action FROM cr_table_source ts WHERE ts.web_view_action IS NOT NULL"); - - String sql = Globals.getTheDataViewActions(); - DataSet ds = DbUtils - .executeQuery(sql); - - for (int i = 0; i < ds.getRowCount(); i++) - dataViewActions.add(ds.getString(i, 0)); - } // catch(Exception e) {} - - return dataViewActions; - } // getDataViewActions - - public static Vector getPublicReportIdNames() throws RaptorException { - // if(publicReportIdNames==null) => needs to be up-to-date at any time - /* try */{ - publicReportIdNames = new Vector(); - - //DataSet ds = DbUtils - // .executeQuery("SELECT rep_id, title FROM cr_report WHERE public_yn = 'Y' ORDER BY title"); - - String sql = Globals.getThePublicReportIdNames(); - DataSet ds = DbUtils - .executeQuery(sql); - for (int i = 0; i < ds.getRowCount(); i++) - publicReportIdNames - .add(new IdNameValue(ds.getString(i, 0), ds.getString(i, 1))); - } // catch(Exception e) {} - - return publicReportIdNames; - } // getPublicReportIdNames - - public static Vector getPrivateAccessibleReportIdNames(String user_id, Vector userRoles) throws RaptorException { - // if(publicReportIdNames==null) => needs to be up-to-date at any time - /* try */{ - privateReportIdNames = new Vector(); - - // StringBuffer query = new StringBuffer(" SELECT cr.rep_id, cr.title FROM cr_report cr "); - String sql = Globals.getThePrivateAccessibleNamesA(); - //query.append(" WHERE cr.rep_id not in (select rep_id from cr_report_access cra where user_id = '"+ user_id+"' "); - sql = sql.replace("[user_id]", user_id); - StringBuffer query = new StringBuffer(sql); - for (int i = 0; i < userRoles.size(); i++) { - if( i == 0){ - // query.append(" OR role_id in ("); - query.append(Globals.getThePrivateAccessibleNamesIf()); - } - if(i < (userRoles.size()-1)) - query.append((String)userRoles.get(i) + ","); - - else if(i == (userRoles.size()-1)) - query.append((String)userRoles.get(i)+")"); - - } - //query.append(" ) "); - //query.append(" AND public_yn = 'N' and cr.owner_id = '"+ user_id+"' order by 2 "); - sql = Globals.getThePrivateAccessibleNamesB(); - sql = sql.replace("[user_id]", user_id); - query.append(sql); - - DataSet ds = DbUtils - .executeQuery(query.toString() ); - - for (int i = 0; i < ds.getRowCount(); i++) - privateReportIdNames - .add(new IdNameValue(ds.getString(i, 0), ds.getString(i, 1))); - } // catch(Exception e) {} - - return privateReportIdNames; - } // getPrivateAccessibleReportIdNames - - - public static Vector getGroupAccessibleReportIdNames(String user_id, Vector userRoles) throws RaptorException { - // if(publicReportIdNames==null) => needs to be up-to-date at any time - /* try */{ - groupReportIdNames = new Vector(); - - //StringBuffer query = new StringBuffer(" SELECT cr.rep_id, cr.title FROM cr_report cr "); - //query.append(" WHERE cr.rep_id in (select rep_id from cr_report_access cra where user_id = '"+ user_id+"' "); - String sql = Globals.getTheGroupAccessibleNamesA(); - sql = sql.replace("[user_id]", user_id); - StringBuffer query = new StringBuffer(sql); - - for (int i = 0; i < userRoles.size(); i++) { - if( i == 0) - query.append(Globals.getThePrivateAccessibleNamesIf()); - if(i < (userRoles.size()-1)) - query.append((String)userRoles.get(i) + ","); - else if(i == (userRoles.size()-1)) - query.append((String)userRoles.get(i)+")"); - - } - //query.append(" ) "); - //query.append(" AND public_yn = 'N' order by 2 "); - - query.append(Globals.getTheGroupAccessibleNamesB()); - DataSet ds = DbUtils - .executeQuery(query.toString() ); - - for (int i = 0; i < ds.getRowCount(); i++) - groupReportIdNames - .add(new IdNameValue(ds.getString(i, 0), ds.getString(i, 1))); - } // catch(Exception e) {} - - return groupReportIdNames; - } // getGroupAccessibleReportIdNames - - - public static TableSource getTableSource(String tableName, String dBinfo, Vector userRoles, String userId, HttpServletRequest request) throws RaptorException { - try { - Vector tableSources = null; - if(Globals.getRestrictTablesByRole()) { - tableSources = getReportTableSources(userRoles, dBinfo, userId, request); - } else { - tableSources = getReportTableSources(dBinfo); - } - for (Iterator iter = getReportTableSources(dBinfo).iterator(); iter.hasNext();) { - TableSource tableSource = (TableSource) iter.next(); - if (tableSource.getTableName().equals(tableName)) - return tableSource; - } // for - } catch (RaptorException e) { - throw new RaptorException(e.getMessage(), e.getCause()); - } - - return null; - } - public static void refreshReportTableSources() { - reportTableSources = null; - } - - public static Vector getReportTableSources(String dBInfo) throws RaptorException { - if (reportTableSources == null) - /* try */{ - reportTableSources = new Vector(); - //String query = " SELECT table_name, display_name, pk_fields, web_view_action, large_data_source_yn, filter_sql FROM cr_table_source "; - String query = Globals.getTheReportTableSourcesA(); - if (dBInfo != null && !dBInfo.equals(AppConstants.DB_LOCAL)){ - //query += " where SOURCE_DB= '" + dBInfo + "'"; - query+=Globals.getTheReportTableSourcesWhere(); - query = query.replace("[dBInfo]", dBInfo); - } - else { - //query += " where SOURCE_DB is null or SOURCE_DB = '" + AppConstants.DB_LOCAL - // + "'"; - query+=Globals.getTheReportTableSourcesIf(); - query = query.replace("[AppConstants.DB_LOCAL]", AppConstants.DB_LOCAL); - } - //query += " ORDER BY table_name "; - query+=Globals.getTheReportTableSourcesElse(); - DataSet ds = DbUtils.executeQuery(query); - for (int i = 0; i < ds.getRowCount(); i++) - reportTableSources.add(new TableSource(ds.getString(i, 0), ds.getString(i, 1), - ds.getString(i, 2), ds.getString(i, 3), ds.getString(i, 4), ds - .getString(i, 5))); - } // catch(Exception e) {} - - return reportTableSources; - } // getReportTableSources - - public static Vector getReportTableSources(Vector userRoles, String dBInfo, String userId, HttpServletRequest request) - throws RaptorException { - if (!Globals.getRestrictTablesByRole()) - return getReportTableSources(dBInfo); - Vector userTableSources = new Vector(); - if (userRoles.size() > 0) - /* try */{ - StringBuffer sb = new StringBuffer(); - for (Iterator iter = userRoles.iterator(); iter.hasNext();) { - sb.append((sb.length() == 0) ? "(" : ", "); - sb.append(iter.next()); - } // for - sb.append(")"); - //StringBuffer query = new StringBuffer("SELECT ts.table_name, ts.display_name, ts.pk_fields, "); - // query.append(" ts.web_view_action, ts.large_data_source_yn, ts.filter_sql FROM cr_table_source ts "); - // query.append (" WHERE "); - StringBuffer query = new StringBuffer(Globals.grabTheReportTableA()); - //if(!(AppUtils.isAdminUser(userId) || AppUtils.isSuperUser(userId))) - // query.append (" (EXISTS (SELECT 1 FROM cr_table_role tr WHERE tr.table_name=ts.table_name AND tr.role_id IN "+sb.toString()+")) and "); - //+ " OR (NOT EXISTS (SELECT 1 FROM cr_table_role tr WHERE tr.table_name=ts.table_name)) "; - if (dBInfo != null && !dBInfo.equals(AppConstants.DB_LOCAL)){ - String d_sql = Globals.grabTheReportTableIf(); - d_sql = d_sql.replace("[dBInfo]", dBInfo); - //query.append( " ts.SOURCE_DB= '" + dBInfo + "'"); - query.append(d_sql); - } - else{ - //query.append(" (ts.SOURCE_DB is null or ts.SOURCE_DB = '"+ AppConstants.DB_LOCAL + "')"); - String d_sql = Globals.grabTheReportTableElse(); - d_sql = d_sql.replace("[AppConstants.DB_LOCAL]", AppConstants.DB_LOCAL); - query.append(d_sql); - } - if(!(AppUtils.isAdminUser(request) || AppUtils.isSuperUser(request))) { - //query.append(" minus "); - - // query.append(" SELECT ts.table_name, ts.display_name, ts.pk_fields, ts.web_view_action, "); - // query.append(" ts.large_data_source_yn, ts.filter_sql from cr_table_source ts where "); - // query.append(" table_name in (select table_name from cr_table_role where role_id not IN "+sb.toString()+") and "); - String e_sql = Globals.grabTheReportTableB(); - e_sql = e_sql.replace("[sb.toString()]", sb.toString()); - query.append(e_sql); - - if (dBInfo != null && !dBInfo.equals(AppConstants.DB_LOCAL)){ - - // query.append( " ts.SOURCE_DB= '" + dBInfo + "'"); - String d_sql = Globals.grabTheReportTableIf(); - d_sql = d_sql.replace("[dBInfo]", dBInfo); - query.append(d_sql); - } - else{ - //query.append(" (ts.SOURCE_DB is null or ts.SOURCE_DB = '"+ AppConstants.DB_LOCAL + "')"); - String d_sql = Globals.grabTheReportTableElse(); - d_sql = d_sql.replace("[AppConstants.DB_LOCAL]", AppConstants.DB_LOCAL); - query.append(d_sql); - } - } - //query.append(" ORDER BY 1 "); - query.append(Globals.grabTheReportTableC()); - DataSet ds = DbUtils.executeQuery(query.toString()); - for (int i = 0; i < ds.getRowCount(); i++) - userTableSources.add(new TableSource(ds.getString(i, 0), ds.getString(i, 1), - ds.getString(i, 2), ds.getString(i, 3), ds.getString(i, 4), ds - .getString(i, 5))); - } // catch(Exception e) {} - - return userTableSources; - } // getReportTableSources - - public static Vector getReportTableJoins() throws RaptorException { - if (reportTableJoins == null) - /* try */{ - reportTableJoins = new Vector(); - - //DataSet ds = DbUtils - // .executeQuery("SELECT src_table_name, dest_table_name, join_expr FROM cr_table_join"); - DataSet ds = DbUtils - .executeQuery(Globals.getTheReportTableCrJoin()); - for (int i = 0; i < ds.getRowCount(); i++) - reportTableJoins.add(new TableJoin(ds.getString(i, 0), ds.getString(i, 1), ds - .getString(i, 2))); - } // catch(Exception e) {} - - return reportTableJoins; - } // getReportTableJoins - - public static Vector getReportTableJoins(Vector userRoles) throws RaptorException { - if (!Globals.getRestrictTablesByRole()) - return getReportTableJoins(); - - Vector userTableJoins = new Vector(); - if (userRoles.size() > 0) - /* try */{ - StringBuffer sb = new StringBuffer(); - for (Iterator iter = userRoles.iterator(); iter.hasNext();) { - sb.append((sb.length() == 0) ? "(" : ", "); - sb.append(iter.next()); - } // for - sb.append(")"); - - /*DataSet ds = DbUtils - .executeQuery("SELECT tj.src_table_name, tj.dest_table_name, tj.join_expr FROM cr_table_join tj " - + "WHERE ((EXISTS (SELECT 1 FROM cr_table_role trs WHERE trs.table_name=tj.src_table_name AND trs.role_id IN " - + sb.toString() - + ")) " - + "OR (NOT EXISTS (SELECT 1 FROM cr_table_role trs WHERE trs.table_name=tj.src_table_name))) " - + "AND ((EXISTS (SELECT 1 FROM cr_table_role trd WHERE trd.table_name=tj.dest_table_name AND trd.role_id IN " - + sb.toString() - + ")) " - + "OR (NOT EXISTS (SELECT 1 FROM cr_table_role trd WHERE trd.table_name=tj.dest_table_name)))");*/ - - - String f_sql = Globals.getTheReportTableJoins(); - f_sql = f_sql.replace("[sb.toString()]", sb.toString()); - - DataSet ds = DbUtils - .executeQuery(f_sql); - - for (int i = 0; i < ds.getRowCount(); i++) - userTableJoins.add(new TableJoin(ds.getString(i, 0), ds.getString(i, 1), ds - .getString(i, 2))); - } // catch(Exception e) {} - - return userTableJoins; - } // getReportTableJoins - - private static void processDollarFields(Vector tableDbColumns) { - int i = 0; - while (i < tableDbColumns.size()) { - DBColumnInfo dbci = (DBColumnInfo) tableDbColumns.get(i); - if (dbci.getColName().equals("DL$MONTH")) { - tableDbColumns.remove(i); - dbci.setLabel("Data Month/Year"); - tableDbColumns.add(0, dbci); - i++; - } else if (dbci.getColName().indexOf('$') >= 0) - tableDbColumns.remove(i); - else - i++; - } // while - } // processDollarFields - - private static String generateReportTableDbUserColumnSQL(String tableName) { - StringBuffer sb = new StringBuffer(); - // sb.append("SELECT a.table_name, a.column_name, a.data_type, a.label "); - //sb.append(" FROM user_column_def a "); - // sb.append("WHERE a.table_name = '" + tableName.toUpperCase() + "' "); - // sb.append("ORDER BY a.column_id"); - - String sql = Globals.getGenerateReportTableCol(); - sql = sql.replace("[tableName.toUpperCase()]", tableName.toUpperCase()); - sb.append(sql); - - return sb.toString(); - }//generateReportTableDbUserColumnSQL - private static String generateReportTableDbColumnsSQL(String tableName, String maskSql) { - StringBuffer sb = new StringBuffer(); - //sb.append("SELECT utc.table_name, utc.column_name, utc.data_type, "); - sb.append(Globals.getGenerateDbUserSqlA()); - if (maskSql == null){ - //sb.append("utc.column_name label "); - sb.append(Globals.getGenerateDbUserSqlIf()); - } - else{ - //sb.append("nvl(x.label, utc.column_name) label "); - //sb.append("FROM user_tab_columns utc "); - sb.append(Globals.getGenerateDbUserSqlElse()); - } - if (maskSql != null) { - sb.append(", ("); - sb.append(maskSql); - sb.append(") AS x "); - } - //sb.append("WHERE utc.table_name = '" + tableName.toUpperCase() + "' "); - String g_sql = Globals.getGenerateDbUserSqlB(); - g_sql = g_sql.replace("[tableName.toUpperCase()]", tableName.toUpperCase()); - sb.append(g_sql); - if (maskSql != null){ - //sb.append(" AND utc.table_name = x.table_name AND utc.column_name = x.column_name "); - sb.append(Globals.getGenerateDbUserSqlC()); - } - //sb.append("ORDER BY utc.column_id"); - sb.append(Globals.getGenerateDbUserSqlD()); - //System.out.println(sb.toString()); - return sb.toString(); - } // generateReportTableDbColumnsSQL - - public static synchronized Vector getReportTableDbColumns(String tableName, - String remoteDbPrefix) throws RaptorException { - Vector tableDbColumns = null; - if(reportTableDbColumns!=null) - tableDbColumns = (Vector) reportTableDbColumns.get(tableName); - else - reportTableDbColumns = new HashMap(); - if (tableDbColumns == null) - /* try */{ - tableDbColumns = new Vector(); - - String maskSql = AppUtils.getReportDbColsMaskSQL(); - DataSet ds = null; - if(Globals.getUserColDef()) { - try { - ds = ConnectionUtils.getDataSet( - generateReportTableDbUserColumnSQL(tableName),AppConstants.DB_LOCAL); - } - catch (ReportSQLException ex) { - throw new ReportSQLException("No Such Table. Please create table or make user_column_def in raptor.properties as \"false\""); - } - - } - else if(maskSql!=null){ - try { - ds = ConnectionUtils.getDataSet( - generateReportTableDbColumnsSQL(tableName, maskSql), remoteDbPrefix); - } - catch(ReportSQLException ex){ - throw new ReportSQLException("Field related table is not present in the database. Please make \"use_field_table\"" + - " as \"no\" in the raptor_app_.properties");} - } - if (ds==null || ds.getRowCount() == 0) { - // In case there are no records in the FIELDS table - ds = ConnectionUtils.getDataSet(generateReportTableDbColumnsSQL(tableName, - null), remoteDbPrefix); - } - for (int i = 0; i < ds.getRowCount(); i++) - tableDbColumns.add(new DBColumnInfo(ds.getString(i, 0), ds.getString(i, 1), ds - .getString(i, 2), ds.getString(i, 3))); - - processDollarFields(tableDbColumns); - reportTableDbColumns.put(tableName, tableDbColumns); - } // catch(Exception e) {} - - return tableDbColumns; - } // getReportTableDbColumns - - public static synchronized String getReportTableDbColumnType(String tableName, - String columnName, String dbInfo) throws RaptorException { - for (Iterator iter = getReportTableDbColumns(tableName, dbInfo).iterator(); iter - .hasNext();) { - DBColumnInfo dbCol = (DBColumnInfo) iter.next(); - if (dbCol.getColName().equals(columnName)) - return dbCol.getColType(); - } // for - - return null; - } // getReportTableDbColumnType - - public static synchronized LookupDBInfo getLookupTable(String tableName, String fieldName) throws RaptorException { - if (reportFieldDbLookups == null) - try { - String sql = AppUtils.getReportDbLookupsSQL(); - - if (sql != null) { - DataSet ds = DbUtils.executeQuery(sql); - reportFieldDbLookups = new HashMap(); - for (int i = 0; i < ds.getRowCount(); i++) { - String tName = ds.getString(i, 0); - String fName = ds.getString(i, 1); - reportFieldDbLookups.put(tName + '|' + fName, new LookupDBInfo(tName, - fName, ds.getString(i, 2), ds.getString(i, 3), ds.getString(i, - 4))); - } // for - } // if - } catch (Exception e) { throw new RaptorException(e.getMessage(), e.getCause()); - } - - LookupDBInfo lookupDBInfo = null; - if (reportFieldDbLookups != null) - lookupDBInfo = (LookupDBInfo) reportFieldDbLookups - .get(tableName + '|' + fieldName); - - if (lookupDBInfo == null) - lookupDBInfo = new LookupDBInfo(tableName, fieldName, tableName, fieldName, - fieldName); - - return lookupDBInfo; - } // getLookupTable - - // public static void setRemoteDBPrefix (String remoteDBPrefix) { - // _remoteDBPrefix = remoteDBPrefix; - // } - // - // public static String getRemoteDBPrefix () { - // return _remoteDBPrefix; - // } - - public static void refreshAll() { - DataCache.dataViewActions = null; - DataCache.privateReportIdNames = null; - DataCache.publicReportIdNames = null; - DataCache.reportFieldDbLookups = null; - DataCache.reportTableDbColumns = null; - DataCache.reportTableJoins = null; - DataCache.reportTableSources = null; - AppUtils.resetUserCache(); - } -} // DataCache - diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportHandler.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportHandler.java deleted file mode 100644 index c663e69c..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportHandler.java +++ /dev/null @@ -1,6605 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -/* =========================================================================================== - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) - * Raptor : This tool is used to generate different kinds of reports with lot of utilities - * =========================================================================================== - * - * ------------------------------------------------------------------------------------------- - * ReportHandler.java - This class is used to generate reports in Excel using POI and also to - * create ReportRuntime and ReportDefinition object using report id. - * ------------------------------------------------------------------------------------------- - * - * - * Changes - * ------- - * 18-Aug-2009 : Version 8.5.1 (Sundar);
        • request Object is passed to prevent caching user/roles - Datamining/Hosting.
        - * 14-Jul-2009 : Version 8.4 (Sundar);
        • Signature for generating excel method has been changed to add the report name as sheet name.
        • - *
        • Dashboard reports can be downloaded with each report as a separate sheet.
        • - *
        - * 08-Jun-2009 : Version 8.3 (Sundar);
        • Short datatype is replaced with default integer datatype to create - * row as short is not expoting more than 32768 rows.
        - * - */ -package org.openecomp.portalsdk.analytics.model; - -import java.io.BufferedInputStream; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.UnsupportedEncodingException; -import java.io.Writer; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.TreeMap; -import java.util.Vector; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFCellStyle; -import org.apache.poi.hssf.usermodel.HSSFDateUtil; -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFFooter; -import org.apache.poi.hssf.usermodel.HSSFHeader; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.hssf.util.Region; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.usermodel.Header; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFDataFormat; -import org.apache.poi.xssf.usermodel.XSSFFont; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.openecomp.portalsdk.analytics.controller.ErrorHandler; -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.ReportSQLException; -import org.openecomp.portalsdk.analytics.model.base.IdNameValue; -import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; -import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.ConnectionUtils; -import org.openecomp.portalsdk.analytics.system.ExecuteQuery; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.ExcelColorDef; -import org.openecomp.portalsdk.analytics.util.HtmlStripper; -import org.openecomp.portalsdk.analytics.util.Log; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.analytics.view.ColumnHeader; -import org.openecomp.portalsdk.analytics.view.ColumnHeaderRow; -import org.openecomp.portalsdk.analytics.view.DataRow; -import org.openecomp.portalsdk.analytics.view.DataValue; -import org.openecomp.portalsdk.analytics.view.HtmlFormatter; -import org.openecomp.portalsdk.analytics.view.ReportData; -import org.openecomp.portalsdk.analytics.view.RowHeader; -import org.openecomp.portalsdk.analytics.view.RowHeaderCol; -import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; -import org.openecomp.portalsdk.analytics.xmlobj.DataSourceType; -import org.openecomp.portalsdk.analytics.xmlobj.FormatList; -import org.openecomp.portalsdk.analytics.xmlobj.FormatType; -import org.openecomp.portalsdk.analytics.xmlobj.Reports; -import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreList; -import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreType; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -import com.lowagie.text.Document; -import com.lowagie.text.Paragraph; -import com.lowagie.text.html.simpleparser.HTMLWorker; -import com.lowagie.text.html.simpleparser.StyleSheet; -import com.lowagie.text.pdf.PdfPTable; -//import javax.servlet.RequestDispatcher; - -public class ReportHandler extends org.openecomp.portalsdk.analytics.RaptorObject { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ReportHandler.class); - - public ReportHandler() { - } - - private String SHEET_NAME = ""; - private static final String XML_ENCODING = "UTF-8"; - private static int font_size = 10; - private static int font_header_title_size = 12; - private static int font_header_descr_size = 9; - private static int font_footer_size = 9; - - - private HashMap loadStyles(ReportRuntime rr, HSSFWorkbook wb) { - HSSFCellStyle styleDefault = wb.createCellStyle(); - //System.out.println("Load Styles"); - // Style default will be normal with no background - HSSFFont fontDefault = wb.createFont(); - // The default will be plain . - fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); - fontDefault.setFontHeight((short) (font_size / 0.05)); - fontDefault.setFontName("Tahoma"); - - styleDefault.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleDefault.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleDefault.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleDefault.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleDefault.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleDefault.setFillForegroundColor(HSSFColor.YELLOW.index); - styleDefault.setFillPattern(HSSFCellStyle.NO_FILL); - styleDefault.setFont(fontDefault); - - HSSFCellStyle styleRed = wb.createCellStyle(); - styleRed.cloneStyleFrom(styleDefault); - styleRed.setFillForegroundColor((short)HSSFColor.RED.index); - styleRed.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); - HSSFFont fontRed = wb.createFont(); - fontRed.setColor((short) HSSFColor.WHITE.index); - fontRed.setFontHeight((short) (font_size / 0.05)); - fontRed.setFontName("Tahoma"); - styleRed.setFont(fontRed); - - HSSFCellStyle styleYellow = wb.createCellStyle(); - styleYellow.cloneStyleFrom(styleDefault); - styleYellow.setFillForegroundColor((short)HSSFColor.YELLOW.index); - styleYellow.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); - HSSFFont fontYellow = wb.createFont(); - fontYellow.setColor((short) HSSFColor.BLACK.index); - fontYellow.setFontHeight((short) (font_size / 0.05)); - fontYellow.setFontName("Tahoma"); - styleYellow.setFont(fontYellow); - - HSSFCellStyle styleGreen = wb.createCellStyle(); - styleGreen.cloneStyleFrom(styleDefault); - styleGreen.setFillForegroundColor((short)HSSFColor.GREEN.index); - styleGreen.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); - HSSFFont fontGreen = wb.createFont(); - fontGreen.setColor((short) HSSFColor.WHITE.index); - fontGreen.setFontHeight((short) (font_size / 0.05)); - fontGreen.setFontName("Tahoma"); - styleGreen.setFont(fontGreen); - - - ArrayList semColumnList = new ArrayList(); - List dsList = rr.getDataSourceList().getDataSource(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType element = (DataSourceType) iter.next(); - List dcList = element.getDataColumnList().getDataColumn(); - for (Iterator iterator = dcList.iterator(); iterator.hasNext();) { - DataColumnType element1 = (DataColumnType) iterator.next(); - semColumnList.add(element1.getSemaphoreId()); - - } - } - SemaphoreList semList = rr.getSemaphoreList(); - HashMap hashMapStyles = new HashMap(); - HashMap hashMapFonts = new HashMap(); - hashMapFonts.put("default", fontDefault); - hashMapFonts.put("red", fontRed); - hashMapFonts.put("yellow", fontYellow); - hashMapFonts.put("green", fontGreen); - hashMapStyles.put("default", styleDefault); - hashMapStyles.put("red", styleRed); - hashMapStyles.put("yellow", styleYellow); - hashMapStyles.put("green", styleGreen); - HSSFCellStyle cellStyle = null; - if (semList == null || semList.getSemaphore() == null) { - return hashMapStyles; - } else { - for (Iterator iter = semList.getSemaphore().iterator(); iter.hasNext();) { - SemaphoreType sem = (SemaphoreType) iter.next(); - if(!semColumnList.contains(sem.getSemaphoreId())) continue; - //System.out.println("SemphoreId ----> " + sem.getSemaphoreId()); - FormatList fList = sem.getFormatList(); - List formatList = fList.getFormat(); - for (Iterator fIter = formatList.iterator(); fIter.hasNext();) { - FormatType fmt = (FormatType) fIter.next(); - if(fmt!=null){ - //if (fmt.getLessThanValue().length() > 0) { - cellStyle = wb.createCellStyle(); - HSSFFont cellFont = wb.createFont(); - //System.out.println("Format Id " + fmt.getFormatId()); - if (nvl(fmt.getBgColor()).length() > 0) { -// System.out.println("Load Styles " + -// fmt.getFormatId() -// + " " +fmt.getBgColor() + " " + -// ExcelColorDef.getExcelColor(fmt.getBgColor())); - cellStyle.setFillForegroundColor(ExcelColorDef.getExcelColor(fmt - .getBgColor())); - cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); - } - if (nvl(fmt.getFontColor()).length() > 0) { - cellFont.setColor(ExcelColorDef.getExcelColor(fmt.getFontColor())); - } else - cellFont.setColor((short) HSSFFont.COLOR_NORMAL); - if (fmt.isBold()) - cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - if (fmt.isItalic()) - cellFont.setItalic(true); - if (fmt.isUnderline()) - cellFont.setUnderline(HSSFFont.U_SINGLE); - if(nvl(fmt.getFontFace()).length()>0) - cellFont.setFontName(fmt.getFontFace()); - else - cellFont.setFontName("Tahoma"); - //cellFont.setFontHeight((short) (10 / 0.05)); - - if(nvl(fmt.getFontSize()).length()>0) { - try { - //cellFont.setFontHeight((short) (Integer.parseInt(fmt.getFontSize()) / 0.05)); - cellFont.setFontHeight((short) (font_size/0.05)); - } catch(NumberFormatException e){ - cellFont.setFontHeight((short) (font_size / 0.05));//10 - } - } - else - cellFont.setFontHeight((short) (font_size / 0.05)); - cellStyle.setFont(cellFont); - cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); - cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); - cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); - cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); - cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); - hashMapStyles.put(fmt.getFormatId(), cellStyle); - } else { - hashMapStyles.put(fmt.getFormatId(), styleDefault); - hashMapStyles.put("default", styleDefault); - } - } - - } - } - return hashMapStyles; - } - - private void paintExcelParams(HSSFWorkbook wb,int rowNum,int col,ArrayList paramsList, String customizedParamInfo, HSSFSheet sheet, String reportTitle, String reportDescr) throws IOException { - //HSSFSheet sheet = wb.getSheet(getSheetName()); - int cellNum = 0; - HSSFRow row = null; - short s1 = 0, s2 = (short) 1; - HtmlStripper strip = new HtmlStripper(); - // Name Style - HSSFCellStyle styleName = wb.createCellStyle(); - //styleName.setFillBackgroundColor(HSSFColor.GREY_80_PERCENT.index); - styleName.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index); - //styleName.setFillPattern(HSSFCellStyle.SPARSE_DOTS); - styleName.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleName.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleName.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleName.setBorderRight(HSSFCellStyle.BORDER_THIN); - styleName.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleName.setDataFormat((short)0); - HSSFFont font = wb.createFont(); - font.setFontHeight((short) (font_size / 0.05)); - font.setFontName("Tahoma"); - font.setColor(HSSFColor.BLACK.index); - font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - styleName.setFont(font); - //Data Style - - // Create some fonts. - HSSFFont fontDefault = wb.createFont(); - // Initialize the styles & fonts. - // The default will be plain . - fontDefault.setColor((short) HSSFFont.COLOR_NORMAL); - fontDefault.setFontHeight((short) (font_size / 0.05)); - fontDefault.setFontName("Tahoma"); - fontDefault.setItalic(true); - // Style default will be normal with no background - HSSFCellStyle styleValue = wb.createCellStyle(); - styleValue.setDataFormat((short)0); - styleValue.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleValue.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleValue.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleValue.setBorderLeft(HSSFCellStyle.BORDER_THIN); - styleValue.setBorderRight(HSSFCellStyle.BORDER_THIN); - // styleValue.setFillForegroundColor(HSSFColor.YELLOW.index); - styleValue.setFillPattern(HSSFCellStyle.NO_FILL); - styleValue.setFont(fontDefault); - HSSFCell cell = null; - HSSFCellStyle styleDescription = wb.createCellStyle(); - styleDescription.setAlignment(HSSFCellStyle.ALIGN_CENTER); -// styleDescription.setBorderBottom(HSSFCellStyle.BORDER_THIN); -// styleDescription.setBorderTop(HSSFCellStyle.BORDER_THIN); -// styleDescription.setBorderRight(HSSFCellStyle.BORDER_THIN); -// styleDescription.setBorderLeft(HSSFCellStyle.BORDER_THIN); - HSSFFont fontDescr = wb.createFont(); - fontDescr.setFontHeight((short) (font_size / 0.05)); //14 - fontDescr.setFontName("Tahoma"); - fontDescr.setColor(HSSFColor.BLACK.index); - fontDescr.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); - styleDescription.setFont(font); - HSSFCell cellDescr = null; - int paramSeq = 0; - HSSFHeader header = sheet.getHeader(); - StringBuffer strBuf = new StringBuffer(); - if(!Globals.customizeFormFieldInfo() || customizedParamInfo.length()<=0) { - for (Iterator iter = paramsList.iterator(); iter.hasNext();) { - IdNameValue value = (IdNameValue) iter.next(); - //System.out.println("\"" + value.getId() + " = " + value.getName() + "\""); - if(nvl(value.getId()).trim().length()>0 && (!nvl(value.getId()).trim().equals("BLANK"))) { - paramSeq += 1; - if(paramSeq <= 1) { - row = sheet.createRow(++rowNum); - cell = row.createCell((short) 0); - sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); - cellDescr = row.createCell((short) 0); - cellDescr.setCellValue("Run-time Parameters"); - cellDescr.setCellStyle(styleDescription); - - - strBuf.append(reportTitle+"\n"); - //strBuf.append("Run-time Parameters\n"); - } - row = sheet.createRow(++rowNum); - cellNum = 0; - //System.out.println("RowNum " + rowNum + " " + value.getId() + " " +value.getName()); - cell = row.createCell((short) cellNum); - cell.setCellValue(value.getId()); - cell.setCellStyle(styleName); - cellNum += 1; - cell = row.createCell((short) cellNum); - cell.setCellValue(value.getName().replaceAll("~",",")); - cell.setCellStyle(styleValue); - - //strBuf.append(value.getId()+": "+ value.getName()+"\n"); - } - } //for - } else { - strBuf.append(reportTitle+"\n"); - Document document = new Document(); - document.open(); - HTMLWorker worker = new HTMLWorker(document); - StyleSheet style = new StyleSheet(); - style.loadTagStyle("body", "leading", "16,0"); - ArrayList p = HTMLWorker.parseToList(new StringReader(customizedParamInfo), style); - String name = ""; - String token = ""; - String value = ""; - String s = ""; - PdfPTable pdfTable = null; - for (int k = 0; k < p.size(); ++k){ - if(p.get(k) instanceof Paragraph) - s = ((Paragraph)p.get(k)).toString(); - else { /*if ((p.get(k) instanceof PdfPTable))*/ - pdfTable = ((PdfPTable)p.get(k)); - } - //todo: Logic for parsing pdfTable should be added after upgrading to iText 5.0.0 - //s = Utils.replaceInString(s, ",", "|"); - s = s.replaceAll(",", "|"); - s = s.replaceAll("~", ","); - if(s.indexOf(":")!= -1) { - //System.out.println("|"+s+"|"); - row = sheet.createRow(++rowNum); - cell = row.createCell((short) 0); - sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); - cellDescr = row.createCell((short) 0); - cellDescr.setCellValue("Run-time Parameters"); - cellDescr.setCellStyle(styleDescription); - - //strBuf.append("Run-time Parameters\n"); - StringTokenizer st = new StringTokenizer(s.trim(), "|"); - while(st.hasMoreTokens()) { - token = st.nextToken(); - token = token.trim(); - if (!(token.trim().equals("|") || token.trim().equals("]]") || token.trim().equals("]") || token.trim().equals("[") )) { - if(token.endsWith(":")) { - name = token; - name = name.substring(0, name.length()-1); - if(name.startsWith("[")) - name = name.substring(1); - value = st.nextToken(); - if(nvl(value).endsWith("]"))value = nvl(value).substring(0, nvl(value).length()-1); - } /*else if(name != null && name.length() > 0) { - value = st.nextToken(); - if(value.endsWith("]]"))value = value.substring(0, value.length()-1); - }*/ - if(name!=null && name.trim().length()>0) { - row = sheet.createRow((short) ++rowNum); - cellNum = 0; - cell = row.createCell((short) cellNum); - cell.setCellValue(name.trim()); - cell.setCellStyle(styleName); - cellNum += 1; - cell = row.createCell((short) cellNum); - cell.setCellValue(value.trim()); - cell.setCellStyle(styleValue); - //strBuf.append(name.trim()+": "+ value.trim()+"\n"); - } -/* if(token.endsWith(":") && (value!=null && value.trim().length()<=0) && (name!=null && name.trim().length()>0 && name.endsWith(":"))) { - name = name.substring(0, name.indexOf(":")+1); - //value = token.substring(token.indexOf(":")+1); - row = sheet.createRow((short) ++rowNum); - cellNum = 0; - cell = row.createCell((short) cellNum); - cell.setCellValue(name.trim()); - cell.setCellStyle(styleName); - cellNum += 1; - cell = row.createCell((short) cellNum); - cell.setCellValue(value.trim()); - cell.setCellStyle(styleValue); - - //strBuf.append(name.trim()+": "+ value.trim()+"\n"); - value = ""; - name = ""; - } -*/ } - int cw = 0; - cw = name.trim().length() + 12; - // if(i!=cellWidth.size()-1) - if(sheet.getColumnWidth((short)0)< (short) name.trim().length()) - sheet.setColumnWidth((short)0, (short) name.trim().length()); - if(sheet.getColumnWidth((short)1)< (short) value.trim().length()) - sheet.setColumnWidth((short)1, (short) value.trim().length()); - name = ""; - value = ""; - - } - - try { - SimpleDateFormat oracleDateFormat = new SimpleDateFormat("MM/dd/yyyy kk:mm:ss"); - Date sysdate = oracleDateFormat.parse(ReportLoader.getSystemDateTime()); - SimpleDateFormat dtimestamp = new SimpleDateFormat(Globals.getScheduleDatePattern()); - - row = sheet.createRow((short) ++rowNum); - cellNum = 0; - cell = row.createCell((short) cellNum); - cell.setCellValue("Report Date/Time"); - cell.setCellStyle(styleName); - cellNum += 1; - cell = row.createCell((short) cellNum); - - cell.setCellValue(dtimestamp.format(sysdate)+" "+Globals.getTimeZone()); - cell.setCellStyle(styleValue); - - } catch(Exception ex) { - //ex.printStackTrace(); - } - - - } - } - - -/* Iterator iter1 = paramsList.iterator(); - s1 = 0; s2 = (short)10; - if(iter1.hasNext()) { - row = sheet.createRow((short) ++rowNum); - cellNum = 0; - cell = row.createCell((short) cellNum); - sheet.addMergedRegion(new Region(rowNum, s1, rowNum, s2)); - cell.setCellValue(strip.stripHtml(customizedParamInfo)); - } -*/ -/* rowNum += 2; - row = sheet.createRow(rowNum);*/ - } // if - Iterator iterCheck = paramsList.iterator(); - if(iterCheck.hasNext()) { - rowNum += 2; - row = sheet.createRow(rowNum); - } - header.setCenter(HSSFHeader.font("Tahoma", "")+ HSSFHeader.fontSize((short) 9)+" " + strBuf.toString()); - HSSFFooter footer = sheet.getFooter(); - footer.setLeft(HSSFFooter.font("Tahoma", "")+ HSSFFooter.fontSize((short) 9)+ "Page " + HSSFFooter.page() - + " of " + HSSFFooter.numPages() ); - footer.setCenter(HSSFFooter.font("Tahoma", "")+ HSSFFooter.fontSize((short) 9)+Globals.getFooterFirstLine()+"\n"+Globals.getFooterSecondLine()); - - } - - - - private int paintExcelData(HSSFWorkbook wb, int rowNum, int col, ReportData rd, - HashMap styles, ReportRuntime rr, HSSFSheet sheet, String sql_whole, OutputStream sos, HttpServletRequest request) throws RaptorException { - int mb = 1024*1024; - Runtime runtime = Runtime.getRuntime(); - int returnValue = 0; - // HSSFSheet sheet = wb.getSheetAt(0); - HSSFCellStyle styleDefault = wb.createCellStyle(); - HSSFCellStyle styleNumber = wb.createCellStyle(); - HSSFCellStyle styleDecimalNumber = wb.createCellStyle(); - HSSFCellStyle styleCurrencyNumber = wb.createCellStyle(); - HSSFCellStyle styleCurrencyDecimalNumber = wb.createCellStyle(); - HSSFCellStyle styleDate = wb.createCellStyle(); - HtmlStripper strip = new HtmlStripper(); - //HSSFSheet sheet = wb.getSheet(getSheetName()); - HSSFCellStyle styleDataHeader = wb.createCellStyle(); - // style.setFillBackgroundColor(HSSFColor.AQUA.index); - styleDataHeader.setFillForegroundColor(HSSFColor.GREY_40_PERCENT.index); - styleDataHeader.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); - styleDataHeader.setAlignment(HSSFCellStyle.ALIGN_CENTER); - styleDataHeader.setBorderBottom(HSSFCellStyle.BORDER_THIN); - styleDataHeader.setBorderTop(HSSFCellStyle.BORDER_THIN); - styleDataHeader.setBorderRight(HSSFCellStyle.BORDER_THIN); - styleDataHeader.setBorderLeft(HSSFCellStyle.BORDER_THIN); - HSSFFont font = wb.createFont(); - font.setFontHeight((short) (font_size / 0.05)); - font.setFontName("Tahoma"); - font.setColor(HSSFColor.BLACK.index); - styleDataHeader.setFont(font); - // Column Header - boolean firstPass = true; - ArrayList cellWidth = new ArrayList(); - java.util.HashMap dataTypeMap = new java.util.HashMap(); - int cellNum = 0; - rowNum += 0; - ColumnHeaderRow chr = null; - String title = ""; - -// System.out.println("***************** Size " + rd.reportColumnHeaderRows.size()); -// for (int i = 0; i < rd.reportColumnHeaderRows.size(); i++) { -// for (int j = 0; j < rd.reportColumnHeaderRows.getColumnHeaderRow(i).size(); j++) { -// System.out.println("Column Title " + rd.reportColumnHeaderRows.getColumnHeaderRow(i).getColumnHeader(j).getColumnTitle() -// + " " + rd.reportColumnHeaderRows.getColumnHeaderRow(i).getColumnHeader(j).isVisible()); -// } -// } -/* List dsList = rr.getDataSourceList().getDataSource(); - HashMap dataColumnTypeHashMap = new HashMap(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType element = (DataSourceType) iter.next(); - List dcList = element.getDataColumnList().getDataColumn(); - for (Iterator iterator = dcList.iterator(); iterator.hasNext();) { - DataColumnType element1 = (DataColumnType) iterator.next(); - dataTypeMap.put(element1.getColId(), element1.getColType()); - dataColumnTypeHashMap.put(element1.getColName(), element1); - } - } -*/ - int columnRows = rr.getVisibleColumnCount() - 1; - - HttpSession session = request.getSession(); - String drilldown_index = (String) session.getAttribute("drilldown_index"); - int index = 0; - try { - index = Integer.parseInt(drilldown_index); - } catch (NumberFormatException ex) { - index = 0; - } - String header = (String) session.getAttribute("TITLE_"+index); - String subtitle = (String) session.getAttribute("SUBTITLE_"+index); - if(nvl(header).length()>0) { - header = Utils.replaceInString(header, "
        ", " "); - header = Utils.replaceInString(header, "
        ", " "); - header = Utils.replaceInString(header, "
        ", " "); - header = strip.stripHtml(nvl(header).trim()); - subtitle = Utils.replaceInString(subtitle, "
        ", " "); - subtitle = Utils.replaceInString(subtitle, "
        ", " "); - subtitle = Utils.replaceInString(subtitle, "
        ", " "); - subtitle = strip.stripHtml(nvl(subtitle).trim()); - HSSFRow row = sheet.createRow(rowNum); - cellNum = 0; - row.createCell((short) cellNum).setCellValue(header); - sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); - rowNum += 1; - row = sheet.createRow(rowNum); - cellNum = 0; - row.createCell((short) cellNum).setCellValue(subtitle); - sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum, (short) (columnRows))); - rowNum += 1; - } - - for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { - HSSFRow row = sheet.createRow(rowNum); - cellNum = -1; - /*if(rd.reportTotalRowHeaderCols!=null) { - cellNum +=1; - row.createCell((short) cellNum).setCellValue("Total"); - row.createCell((short) cellNum).setCellStyle(styleDataHeader); - //row.getCell((short) cellNum).setCellStyle(styleDataHeader); - }*/ - chr = rd.reportColumnHeaderRows.getNext(); - - if(nvl(sql_whole).length() <= 0 || (!rr.getReportType().equals(AppConstants.RT_LINEAR))) { - if(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) - rd.reportRowHeaderCols.resetNext(0); - else - rd.reportRowHeaderCols.resetNext(1); - - for (; rd.reportRowHeaderCols.hasNext();) { - cellNum += 1; - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - - if (firstPass) { - title = rhc.getColumnTitle(); - title = Utils.replaceInString(title,"_nl_", " \n"); - row.createCell((short) cellNum).setCellValue(title); - //commented after bug reported by EPAT 01/17/2015 - //sheet.addMergedRegion(new Region(rowNum, (short) cellNum, rowNum+columnRows, (short) (cellNum))); - //System.out.println(" **************** Row Header Title " + rhc.getColumnTitle() + " " + cellNum + " " ); - //System.out.println(cellNum + " " + cellWidth.size()); - if (cellWidth.size() > 0 && cellWidth.size() > cellNum) { - if (((Integer) cellWidth.get(cellNum)).intValue() < rhc - .getColumnTitle().length()) - cellWidth.set(cellNum, new Integer(title.length())); - } else - cellWidth.add(cellNum, new Integer(title.length())); - row.getCell((short) cellNum).setCellStyle(styleDataHeader); - } - - - } // for - - } - - firstPass = false; - -/* for(chr.resetNext(); chr.hasNext(); ) { - ColumnHeader ch = chr.getNext(); - if(ch.isVisible()) { - cellNum += 1; - row.createCell((short) cellNum).setCellValue(ch.getColumnTitle()); -//
      • <%= ch.getColSpanHtml() %><%= ch.getRowSpanHtml() %>> -// <%= ch.getColumnTitleHtml() %> -//
        "); - if (Globals.getPrintParamsInCSVDownload()) { - ArrayList paramsList = rr.getParamNameValuePairsforPDFExcel(request, 1); - int paramSeq = 0; - for (Iterator iter = paramsList.iterator(); iter.hasNext();) { - IdNameValue value = (IdNameValue) iter.next(); - //System.out.println("\"" + value.getId() + " = " + value.getName() + "\""); - if(nvl(value.getId()).trim().length()>0 && (!nvl(value.getId()).trim().equals("BLANK"))) { - paramSeq += 1; - if(paramSeq <= 1) { - csvOut.println(""); - //strBuf.append("Run-time Parameters\n"); - } - csvOut.println(""); - csvOut.println(""); - csvOut.println(""); - - //strBuf.append(value.getId()+": "+ value.getName()+"\n"); - } - } //for - csvOut.println(""); - csvOut.println(""); - System.out.println("HTML-Excel: Header Rendering complete " + new java.util.Date()); - } - int rowCount = 0; - if(nvl(sql_whole).length()>0) { - try { - conn = ConnectionUtils.getConnection(rr.getDbInfo()); - st = conn.createStatement(); - Log.write("[SQL] " + sql_whole, 4); - int downloadLimit = Globals.getDownloadLimit(); - Callable callable = new ExecuteQuery(st, sql_whole, downloadLimit); - ExecutorService executor = new ScheduledThreadPoolExecutor(5); - System.out.println("Time Started" + new java.util.Date()); - Future future = executor.submit(callable); - try { - rs = future.get(900, TimeUnit.SECONDS); - } catch (TimeoutException ex) { - System.out.println("Cancelling Query"); - st.cancel(); - System.out.println("Query Cancelled"); - throw new Exception("user requested"); - } - rsmd = rs.getMetaData(); - int numberOfColumns = rsmd.getColumnCount(); - HashMap colHash = new HashMap(); - - if(rd!=null) { - for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { - chr = rd.reportColumnHeaderRows.getNext(); - csvOut.println(""); - for (chr.resetNext(); chr.hasNext();) { - ColumnHeader ch = chr.getNext(); - if(ch.isVisible()) { - csvOut.print(""); - //for (int i = 1; i < ch.getColSpan(); i++) - // csvOut.print(","); - - } - } // for - csvOut.println(""); - } // for - - - while(rs.next()) { - csvOut.println(""); -/* if(runtime.freeMemory()/mb <= ((runtime.maxMemory()/mb)*Globals.getMemoryThreshold()/100) ) { - csvOut.print(Globals.getUserDefinedMessageForMemoryLimitReached() + " " + rowCount +"records out of " + rr.getReportDataSize() + " were downloaded to CSV."); - break; - } -*/ rowCount++; - colHash = new HashMap(); - for (int i = 1; i <= numberOfColumns; i++) { - colHash.put(rsmd.getColumnName(i), rs.getString(i)); - } - for (chr.resetNext(); chr.hasNext();) { - ColumnHeader ch = chr.getNext(); - if(ch.isVisible()) { - csvOut.println(""); - } - - } - csvOut.println(""); - } - System.out.println("Downloaded Rows in HTML-Excel " + rowCount + " : "+ new java.util.Date()); - if(rowCount == 0) { - csvOut.print(""); - } else { - } - } else { - csvOut.println(""); - } - csvOut.println("
        " + "Run-time Parameters" + "
        " + value.getId() +"" + value.getName().replaceAll("~",",")+ "
         
         
        " + ch.getColumnTitle() + "
        " + strip.stripCSVHtml(nvl((String)colHash.get(ch.getLinkColId().toUpperCase()))) + "
        No Data Found
        No Data Found
        \n"); - - } catch (SQLException ex) { - throw new RaptorException(ex); - } catch (ReportSQLException ex) { - throw new RaptorException(ex); - } catch (Exception ex) { - throw new RaptorException (ex); - } finally { - try { - if(conn!=null) - conn.close(); - if(st!=null) - st.close(); - if(rs!=null) - rs.close(); - } catch (SQLException ex) { - throw new RaptorException(ex); - } - } - //csvOut.flush(); - } else { - boolean firstPass = true; - int numberOfColumns = 0; - if(rd!=null) { - for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) { - chr = rd.reportColumnHeaderRows.getNext(); - csvOut.println(""); - for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - - if (firstPass) { - numberOfColumns++; - csvOut.print("" + rhc.getColumnTitle() + ""); - } - //csvOut.print(","); - } // for - - - for (chr.resetNext(); chr.hasNext();) { - ColumnHeader ch = chr.getNext(); - if(ch.isVisible()) { - if(firstPass) numberOfColumns++; - csvOut.print("" + ch.getColumnTitle() + ""); - //for (int i = 1; i < ch.getColSpan(); i++) - //csvOut.print(","); - } - } // for - firstPass = false; - csvOut.println(""); - } // for - - firstPass = true; - for (rd.reportDataRows.resetNext(); rd.reportDataRows.hasNext();) { - DataRow dr = rd.reportDataRows.getNext(); - csvOut.println(""); - for (rd.reportRowHeaderCols.resetNext(1); rd.reportRowHeaderCols.hasNext();) { - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - if (firstPass) - rhc.resetNext(); - RowHeader rh = rhc.getNext(); - - csvOut.print("" + strip.stripCSVHtml(rh.getRowTitle()) + ""); - } // for - firstPass = false; - - for (dr.resetNext(); dr.hasNext();) { - DataValue dv = dr.getNext(); - if(dv.isVisible()) - csvOut.print("" + strip.stripCSVHtml(dv.getDisplayValue()) + ""); - } // for - - csvOut.println(""); - - } // for - //csvOut.flush(); - } else { - csvOut.println("No Data Found"); - } - } - csvOut.println("\n"); - System.out.println("HTML-Excel Generation: Data Rendering complete " + new java.util.Date()); - System.out.println("##### Heap utilization statistics [MB] #####"); - System.out.println("Used Memory:" - + (runtime.maxMemory() - runtime.freeMemory()) / mb); - System.out.println("Free Memory:" - + runtime.freeMemory() / mb); - System.out.println("Total Memory:" + runtime.totalMemory() / mb); - System.out.println("Max Memory:" + runtime.maxMemory() / mb); - - } // createCSVFileContent - - /** - * Checking if every row and cell in merging region exists, and create those which are not - * @param sheet in which check is performed - * @param region to check - * @param cellStyle cell style to apply for whole region - */ - private void cleanBeforeMergeOnValidCells(XSSFSheet sheet,CellRangeAddress region, XSSFCellStyle cellStyle ) - { - for(int rowNum =region.getFirstRow();rowNum<=region.getLastRow();rowNum++){ - XSSFRow row= sheet.getRow(rowNum); - if(row==null){ - sheet.createRow(rowNum); - } - for(int colNum=region.getFirstColumn();colNum<=region.getLastColumn();colNum++){ - XSSFCell currentCell = row.getCell(colNum); - if(currentCell==null){ - currentCell = row.createCell(colNum); - } - - currentCell.setCellStyle(cellStyle); - - } - } - - - } -} // ReportHandler - - -/** - * Adapter for a Writer to behave like an OutputStream. - * - * Bytes are converted to chars using the platform default encoding. - * If this encoding is not a single-byte encoding, some data may be lost. - */ - class WriterOutputStream extends OutputStream { - - private final Writer writer; - - public WriterOutputStream(Writer writer) { - this.writer = writer; - } - - public void write(int b) throws IOException { - // It's tempting to use writer.write((char) b), but that may get the encoding wrong - // This is inefficient, but it works - write(new byte[] {(byte) b}, 0, 1); - } - - public void write(byte b[], int off, int len) throws IOException { - writer.write(new String(b, off, len)); - } - - public void flush() throws IOException { - writer.flush(); - } - - public void close() throws IOException { - writer.close(); - } -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportLoader.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportLoader.java deleted file mode 100644 index 2197de66..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/ReportLoader.java +++ /dev/null @@ -1,1061 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -/* =========================================================================================== - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) - * Raptor : This tool is used to generate different kinds of reports with lot of utilities - * =========================================================================================== - * - * ------------------------------------------------------------------------------------------- - * ReportLoader.java - This class is used to call database interaction related to reports. - * ------------------------------------------------------------------------------------------- - * - * - * - * Changes - * ------- - * 28-Aug-2009 : Version 8.5.1 (Sundar);
        • isDashboardType is made to return false, as any report can be added to Dashboard.
        - * 18-Aug-2009 : Version 8.5.1 (Sundar);
        • request Object is passed to prevent caching user/roles - Datamining/Hosting.
        - * 27-Jul-2009 : Version 8.4 (Sundar);
        • Admin User is given the same privilege as Super User when the property - * "admin_role_equiv_to_super_role" in raptor.properties is Y. A check is made in corresponding to that.
        - * - */ -package org.openecomp.portalsdk.analytics.model; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.Writer; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Vector; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.ReportSQLException; -import org.openecomp.portalsdk.analytics.model.base.IdNameValue; -import org.openecomp.portalsdk.analytics.model.base.ReportWrapper; -import org.openecomp.portalsdk.analytics.model.definition.ReportLogEntry; -import org.openecomp.portalsdk.analytics.model.search.ReportSearchResult; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.DbUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.system.fusion.domain.QuickLink; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -public class ReportLoader extends org.openecomp.portalsdk.analytics.RaptorObject { - - static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ReportLoader.class); - - - //private static Properties sqlProperty; - - public static String loadCustomReportXML(String reportID) throws RaptorException { - Connection connection = DbUtils.getConnection(); - try { - return loadCustomReportXML(connection, reportID); - } finally { - DbUtils.clearConnection(connection); - } - } // loadCustomReportXML - - public static String loadCustomReportXML(Connection connection, String reportID) - throws RaptorException { - - StringBuffer sb = new StringBuffer(); - - PreparedStatement stmt = null; - - ResultSet rs = null; - - try { - - String sql = Globals.getLoadCustomReportXml(); - stmt = connection.prepareStatement(sql); - stmt.setInt(1,Integer.parseInt(reportID)); - rs = stmt.executeQuery(); - if(Globals.isWeblogicServer()) { - java.sql.Clob clob= null; - Object obj = null; - if (rs.next()) { - clob = rs.getClob(1); - } - else - throw new RaptorException("Report " + reportID + " not found in the database"); - - int len = 0; - char[] buffer = new char[512]; - Reader in = null; - in = new InputStreamReader(clob.getAsciiStream()); - // if(obj instanceof oracle.sql.CLOB) { - // in = ((oracle.sql.CLOB) obj).getCharacterStream(); - // } else if (obj instanceof weblogic.jdbc.wrapper.Clob) { - // in = ((weblogic.jdbc.base.BaseClob) obj).getCharacterStream(); - // } - while ((len = in.read(buffer)) != -1) - sb.append(buffer, 0, len); - in.close(); - } else if (Globals.isPostgreSQL() || Globals.isMySQL()) { - String clob= null; - Object obj = null; - if (rs.next()) { - sb.append(rs.getString(1)); - } - else - throw new RaptorException("Report " + reportID + " not found in the database"); - } else { - /*oracle.sql.CLOB clob = null; - if (rs.next()) - clob = (oracle.sql.CLOB) rs.getObject(1); - else - throw new RaptorException("Report " + reportID + " not found in the database"); - int len = 0; - char[] buffer = new char[512]; - Reader in = clob.getCharacterStream(); - while ((len = in.read(buffer)) != -1) - sb.append(buffer, 0, len); - in.close();*/ - throw new RaptorException("only maria db support for this "); - } - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } catch (IOException ex) { - throw new RaptorException (ex.getMessage(), ex.getCause()); - } finally { - try { - if(rs!=null) - rs.close(); - if(stmt!=null) - stmt.close(); - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } - } - return sb.toString(); - } // loadCustomReportXML - - private static void dbUpdateReportXML(Connection connection, String reportID, - String reportXML) throws RaptorException { - PreparedStatement stmt = null; - ResultSet rs = null; - - try { - String sql = Globals.getDBUpdateReportXml(); - stmt = connection.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE, - ResultSet.CONCUR_UPDATABLE); - stmt.setInt(1,Integer.parseInt(reportID)); - rs = stmt.executeQuery(); - Writer out = null; - /*if(Globals.isWeblogicServer()) { - java.sql.Clob clob = null; - if (rs.next()) - clob = rs.getClob(1); - else - throw new RaptorException("Report " + reportID + " not found in the database"); - - if (clob.length() > reportXML.length()) - clob.truncate(0); - //clob.trim(reportXML.length()); - out = ((weblogic.jdbc.vendor.oracle.OracleThinClob)clob).getCharacterOutputStream(); - } else*/ - if (Globals.isPostgreSQL() || Globals.isMySQL()) { - if (rs.next()) { - rs.updateString("report_xml",reportXML); - rs.updateRow(); - connection.commit(); - //sb.append(rs.getString(1)); - } - else - throw new RaptorException("Report " + reportID + " not found in the database"); - } else { - /*oracle.sql.CLOB clob = null; - if (rs.next()) - clob = (oracle.sql.CLOB) rs.getObject(1); - else - throw new RaptorException("Report " + reportID + " not found in the database"); - - if (clob.length() > reportXML.length()) - clob.trim(reportXML.length()); - out = clob.getCharacterOutputStream();*/ - throw new RaptorException("only maria db support for this "); - } - if(!(Globals.isPostgreSQL() || Globals.isMySQL())) { - out.write(reportXML); - out.flush(); - out.close(); - } - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } catch (IOException ex) { - throw new RaptorException (ex.getMessage(), ex.getCause()); - } finally { - try { - if(rs!=null) - rs.close(); - if(stmt!=null) - stmt.close(); - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } - } - } // dbUpdateReportXML - - public static void updateCustomReportRec(Connection connection, ReportWrapper rw, - String reportXML) throws RaptorException { - /* DbUtils.executeUpdate(connection,"UPDATE cr_report SET title='" - + Utils.oracleSafe(rw.getReportName()) + "', descr='" - + Utils.oracleSafe(rw.getReportDescr()) + "', public_yn='" - + (rw.isPublic() ? "Y" : "N") + "', menu_id='" + rw.getMenuID() - + "', menu_approved_yn='" + (rw.isMenuApproved() ? "Y" : "N") + "', owner_id=" - + rw.getOwnerID() + ", maint_id=" + rw.getUpdateID() - + ", maint_date=TO_DATE('" + rw.getUpdateDate() + "', '" - + Globals.getOracleTimeFormat() + "'), dashboard_type_yn='"+ (rw.isDashboardType()?"Y":"N")+"', dashboard_yn= '" - + (rw.getReportType().equals(AppConstants.RT_DASHBOARD)?"Y":"N") + "' WHERE rep_id = " + rw.getReportID());*/ - - String sql = Globals.getUpdateCustomReportRec(); - - sql = sql.replace("[Utils.oracleSafe(rw.getReportName())]", Utils.oracleSafe(rw.getReportName())); - sql = sql.replace("[Utils.oracleSafe(rw.getReportDescr())]", Utils.oracleSafe(rw.getReportDescr())); - sql = sql.replace("[(rw.isPublic()]",(rw.isPublic() ? "Y" : "N")); - sql = sql.replace("[rw.getMenuID()]", rw.getMenuID()); - sql = sql.replace("[(rw.isMenuApproved()]", (rw.isMenuApproved() ? "Y" : "N")); - sql = sql.replace("[rw.getOwnerID()]",rw.getOwnerID()); - sql = sql.replace("[rw.getUpdateID()]",rw.getUpdateID()); - sql = sql.replace("[rw.getUpdateDate()]",rw.getUpdateDate()); - sql = sql.replace("[Globals.getOracleTimeFormat()]", Globals.getOracleTimeFormat()); - sql = sql.replace("[(rw.isDashboardType()]", (rw.isDashboardType()?"Y":"N")); - sql = sql.replace("[(rw.getReportType().equals(AppConstants.RT_DASHBOARD)]", (rw.getReportType().equals(AppConstants.RT_DASHBOARD)?"Y":"N")); - sql = sql.replace("[rw.getReportID()]", rw.getReportID()); - - DbUtils.executeUpdate(connection, sql); - - dbUpdateReportXML(connection, rw.getReportID(), reportXML); - } // updateCustomReportRec - - public static boolean isDashboardType ( String reportID ) throws RaptorException { - return false; -/* String sql = "select dashboard_type_yn from cr_report where rep_id = ?"; - Connection connection = DbUtils.getConnection(); - PreparedStatement stmt = null; - ResultSet rs = null; - boolean dashboardType= false; - try { - stmt = connection.prepareStatement(sql); - stmt.setString(1, reportID); - rs = stmt.executeQuery(); - if(rs.next()) { - dashboardType = nvls(rs.getString(1),"N").trim().toUpperCase().startsWith("Y"); - } - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } finally { - try { - rs.close(); - stmt.close(); - DbUtils.clearConnection(connection); - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } - } - return dashboardType;*/ - } - - public static boolean isReportsAlreadyScheduled ( String reportID ) throws RaptorException { - //String sql = "select rep_id from cr_report_schedule where rep_id = ?"; - String sql = Globals.getIsReportAlreadyScheduled(); - - Connection connection = DbUtils.getConnection(); - PreparedStatement stmt = null; - ResultSet rs = null; - boolean isScheduled= false; - try { - stmt = connection.prepareStatement(sql); - stmt.setInt(1, Integer.parseInt(reportID)); - rs = stmt.executeQuery(); - if(rs.next()) { - isScheduled = true; - } - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } finally { - try { - if(rs!=null) - rs.close(); - if(stmt!=null) - stmt.close(); - DbUtils.clearConnection(connection); - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } - } - return isScheduled; -} - - public static void createCustomReportRec(Connection connection, ReportWrapper rw, - String reportXML) throws RaptorException { - - /*DbUtils - .executeUpdate( - connection, - "INSERT INTO cr_report(rep_id, title, descr, public_yn, menu_id, menu_approved_yn, report_xml, owner_id, create_id, create_date, maint_id, maint_date, dashboard_type_yn, dashboard_yn, folder_id) VALUES(" - + rw.getReportID() - + ", '" - + Utils.oracleSafe(rw.getReportName()) - + "', '" - + Utils.oracleSafe(rw.getReportDescr()) - + "', '" - + (rw.isPublic() ? "Y" : "N") - + "', '" - + rw.getMenuID() - + "', '" - + (rw.isMenuApproved() ? "Y" : "N") - + "', '', " - + rw.getOwnerID() - + ", " - + rw.getCreateID() - + ", TO_DATE('" - + rw.getCreateDate() - + "', '" - + Globals.getOracleTimeFormat() - + "'), " - + rw.getUpdateID() - + ", TO_DATE('" - + rw.getUpdateDate() - + "', '" - + Globals.getOracleTimeFormat() - + "'), '" - + (rw.isDashboardType()?"Y":"N") - + "', '" - + (rw.getReportType().equals(AppConstants.RT_DASHBOARD)?"Y":"N") - + "', " - + rw.getFolderId() - + ")");*/ - String sql = Globals.getCreateCustomReportRec(); - - sql = sql.replace("[rw.getReportID()]", rw.getReportID()); - sql = sql.replace("[Utils.oracleSafe(rw.getReportName())]", Utils.oracleSafe(rw.getReportName())); - sql = sql.replace("[Utils.oracleSafe(rw.getReportDescr())]", Utils.oracleSafe(rw.getReportDescr())); - sql = sql.replace("[rw.isPublic()]", (rw.isPublic() ? "Y" : "N")); - sql = sql.replace("[rw.getMenuID()]", rw.getMenuID()); - sql = sql.replace("[rw.isMenuApproved()]", (rw.isMenuApproved() ? "Y" : "N")); - sql = sql.replace("[rw.getOwnerID()]", rw.getOwnerID()); - sql = sql.replace("[rw.getCreateID()]", rw.getCreateID()); - sql = sql.replace("[rw.getCreateDate()]", rw.getCreateDate()); - sql = sql.replace("[Globals.getOracleTimeFormat()]", Globals.getOracleTimeFormat()); - sql = sql.replace("[rw.getUpdateID()]", rw.getUpdateID()); - sql = sql.replace("[rw.getUpdateDate()]", rw.getUpdateDate()); - sql = sql.replace("[rw.isDashboardType()]", (rw.isDashboardType()?"Y":"N")); - sql = sql.replace("[rw.getReportType().equals(AppConstants.RT_DASHBOARD)]", (rw.getReportType().equals(AppConstants.RT_DASHBOARD)?"Y":"N")); - sql = sql.replace("[rw.getFolderId()]", rw.getFolderId()); - - - DbUtils.executeUpdate(connection,sql); - - dbUpdateReportXML(connection, rw.getReportID(), reportXML); - } // createCustomReportRec - - public static Vector getUserReportNames(HttpServletRequest request) { - return getUserReportNames(AppUtils.getUserID(request)); - } // getUserReportNames - - public static Vector getUserReportNames(String userID) { - Vector reportIdNames = new Vector(); - - try { - - String sql = Globals.getTheUserReportNames(); - sql = sql.replace("[userID]", userID); - DataSet ds = DbUtils.executeQuery(sql); - - //DataSet ds = DbUtils - // .executeQuery("SELECT cr.rep_id, cr.title FROM cr_report cr WHERE nvl(cr.owner_id, cr.create_id) = " - // + userID); - - for (int i = 0; i < ds.getRowCount(); i++) - reportIdNames.add(new IdNameValue(ds.getString(i, 0), ds.getString(i, 1))); - } catch (Exception e) { - } - - return reportIdNames; - } // getUserReportNames - - public static String getReportOwnerID(String reportID) throws RaptorException { - - // String sql = "SELECT nvl(cr.owner_id, cr.create_id) owner FROM cr_report cr WHERE rep_id = ?"; - - String sql = Globals.getTheReportOwnerId(); - - Connection connection = DbUtils.getConnection(); - PreparedStatement stmt = null; - ResultSet rs = null; - String reportOwnerID = null; - try { - stmt = connection.prepareStatement(sql); - stmt.setInt(1, Integer.parseInt(reportID)); - rs = stmt.executeQuery(); - if(rs.next()) { - reportOwnerID = rs.getString(1); - } - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } finally { - try { - if(rs!=null) - rs.close(); - if(stmt!=null) - stmt.close(); - DbUtils.clearConnection(connection); - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } - } - - return reportOwnerID; - } // getReportOwnerID - - public static void deleteReportRecord(String reportID) throws RaptorException { - Connection con = DbUtils.startTransaction(); - - /*try { - DbUtils.executeUpdate(con, "DELETE cr_report_log WHERE rep_id = " + reportID); - DbUtils.executeUpdate(con, "DELETE cr_report_schedule_users WHERE rep_id = " - + reportID); - DbUtils.executeUpdate(con, "DELETE cr_report_schedule WHERE rep_id = " + reportID); - DbUtils.executeUpdate(con, "DELETE cr_report_access WHERE rep_id = " + reportID); - DbUtils.executeUpdate(con, "DELETE cr_report_email_sent_log WHERE rep_id = " + reportID); - DbUtils.executeUpdate(con, "DELETE cr_favorite_reports WHERE rep_id = " + reportID); - DbUtils.executeUpdate(con, "DELETE cr_report WHERE rep_id = " + reportID); - DbUtils.commitTransaction(con); - } */ - - try{ - String sql1= Globals.getDeleteReportRecordLog(); - sql1 = sql1.replace("[reportID]", reportID); - String sql2= Globals.getDeleteReportRecordUsers(); - sql2 = sql2.replace("[reportID]", reportID); - String sql3= Globals.getDeleteReportRecordSchedule(); - sql3 = sql3.replace("[reportID]", reportID); - String sql4= Globals.getDeleteReportRecordAccess(); - sql4 = sql4.replace("[reportID]", reportID); - String sql5= Globals.getDeleteReportRecordEmail(); - sql5 = sql5.replace("[reportID]", reportID); - String sql6= Globals.getDeleteReportRecordFavorite(); - sql6 = sql6.replace("[reportID]", reportID); - String sql7= Globals.getDeleteReportRecordReport(); - sql7 = sql7.replace("[reportID]", reportID); - - DbUtils.executeUpdate(con, sql1); - DbUtils.executeUpdate(con, sql2); - DbUtils.executeUpdate(con, sql3); - DbUtils.executeUpdate(con, sql4); - DbUtils.executeUpdate(con, sql5); - DbUtils.executeUpdate(con, sql6); - DbUtils.executeUpdate(con, sql7); - DbUtils.commitTransaction(con); - - } - - - catch (Exception e) { - DbUtils.rollbackTransaction(con); - } finally { - DbUtils.clearConnection(con); - } - } // deleteReportRecord - - public static ArrayList loadQuickLinks(HttpServletRequest request, String menuId, boolean b) throws RaptorException { - String userID = AppUtils.getUserID(request); - StringBuffer roleList = new StringBuffer(); - roleList.append("-1"); - for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) - roleList.append("," + ((String) iter.next())); - - // DataSet ds = DbUtils.executeQuery("SELECT cr.rep_id, cr.title FROM - // cr_report cr WHERE cr.public_yn = 'Y' AND cr.menu_id = - // '"+nvls(menuId)+"' AND cr.menu_approved_yn = 'Y' ORDER BY cr.title"); - // Copied from SearchHandler and simplified - /*String query = "SELECT cr.rep_id, " - + "cr.title, " - + "cr.descr " - + "FROM cr_report cr, " - + "(SELECT rep_id, " - + "MIN(read_only_yn) read_only_yn " - + "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " - + userID - + ") " - + "UNION ALL " - + "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN (" - + roleList.toString() + "))" + ") report_access " - + "GROUP BY rep_id) ra " + "WHERE INSTR('|'||cr.menu_id||'|', '|'||'" - + nvls(menuId) + "'||'|') > 0 AND " + "cr.menu_approved_yn = 'Y' AND " - + "cr.rep_id = ra.rep_id (+) AND " - + "(nvl(cr.owner_id, cr.create_id) = " + userID - + " OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL) " - + "ORDER BY cr.title";*/ - - String query = Globals.getLoadQuickLinks(); - query = query.replace("[userID]", userID); - query = query.replace("[roleList.toString()]", roleList.toString()); - query = query.replace("[nvls(menuId)]", nvls(menuId)); - - DataSet ds = DbUtils - .executeQuery(query); - - ArrayList quickLinks = new ArrayList(ds.getRowCount()); - StringBuffer link = new StringBuffer(""); - for (int i = 0; i < ds.getRowCount(); i++) { - link = new StringBuffer(""); - link.append("" +ds.getString(i, 1) + "" + (Globals.getShowDescrAtRuntime() ? " - " + ds.getString(i, 2) : "") ); - quickLinks.add(link.toString()); - } - - return quickLinks; - } // loadQuickLinks - - public static ArrayList getQuickLinksJSON(HttpServletRequest request, String menuId, boolean b) throws RaptorException { - String userID = AppUtils.getUserID(request); - StringBuffer roleList = new StringBuffer(); - roleList.append("-1"); - for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) - roleList.append("," + ((String) iter.next())); - - String query = Globals.getLoadQuickLinks(); - query = query.replace("[userID]", userID); - query = query.replace("[roleList.toString()]", roleList.toString()); - query = query.replace("[nvls(menuId)]", nvls(menuId)); - - DataSet ds = DbUtils - .executeQuery(query); - - ArrayList quickLinksArray = new ArrayList(ds.getRowCount()); - for (int i = 0; i < ds.getRowCount(); i++) { - QuickLink quickLink = new QuickLink(); - StringBuffer link = new StringBuffer(""); - link.append(AppUtils.getReportExecuteActionURLNG() +"c_master="+ ds.getString(i, 0)); - if(b) link.append("&PAGE_ID="+menuId+"&refresh=Y"); - quickLink.setReportURL(link.toString()); - quickLink.setReportName(ds.getString(i, 1)); - quickLink.setShowDescr(Globals.getShowDescrAtRuntime()); - quickLink.setReportDescr(ds.getString(i, 2)); - quickLinksArray.add(quickLink); - } - - return quickLinksArray; - } // loadQuickLinks - - //this will retrieve all the reports within the specified folder. - public static ReportSearchResult loadFolderReports(HttpServletRequest request, String menuId, boolean b, String folderId, boolean isUserReport, boolean isPublicReport) throws RaptorException { - String HTML_FORM = "forma"; - String userID = AppUtils.getUserID(request); - StringBuffer roleList = new StringBuffer(); - roleList.append("-1"); - String rep_title_sql = "''"; - String PRIVATE_ICON = "Private "; - - for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) - roleList.append("," + ((String) iter.next())); - - /*String sql= "SELECT cr.rep_id, " + - "cr.rep_id report_id, " + - rep_title_sql+ - "||DECODE(cr.public_yn, 'Y', '', '" + - PRIVATE_ICON + - "')||cr.title||'' title, " + - "cr.descr, " + - "au.first_name||' '||au.last_name owner_name, " + - "TO_CHAR(cr.create_date, 'MM/DD/YYYY') create_date, " + - "DECODE(NVL(cr.owner_id, cr.create_id), " + - userID + - ", 'N', NVL(ra.read_only_yn, 'Y')) read_only_yn, " + - "DECODE(NVL(cr.owner_id, cr.create_id), " + - userID + - ", 'Y', 'N') user_is_owner_yn " + - " FROM cr_report cr, " + - "app_user au, " + - "(SELECT rep_id, MIN(read_only_yn) read_only_yn " + - "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " + - userID + - ") " + - "UNION ALL " + - "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN " + - "(-1,1000,1))" + ") report_access GROUP BY rep_id) ra " + - "WHERE TO_CHAR(cr.rep_id) = nvl('', TO_CHAR(cr.rep_id)) AND UPPER(cr.title) LIKE UPPER('%%') " + - "AND nvl(cr.owner_id, cr.create_id) = au.user_id AND cr.rep_id = ra.rep_id (+) " + - " AND cr.folder_id= '" + folderId + "'" ;*/ - - /*String sql = "" + - "SELECT cr.rep_id, " - + "cr.rep_id report_id, " - + rep_title_sql + "||DECODE(cr.public_yn, 'Y', '', '" + PRIVATE_ICON + "')||cr.title||'' title, " - + "cr.descr, " - + "au.first_name||' '||au.last_name owner_name, " - + "TO_CHAR(cr.create_date, 'MM/DD/YYYY') create_date, " - + "DECODE(NVL(cr.owner_id, cr.create_id), " + userID - + ", 'N', NVL(ra.read_only_yn, 'Y')) read_only_yn, " - + "DECODE(NVL(cr.owner_id, cr.create_id), " + userID - + ", 'Y', 'N') user_is_owner_yn " - + "FROM cr_report cr, " - + "app_user au, " - + "(SELECT rep_id, " - + "MIN(read_only_yn) read_only_yn " - + "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " - + userID - + ") " - + "UNION ALL " - + "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN (" - + roleList.toString() + "))" + ") report_access " + "GROUP BY rep_id) ra " - + "WHERE " + "nvl(cr.owner_id, cr.create_id) = au.user_id " - + "AND cr.rep_id = ra.rep_id (+) AND cr.folder_id= '" + folderId + "'";*/ - - String sql = Globals.getLoadFolderReports(); - sql = sql.replace("[userID]", userID); - sql = sql.replace("[PRIVATE_ICON]", PRIVATE_ICON); - sql = sql.replace("[rep_title_sql]", rep_title_sql); - sql = sql.replace("[roleList.toString()]", roleList.toString()); - sql = sql.replace("[folderId]", folderId); - - - // String user_sql = " AND nvl(cr.owner_id, cr.create_id) = " + userID; - // String public_sql = " AND (nvl(cr.owner_id, cr.create_id) = " + userID - // + " OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL)"; - - String user_sql = Globals.getLoadFolderReportsUser(); - user_sql = user_sql.replace("[userID]", userID); - String public_sql = Globals.getLoadFolderReportsPublicSql(); - public_sql = public_sql.replace("[userID]", userID); - - if (isUserReport) - // My reports - user is owner - sql += user_sql; - else if (isPublicReport) - // Public reports - user has read or write access to the report - // (user is owner or report is public or user has explicit user or - // role access) - if (!AppUtils.isSuperUser(request)) - sql += public_sql; - else if (!AppUtils.isSuperUser(request)) - // All reports - // If user is super user - gets unrestricted access to all reports - // (read_only gets overriden later) - // else - not super user - doesn't get access to private reports of - // other users (= Public reports); Admin users get edit right - // override later - sql += public_sql; - logger.debug(EELFLoggerDelegate.debugLogger, ("query is for folder list is : " + sql)); - - DataSet ds = DbUtils.executeQuery(sql); - - /*Vector quickLinks = new Vector(ds.getRowCount()); - StringBuffer link = new StringBuffer(""); - for (int i = 0; i < ds.getRowCount(); i++) { - link = new StringBuffer(""); - link.append("" +ds.getString(i, 2) + "" + (Globals.getShowDescrAtRuntime() ? " - " + ds.getString(i, 2) : "") ); - quickLinks.add(link.toString()); - } - - return quickLinks;*/ - ReportSearchResult rsr = new ReportSearchResult(-1, ds.getRowCount(), 6, 7); - rsr.parseData(ds, request); - //rsr.truncateToPage(pageNo); - - return rsr; - } // loadFolderReports - - public static ArrayList loadQuickDownloadLinks(String userID, HttpServletRequest request) throws RaptorException { - /*String query = " SELECT a.file_name, b.title,to_char(a.dwnld_start_time, 'Dy DD-Mon-YYYY HH24:MI:SS') as time, "+ - " a.dwnld_start_time " + - " FROM cr_report_dwnld_log a, cr_report b where a.user_id = "+userID +" and "+ - " a.rep_id = b.rep_id " + - " and (a.dwnld_start_time) >= to_date(to_char(sysdate-24/24, 'mm/dd/yyyy'), 'mm/dd/yyyy') " + - " and a.record_ready_time is not null " + - " order by a.dwnld_start_time desc"; */ - - String query = Globals.getLoadQuickDownloadLinks(); - query = query.replace("[userID]", userID); - - - DataSet ds = DbUtils - .executeQuery(query); - ArrayList quickDownloadLinks = new ArrayList(ds.getRowCount()); - logger.debug(EELFLoggerDelegate.debugLogger, ("ROW SIZE " + ds.getRowCount())); - for (int i = 0; i < ds.getRowCount(); i++) { - quickDownloadLinks.add("" + ds.getString(i, 1)+ "" + " "+ ds.getString(i, 2)); - } - logger.debug(EELFLoggerDelegate.debugLogger, ("VECTOR SIZE " + quickDownloadLinks.size())); - - return quickDownloadLinks; - } // loadQuickLinks - - public static HashMap loadReportsToSchedule (HttpServletRequest request) throws RaptorException { - String userID = AppUtils.getUserID(request); - StringBuffer roleList = new StringBuffer(); - roleList.append("-1"); - for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) - roleList.append("," + ((String) iter.next())); - /*StringBuffer query = new StringBuffer(""); - query.append("SELECT cr.rep_id, "); - query.append("Initcap(cr.title), "); - query.append("cr.descr "); - query.append("FROM cr_report cr, "); - query.append("(SELECT rep_id, "); - query.append("MIN(read_only_yn) read_only_yn "); - query.append("FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = "); - query.append(userID); - query.append(") "); - query.append("UNION ALL "); - query.append("(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN ("); - query.append(roleList.toString() + "))" + ") report_access "); - query.append("GROUP BY rep_id) ra " + "WHERE "); - query.append("cr.rep_id = ra.rep_id (+) AND "); - query.append(" (cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL or cr.owner_id = " + userID +") "); - query.append("ORDER BY Initcap(cr.title)") ;*/ - - String sql = Globals.getLoadReportsToSchedule(); - sql = sql.replace("[userID]", userID); - sql = sql.replace("[roleList.toString()]", roleList.toString()); - - // DataSet ds = DbUtils - // .executeQuery(query.toString()); - - DataSet ds = DbUtils - .executeQuery(sql); - HashMap map = new HashMap(); - for (int i = 0; i < ds.getRowCount(); i++) { - map.put(ds.getItem(i,0), ds.getItem(i,1)); - } - - return map; - } - - public static HashMap loadReportsToAddInDashboard (HttpServletRequest request) throws RaptorException { - String userID = AppUtils.getUserID(request); - StringBuffer roleList = new StringBuffer(); - roleList.append("-1"); - for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) - roleList.append("," + ((String) iter.next())); - /*StringBuffer query = new StringBuffer(""); - query.append("SELECT cr.rep_id, "); - query.append("cr.title, "); - query.append("cr.descr "); - query.append("FROM cr_report cr, "); - query.append("(SELECT rep_id, "); - query.append("MIN(read_only_yn) read_only_yn "); - query.append("FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = "); - query.append(userID); - query.append(") "); - query.append("UNION ALL "); - query.append("(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN ("); - query.append(roleList.toString() + "))" + ") report_access "); - query.append("GROUP BY rep_id) ra " + "WHERE "); - query.append("cr.rep_id = ra.rep_id (+) AND "); - query.append("(nvl(cr.owner_id, cr.create_id) = " + userID); - query.append(" OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL) "); - query.append(" AND (cr.dashboard_yn = 'N' or cr.dashboard_yn is null) "); - query.append("ORDER BY cr.title") ;*/ - - String sql = Globals.getLoadReportsToAddInDashboard(); - sql = sql.replace("[userID]", userID); - sql = sql.replace("[roleList.toString()]", roleList.toString()); - - // DataSet ds = DbUtils - // .executeQuery(query.toString()); - - DataSet ds = DbUtils - .executeQuery(sql); - - HashMap map = new HashMap(); - for (int i = 0; i < ds.getRowCount(); i++) { - map.put(ds.getItem(i,0), ds.getItem(i,1)); - } - - return map; - } - - public static Vector loadMyRecentLinks(String userID, HttpServletRequest request) throws RaptorException { - /* StringBuffer query = new StringBuffer(""); - query.append("select rep_id, title, descr, form_fields from ( select rownum, rep_id, title, descr, form_fields from "); - query.append(" (select cr.rep_id, cr.title, a.form_fields, cr.descr, a.log_time, a.user_id, a.action, a.action_value " ); - query.append(" from cr_report_log a, cr_report cr where user_id = " + userID); - query.append(" and action = 'Report Execution Time' and a.rep_id = cr.rep_id order by log_time desc) x where rownum <= 6 ) y where rownum >= 1");*/ -// DataSet ds = DbUtils -// .executeQuery( -// " SELECT a.file_name, b.title,to_char(a.dwnld_start_time, 'Dy DD-Mon-YYYY HH24:MI:SS') as time, "+ -// " a.dwnld_start_time " + -// " FROM cr_report_dwnld_log a, cr_report b where a.user_id = "+userID +" and "+ -// " a.rep_id = b.rep_id and (a.dwnld_start_time) >= to_date(to_char(sysdate-24/24, 'mm/dd/yyyy'), 'mm/dd/yyyy') " + -// " and a.record_ready_time is not null " + -// " order by a.dwnld_start_time desc"); -// DataSet ds = DbUtils - // .executeQuery(query.toString()); - - - String sql = Globals.getLoadMyRecentLinks(); - sql = sql.replace("[userID]", userID); - - DataSet ds = DbUtils - .executeQuery(sql); - - Vector myRecentLinks = new Vector(ds.getRowCount()); - logger.debug(EELFLoggerDelegate.debugLogger, ("ROW SIZE " + ds.getRowCount())); - for (int i = 0; i < ds.getRowCount(); i++) { - myRecentLinks.add("" + ds.getString(i, 1)+ ""); - } - logger.debug(EELFLoggerDelegate.debugLogger, ("VECTOR SIZE " + myRecentLinks.size())); - - return myRecentLinks; - } // loadQuickLinks - - public static void createReportLogEntry(Connection connection, String reportID, - String userID, String action, String executionTime,String form_fields) throws RaptorException { - if(form_fields.length()>=4000) form_fields = ""; - //String stmt = "INSERT INTO cr_report_log (rep_id, log_time, user_id, action, action_value, form_fields) VALUES(" - // + reportID + ", SYSDATE, " + userID + ", '" + action + "' , '" + executionTime + "', '"+ form_fields +"')"; - - String stmt = Globals.getCreateReportLogEntry(); - stmt = stmt.replace("[reportID]", reportID); - stmt = stmt.replace("[userID]", userID); - stmt = stmt.replace("[action]", action); - stmt = stmt.replace("[executionTime]", executionTime); - stmt = stmt.replace("[form_fields]", form_fields); - - if (Globals.getEnableReportLog()) - if (connection == null) - DbUtils.executeUpdate(stmt); - else - DbUtils.executeUpdate(connection, stmt); - } // createReportLogEntry - - public static void createReportLogEntryForExecutionTime(Connection connection, String reportID, - String userID, String executionTime, String action, String formFields) throws RaptorException { - if(formFields.length()>=4000) formFields = ""; - //String stmt = "INSERT INTO cr_report_log (rep_id, log_time, user_id, action, action_value, form_fields) VALUES(" - // + reportID + ", sysdate+1/(24*60*60) , " + userID + ", '" + action + "' , '" + executionTime + "', '"+ formFields +"')"; - - String stmt = Globals.getCreateReportLogEntryExecTime(); - stmt = stmt.replace("[reportID]", reportID); - stmt = stmt.replace("[userID]", userID); - stmt = stmt.replace("[action]", action); - stmt = stmt.replace("[executionTime]", executionTime); - stmt = stmt.replace("[formFields]", formFields); - - if (Globals.getEnableReportLog()) - if (connection == null) - DbUtils.executeUpdate(stmt); - else - DbUtils.executeUpdate(connection, stmt); - } // createReportLogEntry - - public static void clearReportLogEntries(String reportId, String userId) throws RaptorException { - String sql = Globals.getClearReportLogEntries(); - Connection connection = DbUtils.getConnection(); - PreparedStatement stmt = null; - String reportOwnerID = null; - int rowsAffected = 0; - try { - stmt = connection.prepareStatement(sql); - stmt.setInt(1, Integer.parseInt(reportId)); - stmt.setInt(2, Integer.parseInt(userId)); - rowsAffected = stmt.executeUpdate(); - if(rowsAffected > 0) connection.commit(); - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } finally { - try { - stmt.close(); - connection.close(); - DbUtils.clearConnection(connection); - } catch (SQLException ex) { - throw new ReportSQLException (ex.getMessage(), ex.getCause()); - } - } - } // clearReportLogEntries - - public static Vector loadReportLogEntries(String reportId) throws RaptorException { - /* StringBuffer query = new StringBuffer("SELECT x.log_time, x.user_id,") ; - query.append(" (CASE WHEN x.action = 'Report Execution Time' THEN "); - query.append(" ''||x.action||''"); - query.append(" ELSE x.action END) action, " ); - query.append(" (CASE WHEN x.action = 'Report Execution Time' THEN "); - query.append(" action_value " ); - query.append(" ELSE 'N/A' END) time_taken, " ); - query.append( " (CASE WHEN x.action = 'Report Execution Time' THEN '\"Run' ELSE 'N/A' END) run_image, " ); - query.append(" x.name FROM "); - query.append(" (SELECT rl.rep_id, TO_CHAR(rl.log_time, 'Month DD, YYYY HH:MI:SS AM') log_time, rl.action_value, fuser.last_name ||', '||fuser.first_name name, "); - query.append(" rl.user_id, rl.action, rl.form_fields FROM cr_report_log rl, fn_user fuser WHERE rl.rep_id = "+ nvls(reportId)+ " and rl.action != 'Report Run' and fuser.user_id = rl.user_id" ); - query.append(" ORDER BY rl.log_time DESC) x WHERE ROWNUM <= 100");*/ -// DataSet ds = DbUtils -// .executeQuery("SELECT x.log_time, x.user_id, x.action FROM (SELECT TO_CHAR(rl.log_time, 'Month DD, YYYY HH:MI:SS AM') log_time, rl.user_id, rl.action FROM cr_report_log rl WHERE rl.rep_id = " -// + nvls(reportId) + " ORDER BY rl.log_time DESC) x WHERE ROWNUM <= 100"); - // DataSet ds = DbUtils.executeQuery(query.toString()); - - String sql = Globals.getLoadReportLogEntries(); - sql = sql.replace("[AppUtils.getRaptorActionURL()]", AppUtils.getRaptorActionURL()); - sql = sql.replace("[AppUtils.getImgFolderURL()]", AppUtils.getImgFolderURL()); - sql = sql.replace("[nvls(reportId)]", nvls(reportId)); - - - DataSet ds = DbUtils.executeQuery(sql); - - Vector logEntries = new Vector(ds.getRowCount()); - - for (int i = 0; i < ds.getRowCount(); i++) - logEntries.add(new ReportLogEntry(ds.getString(i, 0), ds - .getString(i, 5), ds.getString(i, 2), ds.getString(i, 3), ds.getString(i, 4))); - - return logEntries; - } // loadReportLogEntries - - public static boolean doesUserCanScheduleReport(HttpServletRequest request, String scheduleId) throws RaptorException { - boolean flagLimit = false; - boolean flagScheduleIdPresent = false; - String userId = AppUtils.getUserID(request); - if(AppUtils.isAdminUser(request))return true; - //String query = "select crs.sched_user_id, count(*) from cr_report_schedule crs where sched_user_id = " + userId + " group by crs.sched_user_id having count(*) >= " + Globals.getScheduleLimit(); - String query = Globals.getDoesUserCanScheduleReport(); - query = query.replace("[userId]", userId); - query = query.replace("[Globals.getScheduleLimit()]", String.valueOf(Globals.getScheduleLimit())); - - DataSet ds = DbUtils.executeQuery(query); - logger.debug(EELFLoggerDelegate.debugLogger, (" User Schedule ds.getRowCount() " + ds.getRowCount() + " " +(ds.getRowCount()>0))); - if(ds.getRowCount() > 0) flagLimit = true; - else flagLimit = false; - logger.debug(EELFLoggerDelegate.debugLogger, ("scheduleId " + scheduleId)); - if(scheduleId==null || scheduleId.trim().length()<=0) return !flagLimit; - //query = "select crs.schedule_id from cr_report_schedule crs where schedule_id = " + scheduleId; - query = Globals.getDoesUserCanSchedule(); - query = query.replace("[scheduleId]", scheduleId); - - if(ds.getRowCount() > 0) flagScheduleIdPresent = true; - else flagScheduleIdPresent = false; - if(!flagLimit) return true; - if(flagLimit && flagScheduleIdPresent) return true; - else return false; - } - - public static String getSystemDateTime() throws RaptorException { - //String query = "select to_char(sysdate,'MM/dd/yyyy HH24:mi:ss') from dual"; - String query = Globals.getTheSystemDateTime(); - - DataSet ds = DbUtils.executeQuery(query); - String timeStr = ""; - if(ds.getRowCount() > 0) { - timeStr = ds.getString(0,0); - } - return timeStr; - - } - - public static String getNextDaySystemDateTime() throws RaptorException { - //String query = "select to_char(sysdate+1,'MM/dd/yyyy HH24:mi:ss') from dual"; - String query = Globals.getTheNextDayDateTime(); - DataSet ds = DbUtils.executeQuery(query); - String timeStr = ""; - if(ds.getRowCount() > 0) { - timeStr = ds.getString(0,0); - } - return timeStr; - - } - - public static String getNext15MinutesOfSystemDateTime() throws RaptorException { - //String query = "select to_char(sysdate+15/(24*60),'MM/dd/yyyy HH24:mi:ss') from dual"; - String query = Globals.getTheNextFifteenMinDateTime(); - - DataSet ds = DbUtils.executeQuery(query); - String timeStr = ""; - if(ds.getRowCount() > 0) { - timeStr = ds.getString(0,0); - } - return timeStr; - - } - - public static String getNext30MinutesOfSystemDateTime() throws RaptorException { - //String query = "select to_char(sysdate+30/(24*60),'MM/dd/yyyy HH24:mi:ss') from dual"; - String query = Globals.getTheNextThirtyMinDateTime(); - DataSet ds = DbUtils.executeQuery(query); - String timeStr = ""; - if(ds.getRowCount() > 0) { - timeStr = ds.getString(0,0); - } - return timeStr; - - } - - public static String getTemplateFile(String reportId) throws RaptorException { - //String query = "select template_file from cr_report_template_map where report_id = " + reportId; - String query = Globals.getTheTemplateFile(); - query = query.replace("[reportId]", reportId); - String templateFile = ""; - try { - DataSet ds = DbUtils.executeQuery(query); - if(ds.getRowCount() > 0) { - templateFile = ds.getString(0,0); - } - }catch(RaptorException ex) { - logger.debug(EELFLoggerDelegate.debugLogger, ("SQL Exception while trying to access cr_report_template_map ")); - } - return templateFile; - - } - - - public static HashMap loadPDFImgLookUp() throws RaptorException { - StringBuffer query = new StringBuffer(""); - HashMap pdfImgMap = new HashMap(); - //query.append("select image_id, image_loc from cr_raptor_pdf_img"); - query.append(Globals.getLoadPdfImgLookup()); - DataSet ds = DbUtils.executeQuery(query.toString()); - for (int i = 0; i < ds.getRowCount(); i++) { - pdfImgMap.put(ds.getString(i, 0), ds.getString(i,1)); - } - return pdfImgMap; - } // loadQuickLinks - - public static HashMap loadActionImgLookUp() throws RaptorException { - StringBuffer query = new StringBuffer(""); - HashMap pdfImgMap = new HashMap(); - //query.append("select image_id, image_loc from cr_raptor_action_img"); - query.append(Globals.getLoadActionImgLookup()); - DataSet ds = DbUtils.executeQuery(query.toString()); - for (int i = 0; i < ds.getRowCount(); i++) { - pdfImgMap.put(ds.getString(i, 0), ds.getString(i,1)); - } - return pdfImgMap; - } // loadQuickLinks - -} // ReportLoader - diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/SearchHandler.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/SearchHandler.java deleted file mode 100644 index 428bc90a..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/SearchHandler.java +++ /dev/null @@ -1,490 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -/* =========================================================================================== - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) - * Raptor : This tool is used to generate different kinds of reports with lot of utilities - * =========================================================================================== - * - * ------------------------------------------------------------------------------------------- - * SearchHandler.java - This class is used to search reports and sort them in different order - * based on preference. It can also download the list in CSV format. - * ------------------------------------------------------------------------------------------- - * - * - * - * Changes - * ------- - * 18-Aug-2009 : Version 8.5.1 (Sundar);
        • request Object is passed to prevent caching user/roles - Datamining/Hosting.
        - * 13-Aug-2009 : Version 8.5 (Sundar);
        • Refresh is added while running report.
        • - *
        - * 27-Jul-2009 : Version 8.4 (Sundar);
        • A new sort order PUBLIC is added.
        • - *
        • In Public reports option it brings all the reports - * including the one which logged in user didn't create - * and which is not public. This is available for Super users and "Admin equivalent Super Users".
        • - *
        - * - */ -package org.openecomp.portalsdk.analytics.model; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.Iterator; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.analytics.controller.ErrorHandler; -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.model.search.ReportSearchResult; -import org.openecomp.portalsdk.analytics.model.search.ReportSearchResultJSON; -import org.openecomp.portalsdk.analytics.model.search.SearchResultColumn; -import org.openecomp.portalsdk.analytics.model.search.SearchResultField; -import org.openecomp.portalsdk.analytics.model.search.SearchResultRow; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.DbUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.HtmlStripper; - -public class SearchHandler extends org.openecomp.portalsdk.analytics.RaptorObject { - private static final String HTML_FORM = "forma"; - private final static String PRIVATE_ICON = "Private "; - - public SearchHandler() { - } - - public void createCSVFileContent(Writer out, ReportSearchResult sr) throws IOException { - PrintWriter csvOut = new PrintWriter(out); - HtmlStripper strip = new HtmlStripper(); - - for (int c = 1; c < sr.getNumColumns(); c++) { - SearchResultColumn column = sr.getColumn(c); - if (column.getLinkURL() == null) - csvOut.print("\"" + column.getColumnTitle() + "\","); - } // for - csvOut.println(); - - for (int r = 0; r < sr.getNumRows(); r++) { - SearchResultRow row = sr.getRow(r); - - int c = 1; - for (row.resetNext(1); row.hasNext();) { - SearchResultField field = row.getNext(); - if (sr.getColumn(c++).getLinkURL() == null) - if (field.getDisplayValue().startsWith(PRIVATE_ICON)) - csvOut.print("\"" - + strip.stripHtml(field.getDisplayValue().substring(PRIVATE_ICON.length())) - + "\","); - else - csvOut.print("\"" + strip.stripHtml(field.getDisplayValue()) + "\","); - } // for - - csvOut.println(); - } // for - } // createCSVFileContent - - public String saveCSVPageFile(HttpServletRequest request, ReportSearchResult sr) { - try { - String csvFName = AppUtils.generateFileName(request, - (sr.getPageNo() < 0) ? AppConstants.FT_CSV_ALL : AppConstants.FT_CSV); - - BufferedWriter csvOut = new BufferedWriter(new FileWriter(AppUtils - .getTempFolderPath() - + csvFName)); - createCSVFileContent(csvOut, sr); - csvOut.close(); - - if (sr.getPageNo() < 0) - sr.setCsvAllRowsFileName(csvFName); - else - sr.setCsvPageFileName(csvFName); - - return csvFName; - } catch (Exception e) { - (new ErrorHandler()).processError(request, "Exception saving data to CSV file: " - + e.getMessage()); - return null; - } - } // saveCSVPageFile - - public ReportSearchResultJSON loadReportSearchResult(HttpServletRequest request) - throws RaptorException { - String userID = AppUtils.getUserID(request); - String fReportID = nvl(AppUtils.getRequestValue(request, AppConstants.RI_F_REPORT_ID)); - String fReportName = nvl(AppUtils.getRequestValue(request, - AppConstants.RI_F_REPORT_NAME)); - String sortOrder = nvl(AppUtils.getRequestValue(request, AppConstants.RI_SORT_ORDER), - AppConstants.RI_F_REPORT_NAME); - - String menuId = nvl(AppUtils.getRequestValue(request, AppConstants.RI_LIST_CATEGORY)); - - boolean userOnly = AppUtils.getRequestFlag(request, AppConstants.RI_USER_REPORTS); - boolean publicOnly = AppUtils.getRequestFlag(request, AppConstants.RI_PUBLIC_REPORTS); - boolean favoriteOnly = AppUtils.getRequestFlag(request, AppConstants.RI_FAVORITE_REPORTS); - - int pageNo = 0; - try { - pageNo = Integer.parseInt(request.getParameter(AppConstants.RI_NEXT_PAGE)); - } catch (Exception e) { - } - - StringBuffer roleList = new StringBuffer(); - roleList.append("-1"); - String rep_title_sql = "''"; - for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) - roleList.append("," + ((String) iter.next())); - // - /*String sql = "SELECT cr.rep_id, " - + "cr.rep_id report_id, " - + rep_title_sql+ - "||DECODE(cr.public_yn, 'Y', '', '" - + PRIVATE_ICON - + "')||cr.title||'' title, " - + "cr.descr, " - + "au.first_name||' '||au.last_name owner_name, " - + "TO_CHAR(cr.create_date, 'MM/DD/YYYY') create_date, " - + "DECODE(NVL(cr.owner_id, cr.create_id), " - + userID - + ", 'N', NVL(ra.read_only_yn, 'Y')) read_only_yn, " - + "DECODE(NVL(cr.owner_id, cr.create_id), " - + userID - + ", 'Y', 'N') user_is_owner_yn, " - + "case when report_xml like '%N%' " - + "then 'N' " - + "when report_xml like '%Y%' " - + "or 1 = (select distinct 1 from cr_report_schedule where rep_id = cr.rep_id) " - + "then 'Y' " - + "else 'N' end " - + "FROM cr_report cr, " - + "app_user au, " - + "(SELECT rep_id, " - + "MIN(read_only_yn) read_only_yn " - + "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " - + userID - + ") " - + "UNION ALL " - + "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN (" - + roleList.toString() + "))" + ") report_access " + "GROUP BY rep_id) ra " - + "WHERE TO_CHAR(cr.rep_id) = nvl('" + fReportID - + "', TO_CHAR(cr.rep_id)) AND " + "UPPER(cr.title) LIKE UPPER('%" - + fReportName + "%') AND " + "nvl(cr.owner_id, cr.create_id) = au.user_id " - + "AND cr.rep_id = ra.rep_id (+) ";*/ - - String sql = Globals.getLoadReportSearchResult(); - String rep_id = ""; - String rep_id_options = ""; - String rep_id_sql = " AND FORMAT(cr.rep_id, 0) like coalesce('%%', FORMAT(cr.rep_id, 0)) "; - if(request.getParameter("rep_id")!=null) { - rep_id = request.getParameter("rep_id"); - } - if(request.getParameter("rep_id_options")!=null) { - rep_id_options = request.getParameter("rep_id_options"); - } - - /*Default: AND FORMAT(cr.rep_id, 0) like coalesce('%%', FORMAT(cr.rep_id, 0)) */ - - /*Equal to AND cr.rep_id = 1000 0 */ - /*Less than : AND cr.rep_id < 1000 1 */ - /*Greater than AND cr.rep_id > 1000 2 */ - - - if(AppUtils.nvl(rep_id).length()>0 ) { - if(AppUtils.nvl(rep_id_options).length()>0 ) { - switch (rep_id_options) { - case "0": - rep_id_sql = " AND cr.rep_id = "+ rep_id+" "; - break; - case "1": - rep_id_sql = " AND cr.rep_id < "+ rep_id+" "; - break; - case "2": - rep_id_sql = " AND cr.rep_id > "+ rep_id+" "; - break; - default: - rep_id_sql = " AND FORMAT(cr.rep_id, 0) like coalesce('%%', FORMAT(cr.rep_id, 0)) "; - break; - } - } else { - rep_id_sql = " AND cr.rep_id = "+ rep_id+" "; - } - } else { - rep_id_sql = " AND FORMAT(cr.rep_id, 0) like coalesce('%%', FORMAT(cr.rep_id, 0)) "; //equal is default - } - - sql = sql.replace("[fReportID]", rep_id_sql); - - String rep_name = ""; - String rep_name_options = ""; - String rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%%') "; - if(request.getParameter("rep_name")!=null) { - rep_name = request.getParameter("rep_name"); - } - if(request.getParameter("rep_name_options")!=null) { - rep_name_options = request.getParameter("rep_name_options"); - } - - /* Report name AND UPPER(cr.title) LIKE UPPER('Dash%') 0 */ - - /* Report name AND UPPER(cr.title) LIKE UPPER('%1') 1 */ - /* Report name AND UPPER(cr.title) LIKE UPPER('%1%') 2 */ - - if(AppUtils.nvl(rep_name).length()>0 ) { - if(AppUtils.nvl(rep_name_options).length()>0 ) { - switch (rep_name_options) { - case "0": - rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('"+rep_name+"%') "; - break; - case "1": - rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%"+rep_name+"') "; - break; - case "2": - rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%"+rep_name+"%') "; - break; - default: - rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%%') "; - break; - } - } else { - rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%"+rep_name+"%') "; //contains is default - } - } else { - rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%%') "; - } - sql = sql.replace("[fReportName]", rep_name_sql); - - if (menuId.length() > 0){ - /*sql += "AND INSTR('|'||cr.menu_id||'|', '|'||'" + menuId + "'||'|') > 0 " - * +"AND - * cr.menu_approved_yn = - * 'Y' " - ;*/ - String sql_add = Globals.getLoadReportSearchInstr(); - sql+= sql_add; - } - - //String user_sql = " AND nvl(cr.owner_id, cr.create_id) = " + userID; - String user_sql = Globals.getLoadReportSearchResultUser(); - - //String public_sql = " AND (nvl(cr.owner_id, cr.create_id) = " + userID - // + " OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL)"; - String public_sql = Globals.getLoadReportSearchResultPublic(); - - //String fav_sql = " AND cr.rep_id in (select rep_id from cr_favorite_reports where user_id = " + userID +" ) "; - String fav_sql = Globals.getLoadReportSearchResultFav(); - - if (userOnly) - // My reports - user is owner - sql += " " + user_sql; - else if (publicOnly) { - // Public reports - user has read or write access to the report - // (user is owner or report is public or user has explicit user or - // role access) - if (!AppUtils.isSuperUser(request)) - sql += " " + public_sql; - } else if (favoriteOnly) { - sql += " " + public_sql; - sql += " " + fav_sql; - } else if (!AppUtils.isSuperUser(request)) { - // All reports - // If user is super user - gets unrestricted access to all reports - // (read_only gets overriden later) - // else - not super user - doesn't get access to private reports of - // other users (= Public reports); Admin users get edit right - // override later - //sql += public_sql; - sql += " " + public_sql; - } - - - - if (sortOrder.equals(AppConstants.RI_F_OWNER_ID)){ - //sql += " ORDER BY DECODE(nvl(cr.owner_id, cr.create_id), " + userID - //+ ", ' ', upper(au.first_name||' '||au.last_name)), upper(cr.title)"; - String sql_sort = Globals.getLoadReportSearchResultSort(); - sql+=" " + sql_sort; - } - else if (sortOrder.equals(AppConstants.RI_F_REPORT_ID)) - sql += " ORDER BY cr.rep_id"; - else if(sortOrder.equals(AppConstants.RI_F_REPORT_CREATE_DATE)) - sql += " ORDER BY cr.create_date"; - else if(sortOrder.equals(AppConstants.RI_F_PUBLIC)) - sql += " ORDER BY cr.public_yn desc"; - - else - // if(sortOrder.equals(AppConstants.RI_F_REPORT_NAME)) - sql += " ORDER BY upper(cr.title)"; - - sql = sql.replace("[rep_title_sql]", "cr.title"); - sql = sql.replace("[PRIVATE_ICON]", PRIVATE_ICON); - sql = sql.replace("[userID]", userID); - sql = sql.replace("[roleList.toString()]", roleList.toString()); - - //System.out.println("query is for search list is : " + sql); - DataSet ds = DbUtils.executeQuery(sql); - - ReportSearchResultJSON rsr = new ReportSearchResultJSON(0, 6, 7); - rsr.parseData(ds, request, 0, 20, 6, 7); - //saveCSVPageFile(request, rsr); - //rsr.truncateToPage(pageNo); - //saveCSVPageFile(request, rsr); - - return rsr; - } // loadReportSearchResult - - public ReportSearchResult loadFolderReportResult(HttpServletRequest request) - throws Exception { - String userID = AppUtils.getUserID(request); - String fReportID = nvl(AppUtils.getRequestValue(request, AppConstants.RI_F_REPORT_ID)); - String fReportName = nvl(AppUtils.getRequestValue(request, - AppConstants.RI_F_REPORT_NAME)); - String sortOrder = nvl(AppUtils.getRequestValue(request, AppConstants.RI_SORT_ORDER), - AppConstants.RI_F_REPORT_NAME); - - String menuId = nvl(AppUtils.getRequestValue(request, AppConstants.RI_LIST_CATEGORY)); - - boolean userOnly = AppUtils.getRequestFlag(request, AppConstants.RI_USER_REPORTS); - boolean publicOnly = AppUtils.getRequestFlag(request, AppConstants.RI_PUBLIC_REPORTS); - - int pageNo = 0; - try { - pageNo = Integer.parseInt(request.getParameter(AppConstants.RI_NEXT_PAGE)); - } catch (Exception e) { - } - - StringBuffer roleList = new StringBuffer(); - roleList.append("-1"); - String rep_title_sql = "''"; - for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) - roleList.append("," + ((String) iter.next())); - // - /*String sql = "SELECT cr.rep_id, " - + "cr.rep_id report_id, " - + rep_title_sql+ - "||DECODE(cr.public_yn, 'Y', '', '" - + PRIVATE_ICON - + "')||cr.title||'' title, " - + "cr.descr, " - + "au.first_name||' '||au.last_name owner_name, " - + "TO_CHAR(cr.create_date, 'MM/DD/YYYY') create_date, " - + "DECODE(NVL(cr.owner_id, cr.create_id), " - + userID - + ", 'N', NVL(ra.read_only_yn, 'Y')) read_only_yn, " - + "DECODE(NVL(cr.owner_id, cr.create_id), " - + userID - + ", 'Y', 'N') user_is_owner_yn " - + "FROM cr_report cr, " - + "app_user au, " - + "(SELECT rep_id, " - + "MIN(read_only_yn) read_only_yn " - + "FROM ((SELECT ua.rep_id, ua.read_only_yn FROM cr_report_access ua WHERE ua.user_id = " - + userID - + ") " - + "UNION ALL " - + "(SELECT ra.rep_id, ra.read_only_yn FROM cr_report_access ra WHERE ra.role_id IN (" - + roleList.toString() + "))" + ") report_access " + "GROUP BY rep_id) ra " - + "WHERE TO_CHAR(cr.rep_id) = nvl('" + fReportID - + "', TO_CHAR(cr.rep_id)) AND " + "UPPER(cr.title) LIKE UPPER('%" - + fReportName + "%') AND " + "nvl(cr.owner_id, cr.create_id) = au.user_id " - + "AND cr.rep_id = ra.rep_id (+) ";*/ - - String sql = Globals.getLoadFolderReportResult(); - sql = sql.replace("[rep_title_sql]", rep_title_sql); - sql = sql.replace("[PRIVATE_ICON]", PRIVATE_ICON); - sql = sql.replace("[userID]", userID); - sql = sql.replace("[roleList.toString()]", roleList.toString()); - sql = sql.replace("[fReportID]", fReportID); - sql = sql.replace("[fReportName]", fReportName); - - if (menuId.length() > 0){ - /*sql += "AND INSTR('|'||cr.menu_id||'|', '|'||'" + menuId + "'||'|') > 0 " - * +"AND - * cr.menu_approved_yn = - * 'Y' " - ;*/ - String sql_add = Globals.getLoadReportSearchInstr(); - sql+= sql_add; - } - - //String user_sql = " AND nvl(cr.owner_id, cr.create_id) = " + userID; - String user_sql = Globals.getLoadReportSearchResultUser(); - - //String public_sql = " AND (nvl(cr.owner_id, cr.create_id) = " + userID - // + " OR cr.public_yn = 'Y' OR ra.read_only_yn IS NOT NULL)"; - String public_sql = Globals.getLoadReportSearchResultPublic(); - - if (userOnly) - // My reports - user is owner - sql += user_sql; - else if (publicOnly) - // Public reports - user has read or write access to the report - // (user is owner or report is public or user has explicit user or - // role access) - if (!AppUtils.isSuperUser(request)) - sql += public_sql; - else if (!AppUtils.isSuperUser(request)) { - // All reports - // If user is super user - gets unrestricted access to all reports - // (read_only gets overriden later) - // else - not super user - doesn't get access to private reports of - // other users (= Public reports); Admin users get edit right - // override later - sql += public_sql; - } - - if (sortOrder.equals(AppConstants.RI_F_OWNER_ID)){ - - - //sql += " ORDER BY DECODE(nvl(cr.owner_id, cr.create_id), " + userID - // + ", ' ', au.first_name||' '||au.last_name), cr.title"; - - String sql_sort = Globals.getLoadFolderReportResultSort(); - sql+=sql_sort; - } - else if (sortOrder.equals(AppConstants.RI_F_REPORT_ID)) - sql += " ORDER BY cr.rep_id"; - else if(sortOrder.equals(AppConstants.RI_F_REPORT_CREATE_DATE)) - sql += " ORDER BY cr.create_date"; - else if(sortOrder.equals(AppConstants.RI_F_PUBLIC)) - sql += " ORDER BY cr.public_yn desc"; - else - // if(sortOrder.equals(AppConstants.RI_F_REPORT_NAME)) - sql += " ORDER BY cr.title"; - - //System.out.println("query is for search list is : " + sql); - DataSet ds = DbUtils.executeQuery(sql); - - ReportSearchResult rsr = new ReportSearchResult(-1, 6, 7); - rsr.parseData(ds, request); - saveCSVPageFile(request, rsr); - rsr.truncateToPage(pageNo); - saveCSVPageFile(request, rsr); - - return rsr; - } // loadFolderReportResult - - -} // SearchHandler diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameColLookup.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameColLookup.java deleted file mode 100644 index d7fdc33a..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameColLookup.java +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.base; - -public class IdNameColLookup extends IdNameLookup { - private String colId = null; - - public IdNameColLookup(String colId, String dbTableName, String dbIdField, - String dbNameField, String dbSortByField) { - super(dbTableName, dbIdField, dbNameField, dbSortByField, false); - this.colId = colId; - } // IdNameColLookup - - public String getColId() { - return colId; - } - -} // IdNameColLookup diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameList.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameList.java deleted file mode 100644 index dba3db03..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameList.java +++ /dev/null @@ -1,183 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.base; - -import java.util.Vector; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.system.Globals; - -public class IdNameList extends Vector { - protected int pageNo = -1; - - protected int pageSize = 50; - - private int nextElemIdx = 0; - - private String oldSql = null; - - public IdNameList() { - super(); - pageSize = Globals.getFormFieldsListSize(); - } // IdNameList - - public int getPageNo() { - return pageNo; - } // getPageNo - - public int getPageSize() { - return pageSize; - } // getPageSize - - public int getDataSize() { - return size(); - } // getDataSize - - public void resetNext() { - resetNext(0); - } // resetNext - - public void resetNext(int toPos) { - nextElemIdx = toPos; - } // resetNext - - public boolean hasNext() { - return (nextElemIdx < size()); - } // hasNext - - public IdNameValue getNext() { - return hasNext() ? getValue(nextElemIdx++) : null; - } // getNext - - public int getCount() { - return size(); - } // getCount - - public IdNameValue getValue(int idx) { - return (IdNameValue) get(idx); - } // getValue - - public void addValue(IdNameValue value) { - add(value); - } // addValue - - public void addValue(String id, String name, boolean defaultValue) { - addValue(new IdNameValue(id, name, defaultValue)); - } // addValue - - public void addValue(String id, String name, boolean defaultValue, boolean readOnly) { - addValue(new IdNameValue(id, name, defaultValue, readOnly)); - } // addValue - - public void addValue(String id, String name) { - addValue(new IdNameValue(id, name)); - } // addValue - - public void addValue(int idx, IdNameValue value) { - add(idx, value); - } // addValue - - public void addValue(int idx, String id, String name) { - addValue(idx, new IdNameValue(id, name)); - } // addValue - - public String getNameById(String id) { - for (int i = 0; i < size(); i++) { - IdNameValue value = getValue(i); - if (value.getId().equals(id)) - return value.getName(); - } // for - - return null; - } // getNameById - - public String getIdByName(String name) { - for (int i = 0; i < size(); i++) { - IdNameValue value = getValue(i); - if (value.getName().equals(name)) - return value.getId(); - } // for - - return null; - } // getIdByName - - public boolean canUseSearchString() { - return true; - } - - public String getBaseSQL() { - return null; - } - - public String getOldSql() { - return oldSql; - } - - public void setOldSql(String oldSql) { - this.oldSql = oldSql; - } - public String getBaseWholeSQL() { - return null; - } - - public String getBaseWholeReadonlySQL() { - return null; - } - - public String getBaseSQLForPDFExcel(boolean multiParam) { - return null; - } - - public void clearData() { - } - - public void loadData(String pageNo, String searchString, String dbInfo,String userId) throws RaptorException {} - public void loadUserData(String pageNo, String searchString, String dbInfo,String userId) throws RaptorException {} - public void loadUserData(int pageNo, String searchString, String dbInfo, String userId) throws RaptorException {} - public void loadUserData(String searchString, int pageNo, String dbInfo) throws RaptorException {} - - public void loadData(String pageNo) throws RaptorException {} - public void loadData(int pageNo) throws RaptorException {} - public void loadData(String pageNo, String searchString, String dbInfo) throws RaptorException {} - private void loadData(int pageNo, String searchString, String dbInfo) throws RaptorException {} - -/* - public void loadData(int pageNo, String dbInfo) throws RaptorException { - } - - public void loadUserData(int pageNo, String dbInfo, String userId) throws RaptorException { - } - - - - - public void loadData(String pageNo, String searchString) throws RaptorException { - } - -*/ - protected static String nvl(String s) { - return (s == null) ? "" : s; - } - - protected static String nvl(String s, String sDefault) { - return nvl(s).equals("") ? sDefault : s; - } - -} // IdNameList diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameLookup.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameLookup.java deleted file mode 100644 index e4424f62..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameLookup.java +++ /dev/null @@ -1,198 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.base; - -import org.openecomp.portalsdk.analytics.error.RaptorException; - -public class IdNameLookup extends IdNameSql { - private String dbTableName = null; - - private String dbIdField = null; - - private String dbNameField = null; - - private String dbSortByField = null; - - private String searchString = ""; - - public IdNameLookup(int pageNo, String dbTableName, String dbIdField, String dbNameField) { - this(dbTableName, dbIdField, dbNameField); - - this.pageNo = pageNo; - } // IdNameLookup - - public IdNameLookup(String dbTableName, String dbIdField, String dbNameField) { - this(dbTableName, dbIdField, dbNameField, null, "", false); - } // IdNameLookup - -/* public IdNameLookup(String dbTableName, String dbIdField, String dbNameField, - String dbSortByField) { - super(); - - setDbTableName(dbTableName); - setDbIdField(dbIdField); - setDbNameField(dbNameField); - setDbSortByField(dbSortByField); - updateParentSQL(); - } // IdNameLookup - - public IdNameLookup(String dbTableName, String dbIdField, String dbNameField, - String dbSortByField, String defaultSQL) { - super(); - - setDbTableName(dbTableName); - setDbIdField(dbIdField); - setDbNameField(dbNameField); - setDbSortByField(dbSortByField); - setDefaultSQL(defaultSQL); - updateParentSQL(); - } // IdNameLookup -*/ - public IdNameLookup(String dbTableName, String dbIdField, String dbNameField, - String dbSortByField, boolean textField) { - super(); - setDbTableName(dbTableName); - setDbIdField(dbIdField); - setDbNameField(dbNameField); - setDbSortByField(dbSortByField); - if(!textField) - updateParentSQL(); - } // IdNameLookup - - public IdNameLookup(String dbTableName, String dbIdField, String dbNameField, - String dbSortByField, String defaultSQL, boolean textField) { - super(); - - setDbTableName(dbTableName); - setDbIdField(dbIdField); - setDbNameField(dbNameField); - setDbSortByField(dbSortByField); - setDefaultSQL(defaultSQL); - if(!textField) - updateParentSQL(); - } // IdNameLookup - - public String getDbTableName() { - return dbTableName; - } - - public String getDbIdField() { - return dbIdField; - } - - public String getDbNameField() { - return dbNameField; - } - - public String getDbSortByField() { - return dbSortByField; - } - - public void setDbTableName(String dbTableName) { - this.dbTableName = dbTableName; - } - - public void setDbIdField(String dbIdField) { - this.dbIdField = dbIdField; - } - - public void setDbNameField(String dbNameField) { - this.dbNameField = dbNameField; - } - - - public void setDbSortByField(String dbSortByField) { - this.dbSortByField = dbSortByField; - } - - private void updateParentSQL() { - String sql_start = "SELECT DISTINCT " + dbIdField + " id, " + dbNameField + " name"; - String sql_end = " FROM " + dbTableName + " WHERE " + dbIdField + " IS NOT NULL"; - if (searchString.length() > 0) - sql_end += " AND UPPER(" + dbNameField + ") LIKE UPPER('" + searchString + "')"; - - String sql_middle = ""; - if (dbSortByField != null && (!dbSortByField.equals(dbNameField)) && (!dbSortByField.trim().startsWith("TO_DATE"))) - sql_middle = ", " - + ((dbSortByField.indexOf(' ') > 0) ? dbSortByField.substring(0, - dbSortByField.indexOf(' ')) : dbSortByField) + " sort"; - - setSqlNoOrderBy(sql_start + sql_middle + sql_end); -// System.out.println("SQL Start " + sql_start); -// System.out.println("SQL Middle " + sql_middle); -// System.out.println("SQL End " + sql_end); -// System.out.println("DbSortByField " + dbSortByField); - - setSql(sql_start + sql_middle + sql_end + " ORDER BY " + nvl(dbSortByField, "2")); - } // updateParentSQL - - public boolean canUseSearchString() { - return true; - } - - public String getBaseSQL() { - return "SELECT " + dbIdField + " FROM " + dbTableName; - } // getBaseSQL - - public String getBaseWholeSQL() { - return "SELECT " + dbIdField + " FROM " + dbTableName; - } // getBaseSQL - - /* - public void loadData(int pageNo) throws RaptorException { - loadData(pageNo, ""); - } // loadData - - public void loadData(String pageNo) throws RaptorException { - loadData(pageNo, ""); - } // loadData -*/ - - public void loadData(String pageNo, String searchString, String dbInfo) throws RaptorException { - int iPageNo = 0; - - if (pageNo != null) - try { - iPageNo = Integer.parseInt(pageNo); - } catch (NumberFormatException e) { - } - - loadData(iPageNo, searchString, dbInfo); - } // loadData - - private void loadData(int pageNo, String searchString, String dbInfo) throws RaptorException { - boolean dataAlreadyLoaded = (this.pageNo == pageNo) - && (this.searchString.equals(searchString)); - - if (dataAlreadyLoaded) - return; - - if (!this.searchString.equals(searchString)) { - dataSize = -1; - pageNo = 0; - } // if - - this.pageNo = pageNo; - this.searchString = searchString; - updateParentSQL(); - performLoadData(searchString,dbInfo); - } // loadData - -} // IdNameLookup diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameSql.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameSql.java deleted file mode 100644 index 9928ad80..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameSql.java +++ /dev/null @@ -1,400 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -/* =========================================================================================== - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) - * Raptor : This tool is used to generate different kinds of reports with lot of utilities - * =========================================================================================== - * - * ------------------------------------------------------------------------------------------- - * IdNameSql.java - This class is used to generate form field items when sql is provided. - * ------------------------------------------------------------------------------------------- - * - * Created By : Stan Pishamanov - * Modified By: Sundar Ramalingam - * - * Changes - * ------- - * 08-Jun-2009 : Version 8.3 (RS); Rownum references is avoided for reports connnecting to Daytona - * Database. - * - */ -package org.openecomp.portalsdk.analytics.model.base; - -import java.util.HashMap; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.system.ConnectionUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -public class IdNameSql extends IdNameList { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(IdNameSql.class); - - - protected int dataSize = -1; - - protected int dataSizeUsedInPopup = -1; - - private String sql = null; - - private String oldSql = null; - - private String defaultSQL = null; - - private String sqlNoOrderBy = null; - - public IdNameSql(int pageNo, String sql, String defaultSQL) { - this(sql,defaultSQL); - this.pageNo = pageNo; - } // IdNameSql - - public IdNameSql(String sql) { - this(); - setSql(sql); - } // IdNameSql - - public IdNameSql(String sql, String defaultSQL) { - this(); - setDefaultSQL(defaultSQL); - setSql(sql); - } // IdNameSql - - protected IdNameSql() { - super(); - } // IdNameSql - - public boolean canUseSearchString() { - return true; - } - - public String getSql() { - return sql; - } - - public String getOldSql() { - return oldSql; - } - - public String getBaseSQL() { - return "SELECT id FROM (" + sql + ") xid"; - } - - public String getBaseWholeSQL() { - return "SELECT id, name FROM (" + sql + ") xid"; - } - - public String getBaseWholeReadonlySQL() { - return "SELECT id, name, ff_readonly FROM (" + sql + ") xid"; - } - - public String getBaseSQLForPDFExcel(boolean multiParam) { - if(!multiParam) - return "SELECT id, name FROM (" + sql + ") xid where id = '[VALUE]'"; - else - return "SELECT id, name FROM (" + sql + ") xid where id in [VALUE]"; - - } - - // public String getSqlNoOrderBy() { return sqlNoOrderBy; } - - protected void setSql(String sql) { - this.sql = sql; - } - - public void setOldSql(String oldSql) { - this.oldSql = oldSql; - } - - protected void setSqlNoOrderBy(String sql) { - this.sqlNoOrderBy = sql; - } - - public int getDataSize() { - return dataSize; - } // getDataSize - - public int getDataSizeUsedinPopup() { - return dataSizeUsedInPopup; - } // getDataSizeUsedinPopup - - public void setDataSizeUsedinPopup(int dataSizePop) { - this.dataSizeUsedInPopup = dataSizePop; - } // getDataSizeUsedinPopup - - public void clearData() { - removeAllElements(); - } // clearData - -/* public void loadData(String pageNo, String searchString, String dbInfo, String userId) throws RaptorException { - // setSql(searchString); - loadUserData(pageNo, searchString, dbInfo,userId); - } // loadData -*/ - - public void loadUserData(String pageNo, String searchString, String dbInfo,String userId) throws RaptorException { - int iPageNo = 0; - - if (pageNo != null) - try { - iPageNo = Integer.parseInt(pageNo); - } catch (NumberFormatException e) { - } - - loadUserData(iPageNo, searchString, dbInfo,userId); - } // loadData - - public void loadUserData(int pageNo, String searchString, String dbInfo, String userId) throws RaptorException { - if(userId!=null) { - String sql = Utils.replaceInString(getSql(), "[LOGGED_USERID]", userId); - //String defaultSQL = ""; - if(defaultSQL!=null && (defaultSQL.trim().toLowerCase().startsWith("select")) ) { - defaultSQL = Utils.replaceInString(getDefaultSQL(), "[LOGGED_USERID]", userId); - setDefaultSQL(defaultSQL); - } - setSql(sql); - - } - loadData(searchString,pageNo, dbInfo); - } - - public void loadData(String searchString, int pageNo, String dbInfo) throws RaptorException { - - //boolean dataAlreadyLoaded = (this.pageNo == pageNo); - - //if (dataAlreadyLoaded) - // return; - - this.pageNo = pageNo; - - performLoadData(searchString, dbInfo); - } // loadData - - protected void performLoadData(String searchString, String dbInfo) throws RaptorException { - long currentTime = System.currentTimeMillis(); - int startRow = 0; - int endRow = dataSize; - String readOnlyInSql = "ff_readonly"; - String dbType = Globals.getDBType(); - if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { - try { - org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); - dbType = remDbInfo.getDBType(dbInfo); - } catch (Exception ex) { - throw new RaptorException(ex); - } - } - if (pageNo >= 0) { - startRow = pageNo * pageSize; - endRow = startRow + pageSize; - } // if - DataSet ds = null; - DataSet dsDefault = null; - StringBuffer query = new StringBuffer(""); - StringBuffer queryPop = new StringBuffer(""); - String sql = getSql(); - boolean avail_ReadOnly = (sql.toLowerCase().indexOf(readOnlyInSql)!=-1); - - if (dbType.equals("DAYTONA") && getSql().trim().toUpperCase().startsWith("SELECT")) { - query.append(getSql()); - } else { - if(avail_ReadOnly) // need to add readonlyinsql - if(!(Globals.isMySQL() && dbType.equals(AppConstants.MYSQL))) - query.append("SELECT rownum, id, name, " + readOnlyInSql +" FROM ("+ Globals.getReportSqlForFormfield() +", " + readOnlyInSql + " FROM (" + sql - + ") x "+ Globals.getReportSqlForFormfieldSuffix()); - else - query.append("SELECT id, name, " + readOnlyInSql +" FROM ("+ Globals.getReportSqlForFormfield() +", " + readOnlyInSql + " FROM (" + sql - + ") x "+ Globals.getReportSqlForFormfieldSuffix()); - else - query.append(Globals.getReportSqlForFormfieldPrefix()+ Globals.getReportSqlForFormfield() +" FROM (" + sql - + ") x " + Globals.getReportSqlForFormfieldSuffix()); - if(pageNo!= -2 && (dbType.equals(AppConstants.ORACLE)) ) { - query.append(" WHERE rownum <= " + ((dataSize < 0) ? (endRow + 1) : endRow)); - } else if(pageNo!=2 && (dbType.equals(AppConstants.POSTGRESQL))) { - query.append(" LIMIT " + ((dataSize < 0) ? (endRow + 1) : endRow)); - - } else if(pageNo!=2 && (dbType.equals(AppConstants.MYSQL))) { - query.append(" LIMIT " + startRow); //((dataSize < 0) ? (endRow + 1) : endRow) - - } - if(searchString!=null && searchString.length()>0 && !searchString.equals("%")) { - if(pageNo == -2) query.append(" WHERE "); - else query.append(" and "); - query.append("name like '"+ searchString +"'"); - } - if(dbType.equals(AppConstants.POSTGRESQL)) { - query.append(") xx OFFSET " + startRow); - } else if(dbType.equals(AppConstants.MYSQL)) { - query.append(" ," + ((dataSize < 0) ? (endRow + 1) : endRow) +") xx"); - } else if(dbType.equals(AppConstants.ORACLE)) - query.append(") xx WHERE rownum>" + startRow); - } - String defaultQuery =""; - boolean readOnly = true; - ds = ConnectionUtils.getDataSet(query.toString(), dbInfo); - - // if ( (dbInfo!=null) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { - // Globals.getRDbUtils().setDBPrefix(dbInfo); - // ds = RemDbUtils.executeQuery(query); - // } - // else - // ds = DbUtils.executeQuery(query); - clearData(); - if (dbType.equals("DAYTONA") && (getDefaultSQL()!=null && getDefaultSQL().trim().toUpperCase().startsWith("SELECT"))) { - defaultQuery = getDefaultSQL(); - } else if (getDefaultSQL()!=null && getDefaultSQL().length()>10 && getDefaultSQL().substring(0,10).toLowerCase().startsWith("select")) { - defaultQuery = Globals.getReportSqlForFormfieldPrefix()+ Globals.getReportSqlForFormfield() +" FROM (" + getDefaultSQL() - + ") x " - + ") xx "; - logger.debug(EELFLoggerDelegate.debugLogger, ("Default Query " +defaultQuery)); - } - HashMap defaultMap = new HashMap(); - if(!isNull(defaultQuery)) { - dsDefault = ConnectionUtils.getDataSet(defaultQuery, dbInfo); - if(dsDefault!=null && dsDefault.getRowCount()>0) { - for (int i = 0; i < dsDefault.getRowCount(); i++) { - //addValue(dsDefault.getString(i, 0), dsDefault.getString(i, 1), true); - defaultMap.put(dsDefault.getString(i, "id"), dsDefault.getString(i, "name")); - } - } - } - - for (int i = 0; i < ((pageNo!=-2)?Math.min(ds.getRowCount(), pageSize):ds.getRowCount()); i++) { - //if(getCount()==0) - // addValue(ds.getString(i, 0), ds.getString(i, 1)); - if(i==0 && avail_ReadOnly) - readOnly = ds.getString(i, "ff_readonly").toUpperCase().startsWith("Y")||ds.getString(i, "ff_readonly").toUpperCase().startsWith("T"); - if(getCount()>=0) {//&& !((IdNameValue)getValue(0)).getId().equals(ds.getString(i, 0))) - if(defaultMap.get(ds.getString(i, "id")) == null) - if(avail_ReadOnly) - addValue(ds.getString(i, "id"), ds.getString(i, "name"), false, readOnly); - else - addValue(ds.getString(i, "id"), ds.getString(i, "name"), false); - else - if(avail_ReadOnly) - addValue(ds.getString(i, "id"), ds.getString(i, "name"), true, readOnly); - else - addValue(ds.getString(i, "id"), ds.getString(i, "name"), true); - } - } - - if (!(dbType.equals("DAYTONA"))) { - if (ds.getRowCount() <= pageSize) { - if(dsDefault!=null && dsDefault.getRowCount()>0) - dataSize = ds.getRowCount()+1; - else - dataSize = ds.getRowCount(); - - //System.out.println("IDNAME SQL COUNT");*/ - if(searchString!=null && searchString.length()>0 && !searchString.equals("%")) { - queryPop = new StringBuffer(""); - queryPop.append("SELECT count(*) num_rows FROM ("+ Globals.getReportSqlForFormfield() +", name FROM (" + sql - + ") x "); - if(searchString!=null && searchString.length()>0 && !searchString.equals("%")) - queryPop.append(" where name like '"+ searchString +"'"); - queryPop.append(") xx "); - - ds = ConnectionUtils.getDataSet(queryPop.toString(), dbInfo); - try { - dataSizeUsedInPopup = Integer.parseInt(ds.getString(0, 0)); - } catch (NumberFormatException e) { - } - } else if(dataSizeUsedInPopup == -3) { - queryPop = new StringBuffer(""); - //System.out.println("IDNAME SQL COUNT"); - //queryPop.append("SELECT count(*) num_rows FROM ("+query.toString()+") x"); - queryPop.append("SELECT count(*) num_rows FROM ("+ Globals.getReportSqlForFormfield() +", name FROM (" + sql - + ") x "); - queryPop.append(") xx "); - - ds = ConnectionUtils.getDataSet(queryPop.toString(), dbInfo); - // if ( (dbInfo!=null) && - // (!dbInfo.equals(AppConstants.DB_LOCAL))) { - // Globals.getRDbUtils().setDBPrefix(dbInfo); - // ds = RemDbUtils.executeQuery(query); - // } - // else - // ds = DbUtils.executeQuery(query); - // - try { - dataSizeUsedInPopup = Integer.parseInt(ds.getString(0, 0)); - } catch (NumberFormatException e) { - } - - } - - } else { - //pageNo = 0; - if(pageNo!= -2) { - queryPop = new StringBuffer(""); - //System.out.println("IDNAME SQL COUNT"); - //queryPop.append("SELECT count(*) num_rows FROM ("+query.toString()+") x"); - queryPop.append("SELECT count(*) num_rows FROM ("+ Globals.getReportSqlForFormfield() +" FROM (" + sql - + ") x "); - queryPop.append(") xx "); - - ds = ConnectionUtils.getDataSet(queryPop.toString(), dbInfo); - // if ( (dbInfo!=null) && - // (!dbInfo.equals(AppConstants.DB_LOCAL))) { - // Globals.getRDbUtils().setDBPrefix(dbInfo); - // ds = RemDbUtils.executeQuery(query); - // } - // else - // ds = DbUtils.executeQuery(query); - // - try { - dataSize = Integer.parseInt(ds.getString(0, 0)); - dataSizeUsedInPopup = Integer.parseInt(ds.getString(0, 0)); - } catch (NumberFormatException e) { - } - } - } // else - } // dataSize < 0 - long totalTime = System.currentTimeMillis() - currentTime; - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] ------->Time Taken to the above formfield Query (+ count Query if any) --- " + totalTime)); - } // performLoadData - - - public String getDefaultSQL() { - - return defaultSQL; - } - - - public void setDefaultSQL(String defaultSQL) { - - this.defaultSQL = defaultSQL; - } - - public void setSQL(String sql_) - { - this.sql = sql_; - } - - public static boolean isNull(String a) { - if ((a == null) || (a.length() == 0) || a.equalsIgnoreCase("null")) - return true; - else - return false; - } -} // IdNameSql diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameValue.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameValue.java deleted file mode 100644 index 5ac81f7b..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/IdNameValue.java +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.base; - -public class IdNameValue { - private String id = null; - - private String name = null; - - private boolean defaultValue = false; - - private boolean readOnly = false; - - public IdNameValue() { - super(); - } - - public IdNameValue(String id, String name) { - this(); - - setId(id); - setName(name); - setDefaultValue(false); - - } // IdNameValue - - public IdNameValue(String id, String name, boolean defaultValue) { - this(); - - setId(id); - setName(name); - setDefaultValue(defaultValue); - } // IdNameValue - - public IdNameValue(String id, String name, boolean defaultValue, boolean readOnly) { - this(); - - setId(id); - setName(name); - setDefaultValue(defaultValue); - setReadOnly(readOnly); - } // IdNameValue - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public void setId(String id) { - this.id = id; - } - - public void setName(String name) { - this.name = name; - } - - public boolean isDefaultValue() { - return defaultValue; - } - - public void setDefaultValue(boolean defaultValue) { - this.defaultValue = defaultValue; - } - - /** - * @return the visibility - */ - public boolean isReadOnly() { - return readOnly; - } - - /** - * @param visibility the visibility to set - */ - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - - -} // IdNameValue diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/NameComparator.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/NameComparator.java deleted file mode 100644 index 8a6f2a9e..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/NameComparator.java +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.base; - -import java.util.Comparator; - -public class NameComparator implements Comparator { - - public int compare(Object o1, Object o2) { - return ((IdNameValue) o1).getName() - .compareToIgnoreCase((((IdNameValue) o2).getName())); - } // compare - -} // NameComparator - diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportSecurity.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportSecurity.java deleted file mode 100644 index f281ac4d..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportSecurity.java +++ /dev/null @@ -1,407 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.base; - -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Vector; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.UserAccessException; -import org.openecomp.portalsdk.analytics.model.definition.SecurityEntry; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.DbUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -public class ReportSecurity extends org.openecomp.portalsdk.analytics.RaptorObject { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ReportSecurity.class); - - - private String reportID = null; - - private String ownerID = null; - - private String createID = null; - - private String createDate = null; - - private String updateID = null; - - private String updateDate = null; - - private boolean isPublic = false; - - private Hashtable reportRoles = new Hashtable(); - - private Hashtable reportUsers = new Hashtable(); - - public ReportSecurity(String reportID) { - this(reportID, null, null, null, null, null, false); - } // ReportSecurity - - public ReportSecurity(String reportID, String ownerID, String createID, String createDate, - String updateID, String updateDate, boolean isPublic) { - super(); - - if (ownerID == null) - // Need to load the report record from the database - if (!reportID.equals("-1")) - try { - /*DataSet ds = DbUtils - .executeQuery("SELECT NVL(cr.owner_id, cr.create_id) owner_id, cr.create_id, TO_CHAR(cr.create_date, '" - + Globals.getOracleTimeFormat() - + "') create_date, maint_id, TO_CHAR(cr.maint_date, '" - + Globals.getOracleTimeFormat() - + "') update_date, cr.public_yn FROM cr_report cr WHERE cr.rep_id=" - + reportID);*/ - String sql = Globals.getReportSecurity(); - sql = sql.replace("[rw.getReportID()]", reportID); - DataSet ds = DbUtils.executeQuery(sql); - ownerID = ds.getString(0, 0); - createID = ds.getString(0, 1); - createDate = ds.getString(0, 2); - updateID = ds.getString(0, 3); - updateDate = ds.getString(0, 4); - isPublic = nvl(ds.getString(0, 5)).equals("Y"); - } catch (Exception e) { - String eMsg = "ReportSecurity.ReportSecurity: Unable to load report record details. Exception: " - + e.getMessage(); - //Log.write(eMsg); - logger.debug(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] "+eMsg)); - throw new RuntimeException(eMsg); - } - - this.reportID = reportID; - this.ownerID = ownerID; - this.createID = createID; - this.createDate = createDate; - this.updateID = updateID; - this.updateDate = updateDate; - this.isPublic = isPublic; - - /* - * reportUsers.put(ownerID, "N"); // Owner has full access - * reportRoles.put(AppUtils.getSuperRoleID(), "N"); // Super role has - * full access for(Iterator iter=AppUtils.getAdminRoleIDs().iterator(); - * iter.hasNext(); ) reportRoles.put((String) iter.next(), "Y"); // - * Admin role(s) have read-only access - */ - try { - String reportUserAccessSql= Globals.getReportUserAccess(); - reportUserAccessSql = reportUserAccessSql.replace("[reportID]", reportID); - - DataSet ds = DbUtils - .executeQuery(reportUserAccessSql); - for (int i = 0; i < ds.getRowCount(); i++) { - String roleID = nvl(ds.getString(i, 0)); - if (roleID.length() > 0) - reportRoles.put(roleID, ds.getString(i, 2)); - - String userID = nvl(ds.getString(i, 1)); - if (userID.length() > 0) - reportUsers.put(userID, ds.getString(i, 2)); - } // for - } catch (Exception e) { - String eMsg = "ReportSecurity.ReportSecurity: Unable to load access priviledges - error " - + e.getMessage(); - logger.error(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] " + eMsg)); - throw new RuntimeException(eMsg); - } - } // ReportSecurity - - public String getOwnerID() { - return ownerID; - } - - public String getCreateID() { - return createID; - } - - public String getCreateDate() { - return createDate; - } - - public String getUpdateID() { - return updateID; - } - - public String getUpdateDate() { - return updateDate; - } - - public void setOwnerID(String ownerID) { - this.ownerID = ownerID; - } - - public void setPublic(boolean isPublic) { - this.isPublic = isPublic; - } - - public void reportCreate(String reportID, String userID, boolean isPublic) { - this.reportID = reportID; - this.ownerID = userID; - this.createID = userID; - this.createDate = Utils.getCurrentDateTime(); - this.updateID = userID; - this.updateDate = this.createDate; - this.isPublic = isPublic; - } // reportCreate - - public void reportUpdate(HttpServletRequest request) throws RaptorException { - checkUserWriteAccess(request); - String userID = AppUtils.getUserID(request); - this.updateID = userID; - this.updateDate = Utils.getCurrentDateTime(); - } // reportUpdate - - /** ************************************************************* */ - - public Vector getReportUsers(HttpServletRequest request) throws RaptorException { - HttpSession session = request.getSession(); - String query = Globals.getCustomizedScheduleQueryForUsers(); - String[] sessionParameters = Globals.getSessionParams().split(","); - session.setAttribute("login_id", AppUtils.getUserBackdoorLoginId(request)); - String param = ""; - for (int i = 0; i < sessionParameters.length; i++) { - param = (String)session.getAttribute(sessionParameters[0]); - query = Utils.replaceInString(query, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); - } - boolean isAdmin = AppUtils.isAdminUser(request); - Vector allUsers = AppUtils.getAllUsers(query,param, isAdmin); - Vector rUsers = new Vector(allUsers.size()); - - for (Iterator iter = allUsers.iterator(); iter.hasNext();) { - IdNameValue user = (IdNameValue) iter.next(); - String readOnlyAccess = (String) reportUsers.get(user.getId()); - if (readOnlyAccess != null) - rUsers.add(new SecurityEntry(user.getId(), user.getName(), readOnlyAccess - .equals("Y"))); - } // for - - return rUsers; - } // getReportUsers - - public Vector getReportRoles(HttpServletRequest request) throws RaptorException { - HttpSession session = request.getSession(); - String query = Globals.getCustomizedScheduleQueryForRoles(); - String[] sessionParameters = Globals.getSessionParams().split(","); - String param = ""; - for (int i = 0; i < sessionParameters.length; i++) { - param = (String)session.getAttribute(sessionParameters[0]); - query = Utils.replaceInString(query, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); - - } - boolean isAdmin = AppUtils.isAdminUser(request); - Vector allRoles = AppUtils.getAllRoles(query, param, isAdmin); - Vector rRoles = new Vector(allRoles.size()); - - for (Iterator iter = allRoles.iterator(); iter.hasNext();) { - IdNameValue role = (IdNameValue) iter.next(); - String readOnlyAccess = (String) reportRoles.get(role.getId()); - if (readOnlyAccess != null) - rRoles.add(new SecurityEntry(role.getId(), role.getName(), readOnlyAccess - .equals("Y"))); - } // for - - return rRoles; - } // getReportRoles - - /** ************************************************************* */ - - private void validateReadOnlyAccess(String readOnlyAccess) throws Exception { - if (!(readOnlyAccess != null && (readOnlyAccess.equals("Y") || readOnlyAccess - .equals("N")))) - throw new RuntimeException( - "[ReportSecurity.validateReadOnlyAccess] Invalid parameter value"); - } // validateReadOnlyAccess - - public void addUserAccess(String userID, String readOnlyAccess) throws Exception { - validateReadOnlyAccess(readOnlyAccess); - reportUsers.put(userID, readOnlyAccess); - String addUserAccessSql= Globals.getAddUserAccess(); - addUserAccessSql = addUserAccessSql.replace("[reportID]", reportID); - addUserAccessSql = addUserAccessSql.replace("[userID]", userID); - addUserAccessSql = addUserAccessSql.replace("[readOnlyAccess]", readOnlyAccess); - DbUtils - .executeUpdate(addUserAccessSql); - } // addUserAccess - - public void updateUserAccess(String userID, String readOnlyAccess) throws Exception { - validateReadOnlyAccess(readOnlyAccess); - reportUsers.remove(userID); - reportUsers.put(userID, readOnlyAccess); - String updateUserAccessSql= Globals.getUpdateUserAccess(); - updateUserAccessSql = updateUserAccessSql.replace("[reportID]", reportID); - updateUserAccessSql = updateUserAccessSql.replace("[userID]", userID); - updateUserAccessSql = updateUserAccessSql.replace("[readOnlyAccess]", readOnlyAccess); - DbUtils.executeUpdate(updateUserAccessSql); - } // updateUserAccess - - public void removeUserAccess(String userID) throws Exception { - reportUsers.remove(userID); - - String removeUserAccessSql= Globals.getRemoveUserAccess(); - removeUserAccessSql = removeUserAccessSql.replace("[reportID]", reportID); - removeUserAccessSql = removeUserAccessSql.replace("[userID]", userID); - DbUtils.executeUpdate(removeUserAccessSql); - } // removeUserAccess - - public void addRoleAccess(String roleID, String readOnlyAccess) throws Exception { - validateReadOnlyAccess(readOnlyAccess); - reportRoles.put(roleID, readOnlyAccess); - String addRoleAccessSql= Globals.getAddRoleAccess(); - addRoleAccessSql = addRoleAccessSql.replace("[reportID]", reportID); - addRoleAccessSql = addRoleAccessSql.replace("[roleID]", roleID); - addRoleAccessSql = addRoleAccessSql.replace("[readOnlyAccess]", readOnlyAccess); - DbUtils - .executeUpdate(addRoleAccessSql); - } // addRoleAccess - - public void updateRoleAccess(String roleID, String readOnlyAccess) throws Exception { - validateReadOnlyAccess(readOnlyAccess); - reportRoles.remove(roleID); - reportRoles.put(roleID, readOnlyAccess); - String updateRoleAccessSql= Globals.getUpdateRoleAccess(); - updateRoleAccessSql = updateRoleAccessSql.replace("[reportID]", reportID); - updateRoleAccessSql = updateRoleAccessSql.replace("[roleID]", roleID); - updateRoleAccessSql = updateRoleAccessSql.replace("[readOnlyAccess]", readOnlyAccess); - DbUtils.executeUpdate(updateRoleAccessSql); - } // updateRoleAccess - - public void removeRoleAccess(String roleID) throws Exception { - reportRoles.remove(roleID); - String removeRoleAccessSql= Globals.getRemoveRoleAccess(); - removeRoleAccessSql = removeRoleAccessSql.replace("[reportID]", reportID); - removeRoleAccessSql = removeRoleAccessSql.replace("[roleID]", roleID); - DbUtils.executeUpdate(removeRoleAccessSql); - } // removeRoleAccess - - /** ************************************************************* */ - - public void checkUserReadAccess(HttpServletRequest request, String userID) throws RaptorException { - if(userID == null) - userID = AppUtils.getUserID(request); - if(userID != null) { - //userID = AppUtils.getUserID(request); - if (nvl(reportID).equals("-1")) - return; - - if (true) //todo: replace with proper check isPublic - return; - - if (userID.equals(ownerID)) - return; - - if (reportUsers.get(userID) != null) - return; - } - Vector userRoles = null; - String userName = null; - if(userID == null) { - userRoles = AppUtils.getUserRoles(request); - userName = AppUtils.getUserName(request); - userID = AppUtils.getUserID(request); - } else { - userRoles = AppUtils.getUserRoles(userID); - userName = AppUtils.getUserName(userID); - } - if (nvl(reportID).equals("-1")) - return; - - if (isPublic) - return; - - if (userID.equals(ownerID)) - return; - - if (reportUsers.get(userID) != null) - return; - - for (Iterator iter = userRoles.iterator(); iter.hasNext();) { - String userRole = (String) iter.next(); - if (nvl(userRole).equals(AppUtils.getSuperRoleID())) - return; - } - for (Iterator iter = userRoles.iterator(); iter.hasNext();) { - String userRole = (String) iter.next(); - - if (nvl(userRole).equals(AppUtils.getSuperRoleID())) - return; - - if (reportRoles.get(userRole) != null) - return; - - for (Iterator iterA = AppUtils.getAdminRoleIDs().iterator(); iterA.hasNext();) - if (nvl(userRole).equals((String) iterA.next())) - return; - } // for - - throw new UserAccessException(reportID, "[" + userID + "] " - + userName, AppConstants.UA_READ); - } // checkUserReadAccess - - public void checkUserWriteAccess(HttpServletRequest request) throws RaptorException { - String userID = AppUtils.getUserID(request); - if (nvl(reportID).equals("-1")) - return; - - if (userID.equals(ownerID)) - return; - - if (nvl((String) reportUsers.get(userID)).equals("N")) - return; - - for (Iterator iter = AppUtils.getUserRoles(request).iterator(); iter.hasNext();) { - String userRole = (String) iter.next(); - - if (nvl(userRole).equals(AppUtils.getSuperRoleID())) - return; - - if (nvl((String) reportRoles.get(userRole)).equals("N")) - return; - - for (Iterator iterA = AppUtils.getAdminRoleIDs().iterator(); iterA.hasNext();) - if (nvl(userRole).equals((String) iterA.next())) - return; - } // for - - throw new UserAccessException(reportID, "[" + userID + "] " - + AppUtils.getUserName(request), AppConstants.UA_WRITE); - } // checkUserWriteAccess - - public void checkUserDeleteAccess(HttpServletRequest request) throws RaptorException { - String userID = AppUtils.getUserID(request); - if (Globals.getDeleteOnlyByOwner()) { - if (!userID.equals(ownerID)) - throw new UserAccessException(reportID, "[" + userID + "] " - + AppUtils.getUserName(request), AppConstants.UA_DELETE); - } else - checkUserWriteAccess(request); - } // checkUserDeleteAccess - -} // ReportSecurity diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportWrapper.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportWrapper.java deleted file mode 100644 index f856318d..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/base/ReportWrapper.java +++ /dev/null @@ -1,5719 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.base; - -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.TreeSet; -import java.util.Vector; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.transform.stream.StreamResult; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.RaptorRuntimeException; -import org.openecomp.portalsdk.analytics.error.UserDefinedException; -import org.openecomp.portalsdk.analytics.model.DataCache; -import org.openecomp.portalsdk.analytics.model.ReportLoader; -import org.openecomp.portalsdk.analytics.model.definition.TableSource; -import org.openecomp.portalsdk.analytics.model.runtime.FormField; -import org.openecomp.portalsdk.analytics.model.runtime.ReportParamValues; -import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.ConnectionUtils; -import org.openecomp.portalsdk.analytics.system.DbUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.SQLCorrector; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.analytics.xmlobj.ChartAdditionalOptions; -import org.openecomp.portalsdk.analytics.xmlobj.ChartDrillFormfield; -import org.openecomp.portalsdk.analytics.xmlobj.ChartDrillOptions; -import org.openecomp.portalsdk.analytics.xmlobj.ColFilterList; -import org.openecomp.portalsdk.analytics.xmlobj.ColFilterType; -import org.openecomp.portalsdk.analytics.xmlobj.CustomReportType; -import org.openecomp.portalsdk.analytics.xmlobj.DashboardEditorList; -import org.openecomp.portalsdk.analytics.xmlobj.DashboardReports; -import org.openecomp.portalsdk.analytics.xmlobj.DashboardReportsNew; -import org.openecomp.portalsdk.analytics.xmlobj.DataColumnList; -import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; -import org.openecomp.portalsdk.analytics.xmlobj.DataSourceList; -import org.openecomp.portalsdk.analytics.xmlobj.DataSourceType; -import org.openecomp.portalsdk.analytics.xmlobj.DataminingOptions; -import org.openecomp.portalsdk.analytics.xmlobj.FormFieldList; -import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; -import org.openecomp.portalsdk.analytics.xmlobj.FormatList; -import org.openecomp.portalsdk.analytics.xmlobj.FormatType; -import org.openecomp.portalsdk.analytics.xmlobj.JavascriptItemType; -import org.openecomp.portalsdk.analytics.xmlobj.JavascriptList; -import org.openecomp.portalsdk.analytics.xmlobj.Marker; -import org.openecomp.portalsdk.analytics.xmlobj.ObjectFactory; -import org.openecomp.portalsdk.analytics.xmlobj.PDFAdditionalOptions; -import org.openecomp.portalsdk.analytics.xmlobj.PredefinedValueList; -import org.openecomp.portalsdk.analytics.xmlobj.ReportMap; -import org.openecomp.portalsdk.analytics.xmlobj.Reports; -import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreList; -import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreType; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -/**
        - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting)
        - *
        - * - * --------------------------------------------------------------------------------------------------
        - * ReportWrapper.java - This is the base class for the RAPTOR. This involves in creating,
        - * modifying, running RAPTOR reports.
        - * --------------------------------------------------------------------------------------------------
        - * - * - * Change Log

        - * - * 31-Aug-2009 : Version 8.5.1 (Sundar);
        • All the elements in the meta xml is copied to the target reports.
        - * 18-Aug-2009 : Version 8.5.1 (Sundar);
        • request Object is passed to prevent caching user/roles - Datamining/Hosting.
        - * 27-Jul-2009 : Version 8.4 (Sundar);
        • verifySQLBasedReportAccess method checks for Admin user instead of super user.
        - * 09-Jul-2009 : Version 8.4 (Sundar);
        • Bug due to parsing and removing formfields from "and" is bulletproofed to the right "and" to which the formfield is associated.
        - * 08-Jul-2009 : Version 8.4 (Sundar);
        • Bug due to parsing and removing formfields when there is no parameter for Daytona specific database is resolved.
        - * 29-Jun-2009 : Version 8.4 (Sundar);
        • isLastSeriesALineChart() and setLastSeriesALineChart(String value) method have been added for the Bar Chart enhancements.
        - * 23-Jun-2009 : Version 8.4 (Sundar);
        • check for cr.getChartAdditionalOptions() for null value is added.
        - * 22-Jun-2009 : Version 8.4 (Sundar);
        • Wrapper functions to call JAXB were added. These Wrapper - * functions are related to the Pareto chart, Time Difference Chart, Multiple Pie Chart and generic Chart Options.
        - * - */ - -public class ReportWrapper extends org.openecomp.portalsdk.analytics.RaptorObject { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ReportWrapper.class); - - - protected CustomReportType cr = null; - - protected Vector allColumns = null; - - protected Vector allVisibleColumns = null; - - protected Vector allFilters = null; - - protected String generatedSQL = null; - - protected String generatedChartSQL = null; - - protected String wholeSQL = null; // For display purposes only - - - protected String reportID = null; - - protected String menuID = ""; - - protected boolean menuApproved = false; - - protected String reportDefType = ""; - - protected ReportSecurity reportSecurity = null; - - protected String reportSQLWithRowNum = null; - - protected String reportSQLOnlyFirstPart = null; - - - private ReportWrapper(CustomReportType cr, String reportID, ReportSecurity reportSecurity) { - super(); - - if (reportID == null) - reportID = "-1"; - - this.cr = cr; - this.reportID = reportID; - - this.reportSecurity = reportSecurity; - } // ReportWrapper - - public ReportWrapper(ReportWrapper rw) { - this(rw.getCustomReport(), // .cloneCustomReport() - rw.getReportID(), rw.reportSecurity); - - this.menuID = rw.getMenuID(); - this.menuApproved = rw.isMenuApproved(); - - this.reportDefType = rw.getReportDefType(); - } // ReportWrapper - - public ReportWrapper(CustomReportType cr, String reportID, String ownerID, String createID, - String createDate, String updateID, String updateDate, String menuID, - boolean menuApproved) throws RaptorException { - this(cr, reportID, null); - - if (ownerID == null) - // Need to load the report record from the database - if (!reportID.equals("-1")) - try { - /*DataSet ds = DbUtils - .executeQuery("SELECT NVL(cr.owner_id, cr.create_id) owner_id, cr.create_id, TO_CHAR(cr.create_date, '" - + Globals.getOracleTimeFormat() - + "') create_date, maint_id, TO_CHAR(cr.maint_date, '" - + Globals.getOracleTimeFormat() - + "') update_date, cr.menu_id, cr.menu_approved_yn FROM cr_report cr WHERE cr.rep_id=" - + reportID);*/ - - String r_sql = Globals.getReportWrapperFormat(); - r_sql = r_sql.replace("[Globals.getOracleTimeFormat()]", Globals.getOracleTimeFormat()); - r_sql = r_sql.replace("[reportID]", reportID); - - DataSet ds = DbUtils - .executeQuery(r_sql); - - ownerID = ds.getString(0, 0); - createID = ds.getString(0, 1); - createDate = ds.getString(0, 2); - updateID = ds.getString(0, 3); - updateDate = ds.getString(0, 4); - menuID = nvl(ds.getString(0, 5)); - menuApproved = nvl(ds.getString(0, 6)).equals("Y"); - } catch (Exception e) { - String eMsg = "ReportWrapper.ReportWrapper: Unable to load report record details. Exception: " - + e.getMessage(); - //Log.write(eMsg); - logger.error(EELFLoggerDelegate.debugLogger, ("[EXCEPTION ENCOUNTERED IN RAPTOR] "+ eMsg)); - throw new RaptorRuntimeException(eMsg); - } - - this.menuID = nvl(menuID); - this.menuApproved = menuApproved; - - if (!reportID.equals("-1")) - updateReportDefType(); - - reportSecurity = new ReportSecurity(reportID, ownerID, createID, createDate, updateID, - updateDate, cr.isPublic()); - } // ReportWrapper - - public CustomReportType getCustomReport() { - return cr; - } - - public String getReportID() { - return reportID; - } - - public String getMenuID() { - return menuID; - } - - public boolean checkMenuIDSelected(String chkMenuID) { - return ("|" + menuID + "|").indexOf("|" + chkMenuID + "|") >= 0; - } - - public boolean isMenuApproved() { - return menuApproved; - } - - public String getReportDefType() { - return reportDefType; - } - - public void setMenuID(String menuID) { - this.menuID = menuID; - } - - public void setMenuApproved(boolean menuApproved) { - this.menuApproved = menuApproved; - } - - public void setReportDefType(String reportDefType) { - this.reportDefType = reportDefType; - } - - public void updateReportDefType() { - this.reportDefType = (nvl(cr.getReportSQL()).length() > 0) ? ((cr.getDataminingOptions()!=null && nvl(cr.getDataminingOptions().getClassifier()).length()>0) ? - AppConstants.RD_SQL_BASED_DATAMIN:AppConstants.RD_SQL_BASED) - : AppConstants.RD_VISUAL; - } - - public String getJavascriptElement() { - return cr.getJavascriptElement(); - } - - public int getPageSize() { - return cr.getPageSize()==null?50:cr.getPageSize(); - } - - public int getMaxRowsInExcelDownload() { - return cr.getMaxRowsInExcelDownload()==null?500:cr.getMaxRowsInExcelDownload(); - } - - public boolean isDisplayFolderTree() { - return cr.isDisplayFolderTree()!=null?cr.isDisplayFolderTree().booleanValue():false; - } - - public boolean isHideFormFieldAfterRun() { - return cr.isHideFormFieldAfterRun()!=null?cr.isHideFormFieldAfterRun().booleanValue():false; - } - - public void setHideFormFieldAfterRun(boolean hideFormFieldAfterRun) { - cr.setHideFormFieldAfterRun(hideFormFieldAfterRun); - } - - public boolean isReportInNewWindow() { - return cr.isReportInNewWindow()!=null?cr.isReportInNewWindow().booleanValue():false; - } - - public String getReportType() { - return cr.getReportType(); - } - - public String getReportName() { - return cr.getReportName(); - } - - public String getDBInfo() { - return cr.getDbInfo(); - } - - public String getDBType() { - return cr.getDbType(); - } - - public boolean isDrillDownURLInPopupPresent() { - return cr.isDrillURLInPoPUpPresent()!=null?cr.isDrillURLInPoPUpPresent().booleanValue():false; - } - - public void setDrillDownURLInPopupPresent(boolean value) { - cr.setDrillURLInPoPUpPresent(value); - } - - public String getReportDescr() { - return cr.getReportDescr(); - } - - public String getChartType() { - return cr.getChartType(); - } - - public boolean displayChartTitle() { - return cr.isShowChartTitle(); - } - - public void setShowChartTitle(boolean showTitle) { - cr.setShowChartTitle(showTitle); - } - - - public String getChartTypeFixed() { - return cr.getChartTypeFixed(); - } - - public boolean isChartTypeFixed() { - return nvl(cr.getChartTypeFixed()).length() > 0 ? cr.getChartTypeFixed().equals("Y") - : (!Globals.getAllowRuntimeChartSel()); - } - - public String getChartLeftAxisLabel() { - return cr.getChartLeftAxisLabel(); - } - - public String getChartRightAxisLabel() { - return cr.getChartRightAxisLabel(); - } - - public String getChartWidth() { - return cr.getChartWidth(); - } - - public int getChartWidthAsInt() { - return getIntValue(cr.getChartWidth(), Globals.getDefaultChartWidth()); - } - - public String getChartHeight() { - return cr.getChartHeight()==null?"500":cr.getChartHeight(); - } - - /*public boolean isChartMultiSeries() { - //String s = cr.getChartMultiSeries(); - return - return (nvl(s).length()>0)? (s.equals("Y")||s.equals("y")||s.equalsIgnoreCase("true")?true:false):true; - }*/ - - public boolean displayPieOrderinRunPage() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieOrder():""; - if(nvl(s).indexOf("|")!= -1) { - s = s.substring(s.indexOf("|")+1); - return getFlagInBoolean(s); - } else return false; - } - - public boolean isMultiplePieOrderByRow() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieOrder():""; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return (nvl(s).length()>0)? (s.equals("row")?true:false):true; - } - - public boolean isMultiplePieOrderByColumn() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieOrder():""; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return (nvl(s).length()>0)&&(s.equals("column"))?true:false; - } - - public boolean displayPieLabelDisplayinRunPage() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieLabelDisplay():""; - if(nvl(s).indexOf("|")!= -1) { - s = s.substring(s.indexOf("|")+1); - return getFlagInBoolean(s); - } else return false; - } - - public String getMultiplePieLabelDisplay() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartMultiplePieLabelDisplay():""; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return s; - } - - public boolean displayChartDisplayinRunPage() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartDisplay():""; - if(nvl(s).indexOf("|")!= -1) { - s = s.substring(s.indexOf("|")+1); - return getFlagInBoolean(s); - } else return false; - } - - public boolean isChartDisplayIn3D() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartDisplay():""; - if(nvl(s).length()<=0) return true; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return (nvl(s).length()>0)&&(s.equals("3D"))?true:false; - } - - public boolean displayChartOrientationInRunPage() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartOrientation():""; - if(nvl(s).indexOf("|")!= -1) { - s = s.substring(s.indexOf("|")+1); - return getFlagInBoolean(s); - } else return false; - - } - - public String getLinearRegression() { - String s = ""; - s = nvl((cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLinearRegression():"Y"); - return s; - } - - public void setLinearRegression(String linear) { - cr.getChartAdditionalOptions().setLinearRegression(linear); - } - - public String getLinearRegressionColor() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLinearRegressionColor():""; - } - - public String getCustomizedRegressionPoint() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getMaxRegression():""; - } - - public void setCustomizedRegressionPoint( String d) { - cr.getChartAdditionalOptions().setMaxRegression(d); - } - - public void setLinearRegressionColor(String color) { - cr.getChartAdditionalOptions().setLinearRegressionColor(color); - } - - public String getExponentialRegressionColor() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getExponentialRegressionColor():""; - } - - public void setExponentialRegressionColor(String color) { - cr.getChartAdditionalOptions().setExponentialRegressionColor(color); - } - - public void setRangeAxisUpperLimit(String d) { - if(cr.getChartAdditionalOptions()!=null) - cr.getChartAdditionalOptions().setRangeAxisUpperLimit(d); - } - - public void setRangeAxisLowerLimit(String d) { - if(cr.getChartAdditionalOptions()!=null) - cr.getChartAdditionalOptions().setRangeAxisLowerLimit(d); - } - - public String getRangeAxisUpperLimit() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getRangeAxisUpperLimit():""; - } - - public String getRangeAxisLowerLimit() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getRangeAxisLowerLimit():""; - } - - public boolean isChartAnimate() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isAnimate()!=null?cr.getChartAdditionalOptions().isAnimate():false):false; - } - - public boolean isAnimateAnimatedChart() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isAnimateAnimatedChart()!=null?cr.getChartAdditionalOptions().isAnimateAnimatedChart():false):true; - } - - public void setAnimateAnimatedChart(boolean animate) { - cr.getChartAdditionalOptions().setAnimateAnimatedChart(animate); - } - - public void setChartStacked(boolean stacked) { - cr.getChartAdditionalOptions().setStacked(stacked); - } - - public boolean isChartStacked() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isStacked()!=null?cr.getChartAdditionalOptions().isStacked():true):false; - } - - public void setBarControls(boolean barControls) { - cr.getChartAdditionalOptions().setBarControls(barControls); - } - - public boolean displayBarControls() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isBarControls()!=null?cr.getChartAdditionalOptions().isBarControls():false):false; - } - - public void setXAxisDateType(boolean dateType) { - cr.getChartAdditionalOptions().setXAxisDateType(dateType); - } - - public boolean isXAxisDateType() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isXAxisDateType()!=null?cr.getChartAdditionalOptions().isXAxisDateType():false):false; - } - - public void setLessXaxisTickers(boolean lessTickers) { - cr.getChartAdditionalOptions().setLessXaxisTickers(lessTickers); - } - - public boolean isLessXaxisTickers() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isLessXaxisTickers()!=null?cr.getChartAdditionalOptions().isLessXaxisTickers():false):false; - } - - public void setTimeAxis(boolean timeAxis) { - cr.getChartAdditionalOptions().setTimeAxis(timeAxis); - } - - public boolean isTimeAxis() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isTimeAxis()!=null?cr.getChartAdditionalOptions().isTimeAxis():true):true; - } - - public void setLogScale(boolean logScale) { - cr.getChartAdditionalOptions().setLogScale(logScale); - } - - public boolean isLogScale() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isLogScale()!=null?cr.getChartAdditionalOptions().isLogScale():false):false; - } - - - public void setMultiSeries(boolean multiSeries) { - cr.getChartAdditionalOptions().setMultiSeries(multiSeries); - cr.setChartMultiSeries(multiSeries?"Y":"N"); - } - - public boolean isMultiSeries() { - if(AppUtils.nvl(cr.getChartMultiSeries()).equals("Y")) - cr.getChartAdditionalOptions().setMultiSeries(true); - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isMultiSeries()!=null?cr.getChartAdditionalOptions().isMultiSeries():false):false; - } - - public void setTimeSeriesRender(String timeSeriesRenderer) { - cr.getChartAdditionalOptions().setTimeSeriesRender(timeSeriesRenderer); - } - - public String getTimeSeriesRender() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getTimeSeriesRender():"line"; - } - - public void setShowXAxisLabel(boolean showXaxisLabel) { - cr.getChartAdditionalOptions().setShowXAxisLabel(showXaxisLabel); - } - - public boolean isShowXaxisLabel() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isShowXAxisLabel()!=null?cr.getChartAdditionalOptions().isShowXAxisLabel():false):false; - } - - public void setAddXAxisTickers(boolean addXAxisTickers) { - cr.getChartAdditionalOptions().setAddXAxisTickers(addXAxisTickers); - } - - public boolean isAddXAxisTickers() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().isAddXAxisTickers()!=null?cr.getChartAdditionalOptions().isAddXAxisTickers():false):true; - } - - public void setZoomIn(Integer zoomIn) { - cr.getChartAdditionalOptions().setZoomIn(zoomIn); - } - - public Integer getZoomIn() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().getZoomIn()!=null?cr.getChartAdditionalOptions().getZoomIn():new Integer("25")): new Integer("25"); - } - - public void setTimeAxisType(String timeAxisType) { - cr.getChartAdditionalOptions().setTimeAxisType(timeAxisType); - } - - public String getTimeAxisType() { - return (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().getTimeAxisType()!=null?cr.getChartAdditionalOptions().getTimeAxisType():"hourly"): "hourly"; - } - - public void setTopMargin(Integer topMargin) { - cr.getChartAdditionalOptions().setTopMargin(topMargin); - } - - public Integer getTopMargin() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getTopMargin(): new Integer("30"); - } - - public void setBottomMargin(Integer bottomMargin) { - cr.getChartAdditionalOptions().setBottomMargin(bottomMargin); - } - - public Integer getBottomMargin() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getBottomMargin(): new Integer("50"); - } - - public void setRightMargin(Integer rightMargin) { - cr.getChartAdditionalOptions().setRightMargin(rightMargin); - } - - public Integer getRightMargin() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getRightMargin(): new Integer("60"); - } - - public void setLeftMargin(Integer leftMargin) { - cr.getChartAdditionalOptions().setLeftMargin(leftMargin); - } - - public Integer getLeftMargin() { - return (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLeftMargin(): new Integer("100"); - } - - - public boolean isVerticalOrientation() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartOrientation():""; - if(nvl(s).length()<=0) return true; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return (nvl(s).length()>0)&&(s.equals("vertical"))?true:false; - } - - public boolean isHorizontalOrientation() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getChartOrientation():""; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return (nvl(s).length()>0)&&(s.equals("horizontal"))?true:false; - } - - public boolean displaySecondaryChartRendererInRunPage() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getSecondaryChartRenderer():""; - if(nvl(s).indexOf("|")!= -1) { - s = s.substring(s.indexOf("|")+1); - return getFlagInBoolean(s); - } else return false; - - } - - public String getSecondaryChartRenderer() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getSecondaryChartRenderer():""; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return s; - } - - public String getOverlayItemValueOnStackBar() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getOverlayItemValueOnStackBar():"N"; - return s; - } - - public boolean displayIntervalInputInRunPage() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getIntervalFromdate():""; - if(nvl(s).indexOf("|")!= -1) { - s = s.substring(s.indexOf("|")+1); - return getFlagInBoolean(s); - } else return false; - } - - public boolean showLegendDisplayOptionsInRunPage() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getHidechartLegend():""; - if(nvl(s).indexOf("|")!= -1) { - s = s.substring(s.indexOf("|")+1); - return getFlagInBoolean(s); - } else return false; - } - - public String getIntervalFromdate() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getIntervalFromdate():""; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return nvl(s,""); - } - - public String getIntervalTodate() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getIntervalTodate():""; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return nvl(s,""); - } - - public String getIntervalLabel() { - return cr.getChartAdditionalOptions()!=null ? nvl(cr.getChartAdditionalOptions().getIntervalLabel()):""; - } - - public String getLegendPosition() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLegendPosition():""; - return nvl(s,"bottom"); - } - - public String getLegendLabelAngle() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLabelAngle():""; - return nvl(s,"UP90"); - } - - public String getMaxLabelsInDomainAxis() { - String s = ""; - s = (cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getMaxLabelsInDomainAxis():""; - return nvl(s,"99"); - } - - public boolean isLastSeriesALineChart() { - String s = ""; - s = nvl((cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLastSeriesALineChart():""); - return s.equals("Y"); - } - - public boolean isLastSeriesABarChart() { - String s = ""; - s = nvl((cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getLastSeriesABarChart():""); - return s.equals("Y"); - } - - public void setChartLegendDisplay(String value) { - cr.getChartAdditionalOptions().setHidechartLegend(value); - } - - public boolean hideChartLegend() { - String s = ""; - s = nvl((cr.getChartAdditionalOptions()!=null)?cr.getChartAdditionalOptions().getHidechartLegend():"N"); - if(nvl(s).length()<=0) s = "N"; - if(nvl(s).indexOf("|")!= -1) s = s.substring(0, s.indexOf("|")); - return s.equals("Y"); - } - - public void setChartToolTips(String value) { - cr.getChartAdditionalOptions().setHideToolTips(value); - } - - public void setDomainAxisValuesAsString(String value) { - cr.getChartAdditionalOptions().setKeepDomainAxisValueAsString(value); - } - - public boolean hideChartToolTips() { - boolean s = true; - s = (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().getHideToolTips()!=null? - (cr.getChartAdditionalOptions().getHideToolTips().equals("Y")?true:false):(Globals.hideToolTipsGlobally()?true:false)):(Globals.hideToolTipsGlobally()?true:false); - return s; - } - - public boolean keepDomainAxisValueInChartAsString() { - boolean s = true; - s = (cr.getChartAdditionalOptions()!=null)?(cr.getChartAdditionalOptions().getKeepDomainAxisValueAsString()!=null? - (cr.getChartAdditionalOptions().getKeepDomainAxisValueAsString().equals("Y")?true:false):false):false; - return s; - } - - public int getChartHeightAsInt() { - return getIntValue(cr.getChartHeight(), Globals.getDefaultChartHeight()); - } - - public boolean isPublic() { - return cr.isPublic(); - } - - public boolean isDashboardType() throws RaptorException { - return cr.isDashboardType()!=null?cr.isDashboardType().booleanValue():false; - } - - // public String getCreateId() { return cr.getCreateId(); } - // public Calendar getCreateDate() { return cr.getCreateDate(); } - public String getReportSQL() { - return cr.getReportSQL(); - } - - public String getReportTitle() { - return cr.getReportTitle(); - } - - public String getReportSubTitle() { - return cr.getReportSubTitle(); - } - - public String getReportHeader() { - return cr.getReportHeader(); - } - - public String getReportFooter() { - return cr.getReportFooter(); - } - - public String getNumDashCols() { - return cr.getNumDashCols(); - } - - public int getNumDashColsAsInt() { - return getIntValue(cr.getNumDashCols(), 1); - } - - public String getNumFormCols() { - return cr.getNumFormCols(); - } - - public int getNumFormColsAsInt() { - return getIntValue(cr.getNumFormCols(), 5); - } - - public String getDisplayOptions() { - return cr.getDisplayOptions(); - } - - - -//Additional Methods - - public int getJumpTo() { - return cr.getJumpTo()==null?1:cr.getJumpTo(); - } - public void setJumpTo(int value){ - cr.setJumpTo(value); - } - - - public int getSearchPageSize(){ - return cr.getSearchPageSize()==null?20:cr.getSearchPageSize(); - } - public void setSearchPageSize(int value){ - cr.setSearchPageSize(value); - } - - - public boolean isToggleLayout(){ - if(cr.isToggleLayout()!=null) - return cr.isToggleLayout(); - - else - return Globals.displayRuntimeOptionsAsDefault(); - - } - public void setToggleLayout(boolean value){ - cr.setToggleLayout(value); - } - - public boolean isShowPageSize(){ - if(cr.isShowPageSize()!=null) - return cr.isShowPageSize(); - - else - return Globals.displayRuntimeOptionsAsDefault(); - - } - public void setShowPageSize(boolean value){ - cr.setShowPageSize(value); - } - - public boolean isShowNavPos(){ - if(cr.isShowNavPos()!=null) - return cr.isShowNavPos(); - - else - return Globals.displayRuntimeOptionsAsDefault(); - - } - public void setShowNavPos(boolean value){ - cr.setShowNavPos(value); - } - - public boolean isShowGotoOption(){ - if(cr.isShowGotoOption()!=null) - return cr.isShowGotoOption(); - - else - return Globals.displayRuntimeOptionsAsDefault(); - - } - public void setShowGotoOption(boolean value){ - cr.setShowGotoOption(value); - } - - public boolean isPageNav(){ - - if(cr.isPageNav()!=null) - return cr.isPageNav(); - - else - return Globals.displayRuntimeOptionsAsDefault(); - - } - - public void setPageNav(boolean value){ - cr.setPageNav(value); - } - - - public String getNavPosition(){ - if(cr.getNavPosition()!=null) - return cr.getNavPosition(); - - else - return "top"; - //return cr.getNavPosition(); - } - public void setNavPosition(String value){ - cr.setNavPosition(value); - } - - - public String getDashboardEditor(){ - return getDashBoardReportsNew().getDashboardEditor(); - } - - public void setDashboardEditor(String value){ - getDashBoardReportsNew().setDashboardEditor(value); - } - - - public DashboardEditorList getDashboardEditorList(){ - return getDashBoardReportsNew().getDashboardEditorList(); - } - - public void setDashboardEditorList(DashboardEditorList value){ - getDashBoardReportsNew().setDashboardEditorList(value); - } - - public PDFAdditionalOptions getPDFAdditionalOptions() { - try { - if(cr.getPdfAdditionalOptions()==null) - addPDFAdditionalOptions(new ObjectFactory()); - } catch(RaptorException ex) { - ex.printStackTrace(); - } - return cr.getPdfAdditionalOptions(); - } - - public String getPDFFont(){ - return getPDFAdditionalOptions().getPDFFont()!=null?getPDFAdditionalOptions().getPDFFont():Globals.getDataFontFamily(); - } - public void setPDFFont(String value){ - getPDFAdditionalOptions().setPDFFont(value); - } - - public int getPDFFontSize() { - return getPDFAdditionalOptions().getPDFFontSize()==null?9:getPDFAdditionalOptions().getPDFFontSize(); - } - public void setPDFFontSize(int value){ - getPDFAdditionalOptions().setPDFFontSize(value); - } - - public String getPDFOrientation(){ - return getPDFAdditionalOptions().getPDFOrientation()!=null?"portrait":"landscape"; - } - public void setPDFOrientation(String value){ - getPDFAdditionalOptions().setPDFOrientation(value); - } - - public String getPDFLogo1(){ - return getPDFAdditionalOptions().getPDFLogo1(); - } - public void setPDFLogo1(String value){ - getPDFAdditionalOptions().setPDFLogo1(value); - } - - public String getPDFLogo2(){ - return getPDFAdditionalOptions().getPDFLogo2(); - } - public void setPDFLogo2(String value){ - getPDFAdditionalOptions().setPDFLogo2(value); - } - - public int getPDFLogo1Size() { - return getPDFAdditionalOptions().getPDFLogo1Size()==null?0:getPDFAdditionalOptions().getPDFLogo1Size(); - } - public void setPDFLogo1Size(int value){ - getPDFAdditionalOptions().setPDFLogo1Size(value); - } - - public int getPDFLogo2Size() { - return getPDFAdditionalOptions().getPDFLogo2Size()==null?0:getPDFAdditionalOptions().getPDFLogo2Size(); - } - public void setPDFLogo2Size(int value){ - getPDFAdditionalOptions().setPDFLogo2Size(value); - } - - public boolean isPDFCoverPage(){ - - if(getPDFAdditionalOptions().isPDFCoverPage()!=null) - return getPDFAdditionalOptions().isPDFCoverPage(); - - else - return true; - - } - - public void setPDFCoverPage(boolean value){ - getPDFAdditionalOptions().setPDFCoverPage(value); - } - - public String getPDFFooter1(){ - return getPDFAdditionalOptions().getPDFFooter1(); - } - public void setPDFFooter1(String value){ - getPDFAdditionalOptions().setPDFFooter1(value); - } - - public String getPDFFooter2(){ - return getPDFAdditionalOptions().getPDFFooter2(); - } - public void setPDFFooter2(String value){ - getPDFAdditionalOptions().setPDFFooter2(value); - } - - - -//End of Additional Methods - - public String getDataContainerHeight() { - return cr.getDataContainerHeight(); - } - - public String getDataContainerWidth() { - return cr.getDataContainerWidth(); - } - - public boolean isAllowSchedule() { - String allowSchedule = getAllowSchedule(); - return (allowSchedule !=null )? allowSchedule.startsWith("Y"):false; - } - - public String getAllowSchedule() { - return cr.getAllowSchedule(); - } - - /* Multi Group */ - - public boolean isMultiGroupColumn() { - String multiGroupColumn = getMultiGroupColumn(); - return (multiGroupColumn !=null )? multiGroupColumn.startsWith("Y"):false; - } - - public String getMultiGroupColumn() { - return cr.getMultiGroupColumn(); - } - - public void setMultiGroupColumn(String value) { - cr.setMultiGroupColumn(value); - } - - private int getColumnGroupLevel(String colId) throws RaptorException { - DataColumnType dc = getColumnById(colId); - return (dc == null) ? 0 : dc.getLevel(); - } // getColumnGroupLevel - - public int getMaxGroupLevel() { - List reportCols = getAllColumns(); - int maxLevel = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (dc.getLevel()!=null) { - if(maxLevel < dc.getLevel()) - maxLevel = dc.getLevel(); - } - } // for - return maxLevel; - } // getMaxGroupLevel - - private int getColumnGroupStart(String colId) throws RaptorException { - DataColumnType dc = getColumnById(colId); - return (dc == null) ? 0 : dc.getStart(); - } // getColumnGroupStart - - private int getColumnGroupColSpan(String colId) throws RaptorException { - DataColumnType dc = getColumnById(colId); - return (dc == null) ? 0 : dc.getColspan(); - } // getColumnGroupColSpan - - public void setTopDown(String value) { - cr.setTopDown(value); - } - - public boolean isTopDown() { - String topDown = getTopDownOption(); - return (topDown !=null )? topDown.startsWith("Y"):false; - } - - public String getTopDownOption() { - return cr.getTopDown(); - } - - public void setSizedByContent(String value) { - cr.setSizedByContent(value); - } - - public boolean isSizedByContent() { - String sizedByContent = getSizedByContentOption(); - return (sizedByContent !=null )? sizedByContent.startsWith("Y"):false; - } - - public String getSizedByContentOption() { - return cr.getSizedByContent(); - } - - public String getDashboardOptions() { - return cr.getDashboardOptions(); - } - - public boolean isDashboardOptionHideChart() { - return nvl(getDashboardOptions()).length() > 0 && (getDashboardOptions().charAt(0) == 'Y'); - } - - public boolean isDashboardOptionHideData() { - return nvl(getDashboardOptions()).length() > 0 && (getDashboardOptions().charAt(1) == 'Y'); - } - - public boolean isDashboardOptionHideBtns() { - return nvl(getDashboardOptions()).length() > 0 && (getDashboardOptions().charAt(2) == 'Y'); - } - - public boolean isDisplayOptionHideForm() { - return nvl(getDisplayOptions()).length() > 0 && (getDisplayOptions().charAt(0) == 'Y'); - } - - public boolean isDisplayOptionHideChart() { - return nvl(getDisplayOptions()).length() > 1 && (getDisplayOptions().charAt(1) == 'Y'); - } - - public boolean isDisplayOptionHideData() { - return nvl(getDisplayOptions()).length() > 2 && (getDisplayOptions().charAt(2) == 'Y'); - } - - public boolean isDisplayOptionHideBtns() { - return nvl(getDisplayOptions()).length() > 3 && (getDisplayOptions().charAt(3) == 'Y'); - } - - public boolean isDisplayOptionHideMap() { - return nvl(getDisplayOptions()).length() > 4 && (getDisplayOptions().charAt(4) == 'Y'); - } - - public boolean isDisplayOptionHideExcelIcons() { - return nvl(getDisplayOptions()).length() > 5 && (getDisplayOptions().charAt(5) == 'Y'); - } - - public boolean isDisplayOptionHidePDFIcons() { - return nvl(getDisplayOptions()).length() > 6 && (getDisplayOptions().charAt(6) == 'Y'); - } - - public String getComment() { - return cr.getComment(); - } - - public DataSourceList getDataSourceList() { - return cr.getDataSourceList(); - } - - public ChartAdditionalOptions getChartAdditionalOptions() { - return cr.getChartAdditionalOptions(); - } - - public ChartDrillOptions getChartDrillOptions() { - return cr.getChartDrillOptions(); - } - - - public DataminingOptions getDataminingOptions() { - return cr.getDataminingOptions(); - } - - public DashboardReports getDashBoardReports() { - return cr.getDashBoardReports(); - } - - - public DashboardReportsNew getDashBoardReportsNew() { - try { - if(cr.getDashBoardReportsNew()==null) - addDashboardReportsNew(new ObjectFactory()); - } catch(RaptorException ex) { - ex.printStackTrace(); - } - return cr.getDashBoardReportsNew(); - } - - public String getDashboardLayoutHTML() { - return cr.getDashboardLayoutHTML(); - } - - public FormFieldList getFormFieldList() { - return cr.getFormFieldList(); - } - - public JavascriptList getJavascriptList() { - return cr.getJavascriptList(); - } - - public SemaphoreList getSemaphoreList() { - return cr.getSemaphoreList(); - } - - public void setPageSize(int value) { - cr.setPageSize(value); - } - - public void setAllowSchedule(String value) { - cr.setAllowSchedule(value); - } - - public void setMaxRowsInExcelDownload(int value) { - cr.setMaxRowsInExcelDownload(value); - } - - public void setReportInNewWindow (boolean value) { - cr.setReportInNewWindow(value); - } - - public void setDisplayFolderTree (boolean value) { - cr.setDisplayFolderTree(value); - } - - public void setReportType(String value) { - cr.setReportType(value); - } - - public void setReportName(String value) { - cr.setReportName(value); - } - - public void setDBInfo(String value) { - if (!(cr.getDbInfo() != null && cr.getDbInfo().length() > 0)) - cr.setDbInfo(value); - } - - public void setDBType(String value) { - if (!(cr.getDbType() != null && cr.getDbType().length() > 0)) - cr.setDbType(value); - } - - public void setReportDescr(String value) { - cr.setReportDescr(value); - } - - public void setChartType(String value) { - cr.setChartType(value); - } - - public void setChartMultiplePieOrder(String value) { - cr.getChartAdditionalOptions().setChartMultiplePieOrder(value); - } - - public void setChartMultiplePieLabelDisplay(String value) { - cr.getChartAdditionalOptions().setChartMultiplePieLabelDisplay(value); - } - - public void setChartOrientation(String value) { - cr.getChartAdditionalOptions().setChartOrientation(value); - } - - public void setSecondaryChartRenderer(String value) { - cr.getChartAdditionalOptions().setSecondaryChartRenderer(value); - } - - public void setOverlayItemValueOnStackBar(String value) { - cr.getChartAdditionalOptions().setOverlayItemValueOnStackBar(value); - } - - public void setIntervalFromdate(String value) { - cr.getChartAdditionalOptions().setIntervalFromdate(value); - } - - public void setIntervalLabel(String value) { - cr.getChartAdditionalOptions().setIntervalLabel(value); - } - - public void setIntervalTodate(String value) { - cr.getChartAdditionalOptions().setIntervalTodate(value); - } - - public void setLegendPosition(String value) { - cr.getChartAdditionalOptions().setLegendPosition(value); - } - - public void setLegendLabelAngle(String value) { - cr.getChartAdditionalOptions().setLabelAngle(value); - } - - public void setMaxLabelsInDomainAxis(String value) { - if(nvl(value).length()<=0) value = "99"; - cr.getChartAdditionalOptions().setMaxLabelsInDomainAxis(value); - } - - public void setLastSeriesALineChart(String value) { - cr.getChartAdditionalOptions().setLastSeriesALineChart(value); - } - - public void setLastSeriesABarChart(String value) { - cr.getChartAdditionalOptions().setLastSeriesABarChart(value); - } - - public void setChartDisplay(String value) { - cr.getChartAdditionalOptions().setChartDisplay(value); - } - - public void setChartAnimate(boolean animate) { - if(cr.getChartAdditionalOptions()!=null) - cr.getChartAdditionalOptions().setAnimate(animate); - else { - try { - if(getChartAdditionalOptions()==null) - addChartAdditionalOptions(new ObjectFactory()); - } catch(RaptorException ex) { - ex.printStackTrace(); - } - if(cr.getChartAdditionalOptions()!=null) - cr.getChartAdditionalOptions().setAnimate(animate); - - } - - } - - public void addChartAdditionalOptions(ObjectFactory objFactory) throws RaptorException { - ChartAdditionalOptions chartOptions = objFactory.createChartAdditionalOptions(); - cr.setChartAdditionalOptions(chartOptions); - } - - public void addDashboardReportsNew(ObjectFactory objFactory) throws RaptorException { - DashboardReportsNew dashboardReports = objFactory.createDashboardReportsNew(); - cr.setDashBoardReportsNew(dashboardReports); - } - - public void addPDFAdditionalOptions(ObjectFactory objFactory) throws RaptorException { - PDFAdditionalOptions pdfOptions = objFactory.createPDFAdditionalOptions(); - cr.setPdfAdditionalOptions(pdfOptions); - } - - public void setChartTypeFixed(String value) { - cr.setChartTypeFixed(value); - } - - public void setChartLeftAxisLabel(String value) { - cr.setChartLeftAxisLabel(value); - } - - public void setChartRightAxisLabel(String value) { - cr.setChartRightAxisLabel(value); - } - - public void setChartWidth(String value) { - cr.setChartWidth(value); - } - - public void setChartHeight(String value) { - cr.setChartHeight(value); - } - - public void setChartMultiSeries(String value) { - cr.setChartMultiSeries(value); - } - - public void setPublic(boolean value) { - cr.setPublic(value); - if (reportSecurity != null) - reportSecurity.setPublic(value); - } - - // public void setCreateId(String value) { cr.setCreateId(value); } - // public void setCreateDate(Calendar value) { cr.setCreateDate(value); } - public void setReportSQL(String value) { - cr.setReportSQL(value); - } - - public void setReportTitle(String value) { - cr.setReportTitle(value); - } - - public void setReportSubTitle(String value) { - cr.setReportSubTitle(value); - } - - public void setReportHeader(String value) { - cr.setReportHeader(value); - } - - public void setReportFooter(String value) { - cr.setReportFooter(value); - } - - public void setNumFormCols(String value) { - cr.setNumFormCols(value); - } - - public void setNumDashCols(String value) { - cr.setNumDashCols(value); - } - - public void setDisplayOptions(String value) { - cr.setDisplayOptions(value); - } - - public void setDataContainerHeight(String value) { - cr.setDataContainerHeight(value); - } - - public void setDataContainerWidth(String value) { - cr.setDataContainerWidth(value); - } - - public void setDashboardOptions(String value) { - cr.setDashboardOptions(value); - } - - public void setComment(String value) { - cr.setComment(value); - } - - public void setDashboardType(boolean dashboardType) { - cr.setDashboardType(dashboardType); - } - - public void setDashboardLayoutHTML(String html) { - cr.setDashboardLayoutHTML(html); - } - - public void setDataSourceList(DataSourceList value) { - cr.setDataSourceList(value); - } - - public void setFormFieldList(FormFieldList value) { - cr.setFormFieldList(value); - } - - public void setDashBoardReports(DashboardReports value) { - cr.setDashBoardReports(value); - } - - public void setSemaphoreList(SemaphoreList value) { - cr.setSemaphoreList(value); - } - - public void setJavascriptList(JavascriptList value) { - cr.setJavascriptList(value); - } - - public void setJavascriptElement(String javascriptElement) { - cr.setJavascriptElement(javascriptElement); - } - - public void checkUserReadAccess(HttpServletRequest request) throws RaptorException { - reportSecurity.checkUserReadAccess(request, null); - } - public void checkUserReadAccess(HttpServletRequest request, String userID) throws RaptorException { - reportSecurity.checkUserReadAccess(request, userID); - } - - public void checkUserWriteAccess(HttpServletRequest request) throws RaptorException { - reportSecurity.checkUserWriteAccess(request); - verifySQLBasedReportAccess(request); - } - - public String getOwnerID() { - return reportSecurity.getOwnerID(); - } - - public String getCreateID() { - return reportSecurity.getCreateID(); - } - - public String getCreateDate() { - return reportSecurity.getCreateDate(); - } - - public String getUpdateID() { - return reportSecurity.getUpdateID(); - } - - public String getUpdateDate() { - return reportSecurity.getUpdateDate(); - } - - public ReportSecurity getReportSecurity() { - return reportSecurity; - } - - /****Report Maps - Start****/ - public ReportMap getReportMap() { - return cr.getReportMap(); - } - - public void setReportMap(ReportMap reportMap) { - cr.setReportMap(reportMap); - } - /****Report Maps - End****/ - - /****Report Chart Drilldown - Start****/ - public ChartDrillOptions getReportChartDrillOptions() { - return cr.getChartDrillOptions(); - } - - public void setReportChartDrillOptions(ChartDrillOptions chartDrillOptions) { - cr.setChartDrillOptions(chartDrillOptions); - } - /****Report Maps - End****/ - - - /** ************************************************************************************************* */ - - public String getFormHelpText() { - String formHelpText = nvl(getComment()); - - if (formHelpText.indexOf('|') >= 0) - formHelpText = formHelpText.substring(formHelpText.lastIndexOf('|') + 1); - - return formHelpText; - } // getFormHelpText - - public void setFormHelpText(String formHelpText) { - String comment = nvl(getComment()); - - if (comment.indexOf('|') >= 0) - comment = comment.substring(0, comment.lastIndexOf('|')); - if (comment.length() > 0) - comment += '|'; - - setComment(comment + formHelpText); - } // setFormHelpText - - public boolean isRuntimeColSortDisabled() { - String comment = nvl(getComment()); - - if (comment.indexOf('|') < 0) - return false; - - return comment.substring(0, comment.indexOf('|')).equals("Y"); - } // isRuntimeColSortDisabled - - public void setRuntimeColSortDisabled(boolean value) { - String comment = nvl(getComment()); - - if (comment.indexOf('|') >= 0) - comment = comment.substring(comment.indexOf('|') + 1); - - setComment((value ? "Y" : "N") + "|" + comment); - } // setRuntimeColSortDisabled - - /** ************************************************************************************************* */ - - protected void verifySQLBasedReportAccess(HttpServletRequest request) throws RaptorException { - String userID = AppUtils.getUserID(request); - if (getReportDefType().equals(AppConstants.RD_SQL_BASED) - && (!Globals.getAllowSQLBasedReports()) && (!AppUtils.isAdminUser(request))) - throw new org.openecomp.portalsdk.analytics.error.UserAccessException(reportID, "[" + userID + "] " - + AppUtils.getUserName(request), AppConstants.UA_WRITE); - } // verifySQLBasedReportAccess - - /** ************************************************************************************************* */ - - private String getColumnNameById(String colId) throws RaptorException { - DataColumnType dc = getColumnById(colId); - return (dc == null) ? "NULL" : dc.getColName(); - } // getColumnNameById - - // Checks if drill-down URL points to individual record display (return - // true) or another report (return false) - private boolean isViewAction(String value) throws RaptorException { - try { - Vector viewActions = org.openecomp.portalsdk.analytics.model.DataCache.getDataViewActions(); - - for (int i = 0; i < viewActions.size(); i++) - if (value.equals(AppUtils.getBaseActionURL() + ((String) viewActions.get(i)))) - return true; - } catch (Exception e) { - throw new RaptorRuntimeException("ReportWrapper.isViewAction Exception: " - + e.getMessage()); - } - - return false; - } // isViewAction - - public String getSelectExpr(DataColumnType dct) { - // String colName = - // dct.isCalculated()?dct.getColName():((nvl(dct.getTableId()).length()>0)?(dct.getTableId()+"."+dct.getColName()):dct.getColName()); - return getSelectExpr(dct, dct.getColName() /* colName */); - } // getSelectExpr - - /*private String getSelectExpr(DataColumnType dct, String colName) { - String colType = dct.getColType(); - if (colType.equals(AppConstants.CT_CHAR) - || ((nvl(dct.getColFormat()).length() == 0) && (!colType - .equals(AppConstants.CT_DATE)))) - return colName; - else - return "TO_CHAR(" + colName + ", '" - + nvl(dct.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT) + "')"; - } // getSelectExpr - */ - - private String getSelectExpr(DataColumnType dct, String colName) { - String colType = dct.getColType(); - if(colType.equals(AppConstants.CT_NUMBER)) { - return colName; - } else - if (colType.equals(AppConstants.CT_CHAR) - || ((nvl(dct.getColFormat()).length() == 0) && (!colType - .equals(AppConstants.CT_DATE)))) - return colName; - - else - return "TO_CHAR(" + colName + ", '" - + nvl(dct.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT) + "')"; - } // getSelectExpr - - - /** ************************************************************************************************* */ - - public DataSourceType getTableById(String tableId) { - for (Iterator iter = getDataSourceList().getDataSource().iterator(); iter.hasNext();) { - DataSourceType ds = (DataSourceType) iter.next(); - if (ds.getTableId().equals(tableId)) - return ds; - } // for - - return null; - } // getTableById - - public DataSourceType getTableByDBName(String tableName) { - for (Iterator iter = getDataSourceList().getDataSource().iterator(); iter.hasNext();) { - DataSourceType ds = (DataSourceType) iter.next(); - if (ds.getTableName().equals(tableName)) - return ds; - } // for - - return null; - } // getTableByDBName - - public DataSourceType getColumnTableById(String colId) { - return getTableById(getColumnById(colId).getTableId()); - } // getColumnTableById - - public DataColumnType getColumnById(String colId) { - List reportCols = getAllColumns(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (dc.getColId().toLowerCase().equals(colId.toLowerCase())) - return dc; - } // for - - return null; - } // getColumnById - - public DataColumnType getChartLegendColumn() { - List reportCols = getAllColumns(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) - return dc; - } // for - return null; - } // getChartLegendColumn - - /* - * public DataColumnType getChartValueColumn() { List reportCols = - * getAllColumns(); for(Iterator iter=reportCols.iterator(); iter.hasNext(); ) { - * DataColumnType dc = (DataColumnType) iter.next(); if(dc.getChartSeq()>0) - * return dc; } // for - * - * return null; } // getChartValueColumn - */ - - public List getChartValueColumnsList( int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ - List reportCols = getAllColumns(); - - ArrayList chartValueCols = new ArrayList(); - int flag = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); -// if(filter == 2 || filter == 1) { - flag = getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 ) { - if(!AppUtils.nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) { - if(nvl(dc.getChartGroup()).length()<=0) { - if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue())) { - chartValueCols.add(dc); - } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { - chartValueCols.add(dc); - } - else if(filter == 0) chartValueCols.add(dc); - } else chartValueCols.add(dc); - } - } -// } else -// chartValueCols.add(dc); - } // for - Collections.sort(chartValueCols, new ChartSeqComparator()); - return chartValueCols; - } // getChartValueColumnsList - - - /* public ListModelList getChartValueColumnsListModelList( int filter, HashMap formValues) { / *filter; all=0;create without new chart =1; createNewChart=2 * / - List reportCols = getAllColumns(); - - ArrayList chartValueCols = new ArrayList(); - ListModelList chartValueListModelList = new ListModelList(); - int flag = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); -// if(filter == 2 || filter == 1) { - flag = getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 ) { - if(nvl(dc.getChartGroup()).length()<=0) { - if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue())) { - chartValueCols.add(dc); - } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { - chartValueCols.add(dc); - } - else if(filter == 0) chartValueCols.add(dc); - } else chartValueCols.add(dc); - } -// } else -// chartValueCols.add(dc); - chartValueListModelList.add(new Item(dc.getColId(), dc.getDisplayName())); - } // for - Collections.sort(chartValueCols, new ChartSeqComparator()); - return chartValueListModelList; - } // getChartValueColumnsList */ - - - /** Check whether chart has series (Category) columns **/ - public boolean hasSeriesColumn() { - List reportCols = getAllColumns(); - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (dc.isChartSeries()!=null && dc.isChartSeries().booleanValue()) - return true; - } // for - return false; - } // hasSeriesColumn - - - public List getChartDisplayNamesList( int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ - List reportCols = getAllColumns(); - ArrayList chartValueColNames = new ArrayList(); - int flag = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); -// if(filter == 2 || filter == 1) { - flag = getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { - if(nvl(dc.getChartGroup()).length()<=0) { - if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue()) ) { - chartValueColNames.add(dc.getDisplayName()); - } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { - chartValueColNames.add(dc.getDisplayName()); - } - else if(filter == 0) chartValueColNames.add(dc.getDisplayName()); - } else if(filter == 0) chartValueColNames.add(dc.getDisplayName()); - } - // } else - // chartValueColNames.add(dc.getDisplayName()); - - } - return chartValueColNames; - } // getChartDisplayNamesList - - - public List getChartColumnColorsList(int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ - List reportCols = getAllColumns(); - ArrayList chartValueColColors = new ArrayList(); - int flag = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); -// if(filter == 2 || filter == 1) { - flag = getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { - if(nvl(dc.getChartGroup()).length()<=0) { - if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue()) ) { - chartValueColColors.add(dc.getChartColor()); - } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { - chartValueColColors.add(dc.getChartColor()); - } - else if(filter == 0) chartValueColColors.add(dc.getChartColor()); - } else if(filter == 0) chartValueColColors.add(dc.getChartColor()); - } -// } else -// chartValueColColors.add(dc.getChartColor()); - } - return chartValueColColors; - } // getChartColumnColorsList - - public List getChartValueColumnAxisList( int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ - List reportCols = getAllColumns(); - ArrayList chartValueColAxis = new ArrayList(); - int flag = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); -// if(filter == 2 || filter == 1) { - flag = getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { - if(nvl(dc.getChartGroup()).length()<=0) { - if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue())) { - chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); - } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { - chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); - } - else if(filter == 0) chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); - } else if(filter == 0) chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); - } -// } else -// chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); - } - return chartValueColAxis; - } // getChartColumnAxisList - - - public List getChartValueNewChartList() { - ArrayList chartValueNewChartAxis = new ArrayList(); - for (Iterator iter = getChartValueColumnsList(2, null).iterator(); iter.hasNext();) - chartValueNewChartAxis.add(new Boolean(((DataColumnType) iter.next()).isCreateInNewChart())); - return chartValueNewChartAxis; - } // getChartValueNewChartList - - public List getAllChartGroups() { - ArrayList chartGroups = new ArrayList(); - String chartGroupName=""; - List reportCols = getAllColumns(); - Set groupSet = new TreeSet(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if(dc.getChartSeq()!=null && dc.getChartSeq()> 0) { - chartGroupName = dc.getChartGroup(); - if(nvl(chartGroupName).length()>0) - groupSet.add(chartGroupName); - } - } - List l = new ArrayList(groupSet); - return l; - } // getAllChartGroups - - public HashMap getAllChartYAxis(ReportParamValues reportParamValues) { - String chartYAxis=""; - List reportCols = getAllColumns(); - HashMap hashMap = new HashMap(); - FormFieldList formFieldList = getFormFieldList(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if(dc.getChartSeq()!=null && dc.getChartSeq()> 0) { - chartYAxis = dc.getYAxis(); - if(formFieldList!=null && reportParamValues!=null) { - for (Iterator iter1 = getFormFieldList().getFormField().iterator(); iter1.hasNext();) { - FormFieldType fft = (FormFieldType) iter1.next(); - String fieldDisplay = getFormFieldDisplayName(fft); - String fieldId = fft.getFieldId(); - if(!fft.getFieldType().equals(FormField.FFT_BLANK) && !fft.getFieldType().equals(FormField.FFT_LIST_MULTI) && !fft.getFieldType().equals(FormField.FFT_TEXTAREA)) { - String paramValue = Utils.oracleSafe(nvl(reportParamValues.getParamValue(fieldId))); - chartYAxis = Utils.replaceInString(chartYAxis, fieldDisplay, nvl( - paramValue, "")); - } - } - } - if(nvl(dc.getChartGroup()).length()>0) - hashMap.put(dc.getChartGroup(),chartYAxis); - } - } - return hashMap; - } // getAllChartGroups - - public List getChartGroupColumnAxisList( String chartGroupName, HashMap formValues ) { /*filter; all=0;create without new chart =1; createNewChart=2 */ - List reportCols = getAllColumns(); - ArrayList chartGroupColAxis = new ArrayList(); - String chartGroup = chartGroupName.substring(0,chartGroupName.lastIndexOf("|")); - int flag = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); -// if(filter == 2 || filter == 1) { - flag = getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { - if( nvl(dc.getChartGroup()).indexOf("|") > 0 && (nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup))) { - //if( nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup)) { - //System.out.println("$$$$$$$DC " + dc.getColId()+ " " + dc.getColOnChart()); - chartGroupColAxis.add(dc); - } - } -// } else -// chartValueColAxis.add(nvl(dc.getColOnChart(), "0")); - } - Collections.sort(chartGroupColAxis, new ChartSeqComparator()); - return chartGroupColAxis; - } // getChartColumnAxisList - - public List getChartGroupValueColumnAxisList( String chartGroupName, HashMap formValues ) { - List reportCols = getAllColumns(); - String index = chartGroupName.substring(chartGroupName.lastIndexOf("|")+1); - String chartGroup = chartGroupName.substring(0,chartGroupName.lastIndexOf("|")); - //System.out.println("$$$$INDEX " + index); - ArrayList chartGroupValueColAxis = new ArrayList(); - int flag = 0; - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); - flag = getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0) { - //System.out.println(" Chartgroup " + dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))); - if( nvl(dc.getChartGroup()).indexOf("|") > 0 && (nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup))) { - //if( nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup)) { - //System.out.println(" Added Chartgroupname " + chartGroup + " " + dc.getChartGroup() + " " + index); - chartGroupValueColAxis.add(dc); - } - } - } - return chartGroupValueColAxis; - } // getChartColumnAxisList - - public List getChartGroupDisplayNamesList( String chartGroupName, HashMap formValues) { - List reportCols = getAllColumns(); - ArrayList chartGroupValueColNames = new ArrayList(); - String chartGroup = chartGroupName.substring(0,chartGroupName.lastIndexOf("|")); - int flag = 0; - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); - //System.out.println("$$$$$CHART " + dc.getChartSeq()+ " " + dc.getChartGroup()+ " " + chartGroup); - flag = getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 ) { - if( nvl(dc.getChartGroup()).indexOf("|") > 0 && (nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup))) { - chartGroupValueColNames.add(dc.getDisplayName()); - } - } - } - return chartGroupValueColNames; - } // getChartDisplayNamesList - - - public List getChartGroupColumnColorsList(String chartGroupName, HashMap formValues) { - List reportCols = getAllColumns(); - ArrayList chartValueColColors = new ArrayList(); - String chartGroup = chartGroupName.substring(0,chartGroupName.lastIndexOf("|")); - int flag = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); - flag = getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 ) { - if( nvl(dc.getChartGroup()).indexOf("|") > 0 && (nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup))) { - //if( nvl(dc.getChartGroup().substring(0,dc.getChartGroup().lastIndexOf("|"))).equals(chartGroup)) { - chartValueColColors.add(dc.getChartColor()); - } - } - } - return chartValueColColors; - } // getChartColumnColorsList - - - public List getCrossTabRowColumns() { - List reportCols = getAllColumns(); - Vector v = new Vector(reportCols.size()); - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (nvl(dc.getCrossTabValue()).equals(AppConstants.CV_ROW)) - v.add(dc); - } // for - - return v; - } // getCrossTabRowColumns - - public List getCrossTabColColumns() { - List reportCols = getAllColumns(); - Vector v = new Vector(reportCols.size()); - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (nvl(dc.getCrossTabValue()).equals(AppConstants.CV_COLUMN)) - v.add(dc); - } // for - - return v; - } // getCrossTabColColumns - - public String getCrossTabDisplayTotal(String rowColPos) { - DataColumnType dct = getCrossTabValueColumn(); - if (dct == null) - return ""; - - String displayTotal = nvl(dct.getDisplayTotal()); - if (displayTotal.indexOf('|') >= 0) { - String displayColTotal = displayTotal.substring(0, displayTotal.indexOf('|')); - String displayRowTotal = displayTotal.substring(displayTotal.indexOf('|') + 1); - - if (rowColPos.equals(AppConstants.CV_COLUMN)) - displayTotal = displayColTotal; - else if (rowColPos.equals(AppConstants.CV_ROW)) - displayTotal = displayRowTotal; - else if (displayColTotal.equals(displayRowTotal)) - displayTotal = displayColTotal; - } // if - - return displayTotal; - } // getCrossTabDisplayTotal - - public DataColumnType getCrossTabValueColumn() { - List reportCols = getAllColumns(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (nvl(dc.getCrossTabValue()).equals(AppConstants.CV_VALUE)) - return dc; - } // for - - return null; - } // getCrossTabValueColumn - - public int getCrossTabValueColumnIndex() { // Returns the index counting - // only visible columns - List reportCols = getAllColumns(); - - int idx = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (nvl(dc.getCrossTabValue()).equals(AppConstants.CV_VALUE)) - break; - if (dc.isVisible()) - idx++; - } // for - - return idx; - } // getCrossTabValueColumnIndex - - public ColFilterType getFilterById(String colId, int filterIndex) { - DataColumnType dc = getColumnById(colId); - try { - return (ColFilterType) dc.getColFilterList().getColFilter().get(filterIndex); - } catch (Exception e) { - return null; - } - } // getFilterById - - public boolean needFormInput() { - List reportCols = getAllColumns(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - - if (dct.getColFilterList() != null) { - List fList = dct.getColFilterList().getColFilter(); - for (Iterator iterF = fList.iterator(); iterF.hasNext();) { - ColFilterType cft = (ColFilterType) iterF.next(); - - if (nvl(cft.getArgType()).equals(AppConstants.AT_FORM)) - return true; - } // for - } // if - } // for - - return false; - } // needFormInput - - public int getNumSortColumns() { - int numSortCols = 0; - for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - if (dct.getOrderBySeq() != null && dct.getOrderBySeq() > 0) - numSortCols++; - } // for - - return numSortCols; - } // getNumSortColumns - - public SemaphoreType getSemaphoreById(String semaphoreId) { - if (getSemaphoreList() != null && semaphoreId != null) - for (Iterator iter = getSemaphoreList().getSemaphore().iterator(); iter.hasNext();) { - SemaphoreType sem = (SemaphoreType) iter.next(); - if (sem.getSemaphoreId().equals(semaphoreId)) - return sem; - } // for - - return null; - } // getSemaphoreById - - public void deleteSemaphore(SemaphoreType semaphore) { - if (getSemaphoreList() != null) { - if(getSemaphoreList().getSemaphore()!= null) - getSemaphoreList().getSemaphore().remove((SemaphoreType) semaphore); - } - } // deleteSemaphore - - - public void setSemaphore(SemaphoreType sem) { - if (getSemaphoreList() != null) { - getSemaphoreList().getSemaphore().add(sem); - } - - } // setSemaphore - - public static FormatType getSemaphoreFormatById(SemaphoreType semaphore, String formatId) { - if (semaphore != null) - for (Iterator iter = semaphore.getFormatList().getFormat().iterator(); iter - .hasNext();) { - FormatType fmt = (FormatType) iter.next(); - if (fmt.getFormatId().equals(formatId)) - return fmt; - } // for - - return null; - } // getSemaphoreFormatById - - public FormFieldType getFormFieldById(String fieldId) { - if (getFormFieldList() != null && fieldId != null) - for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { - FormFieldType fft = (FormFieldType) iter.next(); - if (fft.getFieldId().equals(fieldId)) - return fft; - } // for - - return null; - } // getFormFieldById - - public FormFieldType getFormFieldByDisplayValue(String fieldDisplay) { - // fieldDisplay expected to be [fieldName] - if (getFormFieldList() != null && fieldDisplay != null) - for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { - FormFieldType fft = (FormFieldType) iter.next(); - if (fieldDisplay.equals(getFormFieldDisplayName(fft))) - return fft; - } // for - - return null; - } // getFormFieldById - - public String getFormFieldDisplayName(FormFieldType fft) { - return "[" + fft.getFieldName() + "]"; - } // getFormFieldDisplayName - - /** ************************************************************************************************* */ - - public void resetCache(boolean sqlOnly) { - generatedSQL = null; - if (!sqlOnly) { - allColumns = null; - allFilters = null; - } - } // resetCache - - public String getOuterJoinType(DataSourceType curTable) { - String refDefinition = nvl(curTable.getRefDefinition()); - int outerJoinIdx = refDefinition.indexOf(" (+)"); - if (outerJoinIdx < 0) - // No outer join - return ""; - - int equalSignIdx = refDefinition.indexOf("="); - if (refDefinition.indexOf(curTable.getTableId()) < equalSignIdx) - // Cur. table is on the left side - return (outerJoinIdx < equalSignIdx) ? AppConstants.OJ_CURRENT - : AppConstants.OJ_JOINED; - else - // Joined table is on the left side - return (outerJoinIdx < equalSignIdx) ? AppConstants.OJ_JOINED - : AppConstants.OJ_CURRENT; - } // getOuterJoinType - - public String getFormFieldName(ColFilterType filter) { - FormFieldType fft = null; - if (filter.getArgType().equals(AppConstants.AT_FORM)) - fft = getFormFieldByDisplayValue(filter.getArgValue()); - - return (fft != null) ? fft.getFieldId() : filter.getColId() + "_f" - + filter.getFilterSeq(); - } // getFormFieldName - - public String getFormFieldDisplayName(DataColumnType column, ColFilterType filter) { - FormFieldType fft = null; - if (filter.getArgType().equals(AppConstants.AT_FORM)) - fft = getFormFieldByDisplayValue(filter.getArgValue()); - - return (fft != null) ? fft.getFieldName() : column.getDisplayName() + " " - + filter.getExpression(); - } // getFormFieldDisplayName - - public Calendar getFormFieldRangeStart(ColFilterType filter) { - FormFieldType fft = null; - if (filter.getArgType().equals(AppConstants.AT_FORM)) - fft = getFormFieldByDisplayValue(filter.getArgValue()); - - return (fft != null) ? fft.getRangeStartDate().toGregorianCalendar() : null; - } // getFormFieldRangeStart - - public Calendar getFormFieldRangeEnd(ColFilterType filter) { - FormFieldType fft = null; - if (filter.getArgType().equals(AppConstants.AT_FORM)) - fft = getFormFieldByDisplayValue(filter.getArgValue()); - - //System.out.println("as " + fft.getRangeEndDate()); - return (fft != null) ? fft.getRangeEndDate().toGregorianCalendar() : null; - } // getFormFieldRangeEnd - - public String getFormFieldRangeStartSQL(ColFilterType filter) { - FormFieldType fft = null; - if (filter.getArgType().equals(AppConstants.AT_FORM)) - fft = getFormFieldByDisplayValue(filter.getArgValue()); - - return (fft != null) ? fft.getRangeStartDateSQL() : null; - } // getFormFieldRangeStart - - public String getFormFieldRangeEndSQL(ColFilterType filter) { - FormFieldType fft = null; - if (filter.getArgType().equals(AppConstants.AT_FORM)) - fft = getFormFieldByDisplayValue(filter.getArgValue()); - - //System.out.println("as " + fft.getRangeEndDate()); - return (fft != null) ? fft.getRangeEndDateSQL() : null; - } // getFormFieldRangeEnd - - public String getUniqueTableId(String tableName) { - String tableIdPrefix = tableName.startsWith("MSA_") ? tableName.substring(4, 6) - : tableName.substring(0, 2); - String tableId = ""; - - int tableIdN = getDataSourceList().getDataSource().size() + 1; - do { - tableId = tableIdPrefix.toLowerCase() + (tableIdN++); - } while (getTableById(tableId) != null); - - return tableId; - } // getUniqueTableId - - /** ************************************************************************************************* */ - - protected void deleteDataSourceType(String tableId) { - List dsList = getDataSourceList().getDataSource(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType dst = (DataSourceType) iter.next(); - if (dst.getTableId().equals(tableId)) - iter.remove(); - else if (nvl(dst.getRefTableId()).equals(tableId)) { - dst.setRefTableId(null); - dst.setRefDefinition(null); - } - } // for - - resetCache(false); - } // deleteDataSourceType - - public static void adjustColumnType(DataColumnType dct) { - dct.setColType(dct.getDbColType()); - - if (dct.isCalculated()) - if (dct.getColName().startsWith("SUM(") || dct.getColName().startsWith("COUNT(") - || dct.getColName().startsWith("AVG(") - || dct.getColName().startsWith("STDDEV(") - || dct.getColName().startsWith("VARIANCE(")) - dct.setColType(AppConstants.CT_NUMBER); - else if (dct.getColName().startsWith("DECODE(") || dct.getColName().startsWith("coalesce(")) - dct.setColType(AppConstants.CT_CHAR); - } // adjustColumnType - - public static boolean getColumnNoParseDateFlag(DataColumnType dct) { - return (nvls(dct.getComment()).indexOf(AppConstants.CF_NO_PARSE_DATE) >= 0); - } // getColumnNoParseDateFlag - - public static void setColumnNoParseDateFlag(DataColumnType dct, boolean noParseDateFlag) { - dct.setComment(noParseDateFlag ? AppConstants.CF_NO_PARSE_DATE : null); - } // setColumnNoParseDateFlag - - /** ************************************************************************************************* */ - - public static String getSQLBasedFFTColTableName(String fftColId) { - return fftColId.substring(0, fftColId.indexOf('.')); - } // getSQLBasedFFTColTableName - - public static String getSQLBasedFFTColColumnName(String fftColId) { - fftColId = (fftColId.indexOf('|') < 0) ? fftColId : fftColId.substring(0, fftColId - .indexOf('|')); - return fftColId.substring(fftColId.indexOf('.') + 1); - } // getSQLBasedFFTColColumnName - - public static String getSQLBasedFFTColDisplayFormat(String fftColId) { - return (fftColId.indexOf('|') < 0) ? "" : fftColId - .substring(fftColId.indexOf('|') + 1); - } // getSQLBasedFFTColDisplayFormat - - /** ************************************************************************************************* */ - - public List getAllColumns() { - if (cr == null) - throw new NullPointerException("CustomReport not initialized"); - - if (allColumns == null) { - allColumns = new Vector(); - - List dsList = getDataSourceList().getDataSource(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType ds = (DataSourceType) iter.next(); - - // allColumns.addAll(ds.getDataColumnList().getDataColumn()); - List dcList = ds.getDataColumnList().getDataColumn(); - for (Iterator iterC = dcList.iterator(); iterC.hasNext();) { - DataColumnType dc = (DataColumnType) iterC.next(); - - allColumns.add(dc); - } // for - } // for - - Collections.sort(allColumns, new OrderSeqComparator()); - } // if - - return allColumns; - } // getAllColumns - - public List getOnlyVisibleColumns() { - if (cr == null) - throw new NullPointerException("CustomReport not initialized"); - - if (allVisibleColumns == null) { - allVisibleColumns = new Vector(); - - List dsList = getDataSourceList().getDataSource(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType ds = (DataSourceType) iter.next(); - - // allColumns.addAll(ds.getDataColumnList().getDataColumn()); - List dcList = ds.getDataColumnList().getDataColumn(); - for (Iterator iterC = dcList.iterator(); iterC.hasNext();) { - DataColumnType dc = (DataColumnType) iterC.next(); - if(dc.isVisible()) - allVisibleColumns.add(dc); - } // for - } // for - - Collections.sort(allVisibleColumns, new OrderSeqComparator()); - } // if - - return allVisibleColumns; - } // getOnlyVisibleColumns - public int getVisibleColumnCount() { - if (cr == null) - throw new NullPointerException("CustomReport not initialized"); - int colCount = 0; - List dsList = getDataSourceList().getDataSource(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType ds = (DataSourceType) iter.next(); - - // allColumns.addAll(ds.getDataColumnList().getDataColumn()); - List dcList = ds.getDataColumnList().getDataColumn(); - for (Iterator iterC = dcList.iterator(); iterC.hasNext();) { - DataColumnType dc = (DataColumnType) iterC.next(); - if(dc.isVisible()) colCount ++; - } // for - } // for - - return colCount; - } - - public List getAllFilters() { - if (cr == null) - throw new NullPointerException("CustomReport not initialized"); - - // if(allFilters==null) { - allFilters = new Vector(); - - List reportCols = getAllColumns(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - - if (dct.getColFilterList() != null) { - List colFilters = dct.getColFilterList().getColFilter(); - - for (Iterator iterF = colFilters.iterator(); iterF.hasNext();) { - ColFilterType cft = (ColFilterType) iterF.next(); - - allFilters.add(cft); - } // for - } // if - } // for - - // Collections.sort(allFilters, ??); - // } // if - - return allFilters; - } // getAllFilters - - private String formatValue(String value, DataColumnType dc, boolean useDefaultDateFormat) throws RaptorException { - return formatValue(value, dc, useDefaultDateFormat, getColumnTableById(dc.getColId()), null); - } // formatValue - - private String formatValue(String value, DataColumnType dc, boolean useDefaultDateFormat, - DataSourceType ds, FormFieldType fft) throws RaptorException { - String fmtValue = null; - - if (nvl(value).length() == 0) - fmtValue = ""; - else if (value.equals(AppConstants.FILTER_MAX_VALUE) - || value.equals(AppConstants.FILTER_MIN_VALUE)) - fmtValue = "(SELECT " - + (value.equals(AppConstants.FILTER_MAX_VALUE) ? "MAX" : "MIN") + "(" - + dc.getColName() + ") FROM " + ds.getTableName() + ")"; - else if (dc.getColType().equals(AppConstants.CT_NUMBER)) { - try { - double vD = Double.parseDouble(value); - fmtValue = value; - } catch(NumberFormatException ex) { - throw new UserDefinedException("Expected number, Given String for the form field \"" + fft.getFieldName()+"\""); - } - } - else if (dc.getColType().equals(AppConstants.CT_DATE)) { - if (fft!=null && (fft.getValidationType().equals(FormField.VT_TIMESTAMP_HR) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) ) { - fmtValue = "TO_DATE('" - + value - + "', '" - + (useDefaultDateFormat ? AppConstants.DEFAULT_DATE_FORMAT : nvl(dc - .getColFormat(), AppConstants.DEFAULT_DATE_FORMAT));//+" HH24:MI:SS')"; - fmtValue = fmtValue + " HH24"; - if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) - fmtValue = fmtValue + ":MI"; - if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) - fmtValue = fmtValue + " HH24:MI:SS"; - } else { - fmtValue = "TO_DATE('" - + value - + "', '" - + (useDefaultDateFormat ? AppConstants.DEFAULT_DATE_FORMAT : nvl(dc - .getColFormat(), AppConstants.DEFAULT_DATE_FORMAT)) + "')"; - if (Globals.getMonthFormatUseLastDay()) - if (!useDefaultDateFormat) - if (nvl(dc.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT).equals( - "MM/YYYY") - || nvl(dc.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT) - .equals("MONTH, YYYY")) - fmtValue = "ADD_MONTHS(" + fmtValue + ", 1)-1"; - } - }else { - fmtValue = value; - if (!fmtValue.startsWith("'")) - fmtValue = "'" + fmtValue + "'"; - } - - return fmtValue; - } // formatValue - - private String formatListValue(String listValue, DataColumnType dc, - boolean useDefaultDateFormat, boolean useOnlyPipeDelimiter) throws RaptorException { - return formatListValue("", listValue, dc, useDefaultDateFormat, useOnlyPipeDelimiter, - getColumnTableById(dc.getColId()), null); - } // formatListValue - - public String formatListValue(String fieldDisplay, String listValue, DataColumnType dc, - boolean useDefaultDateFormat, boolean useOnlyPipeDelimiter, DataSourceType ds, - String listBaseSQL) throws RaptorException { - StringBuffer fmtValue = new StringBuffer(""); - //if(nvl(listValue,"").trim().length()>0) { - // The below statement is commented so that pipe is taken out from parsing for text area form field -// StringTokenizer st = new StringTokenizer(listValue, useOnlyPipeDelimiter ? "|" - //: ",|\n\r\f"); - StringTokenizer st = new StringTokenizer(listValue, useOnlyPipeDelimiter ? "|" - : ",\n\r\f"); - - while (st.hasMoreTokens()) { - if (fmtValue.length() > 0) - fmtValue.append(", "); - - if (dc == null) { - // For SQL-based reports - value always string - String value = st.nextToken().trim(); - if (value.startsWith("'")) - fmtValue.append(value); - else - fmtValue.append("'" + value + "'"); - } else - fmtValue.append(formatValue(st.nextToken().trim(), dc, useDefaultDateFormat, - ds, null) ); - - } // while - - if (fmtValue.length() == 0) { - if(nvl(fieldDisplay).length() > 0) { - fmtValue.append(""); - } else { - fmtValue.append("("); - fmtValue.append(nvl(listBaseSQL, "NULL")); - fmtValue.append(")"); - } - } else if (fmtValue.charAt(0) != '(') { - fmtValue.insert(0, '('); - fmtValue.append(')'); - } - /* } else { - fmtValue = new StringBuffer("()"); - }*/ - return fmtValue.toString(); - } // formatListValue - - private String getColumnSelectStr(DataColumnType dc, ReportParamValues paramValues) { - String colName = dc.isCalculated() ? dc.getColName() - : ((nvl(dc.getTableId()).length() > 0) ? (dc.getTableId() + "." + dc - .getColName()) : dc.getColName()); - String paramValue = null; - if (dc.isCalculated()) - if (getFormFieldList() != null) - for (Iterator iter2 = getFormFieldList().getFormField().iterator(); iter2 - .hasNext();) { - FormFieldType fft = (FormFieldType) iter2.next(); - String fieldId = fft.getFieldId(); - String fieldDisplay = getFormFieldDisplayName(fft); - if (!paramValues.isParameterMultiValue(fieldId)) { - paramValue = paramValues.getParamValue(fieldId); - if(paramValue!=null && paramValue.length() > 0) { - colName = Utils.replaceInString(colName, fieldDisplay, Utils - .oracleSafe(nvl(paramValue, "NULL"))); - } else { - colName = Utils.replaceInString(colName, "'" + fieldDisplay + "'", nvl( - paramValue, "NULL")); - colName = Utils.replaceInString(colName, fieldDisplay, nvl( - paramValue, "NULL")); - } - } - } // for - - return colName; - } // getColumnSelectStr - - private void addExtraIdSelect(StringBuffer selectExtraIdCl, String drillDownParams, - boolean includeSelectExpr) { - // drillDownParams - example value "c_master=[bo1.RECID$]" - drillDownParams = drillDownParams.substring(10, drillDownParams.length() - 1); // i.e. - // "bo1.RECID$" - - selectExtraIdCl.append(", "); - if (includeSelectExpr) { - selectExtraIdCl.append(drillDownParams); - selectExtraIdCl.append(" "); - } // if - selectExtraIdCl.append(drillDownParams.replace('.', '_')); // i.e. - // "bo1_RECID$" - } // addExtraIdSelect - - private void addExtraDateSelect(StringBuffer selectExtraDateCl, String drillDownParams, - ReportParamValues paramValues, boolean includeSelectExpr) { - // drillDownParams - example value "ff1=[dl1]&fc2=[mo3]" - String colId = ""; - while (drillDownParams.indexOf('[') >= 0) { - int startIdx = drillDownParams.indexOf('['); - int endIdx = drillDownParams.indexOf(']'); - - if(startIdx<=endIdx) { - colId = drillDownParams.substring(startIdx + 1, endIdx); // i.e. - } else { - drillDownParams = drillDownParams.substring(endIdx + 1); - continue; - } - // "dl1" - - DataColumnType column = getColumnById(colId); - if (column != null) - if (column.getColType().equals(AppConstants.CT_DATE)) - if (!nvl(column.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT).equals( - AppConstants.DEFAULT_DATE_FORMAT)) - if (selectExtraDateCl.toString().indexOf( - " " + colId + AppConstants.DD_COL_EXTENSION) < 0) { - selectExtraDateCl.append(", "); - if (includeSelectExpr) { - selectExtraDateCl.append("TO_CHAR(" - + getColumnSelectStr(column, paramValues) + ", '" - + AppConstants.DEFAULT_DATE_FORMAT + "')"); - selectExtraDateCl.append(" "); - } // if - selectExtraDateCl.append(colId + AppConstants.DD_COL_EXTENSION); // i.e. - // "dl1_dde" - } // if - - drillDownParams = drillDownParams.substring(endIdx + 1); - } // while - } // addExtraDateSelect - - /* - * public String generateSQL() { return generateSQL(null); } // generateSQL - */ - public String generateSQL(String userId, HttpServletRequest request) throws RaptorException { - return generateSQL(new ReportParamValues(), userId, request); - } // generateSQL - - public String generateSQL(ReportParamValues paramValues, String userId, HttpServletRequest request) throws RaptorException { - return generateSQL(paramValues, null, AppConstants.SO_ASC, userId, request); - } // generateSQL - - public String generateSQL(ReportParamValues paramValues, String overrideSortByColId, - String overrideSortByAscDesc, String userId, HttpServletRequest request) throws RaptorException { - if (cr == null) - throw new NullPointerException("CustomReport not initialized"); - if(nvl(getWholeSQL()).length()>0) return getWholeSQL(); - if (paramValues.size() > 0) - resetCache(true); - //resetCache(true); - if (generatedSQL == null) { - if (getReportDefType().equals(AppConstants.RD_SQL_BASED) || getReportDefType().equals(AppConstants.RD_SQL_BASED_DATAMIN)) { - generatedSQL = generateSQLSQLBased(paramValues, overrideSortByColId, - overrideSortByAscDesc, userId, request ); - generatedChartSQL = generateSQLSQLBased(paramValues, null, - AppConstants.SO_ASC, userId, request ); - } else if (getReportDefType().equals(AppConstants.RD_VISUAL) && !getReportType().equals(AppConstants.RT_CROSSTAB)) { - generatedSQL = generateSQLVisual(paramValues, overrideSortByColId, - overrideSortByAscDesc, userId, request); - generatedChartSQL = generateSQLVisual(paramValues, null, - AppConstants.SO_ASC, userId, request); - } else { - generatedSQL = generateSQLCrossTabVisual(paramValues, overrideSortByColId, - overrideSortByAscDesc, userId, request); - } - - //debugLogger.debug("******************"); - //debugLogger.debug("SQL Before Changing new line \n" + generatedSQL); - //debugLogger.debug("******************"); - generatedSQL = replaceNewLine(generatedSQL, ""+ '\n', " "+'\n'+" " ); - //chart sql should not be null - if(nvl(generatedChartSQL).trim().length()>0) - generatedChartSQL = replaceNewLine(generatedChartSQL, ""+ '\n', " "+'\n'+" " ); - //(generatedSQL, "\n", " \n "); - //debugLogger.debug("******************"); - //debugLogger.debug("SQL After Changing new line \n" + generatedSQL); - //debugLogger.debug("******************"); - //generatedSQL = replaceNewLine(generatedSQL, "SELECT", "SELECT "); - //generatedSQL = replaceNewLine(generatedSQL, "select", "select "); - //debugLogger.debug("SQL After Changing new line \n" + generatedSQL); - //debugLogger.debug("[[[[[[[[[[[[[[[[[["); - //generatedSQL = Utils.replaceInString(generatedSQL, "\n", " "); - //generatedSQL = Utils.replaceInString(generatedSQL, "\t", " "); - } // if - - return generatedSQL; - } // generateSQL - - public String generateSQLSQLBased(ReportParamValues paramValues, - String overrideSortByColId, String overrideSortByAscDesc, String userId, HttpServletRequest request) throws RaptorException { - String sql = getReportSQL(); - DataSet ds = null; - //debugLogger.debug(" generateSQLSQLBased " + sql); - String[] reqParameters = Globals.getRequestParams().split(","); - String[] sessionParameters = Globals.getSessionParams().split(","); - String[] scheduleSessionParameters = Globals.getSessionParamsForScheduling().split(","); - javax.servlet.http.HttpSession session = request.getSession(); - String dbType = ""; - String dbInfo = getDBInfo(); - int fieldCount = 0; - // For Daytona removing all formfields which has null param value - Pattern re1 = null; - Matcher matcher = null; - int index = 0; - int posFormField = 0; - int posAnd = 0; - if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { - try { - org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); - dbType = remDbInfo.getDBType(dbInfo); - } catch (Exception ex) { - throw new RaptorException(ex); - } - } - - sql = sql + " "; - sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ss][Ee][Ll][Ee][Cc][Tt]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" SELECT "); - //sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ff][Rr][Oo][Mm]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" FROM "); - sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ww][Hh][Ee][Rr][Ee]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" WHERE "); - sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ww][Hh][Ee][Nn]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" WHEN "); - sql = Pattern.compile("(^[\r\n]*|([\\s]))[Aa][Nn][Dd]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" AND "); - - if (getFormFieldList() != null) { - for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { - - FormFieldType fft = (FormFieldType) iter.next(); - String fieldId = fft.getFieldId(); - String fieldDisplay = getFormFieldDisplayName(fft); - if(!fft.getFieldType().equals(FormField.FFT_BLANK)) { - if (paramValues.isParameterMultiValue(fieldId)) { - String replaceValue = formatListValue(fieldDisplay, Utils - .oracleSafe(nvl(paramValues.getParamValue(fieldId))), null, false, - true, null, paramValues.getParamBaseSQL(fieldId)); - if(replaceValue.length() > 0) { - sql = Utils.replaceInString(sql, fieldDisplay, replaceValue); - } else { - fieldCount++; - if(fieldCount == 1) { - //sql = sql + " "; - //sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ss][Ee][Ll][Ee][Cc][Tt]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" SELECT "); - //sql = Pattern.compile("(^[\r\n]*|([\\s]))[Ww][Hh][Ee][Rr][Ee]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" WHERE "); - //sql = Pattern.compile("(^[\r\n]*|([\\s]))[Aa][Nn][Dd]([\r\n]*|[\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" AND "); - } - //sql = getReportSQL(); - while(sql.indexOf(fieldDisplay) > 0) { -/* sql = Utils.replaceInString(sql, "SELECT ", "select "); - sql = Utils.replaceInString(sql, "WHERE", "where"); - sql = Utils.replaceInString(sql, " AND ", " and "); -*/ - re1 = Pattern.compile("(^[\r\n]|[\\s])AND(.*?[^\r\n]*)"+ "\\["+fft.getFieldName()+ "\\](.*?)\\s", Pattern.DOTALL); - //re1 = Pattern.compile("(^[\r\n]|[\\s])AND(.*?[^\r\n]*)"+ "\\["+fft.getFieldName()+ "\\]", Pattern.DOTALL); -/* posFormField = sql.indexOf(fieldDisplay); - posAnd = sql.lastIndexOf("and", posFormField); - if(posAnd < 0) posAnd = 0; - else if (posAnd > 2) posAnd = posAnd - 2; - matcher = re1.matcher(sql); -*/ - posFormField = sql.indexOf(fieldDisplay); - int posSelectField = sql.lastIndexOf("SELECT ", posFormField); - int andField = 0; - int whereField = 0, whenField = 0; - andField = sql.lastIndexOf(" AND ", posFormField); - whereField = sql.indexOf(" WHERE" , posSelectField); - whenField = sql.indexOf(" WHEN" , posSelectField); - - if(posFormField > whereField) - andField = sql.lastIndexOf(" AND ", posFormField); - if (posFormField > andField && (andField > whereField || andField > whenField)) - posAnd = andField; - else - posAnd = 0; - matcher = re1.matcher(sql); - - - if (posAnd > 0 && matcher.find(posAnd-1)) { - //sql = Utils.replaceInString(sql, matcher.group(), " "); - matcher = re1.matcher(sql); - index = sql!=null?sql.lastIndexOf("["+fft.getFieldName()+"]"):-1; - - if(andField>0) - index = andField; - else - index = whereField; - if(index >= 0 && matcher.find(index-1)) { - sql = sql.replace(matcher.group(), " "); - } - } else { - - //sql = sql.replace - re1 = Pattern.compile("(^[\r\n]|[\\s])WHERE(.*?[^\r\n]*)\\["+fft.getFieldName()+ "\\](.*?)\\s", Pattern.DOTALL); - matcher = re1.matcher(sql); - if(whereField != -1) { - if(matcher.find(whereField-1)) { - matcher = re1.matcher(sql); - index = sql!=null?sql.lastIndexOf("["+fft.getFieldName()+"]"):-1; - if(index >= 0 && matcher.find(index-30)) { - sql = sql.replace(matcher.group(), " WHERE 1=1 "); - } - //sql = Utils.replaceInString(sql, matcher.group(), " where 1=1 "); - } /*else { - replaceValue = formatListValue("", Utils - .oracleSafe(nvl(paramValues.getParamValue(fieldId))), null, false, - true, null, paramValues.getParamBaseSQL(fieldId)); - sql = Utils.replaceInString(sql, fieldDisplay, replaceValue); - }*/ - } else { - sql = Utils.replaceInString(sql, fieldDisplay, replaceValue); - } - - } - } - } - - //sql = Utils.replaceInString(sql, " select ", " SELECT "); - //sql = Utils.replaceInString(sql, " where ", " WHERE "); - //sql = Utils.replaceInString(sql, " and ", " AND "); - - } else { - String paramValue = ""; - if(paramValues.isParameterTextAreaValueAndModified(fieldId)) { - String value = ""; - value = nvl(paramValues - .getParamValue(fieldId)); -// value = Utils.oracleSafe(nvl(value)); -// if (!(dbType.equals("DAYTONA") && sql.trim().toUpperCase().startsWith("SELECT"))) { -// value = "('" + Utils.replaceInString(value, ",", "'|'") + "')"; -// value = Utils.replaceInString(value, "|", ","); -// paramValue = XSSFilter.filterRequestOnlyScript(value); -// } else if (nvl(value.trim()).length()>0) { -// value = "('" + Utils.replaceInString(value, ",", "'|'") + "')"; -// value = Utils.replaceInString(value, "|", ","); -// paramValue = XSSFilter.filterRequestOnlyScript(value); -// } - paramValue = value; - } else - paramValue = Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId))); - - if (paramValue!=null && paramValue.length() > 0) { - if(paramValue.toLowerCase().trim().startsWith("select ")) { - paramValue = Utils.replaceInString(paramValue, "[LOGGED_USERID]", userId); - paramValue = Utils.replaceInString(paramValue, "[USERID]", userId); - paramValue = Utils.replaceInString(paramValue, "[USER_ID]", userId); - - paramValue = Utils.replaceInString(paramValue, "''", "'"); - ds = ConnectionUtils.getDataSet(paramValue, dbInfo); - if (ds.getRowCount() > 0) paramValue = ds.getString(0, 0); - } - //debugLogger.debug("SQLSQLBASED B4^^^^^^^^^ " + sql + " " + fft.getValidationType() + " " + fft.getFieldName() + " " + fft.getFieldId()); - if(fft!=null && (fft.getValidationType()!=null && (fft.getValidationType().equals(FormField.VT_TIMESTAMP_HR) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) ||fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC) ||fft.getValidationType().equals(FormField.VT_DATE) ))) { - //System.out.println("paramValues.getParamValue(fieldId_Hr) Inside if " + fft.getValidationType() + " " + fieldDisplay); - if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_HR)) { - sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue) +((nvl(paramValues - .getParamValue(fieldId+"_Hr") ).length()>0)?" "+addZero(Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId+"_Hr") ) ) ):"")); - } - else if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN)) { -/* System.out.println("paramValues.getParamValue(fieldId_Hr)" + paramValues - .getParamValue(fieldId+"_Hr") + " " + paramValues - .getParamValue(fieldId+"_Min")) ; -*/ sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue) + ((nvl(paramValues - .getParamValue(fieldId+"_Hr") ).length()>0)?" "+addZero(Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId+"_Hr") ) ) ):"") + ((nvl(paramValues - .getParamValue(fieldId+"_Min") ).length()>0)?":" + addZero(Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId+"_Min") ) ) ) : "") ) ; - } - else if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { - sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue) + ((nvl(paramValues - .getParamValue(fieldId+"_Hr") ).length()>0)?" "+addZero(Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId+"_Hr") ) ) ):"") + ((nvl(paramValues - .getParamValue(fieldId+"_Min") ).length()>0)?":" + addZero(Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId+"_Min") ) ) ) : "") + ((nvl(paramValues - .getParamValue(fieldId+"_Sec") ).length()>0)?":"+addZero(Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId+"_Sec") ) ) ) : "" ) ) ; - } else { - sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue, "NULL")); - } - - - } else { - if(paramValue!=null && paramValue.length() > 0) { - if(sql.indexOf("'"+fieldDisplay+"'")!=-1 || sql.indexOf("'"+fieldDisplay)!=-1 || sql.indexOf(fieldDisplay+"'")!=-1 - || sql.indexOf("'%"+fieldDisplay+"%'")!=-1 || sql.indexOf("'%"+fieldDisplay)!=-1 || sql.indexOf(fieldDisplay+"%'")!=-1 - || sql.indexOf("'_"+fieldDisplay+"_'")!=-1 || sql.indexOf("'_"+fieldDisplay)!=-1 || sql.indexOf(fieldDisplay+"_'")!=-1 - || sql.indexOf("'%_"+fieldDisplay+"_%'")!=-1 || sql.indexOf("^"+fieldDisplay+"^")!=-1 || sql.indexOf("'%_"+fieldDisplay)!=-1 || sql.indexOf(fieldDisplay+"_%'")!=-1) { - sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue, "NULL")); - } else { - if(sql.indexOf(fieldDisplay)!=-1) { - if(nvl(paramValue).length()>0) { - try { - double vD = Double.parseDouble(paramValue); - sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue, "NULL")); - - } catch (NumberFormatException ex) { - if (/*dbType.equals("DAYTONA") &&*/ sql.trim().toUpperCase().startsWith("SELECT")) { - sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue, "NULL")); - } else - throw new UserDefinedException("Expected number, Given String for the form field \"" + fieldDisplay+"\""); - } - /*sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue, "NULL"));*/ - } else - sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue, "NULL")); - - } - } - } - else { - if (dbType.equals("DAYTONA") && sql.trim().toUpperCase().startsWith("SELECT")) { - sql = sql + " "; - re1 = Pattern.compile("(^[\r\n]|[\\s]|[^0-9a-zA-Z])AND(.*?[^\r\n]*)"+ "\\["+fft.getFieldName()+ "\\](.*?)\\s", Pattern.DOTALL); - posFormField = sql.indexOf(fieldDisplay); - posAnd = sql.lastIndexOf(" AND ", posFormField); - if(posAnd < 0) posAnd = 0; - else if (posAnd > 2) posAnd = posAnd - 2; - matcher = re1.matcher(sql); - if (matcher.find(posAnd)) { - sql = sql.replace(matcher.group(), ""); - } - } else { - sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( - paramValue, "NULL")); - sql = Utils.replaceInString(sql, fieldDisplay, nvl( - paramValue, "NULL")); - } - } - } - - } - - if (dbType.equals("DAYTONA") && sql.trim().toUpperCase().startsWith("SELECT")) { - sql = sql + " "; - re1 = Pattern.compile("(^[\r\n]|[\\s]|[^0-9a-zA-Z])AND(.*?[^\r\n]*)"+ "\\["+fft.getFieldName()+ "\\](.*?)\\s", Pattern.DOTALL); //+[\'\\)|\'|\\s] - posFormField = sql.indexOf(fieldDisplay); - posAnd = sql.lastIndexOf(" AND ", posFormField); - if(posAnd < 0) posAnd = 0; - else if (posAnd > 2) posAnd = posAnd - 2; - matcher = re1.matcher(sql); - if (matcher.find(posAnd)) { - sql = sql.replace(matcher.group(), " "); - } - } else { - if( fft.isGroupFormField()!=null && fft.isGroupFormField().booleanValue()) { - sql = Pattern.compile("[[\\s*][,]]\\["+fft.getFieldName()+"\\](.*?)[,]",Pattern.MULTILINE).matcher(sql).replaceAll(" "); - //sql = Pattern.compile("[,][\\s*]\\["+fft.getFieldName()+"\\][\\s]",Pattern.MULTILINE).matcher(sql).replaceAll(" "); - sql = Pattern.compile("(,.+?)[\\s*]\\["+fft.getFieldName()+"\\][\\s]",Pattern.MULTILINE).matcher(sql).replaceAll(" "); - //sql = Pattern.compile("(?:,?)[\\s*]\\["+fft.getFieldName()+"\\]",Pattern.MULTILINE).matcher(sql).replaceAll(""); - //sql = Pattern.compile("[,][\\s*]\\["+fft.getFieldName()+"\\]",Pattern.MULTILINE).matcher(sql).replaceAll(" "); - //sql = Pattern.compile( "\\["+fft.getFieldName()+"\\](.*?[^\r\n]*)[,]",Pattern.DOTALL).matcher(sql).replaceAll(""); - - //sql = Pattern.compile("[,]|(.*?[^\r\n]*)"+fieldDisplay+"(.*?)\\s",Pattern.DOTALL).matcher(sql).replaceAll(""); - //sql = Pattern.compile("(.*?[^\r\n]*)"+fieldDisplay+"(.*?)\\s|[,]",Pattern.DOTALL).matcher(sql).replaceAll(""); -/* sql = Utils.replaceInString(sql, "," + fieldDisplay , nvl( - paramValue, "")); - sql = Utils.replaceInString(sql, fieldDisplay + "," , nvl( - paramValue, "")); -*/ } else { - //debugLogger.debug("ParamValue |" + paramValue + "| Sql |" + sql + "| Multi Value |" + paramValues.isParameterMultiValue(fieldId)); - sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( - paramValue, "NULL")); - sql = Utils.replaceInString(sql, fieldDisplay , nvl( - paramValue, "NULL")); - //debugLogger.debug("SQLSQLBASED AFTER^^^^^^^^^ " + sql); - } - } - - } // else - } // if BLANK - } // for - if(request != null ) { - for (int i = 0; i < reqParameters.length; i++) { - if(!reqParameters[i].startsWith("ff")) { - if (nvl(request.getParameter(reqParameters[i].toUpperCase())).length() > 0) - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); - } - else - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); - } - - for (int i = 0; i < scheduleSessionParameters.length; i++) { - if(nvl(request.getParameter(scheduleSessionParameters[i])).trim().length()>0 ) - sql = Utils.replaceInString(sql, "[" + scheduleSessionParameters[i].toUpperCase()+"]", request.getParameter(scheduleSessionParameters[i]) ); - } - } - if(session != null ) { - for (int i = 0; i < sessionParameters.length; i++) { - //if(!sessionParameters[i].startsWith("ff")) - // paramValue = Utils.replaceInString(paramValue, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i].toUpperCase()) ); - // else { - //debugLogger.debug(" Session " + " sessionParameters[i] " + sessionParameters[i] + " " + (String)session.getAttribute(sessionParameters[i])); - sql = Utils.replaceInString(sql, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); - //} - } - } - } else { - //debugLogger.debug("BEFORE LOGGED USERID REPLACE " + sql); - //sql = Utils.replaceInString(sql, "'[logged_userId]'", "'"+userId+"'"); - //debugLogger.debug("Replacing string 2 " + sql); - sql = Utils.replaceInString(sql, "[LOGGED_USERID]", userId); - sql = Utils.replaceInString(sql, "[USERID]", userId); - sql = Utils.replaceInString(sql, "[USER_ID]", userId); - //debugLogger.debug("AFTER LOGGED USERID REPLACE " + sql); - // Added for Simon's GM Project where they need to get page_id in their query - //debugLogger.debug("SQLSQLBASED no formfields " + sql); - if(request != null ) { - for (int i = 0; i < reqParameters.length; i++) { - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); - } - } - if(session != null ) { - for (int i = 0; i < sessionParameters.length; i++) { - //debugLogger.debug(" Session " + " sessionParameters[i] " + sessionParameters[i] + " " + (String)session.getAttribute(sessionParameters[i])); - sql = Utils.replaceInString(sql, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); - } - } - } - // if it is not multiple select and ParamValue is empty this is the place it can be replaced. - sql = Utils.replaceInString(sql, "[LOGGED_USERID]", userId); - sql = Utils.replaceInString(sql, "[USERID]", userId); - sql = Utils.replaceInString(sql, "[USER_ID]", userId); - //debugLogger.debug("SQLSQLBASED no formfields after" + sql); - //debugLogger.debug("Replacing String 2 "+ sql); - //debugLogger.debug("Replaced String " + sql); - - int closeBracketPos = 0; - if (nvl(overrideSortByColId).length() > 0) { - if(sql.lastIndexOf(")")!= -1) closeBracketPos = sql.lastIndexOf(")"); - int idxOrderBy = (closeBracketPos>0)?sql.toUpperCase().indexOf("ORDER BY", closeBracketPos):sql.toUpperCase().lastIndexOf("ORDER BY"); - DataColumnType dct = getColumnById(overrideSortByColId+"_sort"); - if(dct!=null && dct.getColName().length()>0) { - overrideSortByColId = overrideSortByColId+"_sort"; - } - if (idxOrderBy < 0) - sql += " ORDER BY " + overrideSortByColId + " " + overrideSortByAscDesc; - else { - int braketCount = 0; - int idxOrderByClauseEnd = 0; - for (idxOrderByClauseEnd = idxOrderBy; idxOrderByClauseEnd < sql.length(); idxOrderByClauseEnd++) { - char ch = sql.charAt(idxOrderByClauseEnd); - - if (ch == '(') - braketCount++; - else if (ch == ')') { - if (braketCount == 0) - break; - braketCount--; - } - } // for - - sql = sql.substring(0, idxOrderBy) + " ORDER BY " + overrideSortByColId + " " - + overrideSortByAscDesc + sql.substring(idxOrderByClauseEnd); - } // else - } // if - sql = Pattern.compile("([\n][\\s]*)",Pattern.DOTALL).matcher(sql).replaceAll(" "); - return sql; - } // generateSQLSQLBased - - public String generateSQLVisual(ReportParamValues paramValues, String overrideSortByColId, - String overrideSortByAscDesc, String userId, HttpServletRequest request)throws RaptorException { - StringBuffer selectCl = new StringBuffer(); - StringBuffer fromCl = new StringBuffer(); - StringBuffer whereCl = new StringBuffer(); - StringBuffer groupByCl = new StringBuffer(); - StringBuffer havingCl = new StringBuffer(); - StringBuffer orderByCl = new StringBuffer(); - StringBuffer selectExtraIdCl = new StringBuffer(); - StringBuffer selectExtraDateCl = new StringBuffer(); - - int whereClBracketCount = 0; - int havingClBracketCount = 0; - int whereClCarryoverBrackets = 0; - int havingClCarryoverBrackets = 0; - - // Identifying FROM clause tables and WHERE clause joins - List dsList = getDataSourceList().getDataSource(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType ds = (DataSourceType) iter.next(); - - if (fromCl.length() > 0) - fromCl.append(", "); - fromCl.append(ds.getTableName()); - fromCl.append(" "); - fromCl.append(ds.getTableId()); - - if (nvl(ds.getRefTableId()).length() > 0) { - if (whereCl.length() > 0) - whereCl.append(" AND "); - whereCl.append(ds.getRefDefinition()); - } // if - // Add the condition. - TableSource tableSource = null; - String dBInfo = this.cr.getDbInfo(); - Vector userRoles = AppUtils.getUserRoles(request); - tableSource = DataCache.getTableSource(ds.getTableName(), dBInfo,userRoles,userId, request); - if (userId != null && (!AppUtils.isSuperUser(request)) - && (!AppUtils.isAdminUser(request)) && tableSource != null - && nvl(tableSource.getFilterSql()).length() > 0) { - if (whereCl.length() > 0) - whereCl.append(" AND "); - whereCl.append(Utils.replaceInString(Utils.replaceInString(tableSource - .getFilterSql(), "[" + ds.getTableName() + "]", ds.getTableId()), - "[USER_ID]", userId)); - } // if - } // for - - List reportCols = getAllColumns(); - - boolean isGroupStmt = false; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (dc.isGroupBreak()) { - isGroupStmt = true; - break; - } // if - } // for - - // Identifying SELECT and GROUP BY clause fields and WHERE and HAVING - // clause filters - // Collections.sort(reportCols, new OrderSeqComparator()); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, paramValues); - - // SELECT clause fields - //TODO: Uncomment if it's not working -- if (dc.isVisible()) { - if (selectCl.length() > 0) - selectCl.append(", "); - selectCl.append(getSelectExpr(dc, colName)); - selectCl.append(" "); - selectCl.append(dc.getColId()); - //TODO } // if - - // Checking for extra fields necessary for drill-down - if (nvl(dc.getDrillDownURL()).length() > 0) - if (isViewAction(dc.getDrillDownURL())) - addExtraIdSelect(selectExtraIdCl, nvl(dc.getDrillDownParams()), true); - else - addExtraDateSelect(selectExtraDateCl, nvl(dc.getDrillDownParams()), - paramValues, true); - - // GROUP BY clause fields - if (dc.isGroupBreak()) { - if (groupByCl.length() > 0) - groupByCl.append(", "); - groupByCl.append(colName); - } // if - - // WHERE/HAVING clause fields - //boolean isHavingCl = isGroupStmt && dc.isVisible() && (!dc.isGroupBreak()); - boolean isHavingCl = isGroupStmt && (!dc.isGroupBreak()); - StringBuffer filterCl = isHavingCl ? havingCl : whereCl; - // StringBuffer filterCl = - // isGroupStmt?(dc.isVisible()?(dc.isGroupBreak()?whereCl:havingCl):whereCl):whereCl; - if (dc.getColFilterList() != null) { - int fNo = 0; - List fList = dc.getColFilterList().getColFilter(); - for (Iterator iterF = fList.iterator(); iterF.hasNext(); fNo++) { - ColFilterType cf = (ColFilterType) iterF.next(); - - StringBuffer curFilter = new StringBuffer(); - if (filterCl.length() > 0) - curFilter.append(" " + cf.getJoinCondition() + " "); - if ((isHavingCl ? havingClCarryoverBrackets : whereClCarryoverBrackets) > 0) - for (int b = 0; b < (isHavingCl ? havingClCarryoverBrackets - : whereClCarryoverBrackets); b++) - filterCl.append('('); - curFilter.append(nvl(cf.getOpenBrackets())); - curFilter.append(colName + " "); - curFilter.append(cf.getExpression() + " "); - - boolean applyFilter = true; - if ((nvl(cf.getArgValue()).length() > 0) - || (nvl(cf.getArgType()).equals(AppConstants.AT_FORM))) - if (nvl(cf.getArgType()).equals(AppConstants.AT_FORMULA)) - curFilter.append(cf.getArgValue()); - else if (nvl(cf.getArgType()).equals(AppConstants.AT_VALUE)) - curFilter.append(formatValue(cf.getArgValue(), dc, false)); - else if (nvl(cf.getArgType()).equals(AppConstants.AT_LIST)) - curFilter.append(formatListValue(cf.getArgValue(), dc, false, - false)); - else if (nvl(cf.getArgType()).equals(AppConstants.AT_COLUMN)) - curFilter.append(getColumnNameById(cf.getArgValue())); - else if (nvl(cf.getArgType()).equals(AppConstants.AT_FORM)) { - String fieldName = getFormFieldName(cf); - String fieldValue = Utils.oracleSafe(paramValues - .getParamValue(fieldName)); - boolean isMultiValue = paramValues - .isParameterMultiValue(fieldName); - boolean usePipeDelimiterOnly = false; - - FormFieldType fft = getFormFieldByDisplayValue(cf.getArgValue()); - if (fft == null) - // If not FormField => applying default value - fieldValue = nvl(fieldValue, Utils - .oracleSafe(cf.getArgValue())); - else - usePipeDelimiterOnly = fft.getFieldType().equals( - FormField.FFT_CHECK_BOX) - || fft.getFieldType().equals(FormField.FFT_LIST_MULTI); - //Added for TimeStamp validation - String fieldId = fft.getFieldId(); - if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_HR)||fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN)||fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { - fieldValue = nvl( - fieldValue + " " + addZero(Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId+"_Hr") ) ) ) ) ; - if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { - fieldValue = fieldValue + (nvl(paramValues - .getParamValue(fieldId+"_Min")).length()>0 ? ":" + addZero(Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId+"_Min")))): "") ; - } - if(fft.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { - fieldValue = fieldValue + (nvl(paramValues - .getParamValue(fieldId+"_Sec")).length()>0 ? ":"+ addZero(Utils.oracleSafe(nvl(paramValues - .getParamValue(fieldId+"_Sec")))) : ""); - } - } - - // End - if (nvl(fieldValue).length() == 0) - // Does not append filter with missing form - // field argument - applyFilter = false; - else if (isMultiValue || nvl(cf.getExpression()).equals("IN") - || nvl(cf.getExpression()).equals("NOT IN")) - curFilter.append(formatListValue(fieldValue, dc, true, - usePipeDelimiterOnly)); - else - curFilter.append(formatValue(fieldValue, dc, true, null, fft)); - } // else - curFilter.append(nvl(cf.getCloseBrackets())); - - if (applyFilter) { - filterCl.append(curFilter.toString()); - - if (isHavingCl) { - havingClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - havingClCarryoverBrackets = 0; - } else { - whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - whereClCarryoverBrackets = 0; - } - } else if (nvl(cf.getOpenBrackets()).length() != nvl(cf.getCloseBrackets()) - .length()) - if (nvl(cf.getOpenBrackets()).length() > nvl(cf.getCloseBrackets()) - .length()) { - // Carry over opening brackets - if (isHavingCl) - havingClCarryoverBrackets += (nvl(cf.getOpenBrackets()) - .length() - nvl(cf.getCloseBrackets()).length()); - else - whereClCarryoverBrackets += (nvl(cf.getOpenBrackets()) - .length() - nvl(cf.getCloseBrackets()).length()); - - if (isHavingCl) - havingClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - else - whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - } else { - // Adding closing brackets - if (filterCl.length() > 0) { - for (int b = 0; b < nvl(cf.getCloseBrackets()).length() - - nvl(cf.getOpenBrackets()).length(); b++) - filterCl.append(')'); - - if (isHavingCl) - havingClBracketCount += (nvl(cf.getOpenBrackets()) - .length() - nvl(cf.getCloseBrackets()).length()); - else - whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - } // if - } // else - } // for - } // if - } // for - - // Identifying ORDER BY clause fields - DataColumnType overrideSortByCol = null; - if (overrideSortByColId != null) - overrideSortByCol = getColumnById(overrideSortByColId); - - if (overrideSortByCol != null) { - orderByCl.append(getColumnSelectStr(overrideSortByCol, paramValues)); - orderByCl.append(" "); - orderByCl.append(nvl(overrideSortByAscDesc, AppConstants.SO_ASC)); - } else if (getReportType().equals(AppConstants.RT_CROSSTAB)) { - /* - * for(Iterator iter=reportCols.iterator(); iter.hasNext(); ) { - * DataColumnType dc = (DataColumnType) iter.next(); - * - * if(nvl(dc.getCrossTabValue()).equals(AppConstants.CV_ROW)||nvl(dc.getCrossTabValue()).equals(AppConstants.CV_COLUMN)) { - * if(orderByCl.length()>0) orderByCl.append(", "); - * orderByCl.append(getColumnSelectStr(dc, paramValues)); - * orderByCl.append(" "); - * if(dc.getColType().equals(AppConstants.CT_DATE)) - * orderByCl.append(AppConstants.SO_DESC); else - * orderByCl.append(AppConstants.SO_ASC); } // if } // for - */ - } else { - Collections.sort(reportCols, new OrderBySeqComparator()); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - - if (dc.getOrderBySeq() > 0) { - if (orderByCl.length() > 0) - orderByCl.append(", "); - orderByCl.append(getColumnSelectStr(dc, paramValues)); - orderByCl.append(" "); - orderByCl.append(dc.getOrderByAscDesc()); - } // if - } // for - Collections.sort(reportCols, new OrderSeqComparator()); - } // else - - // Adding up the actual statement - StringBuffer sql = new StringBuffer(); - //sql.append("SELECT "); // Need to add PK for /*+ FIRST_ROWS */ "); - sql.append(Globals.getGenerateSqlVisualSelect()); - //sql.append((selectCl.length() == 0) ? "COUNT(*) cnt" : selectCl.toString()); - sql.append((selectCl.length() == 0) ? Globals.getGenerateSqlVisualCount() : selectCl.toString()); - if (groupByCl.length() == 0) - sql.append(selectExtraIdCl.toString()); - sql.append(selectExtraDateCl.toString()); - // sql.append(" FROM "); - sql.append((fromCl.length() == 0) ? Globals.getGenerateSqlVisualDual() : "FROM "+fromCl.toString()); - if (whereCl.length() > 0) { - if (whereClBracketCount > 0) { - for (int b = 0; b < whereClBracketCount; b++) - whereCl.append(')'); - } else if (whereClBracketCount < 0) { - for (int b = 0; b < Math.abs(whereClBracketCount); b++) - whereCl.insert(0, '('); - } // else - - sql.append(" WHERE "); - sql.append(whereCl.toString()); - } // if - if (groupByCl.length() > 0) { - sql.append(" GROUP BY "); - sql.append(groupByCl.toString()); - - if (havingCl.length() > 0) { - if (havingClBracketCount > 0) { - for (int b = 0; b < havingClBracketCount; b++) - havingCl.append(')'); - } else if (havingClBracketCount < 0) { - for (int b = 0; b < Math.abs(havingClBracketCount); b++) - havingCl.insert(0, '('); - } // else - - sql.append(" HAVING "); - sql.append(havingCl.toString()); - } - } - if (orderByCl.length() > 0) { - sql.append(" ORDER BY "); - sql.append(orderByCl.toString()); - } - //String sqlStr = Utils.replaceInString(sql.toString(), "[LOGGED_USERID]", userId); - //return sqlStr; - return sql.toString(); - } // generateSQLVisual - - public String generateSQLCrossTabVisual(ReportParamValues paramValues, String overrideSortByColId, - String overrideSortByAscDesc, String userId, HttpServletRequest request) throws RaptorException { - StringBuffer selectCl = new StringBuffer(); - StringBuffer fromCl = new StringBuffer(); - StringBuffer whereCl = new StringBuffer(); - StringBuffer groupByCl = new StringBuffer(); - StringBuffer havingCl = new StringBuffer(); - StringBuffer orderByCl = new StringBuffer(); - StringBuffer selectExtraIdCl = new StringBuffer(); - StringBuffer selectExtraDateCl = new StringBuffer(); - - int whereClBracketCount = 0; - int havingClBracketCount = 0; - int whereClCarryoverBrackets = 0; - int havingClCarryoverBrackets = 0; - - // Identifying FROM clause tables and WHERE clause joins - List dsList = getDataSourceList().getDataSource(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType ds = (DataSourceType) iter.next(); - - if (fromCl.length() > 0) - fromCl.append(", "); - fromCl.append(ds.getTableName()); - fromCl.append(" "); - fromCl.append(ds.getTableId()); - - if (nvl(ds.getRefTableId()).length() > 0) { - if (whereCl.length() > 0) - whereCl.append(" AND "); - whereCl.append(ds.getRefDefinition()); - } // if - // Add the condition. - TableSource tableSource = null; - String dBInfo = this.cr.getDbInfo(); - Vector userRoles = AppUtils.getUserRoles(request); - tableSource = DataCache.getTableSource(ds.getTableName(), dBInfo,userRoles,userId, request); - if (userId != null && (!AppUtils.isSuperUser(request)) - && (!AppUtils.isAdminUser(request)) && tableSource != null - && nvl(tableSource.getFilterSql()).length() > 0) { - if (whereCl.length() > 0) - whereCl.append(" AND "); - whereCl.append(Utils.replaceInString(Utils.replaceInString(tableSource - .getFilterSql(), "[" + ds.getTableName() + "]", ds.getTableId()), - "[USER_ID]", userId)); - } // if - } // for - - List reportCols = getAllColumns(); - - boolean isGroupStmt = false; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (dc.isGroupBreak()) { - isGroupStmt = true; - break; - } // if - } // for - - // Identifying SELECT and GROUP BY clause fields and WHERE and HAVING - // clause filters - // Collections.sort(reportCols, new OrderSeqComparator()); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, paramValues); - - // SELECT clause fields - if (dc.isVisible()) { - if (selectCl.length() > 0) - selectCl.append(", "); - selectCl.append(getSelectExpr(dc, colName)); - selectCl.append(" "); - selectCl.append(dc.getColId()); - } // if - - // Checking for extra fields necessary for drill-down - if (nvl(dc.getDrillDownURL()).length() > 0) - if (isViewAction(dc.getDrillDownURL())) - addExtraIdSelect(selectExtraIdCl, nvl(dc.getDrillDownParams()), true); - else - addExtraDateSelect(selectExtraDateCl, nvl(dc.getDrillDownParams()), - paramValues, true); - - // GROUP BY clause fields - if (dc.isGroupBreak()) { - if (groupByCl.length() > 0) - groupByCl.append(", "); - groupByCl.append(colName); - } // if - - // WHERE/HAVING clause fields - boolean isHavingCl = isGroupStmt && dc.isVisible() && (!dc.isGroupBreak()); - //boolean isHavingCl = isGroupStmt && (!dc.isGroupBreak()); - //StringBuffer filterCl = isHavingCl ? havingCl : whereCl; - StringBuffer filterCl = - isGroupStmt?(dc.isVisible()?(dc.isGroupBreak()?whereCl:havingCl):whereCl):whereCl; - if (dc.getColFilterList() != null) { - int fNo = 0; - List fList = dc.getColFilterList().getColFilter(); - for (Iterator iterF = fList.iterator(); iterF.hasNext(); fNo++) { - ColFilterType cf = (ColFilterType) iterF.next(); - - StringBuffer curFilter = new StringBuffer(); - if (filterCl.length() > 0) - curFilter.append(" " + cf.getJoinCondition() + " "); - if ((isHavingCl ? havingClCarryoverBrackets : whereClCarryoverBrackets) > 0) - for (int b = 0; b < (isHavingCl ? havingClCarryoverBrackets - : whereClCarryoverBrackets); b++) - filterCl.append('('); - curFilter.append(nvl(cf.getOpenBrackets())); - curFilter.append(colName + " "); - curFilter.append(cf.getExpression() + " "); - - boolean applyFilter = true; - if ((nvl(cf.getArgValue()).length() > 0) - || (nvl(cf.getArgType()).equals(AppConstants.AT_FORM))) - if (nvl(cf.getArgType()).equals(AppConstants.AT_FORMULA)) - curFilter.append(cf.getArgValue()); - else if (nvl(cf.getArgType()).equals(AppConstants.AT_VALUE)) - curFilter.append(formatValue(cf.getArgValue(), dc, false)); - else if (nvl(cf.getArgType()).equals(AppConstants.AT_LIST)) - curFilter.append(formatListValue(cf.getArgValue(), dc, false, - false)); - else if (nvl(cf.getArgType()).equals(AppConstants.AT_COLUMN)) - curFilter.append(getColumnNameById(cf.getArgValue())); - else if (nvl(cf.getArgType()).equals(AppConstants.AT_FORM)) { - String fieldName = getFormFieldName(cf); - String fieldValue = Utils.oracleSafe(paramValues - .getParamValue(fieldName)); - boolean isMultiValue = paramValues - .isParameterMultiValue(fieldName); - boolean usePipeDelimiterOnly = false; - - FormFieldType fft = getFormFieldByDisplayValue(cf.getArgValue()); - if (fft == null) - // If not FormField => applying default value - fieldValue = nvl(fieldValue, Utils - .oracleSafe(cf.getArgValue())); - else - usePipeDelimiterOnly = fft.getFieldType().equals( - FormField.FFT_CHECK_BOX) - || fft.getFieldType().equals(FormField.FFT_LIST_MULTI); - - if (nvl(fieldValue).length() == 0) - // Does not append filter with missing form - // field argument - applyFilter = false; - else if (isMultiValue || nvl(cf.getExpression()).equals("IN") - || nvl(cf.getExpression()).equals("NOT IN")) - curFilter.append(formatListValue(fieldValue, dc, true, - usePipeDelimiterOnly)); - else - curFilter.append(formatValue(fieldValue, dc, true)); - } // else - curFilter.append(nvl(cf.getCloseBrackets())); - - if (applyFilter) { - filterCl.append(curFilter.toString()); - - if (isHavingCl) { - havingClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - havingClCarryoverBrackets = 0; - } else { - whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - whereClCarryoverBrackets = 0; - } - } else if (nvl(cf.getOpenBrackets()).length() != nvl(cf.getCloseBrackets()) - .length()) - if (nvl(cf.getOpenBrackets()).length() > nvl(cf.getCloseBrackets()) - .length()) { - // Carry over opening brackets - if (isHavingCl) - havingClCarryoverBrackets += (nvl(cf.getOpenBrackets()) - .length() - nvl(cf.getCloseBrackets()).length()); - else - whereClCarryoverBrackets += (nvl(cf.getOpenBrackets()) - .length() - nvl(cf.getCloseBrackets()).length()); - - if (isHavingCl) - havingClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - else - whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - } else { - // Adding closing brackets - if (filterCl.length() > 0) { - for (int b = 0; b < nvl(cf.getCloseBrackets()).length() - - nvl(cf.getOpenBrackets()).length(); b++) - filterCl.append(')'); - - if (isHavingCl) - havingClBracketCount += (nvl(cf.getOpenBrackets()) - .length() - nvl(cf.getCloseBrackets()).length()); - else - whereClBracketCount += (nvl(cf.getOpenBrackets()).length() - nvl( - cf.getCloseBrackets()).length()); - } // if - } // else - } // for - } // if - } // for - - // Identifying ORDER BY clause fields - DataColumnType overrideSortByCol = null; - if (overrideSortByColId != null) - overrideSortByCol = getColumnById(overrideSortByColId); - - if (overrideSortByCol != null) { - orderByCl.append(getColumnSelectStr(overrideSortByCol, paramValues)); - orderByCl.append(" "); - orderByCl.append(nvl(overrideSortByAscDesc, AppConstants.SO_ASC)); - } else if (getReportType().equals(AppConstants.RT_CROSSTAB)) { - /* - * for(Iterator iter=reportCols.iterator(); iter.hasNext(); ) { - * DataColumnType dc = (DataColumnType) iter.next(); - * - * if(nvl(dc.getCrossTabValue()).equals(AppConstants.CV_ROW)||nvl(dc.getCrossTabValue()).equals(AppConstants.CV_COLUMN)) { - * if(orderByCl.length()>0) orderByCl.append(", "); - * orderByCl.append(getColumnSelectStr(dc, paramValues)); - * orderByCl.append(" "); - * if(dc.getColType().equals(AppConstants.CT_DATE)) - * orderByCl.append(AppConstants.SO_DESC); else - * orderByCl.append(AppConstants.SO_ASC); } // if } // for - */ - } else { - Collections.sort(reportCols, new OrderBySeqComparator()); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - - if (dc.getOrderBySeq() > 0) { - if (orderByCl.length() > 0) - orderByCl.append(", "); - orderByCl.append(getColumnSelectStr(dc, paramValues)); - orderByCl.append(" "); - orderByCl.append(dc.getOrderByAscDesc()); - } // if - } // for - Collections.sort(reportCols, new OrderSeqComparator()); - } // else - - // Adding up the actual statement - StringBuffer sql = new StringBuffer(); - //sql.append("SELECT "); // Need to add PK for /*+ FIRST_ROWS */ "); - sql.append(Globals.getGenerateSqlVisualSelect()); - // sql.append((selectCl.length() == 0) ? "COUNT(*) cnt" : selectCl.toString()); - sql.append((selectCl.length() == 0) ? Globals.getGenerateSqlVisualCount() : selectCl.toString()); - if (groupByCl.length() == 0) - sql.append(selectExtraIdCl.toString()); - sql.append(selectExtraDateCl.toString()); - // sql.append(" FROM "); - sql.append((fromCl.length() == 0) ? Globals.getGenerateSqlVisualDual() : "FROM "+fromCl.toString()); - if (whereCl.length() > 0) { - if (whereClBracketCount > 0) { - for (int b = 0; b < whereClBracketCount; b++) - whereCl.append(')'); - } else if (whereClBracketCount < 0) { - for (int b = 0; b < Math.abs(whereClBracketCount); b++) - whereCl.insert(0, '('); - } // else - - sql.append(" WHERE "); - sql.append(whereCl.toString()); - } // if - if (groupByCl.length() > 0) { - sql.append(" GROUP BY "); - sql.append(groupByCl.toString()); - - if (havingCl.length() > 0) { - if (havingClBracketCount > 0) { - for (int b = 0; b < havingClBracketCount; b++) - havingCl.append(')'); - } else if (havingClBracketCount < 0) { - for (int b = 0; b < Math.abs(havingClBracketCount); b++) - havingCl.insert(0, '('); - } // else - - sql.append(" HAVING "); - sql.append(havingCl.toString()); - } - } - if (orderByCl.length() > 0) { - sql.append(" ORDER BY "); - sql.append(orderByCl.toString()); - } - - System.out.println("Created SQL statement: "+sql); - - //String sqlStr = Utils.replaceInString(sql.toString(), "[LOGGED_USERID]", userId); - //return sqlStr; - return sql.toString(); - } // generateSQLCrossTabVisual - - - public String generatePagedSQL(int pageNo, String userId, HttpServletRequest request, boolean getColumnNamesFromReportSQL, ReportParamValues paramValues) throws RaptorException { - int counter = 0; - if(!Globals.isMySQL()) - counter = 1; - return generateSubsetSQL(pageNo * getPageSize() + counter, ((pageNo + 1) * getPageSize()) - + ((pageNo == 0) ? 1 : 0), userId, request, getColumnNamesFromReportSQL, paramValues); - } // generatePagedSQL - - public String generateSubsetSQL(int startRow, int endRow, String userId, HttpServletRequest request, boolean getColumnNamesFromReportSQL, ReportParamValues paramValues) throws RaptorException { - //debugLogger.debug(" ******** End Row ********* " + endRow); - String dbInfo = getDBInfo(); - String dbType = ""; - if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { - try { - org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); - dbType = remDbInfo.getDBType(dbInfo); - } catch (Exception ex) { - throw new RaptorException(ex); - } - } - List reportCols = getAllColumns(); - String wholeSQL_OrderBy = getWholeSQL(); - String reportSQL = getWholeSQL(); - reportSQL = reportSQL.replace(";", ""); - setWholeSQL(reportSQL); - if(nvl(reportSQL).length()>0) - reportSQL = generateSQL(userId, request); - - if (reportSQL.toUpperCase().indexOf("ORDER BY ") < 0) { - StringBuffer sortBy = null; - - if (reportSQL.toUpperCase().indexOf("GROUP BY ") < 0) - if (getDataSourceList().getDataSource().size() > 0) { - DataSourceType dst = (DataSourceType) getDataSourceList().getDataSource() - .get(0); - String tId = dst.getTableId(); - String tPK = dst.getTablePK(); - if (nvl(tPK).length() > 0) { - sortBy = new StringBuffer(); - StringTokenizer st = new StringTokenizer(tPK, ", "); - while (st.hasMoreTokens()) { - if (sortBy.length() > 0) - sortBy.append(","); - sortBy.append(tId); - sortBy.append("."); - sortBy.append(st.nextToken()); - } // while - } - } // if - if (reportSQL.trim().toUpperCase().startsWith("SELECT")) { - //if (!(dbType.equals("DAYTONA") && reportSQL.trim().toUpperCase().startsWith("SELECT"))) - // reportSQL += " ORDER BY " + ((sortBy == null) ? "1" : sortBy.toString()); - } - } - - StringBuffer colNames = new StringBuffer(); - StringBuffer colExtraIdNames = new StringBuffer(); - StringBuffer colExtraDateNames = new StringBuffer(); - - if(getColumnNamesFromReportSQL) { - DataSet ds = ConnectionUtils.getDataSet(reportSQL, dbInfo); - List reportCols1 = getAllColumns(); - reportCols = new Vector(); - outer: - for (Iterator iter = reportCols1.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - for (int k=0; k 0) - colNames.append(", "); - colNames.append(dc.getColId()); - //TODO uncomment if it's not working} // if - - // Checking for extra fields necessary for drill-down - if (nvl(dc.getDrillDownURL()).length() > 0) - if (isViewAction(dc.getDrillDownURL())) - addExtraIdSelect(colExtraIdNames, nvl(dc.getDrillDownParams()), false); - else - addExtraDateSelect(colExtraDateNames, nvl(dc.getDrillDownParams()), null, - false); - } // for - - if (reportSQL.toUpperCase().indexOf("GROUP BY ") < 0) - colNames.append(colExtraIdNames.toString()); - //commented to avoid coldId_dde - //colNames.append(colExtraDateNames.toString()); - - /* - * if(pageNo==0) if(reportSQL.toUpperCase().indexOf(" WHERE ")<0) - * if(reportSQL.toUpperCase().indexOf(" GROUP BY ")<0) reportSQL = - * reportSQL.substring(0, reportSQL.toUpperCase().indexOf(" ORDER BY - * "))+" WHERE ROWNUM <= - * "+getPageSize()+reportSQL.substring(reportSQL.toUpperCase().indexOf(" - * ORDER BY ")); else reportSQL = "SELECT "+colNames.toString()+" FROM - * (SELECT ROWNUM rnum, "+colNames.toString()+" FROM ("+reportSQL+") x) - * y WHERE rnum <= "+getPageSize()+" ORDER BY rnum"; else reportSQL = - * reportSQL.substring(0, reportSQL.toUpperCase().indexOf(" WHERE "))+" - * WHERE ROWNUM <= "+getPageSize()+" AND - * "+reportSQL.substring(reportSQL.toUpperCase().indexOf(" WHERE ")+7); - * else reportSQL = "SELECT "+colNames.toString()+" FROM (SELECT ROWNUM - * rnum, "+colNames.toString()+" FROM ("+reportSQL+") x) y WHERE rnum >= - * "+(pageNo*getPageSize()+1)+" AND rnum <= - * "+((pageNo+1)*getPageSize())+" ORDER BY rnum"; - */ - if (dbType.equals("DAYTONA") && reportSQL.trim().toUpperCase().startsWith("SELECT")) { - if(endRow == -1) endRow = (getMaxRowsInExcelDownload()>0)?getMaxRowsInExcelDownload():Globals.getDownloadLimit(); - reportSQL = reportSQL + " LIMIT TO " +(startRow==0?startRow+1:startRow)+"->"+endRow; - return reportSQL; - } else if (dbType.equals("DAYTONA")) { - return reportSQL; - } - - //reportSQL = "SELECT " + colNames.toString() + " FROM (SELECT ROWNUM rnum, " - // + colNames.toString() + " FROM (" + reportSQL + ") x "; - - String rSQL = Globals.getGenerateSubsetSql(); - rSQL = rSQL.replace("[colNames.toString()]", colNames.toString()); - rSQL = rSQL.replace("[reportSQL]", reportSQL); - - reportSQL=rSQL; - //added rownum for total report where row header need to be shown - //reportSQLOnlyFirstPart = "SELECT rnum," + colNames.toString() + " FROM (SELECT ROWNUM rnum, " - //+ colNames.toString() + " FROM (" ; - - reportSQLOnlyFirstPart = Globals.getReportSqlOnlyFirstPart(); - reportSQLOnlyFirstPart = reportSQLOnlyFirstPart.replace("[colNames.toString()]", colNames.toString()); - - - reportSQLWithRowNum = reportSQL; - - /* if( endRow != -1) - reportSQL += " WHERE ROWNUM <= " + endRow; - reportSQL += " ) y WHERE rnum >= " + startRow + " ORDER BY rnum"; - return reportSQL;*/ - String parta = Globals.getReportSqlOnlySecondPartA(); - String partb = Globals.getReportSqlOnlySecondPartB(); - - String partSql = ""; - if(!AppUtils.isNotEmpty(getDBType())){ - setDBType(Globals.getDBType()); - } - - int closeBracketPos = 0; - if(wholeSQL_OrderBy.lastIndexOf(")")!= -1) closeBracketPos = wholeSQL_OrderBy.lastIndexOf(")"); - int idxOrderBy = (closeBracketPos>0)?wholeSQL_OrderBy.toUpperCase().indexOf("ORDER BY", closeBracketPos):wholeSQL_OrderBy.toUpperCase().lastIndexOf("ORDER BY"); - String orderbyclause = ""; - if (idxOrderBy < 0) { - orderbyclause = " ORDER BY 1 "; - partSql += " "+ orderbyclause+ " "; - } - else { - orderbyclause = wholeSQL_OrderBy.substring(idxOrderBy); - partSql += " "+ orderbyclause+ " "; - } - - if(getDBType().equals(AppConstants.MYSQL)) { - partSql = "LIMIT "+ String.valueOf(startRow)+" , "+ String.valueOf(getPageSize()); - } else if(getDBType().equals(AppConstants.ORACLE)) { - reportSQL = reportSQL.replace(" AS ", " "); - partSql = "where rownum >= "+ String.valueOf(startRow)+" and rownum <= "+(Integer.parseInt(String.valueOf(startRow)) + Integer.parseInt(String.valueOf(getPageSize()))); - } else if(getDBType().equals(AppConstants.POSTGRESQL)) { - partSql = "LIMIT "+ String.valueOf(getPageSize())+" , "+ String.valueOf(startRow);//limit [pageSize] offset [startRow] - } - - // Limit only to MYSQL or MariaDB - //if (reportSQL.toUpperCase().indexOf("ORDER BY ") < 0) - //partSql += " ORDER BY 1"; - //else { - - - - /*if(!Globals.isMySQL()) - parta = parta.replace("[endRow]", String.valueOf(endRow)); - else - parta = parta.replace("[startRow]", String.valueOf(startRow)); - - //String partb = Globals.getReportSqlOnlySecondPartB(); - if(!Globals.isMySQL()) - partb = partb.replace("[startRow]", String.valueOf(startRow)); - else - partb = partb.replace("[pageSize]", String.valueOf(getPageSize())); - - if( endRow != -1) - reportSQL += parta;*/ - reportSQL += partSql; - - return reportSQL; - - } // generateSubsetSQL - - public String generateChartSQL(ReportParamValues paramValues, String userId, HttpServletRequest request ) throws RaptorException { - List reportCols = getAllColumns(); - List chartValueCols = getChartValueColumnsList(AppConstants.CHART_ALL_COLUMNS, null); // parameter is 0 has this requires all columns. - String reportSQL = generateSQL(userId, request); - //if(nvl(reportSQL).length()>0) reportSQL = generatedChartSQL; - logger.debug(EELFLoggerDelegate.debugLogger, ("SQL " + reportSQL)); - String legendCol = "1 a"; - // String valueCol = "1"; - StringBuffer groupCol = new StringBuffer(); - StringBuffer seriesCol = new StringBuffer(); - StringBuffer valueCols = new StringBuffer(); - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, paramValues); - if (nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) - legendCol = getSelectExpr(dc, colName)+" " + dc.getColId(); - // if(dc.getChartSeq()>0) - // valueCol = "NVL("+colName+", 0) "+dc.getColId(); - if ((!nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) - && (dc.getChartSeq()==null || dc.getChartSeq() <= 0) && dc.isGroupBreak()) { - groupCol.append(", "); - groupCol.append(colName + " " + dc.getColId()); - } - } // for - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if(dc.isChartSeries()!=null && dc.isChartSeries().booleanValue()) { - //System.out.println("*****************, "+ " " +getColumnSelectStr(dc, paramValues)+ " "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))); - seriesCol.append(", "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))+ " " + dc.getColId()); - } - } - - /*for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if(!dc.isChartSeries() && !(nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND))) { - //System.out.println("*****************, "+ " " +getColumnSelectStr(dc, paramValues)+ " "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))); - seriesCol.append(", "+ formatChartColumn(getSelectExpr(dc,getColumnSelectStr(dc, paramValues)))+ " " + dc.getColId()); - } - }*/ - - for (Iterator iter = chartValueCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, paramValues); - //valueCols.append(", NVL(" + formatChartColumn(colName) + ",0) " + dc.getColId()); - seriesCol.append("," + formatChartColumn(colName) + " " + dc.getColId()); - } // for - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, paramValues); - if(colName.equals(AppConstants.RI_CHART_TOTAL_COL)) - seriesCol.append(", " + AppConstants.RI_CHART_TOTAL_COL + " " + AppConstants.RI_CHART_TOTAL_COL ); - if (colName.equals(AppConstants.RI_CHART_COLOR)) - seriesCol.append(", " + AppConstants.RI_CHART_COLOR + " " + AppConstants.RI_CHART_COLOR ); - if(colName.equals(AppConstants.RI_CHART_MARKER_START)) - seriesCol.append(", " + AppConstants.RI_CHART_MARKER_START + " " + AppConstants.RI_CHART_MARKER_START ); - if(colName.equals(AppConstants.RI_CHART_MARKER_END)) - seriesCol.append(", " + AppConstants.RI_CHART_MARKER_END + " " + AppConstants.RI_CHART_MARKER_END ); - if(colName.equals(AppConstants.RI_CHART_MARKER_TEXT_LEFT)) - seriesCol.append(", " + AppConstants.RI_CHART_MARKER_TEXT_LEFT + " " + AppConstants.RI_CHART_MARKER_TEXT_LEFT ); - if(colName.equals(AppConstants.RI_CHART_MARKER_TEXT_RIGHT)) - seriesCol.append(", " + AppConstants.RI_CHART_MARKER_TEXT_RIGHT + " " + AppConstants.RI_CHART_MARKER_TEXT_RIGHT ); - if(colName.equals(AppConstants.RI_ANOMALY_TEXT)) - seriesCol.append(", " + AppConstants.RI_ANOMALY_TEXT + " " + AppConstants.RI_ANOMALY_TEXT ); - } - - //debugLogger.debug("ReportSQL Chart " + reportSQL ); - /*for (Iterator iter = chartValueCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, paramValues); - //valueCols.append(", NVL(" + formatChartColumn(colName) + ",0) " + dc.getColId()); - valueCols.append("," + formatChartColumn(colName) + " " + dc.getColId()); - } // for - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, paramValues); - //if(colName.equals(AppConstants.RI_CHART_TOTAL_COL) || colName.equals(AppConstants.RI_CHART_COLOR)) { - if(colName.equals(AppConstants.RI_CHART_TOTAL_COL)) - valueCols.append(", " + AppConstants.RI_CHART_TOTAL_COL + " " + AppConstants.RI_CHART_TOTAL_COL ); - if (colName.equals(AppConstants.RI_CHART_COLOR)) - valueCols.append(", " + AppConstants.RI_CHART_COLOR + " " + AppConstants.RI_CHART_COLOR ); - if (colName.equals(AppConstants.RI_CHART_INCLUDE)) - valueCols.append(", " + AppConstants.RI_CHART_INCLUDE + " " + AppConstants.RI_CHART_INCLUDE ); - //} - }*/ - String final_sql = ""; - reportSQL = Utils.replaceInString(reportSQL, " from ", " FROM "); - reportSQL = Utils.replaceInString(reportSQL, " select ", " SELECT "); - reportSQL = Utils.replaceInString(reportSQL, " union ", " UNION "); - //reportSQL = reportSQL.replaceAll("[\\s]*\\(", "("); -// if(reportSQL.indexOf("UNION") != -1) { -// if(reportSQL.indexOf("FROM(")!=-1) -// final_sql += " "+reportSQL.substring(reportSQL.indexOf("FROM(") ); -// else if (reportSQL.indexOf("FROM (")!=-1) -// final_sql += " "+reportSQL.substring(reportSQL.indexOf("FROM (") ); -// //TODO ELSE THROW ERROR -// } -// else { -// final_sql += " "+reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM ")); -// } - int pos = 0; - int pos_first_select = 0; - int pos_dup_select = 0; - int pos_prev_select = 0; - int pos_last_select = 0; - if (reportSQL.indexOf("FROM", pos)!=-1) { - pos = reportSQL.indexOf("FROM", pos); - pos_dup_select = reportSQL.lastIndexOf("SELECT",pos); - pos_first_select = reportSQL.indexOf("SELECT");//,pos); - logger.debug(EELFLoggerDelegate.debugLogger, ("pos_select " + pos_first_select + " " + pos_dup_select)); - if(pos_dup_select > pos_first_select) { - logger.debug(EELFLoggerDelegate.debugLogger, ("********pos_dup_select ********" + pos_dup_select)); - //pos_dup_select1 = pos_dup_select; - pos_prev_select = pos_first_select; - pos_last_select = pos_dup_select; - while (pos_last_select > pos_prev_select) { - logger.debug(EELFLoggerDelegate.debugLogger, ("pos_last , pos_prev " + pos_last_select + " " + pos_prev_select)); - pos = reportSQL.indexOf("FROM", pos+2); - pos_prev_select = pos_last_select; - pos_last_select = reportSQL.lastIndexOf("SELECT",pos); - logger.debug(EELFLoggerDelegate.debugLogger, ("in WHILE LOOP LAST " + pos_last_select)); - } - } - - } - final_sql += " "+reportSQL.substring(pos); - logger.debug(EELFLoggerDelegate.debugLogger, ("Final SQL " + final_sql)); - String sql = "SELECT " + legendCol + ", " + legendCol+"_1" + seriesCol.toString()+ nvl(valueCols.toString(), ", 1") - + groupCol.toString() - + final_sql; - logger.debug(EELFLoggerDelegate.debugLogger, ("Final sql in generateChartSQL " +sql)); - - return sql; - } // generateChartSQL - - private String formatChartColumn(String colName) { - - logger.debug(EELFLoggerDelegate.debugLogger, ("Format Chart Column Input colName" + colName)); - colName = colName.trim(); - colName = Utils.replaceInString(colName, "TO_CHAR", "to_char"); - colName = Utils.replaceInString(colName, "to_number", "TO_NUMBER"); - //reportSQL = reportSQL.replaceAll("[\\s]*\\(", "("); - colName = colName.replaceAll(",[\\s]*\\(", ",("); - StringBuffer colNameBuf = new StringBuffer(colName); - int pos = 0, posFormatStart = 0, posFormatEnd = 0; - String format = ""; - if(colNameBuf.indexOf("999")==-1 && colNameBuf.indexOf("990")==-1) { - logger.debug(EELFLoggerDelegate.debugLogger, (" return colName " + colNameBuf.toString())); - return colNameBuf.toString(); - } - while (colNameBuf.indexOf("to_char")!=-1) { - if(colNameBuf.indexOf("999")!=-1 || colNameBuf.indexOf("990")!=-1) { - pos = colNameBuf.indexOf("to_char"); - colNameBuf.insert(pos, " TO_NUMBER ( CR_RAPTOR.SAFE_TO_NUMBER ("); - pos = colNameBuf.indexOf("to_char"); - colNameBuf.replace(pos, pos+7, "TO_CHAR"); - //colName = Utils.replaceInString(colNameBuf.toString(), "to_char", " TO_NUMBER ( CR_RAPTOR.SAFE_TO_NUMBER ( TO_CHAR "); - logger.debug(EELFLoggerDelegate.debugLogger, ("After adding to_number " + colNameBuf.toString())); - //posFormatStart = colNameBuf.lastIndexOf(",'")+1; - posFormatStart = colNameBuf.indexOf(",'", pos)+1; - posFormatEnd = colNameBuf.indexOf(")",posFormatStart); - logger.debug(EELFLoggerDelegate.debugLogger, (posFormatStart + " " + posFormatEnd + " "+ pos)); - format = colNameBuf.substring(posFormatStart, posFormatEnd); - //posFormatEnd = colNameBuf.indexOf(")",posFormatEnd); - colNameBuf.insert(posFormatEnd+1, " ," + format + ") , "+ format + ")"); - logger.debug(EELFLoggerDelegate.debugLogger, ("colNameBuf " + colNameBuf.toString())); - } - } - logger.debug(EELFLoggerDelegate.debugLogger, (" return colName " + colNameBuf.toString())); - return colNameBuf.toString(); - } - public String generateTotalSQLLinear(ReportParamValues paramValues, String userId, HttpServletRequest request) throws RaptorException { - List reportCols = getAllColumns(); - String reportSQL = generateSQL(userId,request); - //debugLogger.debug("After GenerateSQL " + reportSQL); - - StringBuffer sbSelect = new StringBuffer(); - StringBuffer sbTotal = new StringBuffer(); - StringBuffer colNames = new StringBuffer(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - - DataColumnType dc = (DataColumnType) iter.next(); - if (colNames.length() > 0) - colNames.append(", "); - colNames.append(dc.getColId()); - } - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - - //if (!dct.isVisible()) - // continue; - - String colName = getColumnSelectStr(dct, paramValues); - - sbSelect.append((sbSelect.length() == 0) ? "SELECT " : ", "); - - sbSelect.append(colName); - sbSelect.append(" "); - sbSelect.append(dct.getColId()); - - - sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); - if (nvl(dct.getDisplayTotal()).length() > 0) { - // sbTotal.append(getSelectExpr(dct, - // dct.getDisplayTotal()+dct.getColId()+")")); - String displayTotal = dct.getDisplayTotal(); - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < displayTotal.length(); i++) { - char ch = displayTotal.charAt(i); - if (ch == '+' || ch == '-') - sb.append(dct.getColId() + ")"); - sb.append(ch); - } // for - sb.append(dct.getColId() + ")"); - - //debugLogger.debug("SB " + sb.toString() + "\n " + getSelectExpr(dct, sb.toString())); - sbTotal.append(getSelectExpr(dct, sb.toString())); - //debugLogger.debug("SBTOTAL " + sbTotal.toString()); - } else - sbTotal.append("NULL"); - sbTotal.append(" total_"); - sbTotal.append(dct.getColId()); - } // for - - //debugLogger.debug(" ****** " + sbTotal.toString()); - logger.debug(EELFLoggerDelegate.debugLogger, ("REPORTWRAPPER " + reportSQL)); - int pos = 0; - int pos_first_select = 0; - int pos_dup_select = 0; - int pos_prev_select = 0; - int pos_last_select = 0; - - //reportSQL = Utils.replaceInString(reportSQL, " from ", " FROM "); - //reportSQL = Utils.replaceInString(reportSQL, "select ", "SELECT "); - reportSQL = replaceNewLine(reportSQL, " from ", " FROM "); - reportSQL = replaceNewLine(reportSQL, "from ", " FROM "); - reportSQL = replaceNewLine(reportSQL, "FROM ", " FROM "); - - reportSQL = " "+reportSQL; - reportSQL = replaceNewLine(reportSQL, "select ", " SELECT "); - reportSQL = replaceNewLine(reportSQL, "SELECT ", " SELECT "); - if (reportSQL.indexOf("FROM", pos)!=-1) { - pos = reportSQL.indexOf("FROM", pos); - pos_dup_select = reportSQL.lastIndexOf("SELECT",pos); - pos_first_select = reportSQL.indexOf("SELECT");//,pos); - logger.debug(EELFLoggerDelegate.debugLogger, ("pos_select " + pos_first_select + " " + pos_dup_select)); - if(pos_dup_select > pos_first_select) { - logger.debug(EELFLoggerDelegate.debugLogger, ("********pos_dup_select ********" + pos_dup_select)); - //pos_dup_select1 = pos_dup_select; - pos_prev_select = pos_first_select; - pos_last_select = pos_dup_select; - while (pos_last_select > pos_prev_select) { - logger.debug(EELFLoggerDelegate.debugLogger, ("pos_last , pos_prev " + pos_last_select + " " + pos_prev_select)); - pos = reportSQL.indexOf("FROM", pos+2); - pos_prev_select = pos_last_select; - pos_last_select = reportSQL.lastIndexOf("SELECT",pos); - logger.debug(EELFLoggerDelegate.debugLogger, ("in WHILE LOOP LAST " + pos_last_select)); - } - } - - } - - - //sbSelect.append(reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM "))); - - logger.debug(EELFLoggerDelegate.debugLogger, (" *************** " + pos + " " + reportSQL)); - //sbSelect.append(" "+ reportSQL.substring(pos)); - sbSelect.append(" "+reportSQL.substring(pos)); - logger.debug(EELFLoggerDelegate.debugLogger, (" **************** " + sbSelect.toString())); - sbTotal.append(" FROM ("); - sbTotal.append(sbSelect.toString()); - sbTotal.append(") totalSQL"); - - String dbType = ""; - String dbInfo = getDBInfo(); - if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { - try { - org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); - dbType = remDbInfo.getDBType(dbInfo); - } catch (Exception ex) { - throw new RaptorException(ex); - } - } - if (dbType.equals("DAYTONA")) { - sbTotal.append("("+ colNames+ ")"); - } - String sql = sbTotal.toString(); - sql = Utils.replaceInString(sql, " from ", " FROM "); - sql = Utils.replaceInString(sql, "select ", "SELECT "); - //sql = Utils.replaceInString(sql, " select ", " SELECT "); - logger.debug(EELFLoggerDelegate.debugLogger, ("Before SQL Corrector " + sql)); - String corrected_SQL = new SQLCorrector().fixSQL(new StringBuffer(sql)); - logger.debug(EELFLoggerDelegate.debugLogger, ("************")); - logger.debug(EELFLoggerDelegate.debugLogger, ("Corrected SQL " + corrected_SQL)); - return corrected_SQL; - //return sbTotal.toString(); - } // generateTotalSQLLinear - - public String generateTotalSQLCrossTab(String sql, String rowColPos, - String userId, HttpServletRequest request, ReportParamValues paramValues) throws RaptorException { - List reportCols = getAllColumns(); - String reportSQL = sql; - - StringBuffer sbSelect = new StringBuffer(); - StringBuffer sbGroup = new StringBuffer(); - // StringBuffer sbOrder = new StringBuffer(); - StringBuffer sbTotal = new StringBuffer(); - StringBuffer colNames = new StringBuffer(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - - DataColumnType dc = (DataColumnType) iter.next(); - if (colNames.length() > 0) - colNames.append(", "); - colNames.append(dc.getColId()); - } - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - - if (!dct.isVisible()) - continue; - - - String colName = getColumnSelectStr(dct, paramValues); - String colExpr = getSelectExpr(dct, colName); - - sbSelect.append((sbSelect.length() == 0) ? "SELECT " : ", "); - - if (nvl(dct.getCrossTabValue()).equals(rowColPos)) { - //sbSelect.append(colExpr); - sbSelect.append(dct.getColId()); - sbGroup.append((sbGroup.length() == 0) ? " GROUP BY " : ", "); - sbGroup.append(dct.getColId()); - - /* - * sbOrder.append((sbOrder.length()==0)?" ORDER BY ":", "); - * sbOrder.append(dct.getColId()); - * if(dct.getColType().equals(AppConstants.CT_DATE)) - * sbOrder.append(" DESC"); - */ - - sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); - sbTotal.append(dct.getColId()); - } else if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_VALUE)) { - //sbSelect.append(colName); - sbSelect.append(dct.getColId()); - - String displayTotal = getCrossTabDisplayTotal(rowColPos); - if (displayTotal.length() > 0) { - // displayTotal += dct.getColId()+")"; - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < displayTotal.length(); i++) { - char ch = displayTotal.charAt(i); - if (ch == '+' || ch == '-') - sb.append(dct.getColId() + ")"); - sb.append(ch); - } // for - sb.append(dct.getColId() + ")"); - - displayTotal = sb.toString(); - } else - displayTotal = "COUNT(*)"; - - sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); - sbTotal.append(getSelectExpr(dct, displayTotal)); - sbTotal.append(" total_"); - sbTotal.append(dct.getColId()); - } else { - //sbSelect.append(colExpr); - sbSelect.append(dct.getColId()); - } // if - - sbSelect.append(" "); - sbSelect.append(dct.getColId()); - } // for - - sbSelect.append(reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM "))); - - sbTotal.append(" FROM ("); - sbTotal.append(sbSelect.toString()); - sbTotal.append(") totalSQL"); - sbTotal.append(sbGroup.toString()); - String dbType = ""; - String dbInfo = getDBInfo(); - if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { - try { - org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); - dbType = remDbInfo.getDBType(dbInfo); - } catch (Exception ex) { - throw new RaptorException(ex); - } - } - if (dbType.equals("DAYTONA")) { - sbTotal.append("("+ colNames+ ")"); - } - - // sbTotal.append(sbOrder.toString()); - - //debugLogger.debug(getReportDefType() + " " + AppConstants.RD_SQL_BASED); - //debugLogger.debug("SQL To Delete " + sbTotal.toString()); - sql = ""; - if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) { - sql = Utils.replaceInString(sbTotal.toString(), " from ", " FROM "); - sql = Utils.replaceInString(sql, "select ", "SELECT "); - return new SQLCorrector().fixSQL(new StringBuffer(sql)); - } - - return sbTotal.toString(); - - } // generateTotalSQLCrossTab - - - public String generateTotalSQLCrossTab(ReportParamValues paramValues, String rowColPos, - String userId, HttpServletRequest request) throws RaptorException { - List reportCols = getAllColumns(); - String reportSQL = generateSQL(userId, request); - - StringBuffer sbSelect = new StringBuffer(); - StringBuffer sbGroup = new StringBuffer(); - // StringBuffer sbOrder = new StringBuffer(); - StringBuffer sbTotal = new StringBuffer(); - StringBuffer colNames = new StringBuffer(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - - DataColumnType dc = (DataColumnType) iter.next(); - if (colNames.length() > 0) - colNames.append(", "); - colNames.append(dc.getColId()); - } - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - - if (!dct.isVisible()) - continue; - - String colName = getColumnSelectStr(dct, paramValues); - String colExpr = getSelectExpr(dct, colName); - - sbSelect.append((sbSelect.length() == 0) ? "SELECT " : ", "); - - if (nvl(dct.getCrossTabValue()).equals(rowColPos)) { - sbSelect.append(colExpr); - - sbGroup.append((sbGroup.length() == 0) ? " GROUP BY " : ", "); - sbGroup.append(dct.getColId()); - - /* - * sbOrder.append((sbOrder.length()==0)?" ORDER BY ":", "); - * sbOrder.append(dct.getColId()); - * if(dct.getColType().equals(AppConstants.CT_DATE)) - * sbOrder.append(" DESC"); - */ - - sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); - sbTotal.append(dct.getColId()); - } else if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_VALUE)) { - sbSelect.append(colName); - - String displayTotal = getCrossTabDisplayTotal(rowColPos); - if (displayTotal.length() > 0) { - // displayTotal += dct.getColId()+")"; - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < displayTotal.length(); i++) { - char ch = displayTotal.charAt(i); - if (ch == '+' || ch == '-') - sb.append(dct.getColId() + ")"); - sb.append(ch); - } // for - sb.append(dct.getColId() + ")"); - - displayTotal = sb.toString(); - } else - displayTotal = "COUNT(*)"; - - sbTotal.append((sbTotal.length() == 0) ? "SELECT " : ", "); - sbTotal.append(getSelectExpr(dct, displayTotal)); - sbTotal.append(" total_"); - sbTotal.append(dct.getColId()); - } else { - sbSelect.append(colExpr); - } // if - - sbSelect.append(" "); - sbSelect.append(dct.getColId()); - } // for - - sbSelect.append(reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM "))); - - sbTotal.append(" FROM ("); - sbTotal.append(sbSelect.toString()); - sbTotal.append(") totalSQL"); - sbTotal.append(sbGroup.toString()); - String dbType = ""; - String dbInfo = getDBInfo(); - if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { - try { - org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); - dbType = remDbInfo.getDBType(dbInfo); - } catch (Exception ex) { - throw new RaptorException(ex); - } - } - if (dbType.equals("DAYTONA")) { - sbTotal.append("("+ colNames+ ")"); - } - - // sbTotal.append(sbOrder.toString()); - - //debugLogger.debug(getReportDefType() + " " + AppConstants.RD_SQL_BASED); - //debugLogger.debug("SQL To Delete " + sbTotal.toString()); - String sql = ""; - if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) { - sql = Utils.replaceInString(sbTotal.toString(), " from ", " FROM "); - sql = Utils.replaceInString(sql, "select ", "SELECT "); - return new SQLCorrector().fixSQL(new StringBuffer(sql)); - } - - return sbTotal.toString(); - - } // generateTotalSQLCrossTab - - public String generateDistinctValuesSQL(ReportParamValues paramValues, DataColumnType dct, - String userId, HttpServletRequest request) throws RaptorException { - DataSourceType dst = getColumnTableById(dct.getColId()); - String colName = getColumnSelectStr(dct, paramValues); - String colExpr = getSelectExpr(dct, colName); - ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); - StringBuffer sb = new StringBuffer(); - sb.append("SELECT DISTINCT "); - if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) { - sb.append(dct.getColId()); - sb.append(" FROM ("); - //paramvalues added below to filter distinct values based on formfields. - //sb.append(generateSQL(paramValues, userId, request)); - sb.append(rr.getWholeSQL()); - sb.append(") " + (Globals.isPostgreSQL() || Globals.isMySQL() ?" AS ":"") + " report_sql ORDER BY 1"); - } else { - sb.append(colExpr); - sb.append(" "); - sb.append(dct.getColId()); - if (!colExpr.equals(colName)) { - sb.append(", "); - sb.append(colName); - } // if - sb.append(" FROM "); - sb.append(dst.getTableName()); - sb.append(" "); - sb.append(dst.getTableId()); - sb.append(" ORDER BY "); - sb.append(colName); - if (dct.getColType().equals(AppConstants.CT_DATE)) - sb.append(" DESC"); - } // else - - return sb.toString(); - } // generateDistinctValuesSQL - - /** ************************************************************************************************* */ - - public DataSourceType getTableWithoutColumns() { - List dsList = getDataSourceList().getDataSource(); - for (Iterator iter = dsList.iterator(); iter.hasNext();) { - DataSourceType ds = (DataSourceType) iter.next(); - - if (ds.getDataColumnList().getDataColumn().size() == 0) - return ds; - } // for - - return null; - } // getTableWithoutColumns - - public CustomReportType cloneCustomReportClearTables() throws RaptorException { - ReportWrapper nrw = new ReportWrapper(cloneCustomReport(), reportID, getOwnerID(), - getCreateID(), getCreateDate(), getUpdateID(), getUpdateDate(), getMenuID(), - isMenuApproved()); - - DataSourceType ndst = null; - while ((ndst = nrw.getTableWithoutColumns()) != null) - nrw.deleteDataSourceType(ndst.getTableId()); - - return nrw.getCustomReport(); - } // cloneCustomReportClearTables - - public String marshal() throws RaptorException { - StringWriter sw = new StringWriter(); - ObjectFactory objFactory = new ObjectFactory(); - - try { - JAXBContext jc = JAXBContext.newInstance("org.openecomp.portalsdk.analytics.xmlobj"); - Marshaller m = jc.createMarshaller(); - m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - //JAXBElement jaxbElement = new JAXBElement(new QName("customReport"), Object.class, ""); - //m.marshal( System.out ); - //m.marshal(jaxbElement, new StreamResult(sw)); - m.marshal((getTableWithoutColumns() == null) ? objFactory.createCustomReport(cr) : objFactory.createCustomReport(cloneCustomReportClearTables()), - new StreamResult(sw)); - } catch (JAXBException ex) { - throw new RaptorException (ex.getMessage(), ex.getCause()); - } - return sw.toString(); - } // marshal - - public static CustomReportType unmarshalCR(String reportXML) throws RaptorException { - //CustomReport cr = null; - try { - JAXBContext jc = JAXBContext.newInstance("org.openecomp.portalsdk.analytics.xmlobj"); - Unmarshaller u = jc.createUnmarshaller(); - javax.xml.bind.JAXBElement doc = (javax.xml.bind.JAXBElement) u.unmarshal(new java.io.StringReader( - reportXML)); - return doc.getValue(); - } catch (JAXBException ex) { - ex.printStackTrace(); - throw new RaptorException (ex.getMessage(), ex.getCause()); - } - - - } // unmarshal - - protected static CustomReportType createBlankCR() throws RaptorException { - return createBlankCR("N/A"); - } // createBlank - - protected static CustomReportType createBlankCR(String createID) throws RaptorException { - ObjectFactory objFactory = new ObjectFactory(); - CustomReportType cr = objFactory.createCustomReportType(); - //CustomReport cr = null; - try { - //cr = (CustomReport) objFactory.createCustomReport(customReportType); - - cr.setReportName(""); - cr.setReportDescr(""); - cr.setChartType(""); - cr.setPublic(false); - cr.setCreateId(createID); - cr.setCreateDate(DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar())); - // cr.setReportSQL(""); - cr.setReportType(""); - cr.setPageSize(50); - - DataSourceList dataSourceList = objFactory.createDataSourceList(); - cr.setDataSourceList(dataSourceList); - } catch (DatatypeConfigurationException ex) { - throw new RaptorException (ex.getMessage(), ex.getCause()); - } - return cr; - } // createBlank - - protected void replaceCustomReportWithClone() throws RaptorException { - try { - CustomReportType clone = cloneCustomReport(); - this.cr = clone; - } catch (Exception e) { - e.printStackTrace(); - logger.debug(EELFLoggerDelegate.debugLogger, ("[SYSTEM ERROR] ReportWrapper.replaceCustomReportWithClone generated exception for report [" - + reportID + "]. Exception: " + e.getMessage())); - throw new RaptorException("[SYSTEM ERROR] ReportWrapper.replaceCustomReportWithClone generated exception for report [" - + reportID + "]. Exception: " + e.getMessage(), e.getCause()); - } - } // replaceCustomReportWithClone - - /** ************************************************************************************************* */ - - public FormatType cloneFormatType(ObjectFactory objFactory, FormatType ft) - throws JAXBException { - FormatType nft = objFactory.createFormatType(); - - nft.setLessThanValue(ft.getLessThanValue()); - nft.setExpression(ft.getExpression()); - nft.setBold(ft.isBold()); - nft.setItalic(ft.isItalic()); - nft.setUnderline(ft.isUnderline()); - if (nvl(ft.getBgColor()).length() > 0) - nft.setBgColor(ft.getBgColor()); - if (nvl(ft.getFontColor()).length() > 0) - nft.setFontColor(ft.getFontColor()); - if (nvl(ft.getFontFace()).length() > 0) - nft.setFontFace(ft.getFontFace()); - if (nvl(ft.getFontSize()).length() > 0) - nft.setFontSize(ft.getFontSize()); - if (nvl(ft.getAlignment()).length() > 0) - nft.setAlignment(ft.getAlignment()); - if (nvl(ft.getComment()).length() > 0) - nft.setComment(ft.getComment()); - - nft.setFormatId(ft.getFormatId()); - - return nft; - } // cloneFormatType - - public SemaphoreType cloneSemaphoreType(ObjectFactory objFactory, SemaphoreType st) - throws JAXBException { - SemaphoreType nst = objFactory.createSemaphoreType(); - - nst.setSemaphoreName(st.getSemaphoreName()); - nst.setSemaphoreType(st.getSemaphoreType()); - nst.setSemaphoreId(st.getSemaphoreId()); - if (nvl(st.getComment()).length() > 0) - nst.setComment(st.getComment()); - - if (st.getFormatList() != null) { - FormatList formatList = objFactory.createFormatList(); - nst.setFormatList(formatList); - - for (Iterator iter = st.getFormatList().getFormat().iterator(); iter.hasNext();) - formatList.getFormat().add( - cloneFormatType(objFactory, (FormatType) iter.next())); - } // if - - return nst; - } // cloneSemaphoreType - - public Reports cloneDashboardType(ObjectFactory objFactory, Reports rpt) - throws JAXBException { - Reports nrpt = objFactory.createReports(); - - nrpt.setReportId(rpt.getReportId()); - nrpt.setBgcolor(rpt.getBgcolor()); - return nrpt; - } // cloneDashboardType - - public Marker cloneMarkerType(ObjectFactory objFactory, Marker marker) - throws JAXBException { - Marker nMarker = objFactory.createMarker(); - nMarker.setAddressColumn(marker.getAddressColumn()); - nMarker.setDataColumn(marker.getDataColumn()); - nMarker.setDataHeader(marker.getDataHeader()); - nMarker.setMarkerColor(marker.getMarkerColor()); - return nMarker; - } // cloneDashboardType - - public ChartDrillFormfield cloneChartDrillFormfield(ObjectFactory objFactory, ChartDrillFormfield chartDrillFormfield) - throws JAXBException { - ChartDrillFormfield nChartDrillFormfield = objFactory.createChartDrillFormfield(); - nChartDrillFormfield.setFormfield(chartDrillFormfield.getFormfield()); - return nChartDrillFormfield; - } // cloneDashboardType - - public boolean isChartDrillDownContainsName(String name) { - for (Iterator iter = getChartDrillOptions().getTargetFormfield().iterator(); iter - .hasNext();) { - org.openecomp.portalsdk.analytics.xmlobj.ChartDrillFormfield cdf = (org.openecomp.portalsdk.analytics.xmlobj.ChartDrillFormfield) iter.next(); - if(cdf.getFormfield().equals(name)) { - return true; - } - } - return false; - } - public FormFieldType cloneFormFieldType(ObjectFactory objFactory, FormFieldType fft) - throws JAXBException { - FormFieldType nfft = objFactory.createFormFieldType(); - - nfft.setColId(fft.getColId()); - nfft.setFieldName(fft.getFieldName()); - nfft.setFieldType(fft.getFieldType()); - if (nvl(fft.getVisible()).length() > 0) - nfft.setVisible(fft.getVisible()); - if (nvl(fft.getValidationType()).length() > 0) - nfft.setValidationType(fft.getValidationType()); - if (nvl(fft.getMandatory()).length() > 0) - nfft.setMandatory(fft.getMandatory()); - if (nvl(fft.getDefaultValue()).length() > 0) - nfft.setDefaultValue(fft.getDefaultValue()); - nfft.setOrderBySeq(fft.getOrderBySeq()); - if (nvl(fft.getFieldSQL()).length() > 0) - nfft.setFieldSQL(fft.getFieldSQL()); - if (nvl(fft.getFieldDefaultSQL()).length() > 0) - nfft.setFieldDefaultSQL(fft.getFieldDefaultSQL()); - if(fft.getRangeStartDate()!=null) - nfft.setRangeStartDate(fft.getRangeStartDate()); - if(fft.getRangeEndDate()!=null) - nfft.setRangeEndDate(fft.getRangeEndDate()); - if(fft.getRangeStartDateSQL()!=null) - nfft.setRangeStartDateSQL(fft.getRangeStartDateSQL()); - if(fft.getRangeEndDateSQL()!=null) - nfft.setRangeEndDateSQL(fft.getRangeEndDateSQL()); - - if (nvl(fft.getComment()).length() > 0) - nfft.setComment(fft.getComment()); - - if (fft.getPredefinedValueList() != null) { - PredefinedValueList predefinedValueList = objFactory.createPredefinedValueList(); - nfft.setPredefinedValueList(predefinedValueList); - - for (Iterator iter = fft.getPredefinedValueList().getPredefinedValue().iterator(); iter - .hasNext();) - predefinedValueList.getPredefinedValue().add(new String((String) iter.next())); - } // if - if (nvl(fft.getDependsOn()).length() > 0) - nfft.setDependsOn(fft.getDependsOn()); - - nfft.setGroupFormField((fft.isGroupFormField()!=null && fft.isGroupFormField().booleanValue())?true:false); - if (nvl(fft.getMultiSelectListSize()).length() > 0) - nfft.setMultiSelectListSize(fft.getMultiSelectListSize()); - - nfft.setFieldId(fft.getFieldId()); - return nfft; - } // cloneFormFieldType - - public JavascriptItemType cloneJavascriptType(ObjectFactory objFactory, JavascriptItemType jit) - throws JAXBException { - JavascriptItemType njit = objFactory.createJavascriptItemType(); - - njit.setId(jit.getId()); - njit.setFieldId(jit.getFieldId()); - njit.setCallText(jit.getCallText()); - return njit; - } // cloneJavascriptType - - public ColFilterType cloneColFilterType(ObjectFactory objFactory, ColFilterType cft) - throws JAXBException { - ColFilterType ncft = objFactory.createColFilterType(); - - ncft.setColId(cft.getColId()); - ncft.setFilterSeq(cft.getFilterSeq()); - ncft.setJoinCondition(cft.getJoinCondition()); - if (nvl(cft.getOpenBrackets()).length() > 0) - ncft.setOpenBrackets(cft.getOpenBrackets()); - ncft.setExpression(cft.getExpression()); - if (nvl(cft.getArgType()).length() > 0) - ncft.setArgType(cft.getArgType()); - if (nvl(cft.getArgValue()).length() > 0) - ncft.setArgValue(cft.getArgValue()); - if (nvl(cft.getCloseBrackets()).length() > 0) - ncft.setCloseBrackets(cft.getCloseBrackets()); - if (nvl(cft.getComment()).length() > 0) - ncft.setComment(cft.getComment()); - - return ncft; - } // cloneColFilterType - - public DataColumnType cloneDataColumnType(ObjectFactory objFactory, DataColumnType dct) - throws JAXBException { - DataColumnType ndct = objFactory.createDataColumnType(); - - ndct.setTableId(dct.getTableId()); - ndct.setDbColName(dct.getDbColName()); - if (nvl(dct.getCrossTabValue()).length() > 0) - ndct.setCrossTabValue(dct.getCrossTabValue()); - ndct.setColName(dct.getColName()); - ndct.setDisplayName(dct.getDisplayName()); - if (dct.getDisplayWidth() > 0) - ndct.setDisplayWidth(dct.getDisplayWidth()); - if (nvl(dct.getDisplayWidthInPxls()).length()>0) - ndct.setDisplayWidthInPxls(dct.getDisplayWidthInPxls()); - if (nvl(dct.getDisplayAlignment()).length() > 0) - ndct.setDisplayAlignment(dct.getDisplayAlignment()); - if (nvl(dct.getDisplayHeaderAlignment()).length() > 0) - ndct.setDisplayHeaderAlignment(dct.getDisplayHeaderAlignment()); - ndct.setOrderSeq(dct.getOrderSeq()); - ndct.setVisible(dct.isVisible()); - ndct.setCalculated(dct.isCalculated()); - ndct.setColType(dct.getColType()); - if(dct.getColType().equals(AppConstants.CT_HYPERLINK)) { - ndct.setHyperlinkURL(dct.getHyperlinkURL()); - ndct.setHyperlinkType(dct.getHyperlinkType()); - if(dct.getHyperlinkType().equals("IMAGE")) { - ndct.setActionImg(dct.getActionImg()); - } - } - - if(dct.getIndentation()!=null) { - ndct.setIndentation(dct.getIndentation()); - } - - if (nvl(dct.getColFormat()).length() > 0) - ndct.setColFormat(dct.getColFormat()); - ndct.setGroupBreak(dct.isGroupBreak()); - ndct.setNowrap(dct.getNowrap()); - if (nvl(dct.getYAxis()).length() > 0) - ndct.setYAxis(dct.getYAxis()); - if (dct.getOrderBySeq()!=null && dct.getOrderBySeq() > 0) - ndct.setOrderBySeq(dct.getOrderBySeq()); - if (nvl(dct.getOrderByAscDesc()).length() > 0) - ndct.setOrderByAscDesc(dct.getOrderByAscDesc()); - if (nvl(dct.getDisplayTotal()).length() > 0) - ndct.setDisplayTotal(dct.getDisplayTotal()); - if (nvl(dct.getColOnChart()).length() > 0) - ndct.setColOnChart(dct.getColOnChart()); - if (dct.getChartSeq() !=null) - ndct.setChartSeq(dct.getChartSeq()); - if (nvl(dct.getChartColor()).length() > 0) - ndct.setChartColor(dct.getChartColor()); - if (nvl(dct.getChartLineType()).length() > 0) - ndct.setChartLineType(dct.getChartLineType()); - ndct.setChartSeries((dct.isChartSeries()!=null && dct.isChartSeries().booleanValue())?true:false); - ndct.setIsRangeAxisFilled((dct.isIsRangeAxisFilled()!=null && dct.isIsRangeAxisFilled().booleanValue())?true:false); - - if (dct.isCreateInNewChart()!=null) - ndct.setCreateInNewChart(dct.isCreateInNewChart()); - if (nvl(dct.getDrillDownType()).length() > 0) - ndct.setDrillDownType(dct.getDrillDownType()); - ndct.setDrillinPoPUp(dct.isDrillinPoPUp()!=null?dct.isDrillinPoPUp():false); - if (nvl(dct.getDrillDownURL()).length() > 0) - ndct.setDrillDownURL(dct.getDrillDownURL()); - if (nvl(dct.getDrillDownParams()).length() > 0) - ndct.setDrillDownParams(dct.getDrillDownParams()); - if (nvl(dct.getComment()).length() > 0) - ndct.setComment(dct.getComment()); - if (nvl(dct.getDependsOnFormField()).length() > 0) - ndct.setDependsOnFormField(dct.getDependsOnFormField()); - if (dct.getColFilterList() != null) { - ColFilterList colFilterList = objFactory.createColFilterList(); - ndct.setColFilterList(colFilterList); - - for (Iterator iter = dct.getColFilterList().getColFilter().iterator(); iter - .hasNext();) - colFilterList.getColFilter().add( - cloneColFilterType(objFactory, (ColFilterType) iter.next())); - } // if - - if (nvl(dct.getSemaphoreId()).length() > 0) - ndct.setSemaphoreId(dct.getSemaphoreId()); - if (nvl(dct.getDbColType()).length() > 0) - ndct.setDbColType(dct.getDbColType()); - else { - ndct.setDbColType(dct.getColType()); - adjustColumnType(ndct); - } - if (nvl(dct.getChartGroup()).length() > 0) - ndct.setChartGroup(dct.getChartGroup()); - - if (nvl(dct.getYAxis()).length() > 0) - ndct.setYAxis(dct.getYAxis()); - - if (nvl(dct.getDependsOnFormField()).length() > 0) - ndct.setDependsOnFormField(dct.getDependsOnFormField()); - - - - if(nvl(dct.getNowrap()).length() > 0) - ndct.setNowrap(dct.getNowrap()); - - if(dct.getIndentation()!=null) { - ndct.setIndentation(dct.getIndentation()); - } - - ndct.setEnhancedPagination((dct.isEnhancedPagination()!=null && dct.isEnhancedPagination().booleanValue())?true:false); - if(nvl(dct.getDataMiningCol()).length() > 0) - ndct.setDataMiningCol(dct.getDataMiningCol()); - - ndct.setColId(dct.getColId()); - - // ndct.setSemaphoreId(nvl(dct.getSemaphoreId())); - // if(nvl(dct.getDbColType()).length()>0) - // ndct.setDbColType(dct.getDbColType()); - return ndct; - } // cloneDataColumnType - - public DataSourceType cloneDataSourceType(ObjectFactory objFactory, DataSourceType dst) - throws JAXBException { - DataSourceType ndst = objFactory.createDataSourceType(); - - ndst.setTableName(dst.getTableName()); - ndst.setTablePK(dst.getTablePK()); - ndst.setDisplayName(dst.getDisplayName()); - if (nvl(dst.getRefTableId()).length() > 0) - ndst.setRefTableId(dst.getRefTableId()); - if (nvl(dst.getRefDefinition()).length() > 0) - ndst.setRefDefinition(dst.getRefDefinition()); - if (nvl(dst.getComment()).length() > 0) - ndst.setComment(dst.getComment()); - DataColumnList dataColumnList = objFactory.createDataColumnList(); - ndst.setDataColumnList(dataColumnList); - - for (Iterator iter = dst.getDataColumnList().getDataColumn().iterator(); iter - .hasNext();) - dataColumnList.getDataColumn().add( - cloneDataColumnType(objFactory, (DataColumnType) iter.next())); - ndst.setTableId(dst.getTableId()); - - - return ndst; - } // cloneDataSourceType - - public CustomReportType cloneCustomReport() throws RaptorException { - ObjectFactory objFactory = new ObjectFactory(); - CustomReportType ncr = objFactory.createCustomReportType(); - - //CustomReport ncr = null; - try { - //ncr = (CustomReport) objFactory.createCustomReport(customReportType); - ncr.setReportName(cr.getReportName()); - ncr.setReportDescr(cr.getReportDescr()); - if (nvl(cr.getNumDashCols()).length() > 0) - ncr.setNumDashCols(cr.getNumDashCols()); - if (nvl(cr.getDashboardLayoutHTML()).length() > 0) - ncr.setDashboardLayoutHTML(cr.getDashboardLayoutHTML()); - if (nvl(cr.getDbInfo()).length() > 0) - ncr.setDbInfo(cr.getDbInfo()); - ncr.setChartType(cr.getChartType()); - if (nvl(cr.getChartTypeFixed()).length() > 0) - ncr.setChartTypeFixed(cr.getChartTypeFixed()); - if (nvl(cr.getChartMultiSeries()).length() > 0) - ncr.setChartMultiSeries(cr.getChartMultiSeries()); - if (nvl(cr.getChartLeftAxisLabel()).length() > 0) - ncr.setChartLeftAxisLabel(cr.getChartLeftAxisLabel()); - if (nvl(cr.getChartRightAxisLabel()).length() > 0) - ncr.setChartRightAxisLabel(cr.getChartRightAxisLabel()); - if (nvl(cr.getChartWidth()).length() > 0) - ncr.setChartWidth(cr.getChartWidth()); - if (nvl(cr.getChartHeight()).length() > 0) - ncr.setChartHeight(cr.getChartHeight()); - ncr.setShowChartTitle(cr.isShowChartTitle()); - ncr.setPublic(cr.isPublic()); - ncr.setHideFormFieldAfterRun(cr.isHideFormFieldAfterRun()); - ncr.setCreateId(cr.getCreateId()); - ncr.setCreateDate(cr.getCreateDate()); - if (nvl(cr.getReportSQL()).length() > 0) - ncr.setReportSQL(cr.getReportSQL()); - if (nvl(cr.getReportTitle()).length() > 0) - ncr.setReportTitle(cr.getReportTitle()); - if (nvl(cr.getReportSubTitle()).length() > 0) - ncr.setReportSubTitle(cr.getReportSubTitle()); - if (nvl(cr.getReportHeader()).length() > 0) - ncr.setReportHeader(cr.getReportHeader()); - if (cr.getFrozenColumns()!=null) - ncr.setFrozenColumns(cr.getFrozenColumns()); - if (nvl(cr.getPdfImgLogo()).length()>0) - ncr.setPdfImgLogo(cr.getPdfImgLogo()); - if (nvl(cr.getEmptyMessage()).length()>0) - ncr.setEmptyMessage(cr.getEmptyMessage()); - if (nvl(cr.getWidthNoColumn()).length()>0) - ncr.setWidthNoColumn(cr.getWidthNoColumn()); - if (nvl(cr.getDataGridAlign()).length()>0) - ncr.setDataGridAlign(cr.getDataGridAlign()); - - if (nvl(cr.getReportFooter()).length() > 0) - ncr.setReportFooter(cr.getReportFooter()); - if (nvl(cr.getNumFormCols()).length() > 0) - ncr.setNumFormCols(cr.getNumFormCols()); - if (nvl(cr.getDisplayOptions()).length() > 0) - ncr.setDisplayOptions(cr.getDisplayOptions()); - if (nvl(cr.getDataContainerHeight()).length() > 0) - ncr.setDataContainerHeight(cr.getDataContainerHeight()); - if (nvl(cr.getDataContainerWidth()).length() > 0) - ncr.setDataContainerWidth(cr.getDataContainerWidth()); - if (nvl(cr.getAllowSchedule()).length() > 0) - ncr.setAllowSchedule(cr.getAllowSchedule()); - if (nvl(cr.getTopDown()).length() > 0) - ncr.setTopDown(cr.getTopDown()); - if (nvl(cr.getSizedByContent()).length() > 0) - ncr.setSizedByContent(cr.getSizedByContent()); - if (nvl(cr.getComment()).length() > 0) - ncr.setComment(cr.getComment()); - if (nvl(cr.getDashboardOptions()).length()>0) - ncr.setDashboardOptions(cr.getDashboardOptions()); - - if(cr.isDashboardType()!=null) - ncr.setDashboardType(cr.isDashboardType()); - if(cr.isReportInNewWindow()!=null) - ncr.setReportInNewWindow(cr.isReportInNewWindow()); - ncr.setDisplayFolderTree(cr.isDisplayFolderTree()); - if (cr.getDashBoardReports() == null) { - if (cr.getMaxRowsInExcelDownload()!=null && cr.getMaxRowsInExcelDownload()>0) - ncr.setMaxRowsInExcelDownload(cr.getMaxRowsInExcelDownload()); - } - - if (nvl(cr.getJavascriptElement()).length()>0) - ncr.setJavascriptElement(cr.getJavascriptElement()); - if (nvl(cr.getFolderId()).length()>0) - ncr.setFolderId(cr.getFolderId()); - ncr.setDrillURLInPoPUpPresent((cr.isDrillURLInPoPUpPresent()!=null && cr.isDrillURLInPoPUpPresent().booleanValue())?true:false); - - if (nvl(cr.getIsOneTimeScheduleAllowed()).length()>0) - ncr.setIsOneTimeScheduleAllowed(cr.getIsOneTimeScheduleAllowed()); - if (nvl(cr.getIsHourlyScheduleAllowed()).length()>0) - ncr.setIsHourlyScheduleAllowed(cr.getIsHourlyScheduleAllowed()); - if (nvl(cr.getIsDailyScheduleAllowed()).length()>0) - ncr.setIsDailyScheduleAllowed(cr.getIsDailyScheduleAllowed()); - if (nvl(cr.getIsDailyMFScheduleAllowed()).length()>0) - ncr.setIsDailyMFScheduleAllowed(cr.getIsDailyMFScheduleAllowed()); - if (nvl(cr.getIsWeeklyScheduleAllowed()).length()>0) - ncr.setIsWeeklyScheduleAllowed(cr.getIsWeeklyScheduleAllowed()); - if (nvl(cr.getIsMonthlyScheduleAllowed()).length()>0) - ncr.setIsMonthlyScheduleAllowed(cr.getIsMonthlyScheduleAllowed()); - - ncr.setPageSize(cr.getPageSize()); - ncr.setReportType(cr.getReportType()); - - - DataSourceList dataSourceList = objFactory.createDataSourceList(); - ncr.setDataSourceList(dataSourceList); - - for (Iterator iter = cr.getDataSourceList().getDataSource().iterator(); iter.hasNext();) { - dataSourceList.getDataSource().add( - cloneDataSourceType(objFactory, (DataSourceType) iter.next())); - } - - if (cr.getFormFieldList() != null) { - FormFieldList formFieldList = objFactory.createFormFieldList(); - ncr.setFormFieldList(formFieldList); - ncr.getFormFieldList().setComment(formFieldList.getComment()); - - for (Iterator iter = cr.getFormFieldList().getFormField().iterator(); iter - .hasNext();) - formFieldList.getFormField().add( - cloneFormFieldType(objFactory, (FormFieldType) iter.next())); - formFieldList.setComment(cr.getFormFieldList().getComment()); - } // if - - if (cr.getJavascriptList() != null) { - JavascriptList javascriptList = objFactory.createJavascriptList(); - ncr.setJavascriptList(javascriptList); - - for (Iterator iter = cr.getJavascriptList().getJavascriptItem().iterator(); iter - .hasNext();) - javascriptList.getJavascriptItem().add( - cloneJavascriptType(objFactory, (JavascriptItemType) iter.next())); - } // if - - if (cr.getSemaphoreList() != null) { - SemaphoreList semaphoreList = objFactory.createSemaphoreList(); - ncr.setSemaphoreList(semaphoreList); - - for (Iterator iter = cr.getSemaphoreList().getSemaphore().iterator(); iter - .hasNext();) { - semaphoreList.getSemaphore().add( - cloneSemaphoreType(objFactory, (SemaphoreType) iter.next())); - } - } // if - - if (nvl(cr.getDashboardOptions()).length()>0) - ncr.setDashboardOptions(cr.getDashboardOptions()); - if(cr.isDashboardType()!=null) - ncr.setDashboardType(cr.isDashboardType()); - if(cr.isReportInNewWindow()!=null) - ncr.setReportInNewWindow(cr.isReportInNewWindow()); - ncr.setDisplayFolderTree(cr.isDisplayFolderTree()); - if (cr.getDashBoardReports() == null) { - if (cr.getMaxRowsInExcelDownload()!=null && cr.getMaxRowsInExcelDownload()>0) - ncr.setMaxRowsInExcelDownload(cr.getMaxRowsInExcelDownload()); - } - - if (cr.getDashBoardReports() != null) { - DashboardReports dashboardReports = objFactory.createDashboardReports(); - ncr.setDashBoardReports(dashboardReports); - - for (Iterator iter = cr.getDashBoardReports().getReportsList().iterator(); iter - .hasNext();) { - dashboardReports.getReportsList().add( - cloneDashboardType(objFactory, (Reports) iter.next())); - } - } // if - - if (cr.getChartAdditionalOptions() != null) { - ChartAdditionalOptions chartAdditionalOptions = objFactory.createChartAdditionalOptions(); - if(nvl(cr.getChartAdditionalOptions().getChartMultiplePieOrder()).length()>0) - chartAdditionalOptions.setChartMultiplePieOrder(cr.getChartAdditionalOptions().getChartMultiplePieOrder()); - if(nvl(cr.getChartAdditionalOptions().getChartMultiplePieLabelDisplay()).length()>0) - chartAdditionalOptions.setChartMultiplePieLabelDisplay(cr.getChartAdditionalOptions().getChartMultiplePieLabelDisplay()); - - if(nvl(cr.getChartAdditionalOptions().getChartOrientation()).length()>0) - chartAdditionalOptions.setChartOrientation(cr.getChartAdditionalOptions().getChartOrientation()); - if(nvl(cr.getChartAdditionalOptions().getSecondaryChartRenderer()).length()>0) - chartAdditionalOptions.setSecondaryChartRenderer(cr.getChartAdditionalOptions().getSecondaryChartRenderer()); - - if(nvl(cr.getChartAdditionalOptions().getChartDisplay()).length()>0) - chartAdditionalOptions.setChartDisplay(cr.getChartAdditionalOptions().getChartDisplay()); - if(nvl(cr.getChartAdditionalOptions().getHideToolTips()).length()>0) - chartAdditionalOptions.setHideToolTips(cr.getChartAdditionalOptions().getHideToolTips()); - if(nvl(cr.getChartAdditionalOptions().getHidechartLegend()).length()>0) - chartAdditionalOptions.setHidechartLegend(cr.getChartAdditionalOptions().getHidechartLegend()); - if(nvl(cr.getChartAdditionalOptions().getLegendPosition()).length()>0) - chartAdditionalOptions.setLegendPosition(cr.getChartAdditionalOptions().getLegendPosition()); - if(nvl(cr.getChartAdditionalOptions().getLabelAngle()).length()>0) - chartAdditionalOptions.setLabelAngle(cr.getChartAdditionalOptions().getLabelAngle()); - - if(nvl(cr.getChartAdditionalOptions().getIntervalFromdate()).length()>0) - chartAdditionalOptions.setIntervalFromdate(cr.getChartAdditionalOptions().getIntervalFromdate()); - if(nvl(cr.getChartAdditionalOptions().getIntervalTodate()).length()>0) - chartAdditionalOptions.setIntervalTodate(cr.getChartAdditionalOptions().getIntervalTodate()); - if(nvl(cr.getChartAdditionalOptions().getIntervalLabel()).length()>0) - chartAdditionalOptions.setIntervalLabel(cr.getChartAdditionalOptions().getIntervalLabel()); - - if(nvl(cr.getChartAdditionalOptions().getLastSeriesALineChart()).length()>0) - chartAdditionalOptions.setLastSeriesALineChart(cr.getChartAdditionalOptions().getLastSeriesALineChart()); - if(nvl(cr.getChartAdditionalOptions().getLastSeriesABarChart()).length()>0) - chartAdditionalOptions.setLastSeriesABarChart(cr.getChartAdditionalOptions().getLastSeriesABarChart()); - - if(nvl(cr.getChartAdditionalOptions().getMaxLabelsInDomainAxis()).length()>0) - chartAdditionalOptions.setMaxLabelsInDomainAxis(cr.getChartAdditionalOptions().getMaxLabelsInDomainAxis()); - if(nvl(cr.getChartAdditionalOptions().getLinearRegression()).length()>0) - chartAdditionalOptions.setLinearRegression(cr.getChartAdditionalOptions().getLinearRegression()); - if(nvl(cr.getChartAdditionalOptions().getLinearRegressionColor()).length()>0) - chartAdditionalOptions.setLinearRegressionColor(cr.getChartAdditionalOptions().getLinearRegressionColor()); - if(nvl(cr.getChartAdditionalOptions().getExponentialRegressionColor()).length()>0) - chartAdditionalOptions.setExponentialRegressionColor(cr.getChartAdditionalOptions().getExponentialRegressionColor()); - if(nvl(cr.getChartAdditionalOptions().getMaxRegression()).length()>0) - chartAdditionalOptions.setMaxRegression(cr.getChartAdditionalOptions().getMaxRegression()); - if(nvl(cr.getChartAdditionalOptions().getRangeAxisUpperLimit()).length()>0) - chartAdditionalOptions.setRangeAxisUpperLimit(cr.getChartAdditionalOptions().getRangeAxisUpperLimit()); - if(nvl(cr.getChartAdditionalOptions().getRangeAxisLowerLimit()).length()>0) - chartAdditionalOptions.setRangeAxisLowerLimit(cr.getChartAdditionalOptions().getRangeAxisLowerLimit()); - if(nvl(cr.getChartAdditionalOptions().getOverlayItemValueOnStackBar()).length()>0) - chartAdditionalOptions.setOverlayItemValueOnStackBar(cr.getChartAdditionalOptions().getOverlayItemValueOnStackBar()); - chartAdditionalOptions.setAnimate((cr.getChartAdditionalOptions().isAnimate()!=null && cr.getChartAdditionalOptions().isAnimate().booleanValue())?true:false); - - if(nvl(cr.getChartAdditionalOptions().getKeepDomainAxisValueAsString()).length()>0) - chartAdditionalOptions.setKeepDomainAxisValueAsString(cr.getChartAdditionalOptions().getKeepDomainAxisValueAsString()); - - - // Animate - chartAdditionalOptions.setAnimateAnimatedChart((cr.getChartAdditionalOptions().isAnimateAnimatedChart()!=null && cr.getChartAdditionalOptions().isAnimateAnimatedChart().booleanValue())?true:false); - chartAdditionalOptions.setStacked((cr.getChartAdditionalOptions().isStacked()!=null && cr.getChartAdditionalOptions().isStacked().booleanValue())?true:false); - chartAdditionalOptions.setBarControls((cr.getChartAdditionalOptions().isBarControls()!=null && cr.getChartAdditionalOptions().isBarControls().booleanValue())?true:false); - chartAdditionalOptions.setXAxisDateType((cr.getChartAdditionalOptions().isXAxisDateType()!=null && cr.getChartAdditionalOptions().isXAxisDateType().booleanValue())?true:false); - chartAdditionalOptions.setLessXaxisTickers((cr.getChartAdditionalOptions().isLessXaxisTickers()!=null && cr.getChartAdditionalOptions().isLessXaxisTickers().booleanValue())?true:false); - chartAdditionalOptions.setTimeAxis((cr.getChartAdditionalOptions().isTimeAxis()!=null && cr.getChartAdditionalOptions().isTimeAxis().booleanValue())?true:false); - - if(nvl(cr.getChartAdditionalOptions().getTimeSeriesRender()).length()>0) - chartAdditionalOptions.setTimeSeriesRender(cr.getChartAdditionalOptions().getTimeSeriesRender()); - - chartAdditionalOptions.setMultiSeries((cr.getChartAdditionalOptions().isMultiSeries()!=null && cr.getChartAdditionalOptions().isMultiSeries().booleanValue())?true:false); - - chartAdditionalOptions.setTopMargin(cr.getChartAdditionalOptions().getTopMargin()!=null?cr.getChartAdditionalOptions().getTopMargin():new Integer(30)); - chartAdditionalOptions.setBottomMargin(cr.getChartAdditionalOptions().getBottomMargin()!=null?cr.getChartAdditionalOptions().getBottomMargin():new Integer(50)); - chartAdditionalOptions.setLeftMargin(cr.getChartAdditionalOptions().getLeftMargin()!=null?cr.getChartAdditionalOptions().getLeftMargin():new Integer(100)); - chartAdditionalOptions.setRightMargin(cr.getChartAdditionalOptions().getRightMargin()!=null?cr.getChartAdditionalOptions().getRightMargin():new Integer(60)); - - - ncr.setChartAdditionalOptions(chartAdditionalOptions); - } // if - - if (nvl(cr.getJavascriptElement()).length()>0) - ncr.setJavascriptElement(cr.getJavascriptElement()); - if (nvl(cr.getFolderId()).length()>0) - ncr.setFolderId(cr.getFolderId()); - - if (cr.getChartDrillOptions() != null) { - ChartDrillOptions chartDrillOptions = objFactory.createChartDrillOptions(); - - if(nvl(cr.getChartDrillOptions().getDrillReportId()).length()>0) - chartDrillOptions.setDrillReportId(cr.getChartDrillOptions().getDrillReportId()); - - for (Iterator iter = cr.getChartDrillOptions().getTargetFormfield().iterator(); iter - .hasNext();) { - chartDrillOptions.getTargetFormfield().add( - cloneChartDrillFormfield(objFactory, (ChartDrillFormfield)iter.next())); - - } - - if(nvl(cr.getChartDrillOptions().getDrillXAxisFormField()).length()>0) - chartDrillOptions.setDrillXAxisFormField(cr.getChartDrillOptions().getDrillXAxisFormField()); - if(nvl(cr.getChartDrillOptions().getDrillYAxisFormField()).length()>0) - chartDrillOptions.setDrillYAxisFormField(cr.getChartDrillOptions().getDrillYAxisFormField()); - if(nvl(cr.getChartDrillOptions().getDrillSeriesFormField()).length()>0) - chartDrillOptions.setDrillSeriesFormField(cr.getChartDrillOptions().getDrillSeriesFormField()); - - - ncr.setChartDrillOptions(chartDrillOptions); - } - - if (nvl(cr.getIsOneTimeScheduleAllowed()).length()>0) - ncr.setIsOneTimeScheduleAllowed(cr.getIsOneTimeScheduleAllowed()); - if (nvl(cr.getIsHourlyScheduleAllowed()).length()>0) - ncr.setIsHourlyScheduleAllowed(cr.getIsHourlyScheduleAllowed()); - if (nvl(cr.getIsDailyScheduleAllowed()).length()>0) - ncr.setIsDailyScheduleAllowed(cr.getIsDailyScheduleAllowed()); - if (nvl(cr.getIsDailyMFScheduleAllowed()).length()>0) - ncr.setIsDailyMFScheduleAllowed(cr.getIsDailyMFScheduleAllowed()); - if (nvl(cr.getIsWeeklyScheduleAllowed()).length()>0) - ncr.setIsWeeklyScheduleAllowed(cr.getIsWeeklyScheduleAllowed()); - if (nvl(cr.getIsMonthlyScheduleAllowed()).length()>0) - ncr.setIsMonthlyScheduleAllowed(cr.getIsMonthlyScheduleAllowed()); - - ncr.setPageSize(cr.getPageSize()); - ncr.setReportType(cr.getReportType()); - - if (cr.getReportMap() != null){ - ReportMap repMap = objFactory.createReportMap(); - if(nvl(cr.getReportMap().getMarkerColor()).length()>0) - repMap.setMarkerColor(cr.getReportMap().getMarkerColor()); - if(nvl(cr.getReportMap().getUseDefaultSize()).length()>0) - repMap.setUseDefaultSize(cr.getReportMap().getUseDefaultSize()); - if(nvl(cr.getReportMap().getHeight()).length()>0) - repMap.setHeight(cr.getReportMap().getHeight()); - if(nvl(cr.getReportMap().getWidth()).length()>0) - repMap.setWidth(cr.getReportMap().getWidth()); - if(nvl(cr.getReportMap().getIsMapAllowedYN()).length()>0) - repMap.setIsMapAllowedYN(cr.getReportMap().getIsMapAllowedYN()); - if(nvl(cr.getReportMap().getAddAddressInDataYN()).length()>0) - repMap.setAddAddressInDataYN(cr.getReportMap().getAddAddressInDataYN()); - if(nvl(cr.getReportMap().getAddressColumn()).length()>0) - repMap.setAddressColumn(cr.getReportMap().getAddressColumn()); - if(nvl(cr.getReportMap().getDataColumn()).length()>0) - repMap.setDataColumn(cr.getReportMap().getDataColumn()); - if(nvl(cr.getReportMap().getDefaultMapType()).length()>0) - repMap.setDefaultMapType(cr.getReportMap().getDefaultMapType()); - if(nvl(cr.getReportMap().getLatColumn()).length()>0) - repMap.setLatColumn(cr.getReportMap().getLatColumn()); - if(nvl(cr.getReportMap().getLongColumn()).length()>0) - repMap.setLongColumn(cr.getReportMap().getLongColumn()); - if(nvl(cr.getReportMap().getColorColumn()).length()>0) - repMap.setColorColumn(cr.getReportMap().getColorColumn()); - if(nvl(cr.getReportMap().getLegendColumn()).length()>0) - repMap.setLegendColumn(cr.getReportMap().getLegendColumn()); - - - for (Iterator iter = cr.getReportMap().getMarkers().iterator(); iter - .hasNext();) { - repMap.getMarkers().add( - cloneMarkerType(objFactory, (Marker)iter.next())); - - } - - ncr.setReportMap(repMap); - } - - - - } catch (JAXBException ex) { // try - throw new RaptorException(ex.getMessage(), ex.getCause()); - } - - return ncr; - } // cloneCustomReport - - /** ************************************************************************************************* */ - - public void printFormatType(FormatType ft) { - System.out.println("------------------------------------------------"); - System.out.println("Semaphore Col Format"); - System.out.println("------------------------------------------------"); - System.out.println("FormatId: [" + ft.getFormatId() + "]"); - System.out.println("LessThanValue: [" + ft.getLessThanValue() + "]"); - System.out.println("Expression: [" + ft.getExpression() + "]"); - System.out.println("Bold: [" + ft.isBold() + "]"); - System.out.println("Italic: [" + ft.isItalic() + "]"); - System.out.println("Underline: [" + ft.isUnderline() + "]"); - System.out.println("BgColor: [" + ft.getBgColor() + "]"); - System.out.println("FontColor: [" + ft.getFontColor() + "]"); - System.out.println("FontFace: [" + ft.getFontFace() + "]"); - System.out.println("FontSize: [" + ft.getFontSize() + "]"); - System.out.println("Alignment: [" + ft.getAlignment() + "]"); - System.out.println("Comment: [" + ft.getComment() + "]"); - System.out.println("------------------------------------------------"); - } // printFormatType - - public void printSemaphoreType(SemaphoreType st) { - System.out.println("------------------------------------------------"); - System.out.println("Semaphore"); - System.out.println("------------------------------------------------"); - System.out.println("SemaphoreId: [" + st.getSemaphoreId() + "]"); - System.out.println("SemaphoreName: [" + st.getSemaphoreName() + "]"); - System.out.println("SemaphoreType: [" + st.getSemaphoreType() + "]"); - System.out.println("Comment: [" + st.getComment() + "]"); - - if (st.getFormatList() != null) - for (Iterator iter = st.getFormatList().getFormat().iterator(); iter.hasNext();) - printFormatType((FormatType) iter.next()); - - System.out.println("------------------------------------------------"); - } // printSemaphoreType - - public void printFormFieldType(FormFieldType fft) { - System.out.println("------------------------------------------------"); - System.out.println("Form Field"); - System.out.println("------------------------------------------------"); - System.out.println("FieldId: [" + fft.getFieldId() + "]"); - System.out.println("ColId: [" + fft.getColId() + "]"); - System.out.println("FieldName: [" + fft.getFieldName() + "]"); - System.out.println("FieldType: [" + fft.getFieldType() + "]"); - System.out.println("ValidationType: [" + fft.getValidationType() + "]"); - System.out.println("Mandatory: [" + fft.getMandatory() + "]"); - System.out.println("DefaultValue: [" + fft.getDefaultValue() + "]"); - System.out.println("OrderBySeq: [" + fft.getOrderBySeq() + "]"); - System.out.println("FieldSQL: [" + fft.getFieldSQL() + "]"); - System.out.println("Comment: [" + fft.getComment() + "]"); - if (fft.getPredefinedValueList() != null) - for (Iterator iter = fft.getPredefinedValueList().getPredefinedValue().iterator(); iter - .hasNext();) - System.out.println("PredefinedValues: [" + ((String) iter.next()) + "]"); - - System.out.println("------------------------------------------------"); - } // printFormFieldType - - public void printColFilterType(ColFilterType cft) { - System.out.println("------------------------------------------------"); - System.out.println("Col Filter"); - System.out.println("------------------------------------------------"); - System.out.println("ColId: [" + cft.getColId() + "]"); - System.out.println("FilterSeq: [" + cft.getFilterSeq() + "]"); - System.out.println("JoinCondition: [" + cft.getJoinCondition() + "]"); - System.out.println("OpenBrackets: [" + cft.getOpenBrackets() + "]"); - System.out.println("Expression: [" + cft.getExpression() + "]"); - System.out.println("ArgType: [" + cft.getArgType() + "]"); - System.out.println("ArgValue: [" + cft.getArgValue() + "]"); - System.out.println("CloseBrackets: [" + cft.getCloseBrackets() + "]"); - System.out.println("Comment: [" + cft.getComment() + "]"); - System.out.println("------------------------------------------------"); - } // printColFilterType - - public void printDataColumnType(DataColumnType dct) { - System.out.println("------------------------------------------------"); - System.out.println("Data Column"); - System.out.println("------------------------------------------------"); - System.out.println("ColId: [" + dct.getColId() + "]"); - System.out.println("TableId: [" + dct.getTableId() + "]"); - System.out.println("DbColName: [" + dct.getDbColName() + "]"); - System.out.println("CrossTabValue: [" + dct.getCrossTabValue() + "]"); - System.out.println("ColName: [" + dct.getColName() + "]"); - System.out.println("DisplayName: [" + dct.getDisplayName() + "]"); - System.out.println("DisplayWidth: [" + dct.getDisplayWidth() + "]"); - System.out.println("DisplayAlignment: [" + dct.getDisplayAlignment() + "]"); - System.out.println("DisplayHeaderAlignment: [" + dct.getDisplayHeaderAlignment() + "]"); - System.out.println("OrderSeq(): [" + dct.getOrderSeq() + "]"); - System.out.println("Visible: [" + dct.isVisible() + "]"); - System.out.println("Calculated: [" + dct.isCalculated() + "]"); - System.out.println("ColType: [" + dct.getColType() + "]"); - System.out.println("ColFormat: [" + dct.getColFormat() + "]"); - System.out.println("GroupBreak: [" + dct.isGroupBreak() + "]"); - System.out.println("OrderBySeq: [" + dct.getOrderBySeq() + "]"); - System.out.println("OrderByAscDesc: [" + dct.getOrderByAscDesc() + "]"); - System.out.println("DisplayTotal: [" + dct.getDisplayTotal() + "]"); - System.out.println("ColOnChart: [" + dct.getColOnChart() + "]"); - System.out.println("ChartSeq: [" + dct.getChartSeq() + "]"); - System.out.println("ChartColor: [" + dct.getChartColor() + "]"); - System.out.println("DrillDownType: [" + dct.getDrillDownType() + "]"); - System.out.println("DrillDownURL: [" + dct.getDrillDownURL() + "]"); - System.out.println("DrillDownParams: [" + dct.getDrillDownParams() + "]"); - System.out.println("Comment: [" + dct.getComment() + "]"); - - if (dct.getColFilterList() != null) - for (Iterator iter = dct.getColFilterList().getColFilter().iterator(); iter - .hasNext();) - printColFilterType((ColFilterType) iter.next()); - - System.out.println("SemaphoreId: [" + dct.getSemaphoreId() + "]"); - System.out.println("DbColType: [" + dct.getDbColType() + "]"); - System.out.println("------------------------------------------------"); - } // printDataColumnType - - public void printDataSourceType(DataSourceType dst) { - System.out.println("------------------------------------------------"); - System.out.println("Data Source"); - System.out.println("------------------------------------------------"); - System.out.println("TableId: [" + dst.getTableId() + "]"); - System.out.println("TableName: [" + dst.getTableName() + "]"); - System.out.println("TablePK: [" + dst.getTablePK() + "]"); - System.out.println("DisplayName: [" + dst.getDisplayName() + "]"); - System.out.println("RefTableId: [" + dst.getRefTableId() + "]"); - System.out.println("RefDefinition: [" + dst.getRefDefinition() + "]"); - System.out.println("Comment: [" + dst.getComment() + "]"); - - for (Iterator iter = dst.getDataColumnList().getDataColumn().iterator(); iter - .hasNext();) - printDataColumnType((DataColumnType) iter.next()); - - System.out.println("------------------------------------------------"); - } // printDataSourceType - - public void print() { - System.out.println("------------------------------------------------"); - System.out.println("ReportWrapper object"); - System.out.println("------------------------------------------------"); - System.out.println("PageSize: [" + getPageSize() + "]"); - System.out.println("ReportType: [" + getReportType() + "]"); - System.out.println("ReportName: [" + getReportName() + "]"); - System.out.println("ReportDescr: [" + getReportDescr() + "]"); - System.out.println("ChartType: [" + getChartType() + "]"); - System.out.println("ChartTypeFixed: [" + getChartTypeFixed() + "]"); - //System.out.println("ChartLeftAxisLabel: [" + getChartLeftAxisLabel() + "]"); - //System.out.println("ChartRightAxisLabel: [" + getChartRightAxisLabel() + "]"); - System.out.println("ChartWidth: [" + getChartWidth() + "]"); - System.out.println("ChartHeight: [" + getChartHeight() + "]"); - System.out.println("Public: [" + isPublic() + "]"); - System.out.println("CreateId: NOT USED ANYMORE[" + /* getCreateId()+ */"]"); - System.out.println("CreateDate: NOT USED ANYMORE[" + /* getCreateDate()+ */"]"); - System.out.println("ReportSQL: [" + getReportSQL() + "]"); - System.out.println("ReportTitle: [" + getReportTitle() + "]"); - System.out.println("DbInfo: [" + getDBInfo() + "]"); - System.out.println("ReportSubTitle: [" + getReportSubTitle() + "]"); - System.out.println("ReportHeader: [" + getReportHeader() + "]"); - System.out.println("ReportFooter: [" + getReportFooter() + "]"); - System.out.println("NumFormCols: [" + getNumFormCols() + "]"); - System.out.println("DisplayOptions: [" + getDisplayOptions() + "]"); - System.out.println("Comment: [" + getComment() + "]"); - - for (Iterator iter = cr.getDataSourceList().getDataSource().iterator(); iter.hasNext();) - printDataSourceType((DataSourceType) iter.next()); - - if (cr.getFormFieldList() != null) - for (Iterator iter = cr.getFormFieldList().getFormField().iterator(); iter - .hasNext();) - printFormFieldType((FormFieldType) iter.next()); - - if (cr.getSemaphoreList() != null) - for (Iterator iter = cr.getSemaphoreList().getSemaphore().iterator(); iter - .hasNext();) - printSemaphoreType((SemaphoreType) iter.next()); - - System.out.println("------------------------------------------------"); - System.out.println("ReportWrapper object end"); - System.out.println("------------------------------------------------"); - } // print - - private int getIntValue(String value, int defaultValue) { - int iValue = defaultValue; - try { - iValue = Integer.parseInt(value); - } catch (Exception e) { - } - - return iValue; - } // getIntValue - public static String replaceNewLine( String strSource, String strFind, String chrReplace ) - { - // buffer to hold the target string after replacement is done. - StringBuffer sbfTemp = new StringBuffer(); - - try - { - // for each occurrence of strFind in strSource, replace it with chrReplace. - int intIndex = strSource.indexOf( strFind, 0 ); - - // check if there is any instace of strFind in strSource - if( intIndex >= 0 ) - { - // holds the index from where the search is supposed to happen. - int intStart = 0; - - // size of the source string - int intTotalSize = strSource.length(); - - while( intStart < intTotalSize && - ( ( intIndex = strSource.indexOf( strFind, intStart ) ) >= 0 ) ) - { - // check if strFind is at the beginning... i.e., at index intStart - if( intIndex == intStart ) - { - /* - * starts with strFind...just append chrReplace - * to the target - */ - sbfTemp.append( chrReplace ); - } - else - { - // append the sub-string...plus chrReplace - sbfTemp.append( strSource.substring( intStart, intIndex ) ); - sbfTemp.append( chrReplace ); - } - - // advance string index - intStart = intIndex + strFind.length(); - } - - // append the last portion of the source string. - sbfTemp.append( strSource.substring( intStart ) ); - } - else - { - // strFind not found... just copy the text as it is. - sbfTemp.append( strSource ); - } - } - catch( Exception expGeneral ) - { - // in case of any exception, return the source string as it is. - sbfTemp = new StringBuffer( strSource ); - } - - return sbfTemp.toString(); - } - - /*folder id*/ - public String getFolderId() { - return nvl(cr.getFolderId()).length()>0?cr.getFolderId():"NULL"; - } - public void setFolderId(String folderId ) { - cr.setFolderId(folderId); - } - - public String addZero(String num) { - int numInt = 0; - try { - numInt = Integer.parseInt(num); - }catch(NumberFormatException ex){ - numInt = 0; - } - if(numInt < 10) return "0"+numInt; - else return ""+numInt; - } - - public String getIsDailyMFScheduleAllowed() { - return cr.getIsDailyMFScheduleAllowed(); - } - - public void setIsDailyMFScheduleAllowed(String isDailyMFScheduleAllowed) { - cr.setIsDailyMFScheduleAllowed(isDailyMFScheduleAllowed); - } - - public String getIsDailyScheduleAllowed() { - return cr.getIsDailyScheduleAllowed(); - } - - public void setIsDailyScheduleAllowed(String isDailyScheduleAllowed) { - cr.setIsDailyScheduleAllowed(isDailyScheduleAllowed); - } - - public String getIsHourlyScheduleAllowed() { - return cr.getIsHourlyScheduleAllowed(); - } - - public void setIsHourlyScheduleAllowed(String isHourlyScheduleAllowed) { - cr.setIsHourlyScheduleAllowed(isHourlyScheduleAllowed); - } - - public String getIsMonthlyScheduleAllowed() { - return cr.getIsMonthlyScheduleAllowed(); - } - - public void setIsMonthlyScheduleAllowed(String isMonthlyScheduleAllowed) { - cr.setIsMonthlyScheduleAllowed(isMonthlyScheduleAllowed); - } - - public String getIsOneTimeScheduleAllowed() { - return cr.getIsOneTimeScheduleAllowed(); - } - - public void setIsOneTimeScheduleAllowed(String isOneTimeScheduleAllowed) { - cr.setIsOneTimeScheduleAllowed(isOneTimeScheduleAllowed); - } - - public String getIsWeeklyScheduleAllowed() { - return cr.getIsWeeklyScheduleAllowed(); - } - - public void setIsWeeklyScheduleAllowed(String isWeeklyScheduleAllowed) { - cr.setIsWeeklyScheduleAllowed(isWeeklyScheduleAllowed); - - } - - public static boolean isNull(String a) { - if ((a == null) || (a.length() == 0) || a.equalsIgnoreCase("null")) - return true; - else - return false; - } - - public int getDependsOnFormFieldFlag(DataColumnType dc, HashMap formValues) { - int flag = 0; - String fieldValue = ""; - if(nvl(dc.getDependsOnFormField()).length()>0 && nvl(dc.getDependsOnFormField()).indexOf("[")!=-1) { - if(formValues != null) { - Set set = formValues.entrySet(); - String value = ""; - for(Iterator iter1 = set.iterator(); iter1.hasNext(); ) { - Map.Entry entry = (Entry) iter1.next(); - value = (String) entry.getValue(); - if (dc.getDependsOnFormField().equals("["+entry.getKey()+"]")) { - fieldValue = nvl(value); - - if (fieldValue.length()>0 && !fieldValue.equals("NULL")) { - flag = 0; - } else { - flag = 1; - } - - } - } - } - } - - return flag; - } - - /* Datamining Getter Setter */ - - public String getClassifier() { - return (cr.getDataminingOptions()!=null?cr.getDataminingOptions().getClassifier():""); - } - - public void setClassifier( String classifier) { - cr.getDataminingOptions().setClassifier(classifier); - } - - - public int getForecastingPeriod() { - return (cr.getDataminingOptions()!=null? new Integer(cr.getDataminingOptions().getForecastingUnits()).intValue():-1); - } - - public void setForecastingPeriod( String period) { - cr.getDataminingOptions().setForecastingUnits(period); - } - - public String getForecastingTimeFormat() { - return (cr.getDataminingOptions()!=null?cr.getDataminingOptions().getTimeformat():""); - } - - public void setForecastingTimeFormat( String format) { - cr.getDataminingOptions().setTimeformat(format); - } - - /** - * Get Number of Columns to Frozen in Data Grid - */ - - public int getFrozenColumns() { - return cr.getFrozenColumns()==null?0:cr.getFrozenColumns(); - } - - public String getFrozenColumnId() { - int noOfColumns = cr.getFrozenColumns()==null?0:cr.getFrozenColumns(); - if(noOfColumns != 0) { - List reportCols = getOnlyVisibleColumns(); - int colIdx = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - ++colIdx; - DataColumnType dc = (DataColumnType) iter.next(); - if(colIdx == noOfColumns) { - - return dc.getColId(); - } else continue; - } // for - return ""; - } else return ""; - - } - - /** - * Set Number of Columns to Frozen in Data Grid - */ - - public void setFrozenColumns( int frozenColumns) { - cr.setFrozenColumns(frozenColumns); - } - - /** - * @return the reportSQLWithRowNum for ZK Support - */ - public String getReportSQLWithRowNum() { - return reportSQLWithRowNum; - } - - /** - * @param reportSQLWithRowNum the reportSQLWithRowNum to set for ZK Support - */ - public void setReportSQLWithRowNum(String reportSQLWithRowNum) { - this.reportSQLWithRowNum = reportSQLWithRowNum; - } - - //used for Zk sort - public void setReportSQLOnlyFirstPart(String reportSQLOnlyFirstPart) { - this.reportSQLOnlyFirstPart = reportSQLOnlyFirstPart; - } - - public String getReportSQLOnlyFirstPart() { - return this.reportSQLOnlyFirstPart; - } - - public String getTemplateFile() throws RaptorException { - return ReportLoader.getTemplateFile(getReportID()); - } - - public String getPdfImg() { - return cr.getPdfImgLogo(); - } - - - public String getEmptyMessage() { - String emptyMessage = cr.getEmptyMessage(); - if(nvl(emptyMessage).length()<=0) - emptyMessage = Globals.getReportEmptyMessage(); - return emptyMessage; - } - - public void setPdfImg(String img_loc) { - cr.setPdfImgLogo(img_loc); - } - - public void setEmptyMessage(String emptyMessage) { - cr.setEmptyMessage(emptyMessage); - } - - public void setDrillReportIdForChart(String reportId) { - //(cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().setDrillReportId():""; - cr.getChartDrillOptions().setDrillReportId(reportId); - } - - public String getDrillReportIdForChart() { - return (cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().getDrillReportId():""; - } - - public void setDrillXAxisFormField(String formField) { - //(cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().setDrillReportId():""; - cr.getChartDrillOptions().setDrillXAxisFormField(formField); - } - - public String getDrillXAxisFormField() { - return (cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().getDrillXAxisFormField():""; - } - - public void setDrillYAxisFormField(String formField) { - //(cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().setDrillReportId():""; - cr.getChartDrillOptions().setDrillYAxisFormField(formField); - } - - public String getDrillYAxisFormField() { - return (cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().getDrillYAxisFormField():""; - } - - public void setDrillSeriesFormField(String formField) { - //(cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().setDrillReportId():""; - cr.getChartDrillOptions().setDrillSeriesFormField(formField); - } - - public String getDrillSeriesFormField() { - return (cr.getChartDrillOptions()!=null)?cr.getChartDrillOptions().getDrillSeriesFormField():""; - } - - public boolean isEnhancedPaginationNeeded() { - List reportCols = getAllColumns(); - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (dc.isEnhancedPagination()!=null && dc.isEnhancedPagination().booleanValue()) - return true; - } // for - return false; - } - - public DataColumnType getColumnWhichNeedEnhancedPagination() { - List reportCols = getAllColumns(); - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if (dc.isEnhancedPagination()!=null && dc.isEnhancedPagination().booleanValue()) - return dc; - } // for - return null; - } - - public void setDataGridAlign(String align) { - cr.setDataGridAlign(align); - } - - - public String getDataGridAlign() { - return (cr.getDataGridAlign()!=null)?cr.getDataGridAlign():"left"; - } - - public void setWidthNoColumn(String width) { - cr.setWidthNoColumn(width); - } - - - public String getWidthNoColumn() { - return (cr.getWidthNoColumn()!=null)?cr.getWidthNoColumn():"30px"; - } - - public void setWholeSQL(String sql) { - wholeSQL = sql; - } - public String getWholeSQL() { - return wholeSQL; - } - -} // ReportWrapper diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportDefinition.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportDefinition.java deleted file mode 100644 index 71ec9f87..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportDefinition.java +++ /dev/null @@ -1,1465 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.definition; - -import java.io.Serializable; -import java.sql.Connection; -import java.util.Calendar; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.StringTokenizer; -import java.util.Vector; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; -import javax.xml.bind.JAXBException; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -//import javax.xml.transform.stream.*; - -import org.openecomp.portalsdk.analytics.controller.WizardSequence; -import org.openecomp.portalsdk.analytics.controller.WizardSequenceCrossTab; -import org.openecomp.portalsdk.analytics.controller.WizardSequenceDashboard; -import org.openecomp.portalsdk.analytics.controller.WizardSequenceLinear; -import org.openecomp.portalsdk.analytics.controller.WizardSequenceSQLBasedCrossTab; -import org.openecomp.portalsdk.analytics.controller.WizardSequenceSQLBasedHive; -import org.openecomp.portalsdk.analytics.controller.WizardSequenceSQLBasedLinear; -import org.openecomp.portalsdk.analytics.controller.WizardSequenceSQLBasedLinearDatamining; -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.model.DataCache; -import org.openecomp.portalsdk.analytics.model.ReportLoader; -import org.openecomp.portalsdk.analytics.model.base.OrderBySeqComparator; -import org.openecomp.portalsdk.analytics.model.base.OrderSeqComparator; -import org.openecomp.portalsdk.analytics.model.base.ReportWrapper; -import org.openecomp.portalsdk.analytics.model.runtime.FormField; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.DbUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.analytics.xmlobj.ChartAdditionalOptions; -import org.openecomp.portalsdk.analytics.xmlobj.ChartDrillOptions; -import org.openecomp.portalsdk.analytics.xmlobj.ColFilterType; -import org.openecomp.portalsdk.analytics.xmlobj.CustomReportType; -import org.openecomp.portalsdk.analytics.xmlobj.DataColumnList; -import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; -import org.openecomp.portalsdk.analytics.xmlobj.DataSourceType; -import org.openecomp.portalsdk.analytics.xmlobj.DataminingOptions; -import org.openecomp.portalsdk.analytics.xmlobj.FormFieldList; -import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; -import org.openecomp.portalsdk.analytics.xmlobj.FormatList; -import org.openecomp.portalsdk.analytics.xmlobj.FormatType; -import org.openecomp.portalsdk.analytics.xmlobj.JavascriptItemType; -import org.openecomp.portalsdk.analytics.xmlobj.ObjectFactory; -import org.openecomp.portalsdk.analytics.xmlobj.PredefinedValueList; -import org.openecomp.portalsdk.analytics.xmlobj.SemaphoreType; -import org.openecomp.portalsdk.core.controller.FavoritesController; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -/**
        - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting)
        - *
        - * - * --------------------------------------------------------------------------------------------------
        - * ReportDefinition.java - This involves in creating and modifying RAPTOR reports. - * --------------------------------------------------------------------------------------------------
        - * - * - * Change Log

        - * - * 18-Aug-2009 : Version 8.5.1 (Sundar);
        • request Object is passed to prevent caching user/roles - Datamining/Hosting.
        - * 27-Jul-2009 : Version 8.4 (Sundar);
        • userIsAuthorizedToSeeLog is checked for Admin User instead of Super User.
        - * 22-Jun-2009 : Version 8.4 (Sundar);
        • A new type ChartAdditionalOptions is introduced in RAPTOR XSD. - * For this type a create procedure is added to this class.
        - * - */ - -public class ReportDefinition extends ReportWrapper implements Serializable { - - static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(FavoritesController.class); - - - private ReportSchedule reportSchedule = null; - - private WizardSequence wizardSequence = null; - - - private boolean reportUpdateLogged = false; // Used to avoid multiple - // entries in the report log - // when persisting report on - // each step - - private ReportDefinition(CustomReportType crType, String reportID, String ownerID, - String createID, String createDate, String updateID, String updateDate, - String menuID, boolean menuApproved, HttpServletRequest request) throws RaptorException { - super(crType, reportID, ownerID, createID, createDate, updateID, updateDate, menuID, - menuApproved); - if(reportID.equals("-1")) - reportSchedule = new ReportSchedule(getReportID(), getOwnerID(), false, request); - else - reportSchedule = new ReportSchedule(getReportID(), getOwnerID(), true, request); - generateWizardSequence(null); - } // ReportDefinition - - public ReportDefinition(ReportWrapper rw, HttpServletRequest request)throws RaptorException { - super(rw); - - reportSchedule = new ReportSchedule(reportID, rw.getOwnerID(),false, request); - generateWizardSequence(null); - } // ReportDefinition - - private void setReportID(String reportID) { - this.reportID = reportID; - reportSchedule.setReportID(reportID); - reportSchedule.setScheduleUserID(getOwnerID()); - } // setReportID - - public ReportSchedule getReportSchedule() { - return reportSchedule; - } - - public static ReportDefinition unmarshal(String reportXML, String reportID, HttpServletRequest request) - throws RaptorException { - ReportDefinition rn = null; - CustomReportType crType = ReportWrapper.unmarshalCR(reportXML); - //Log.write("Report [" + reportID + "]: XML unmarshalled", 4); - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] Report [" + reportID + "]: XML unmarshalled")); - - rn = new ReportDefinition(crType, reportID, null, null, null, null, null, null, false, request); - return rn; - } // unmarshal - - public static ReportDefinition createBlank(HttpServletRequest request) throws RaptorException { - String curTime = Utils.getCurrentDateTime(); - String userID = AppUtils.getUserID(request); - ReportDefinition rd = new ReportDefinition(ReportWrapper.createBlankCR(userID), "-1", - userID, userID, curTime, userID, curTime, "", false, request); - - // Necessary initialization - - return rd; - } // ReportDefinition - - public void setAsCopy(HttpServletRequest request) throws RaptorException { - verifySQLBasedReportAccess(request); - - replaceCustomReportWithClone(); - - setReportID("-1"); - setReportName("Copy: " + getReportName()); - } // setAsCopy - - public WizardSequence getWizardSequence() { - return wizardSequence; - } // getWizardSequence - - public void generateWizardSequence(HttpServletRequest request) throws RaptorException { - boolean userIsAuthorizedToSeeLog = false; - String userId = null; - if(request!=null) { - userId = AppUtils.getUserID(request); - if (userId != null) - userIsAuthorizedToSeeLog = AppUtils.isAdminUser(request) - || AppUtils.isAdminUser(request); - //System.out.println("******** Report Type "+getReportType() + " userIsAuthorizedToSeeLog " + userIsAuthorizedToSeeLog); - } - if (getReportType().equals(AppConstants.RT_LINEAR)){ - if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) - wizardSequence = new WizardSequenceSQLBasedLinear(userIsAuthorizedToSeeLog); - else if (getReportDefType().equals(AppConstants.RD_SQL_BASED_DATAMIN)) - wizardSequence = new WizardSequenceSQLBasedLinearDatamining(userIsAuthorizedToSeeLog); - else - wizardSequence = new WizardSequenceLinear(userIsAuthorizedToSeeLog); - } else if (getReportType().equals(AppConstants.RT_CROSSTAB)) { - if (getReportDefType().equals(AppConstants.RD_SQL_BASED)) - wizardSequence = new WizardSequenceSQLBasedCrossTab(userIsAuthorizedToSeeLog); - else - wizardSequence = new WizardSequenceCrossTab(userIsAuthorizedToSeeLog); - } else if (getReportType().equals(AppConstants.RT_DASHBOARD)) { - wizardSequence = new WizardSequenceDashboard(userIsAuthorizedToSeeLog); - } else if (getReportType().equals(AppConstants.RT_HIVE)) { - wizardSequence = new WizardSequenceSQLBasedHive(userIsAuthorizedToSeeLog); - } else - wizardSequence = new WizardSequence(); - } // generateWizardSequence - - private boolean canPersistDashboard() { - //System.out.println(" getDashBoardReports().getReportsList().size() " + getDashBoardReports().getReportsList().size()); - /* Commented for New DashBoard - if (getDashBoardReports()!=null && getDashBoardReports().getReportsList()!=null && getDashBoardReports().getReportsList().size() > 0) { - for (Iterator iter = getDashBoardReports().getReportsList().iterator(); iter.hasNext();) { - Reports report = (Reports)iter.next(); - try { - if(Integer.parseInt(report.getReportId())>0) return true; - } catch (NumberFormatException ex) {} - } // for - } //if - */ - - //if( ) - return nvl(getDashboardLayoutHTML()).length() > 0; - } //canPersistDashboard - - private boolean canPersistLinearReport() { - boolean visibleColExist = false; - - if (getDataSourceList().getDataSource().size() > 0) { - for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - - if (dct.isVisible()) { - visibleColExist = true; - break; - } - } // for - } // if - - return visibleColExist; - } // canPersistLinearReport - - private boolean canPersistCrossTabReport() { - boolean rowColExist = false; - boolean colColExist = false; - boolean valColExist = false; - - if (getDataSourceList().getDataSource().size() > 0) { - for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - - if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_ROW)) - rowColExist = true; - if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_COLUMN)) - colColExist = true; - if (nvl(dct.getCrossTabValue()).equals(AppConstants.CV_VALUE)) - valColExist = true; - } // for - } // if - - return rowColExist && colColExist && valColExist; - } // canPersistCrossTabReport - - private boolean canPersistReport() { - return getReportType().equals(AppConstants.RT_CROSSTAB) ? canPersistCrossTabReport() - : (getReportType().equals(AppConstants.RT_LINEAR)? canPersistLinearReport():((getReportType().equals(AppConstants.RT_HIVE)? canPersistLinearReport():canPersistDashboard()))); - } // canPersistReport - - public void persistReport(HttpServletRequest request) throws RaptorException { - if (!canPersistReport()) - return; - - Connection connection = null; - try { - String userID = AppUtils.getUserID(request); - String reportXML = marshal(); - logger.debug(EELFLoggerDelegate.debugLogger, ("Ocurring during Schedule ")); - if (nvl(reportID, "-1").equals("-1")) { - connection = DbUtils.startTransaction(); - // Add report - String sql = ""; - if (nvl(Globals.getAdhocReportSequence()).length()> 0 && nvl(Globals.getAdhocUserRoldId()).length() > 0 && AppUtils.isUserInRole(request, Globals.getAdhocUserRoldId()) && !AppUtils.isAdminUser(request)) { - //sql = "SELECT "+ Globals.getAdhocReportSequence() + ".nextval FROM dual"; - sql = Globals.getPersistReportAdhoc(); - sql = sql.replace("[Globals.getAdhocReportSequence()]", Globals.getAdhocReportSequence()); - - } else{ - //sql = "SELECT seq_cr_report.nextval FROM dual"; - sql = Globals.getNewReportData(); - } - DataSet ds = DbUtils.executeQuery(connection,sql); - setReportID(ds.getString(0, 0)); - - reportSecurity.reportCreate(reportID, userID, isPublic()); - ReportLoader.createCustomReportRec(connection, this, reportXML); - ReportLoader.createReportLogEntry(connection, reportID, userID, - AppConstants.RLA_CREATE, "", ""); - reportUpdateLogged = true; - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] DB insert report " + reportID + " succesfull")); - } else { - // Update report - verifySQLBasedReportAccess(request); - reportSecurity.reportUpdate(request); - connection = DbUtils.startTransaction(); - ReportLoader.updateCustomReportRec(connection, this, reportXML); - if (!reportUpdateLogged) { - ReportLoader.createReportLogEntry(connection, reportID, userID, - AppConstants.RLA_UPDATE,"",""); - reportUpdateLogged = true; - } // if - logger.debug(EELFLoggerDelegate.debugLogger, ("[DEBUG MESSAGE FROM RAPTOR] DB update report " + reportID + " succesfull")); - } - - getReportSchedule().persistScheduleData(connection, request); - - DbUtils.commitTransaction(connection); - } catch (RaptorException e) { - e.printStackTrace(); - DbUtils.rollbackTransaction(connection); - throw e; - } finally { - DbUtils.clearConnection(connection); - } - } // persistReport - - public String getCrossTabDisplayValue(String crossTabValue) { - return nvl(crossTabValue).equals(AppConstants.CV_ROW) ? "Row headings" : (nvl( - crossTabValue).equals(AppConstants.CV_COLUMN) ? "Column headings" : (nvl( - crossTabValue).equals(AppConstants.CV_VALUE) ? "Report values" : "Invisible/Filter")); - } // getCrossTabDisplayValue - - public String getCrossTabDisplayValue(DataColumnType dct) { - return getCrossTabDisplayValue(dct.getCrossTabValue()); - } // getCrossTabDisplayValue - - public String getColumnLabel(DataColumnType dct) throws Exception { - String tableName = getTableById(dct.getTableId()).getTableName(); - Vector dbColumns = null; - dbColumns = DataCache.getReportTableDbColumns(tableName, cr.getDbInfo()); - if (dbColumns != null) - for (int i = 0; i < dbColumns.size(); i++) { - DBColumnInfo dbCol = (DBColumnInfo) dbColumns.get(i); - if (dct.getDbColName().equals(dbCol.getColName())) - return dbCol.getLabel(); - } // for - - return ""; - } // getCrossTabDisplayValue - - public String getFilterLabel(ColFilterType cft) { - StringBuffer fLabel = new StringBuffer(); - - fLabel.append(cft.getExpression()); - fLabel.append(" "); - if (cft.getArgType() != null) - if (cft.getArgType().equals(AppConstants.AT_FORMULA)) { - fLabel.append("[" + cft.getArgValue() + "]"); - } else if (cft.getArgType().equals(AppConstants.AT_VALUE)) { - fLabel.append(cft.getArgValue()); - } else if (cft.getArgType().equals(AppConstants.AT_LIST)) { - fLabel.append("(" + cft.getArgValue() + ")"); - } else if (cft.getArgType().equals(AppConstants.AT_COLUMN)) { - DataColumnType dctFilter = getColumnById(cft.getArgValue()); - fLabel.append("[" + dctFilter.getDisplayName() + "]"); - } else if (cft.getArgType().equals(AppConstants.AT_FORM)) { - fLabel.append("[Form Field]"); - } - - return fLabel.toString(); - } // getFilterLabel - - public Vector getReportUsers(HttpServletRequest request) throws RaptorException { - return reportSecurity.getReportUsers(request); - } // getReportUsers - - public Vector getReportRoles(HttpServletRequest request) throws RaptorException { - return reportSecurity.getReportRoles(request); - } // getReportRoles - - /** ************************************************************************************************* */ - - public void clearAllDrillDowns() { - List reportCols = getAllColumns(); - for (int i = 0; i < reportCols.size(); i++) { - DataColumnType dct = (DataColumnType) reportCols.get(i); - dct.setDrillDownURL(null); - dct.setDrillDownParams(null); - dct.setDrillDownType(null); - } // for - } // clearAllDrillDowns - - public void setOuterJoin(DataSourceType curTable, String joinType) { - String refDefinition = nvl(curTable.getRefDefinition()); - int outerJoinIdx = refDefinition.indexOf(" (+)"); - if (outerJoinIdx >= 0) - // Clear existing outer join - if (outerJoinIdx == (refDefinition.length() - 4)) - refDefinition = refDefinition.substring(0, outerJoinIdx); - else - refDefinition = refDefinition.substring(0, outerJoinIdx) - + refDefinition.substring(outerJoinIdx + 4); - - int equalSignIdx = refDefinition.indexOf("="); - if (equalSignIdx < 0) - // Ref. definition not present - return; - - if (refDefinition.indexOf(curTable.getTableId()) < equalSignIdx) { - // Cur. table is on the left side - if (nvl(joinType).equals(AppConstants.OJ_CURRENT)) - refDefinition = refDefinition.substring(0, equalSignIdx) + " (+)" - + refDefinition.substring(equalSignIdx); - else if (nvl(joinType).equals(AppConstants.OJ_JOINED)) - refDefinition = refDefinition + " (+)"; - } else { - // Joined table is on the left side - if (nvl(joinType).equals(AppConstants.OJ_CURRENT)) - refDefinition = refDefinition + " (+)"; - else if (nvl(joinType).equals(AppConstants.OJ_JOINED)) - refDefinition = refDefinition.substring(0, equalSignIdx) + " (+)" - + refDefinition.substring(equalSignIdx); - } - - curTable.setRefDefinition(refDefinition); - } // setOuterJoin - - public void addDataSourceType(ObjectFactory objFactory, String tableId, String tableName, - String tablePK, String displayName, String refTableId, String refDefinition, - String comment) throws RaptorException { - DataSourceType dst = objFactory.createDataSourceType(); - - dst.setTableId(tableId); - dst.setTableName(tableName); - dst.setTablePK(tablePK); - dst.setDisplayName(displayName); - if (nvl(refTableId).length() > 0) - dst.setRefTableId(refTableId); - if (nvl(refDefinition).length() > 0) - dst.setRefDefinition(refDefinition); - if (nvl(comment).length() > 0) - dst.setComment(comment); - - DataColumnList dataColumnList = objFactory.createDataColumnList(); - dst.setDataColumnList(dataColumnList); - - getDataSourceList().getDataSource().add(dst); - - resetCache(true); - } // addDataSourceType - - public void deleteDataSourceType(String tableId) { - super.deleteDataSourceType(tableId); - } // deleteDataSourceType - - public String getUniqueColumnId(String colName) { - String colId = ""; - - int colIdN = getAllColumns().size() + 1; - do { - colId = colName.substring(0, 2).toLowerCase() + (colIdN++); - } while (getColumnById(colId) != null); - - return colId; - } // getUniqueColumnId - - public DataColumnType addDataColumnType(ObjectFactory objFactory, String colId, - String tableId, // Table to which the new column belongs - String dbColName, String crossTabValue, String colName, String displayName, - int displayWidth, String displayAlignment, int orderSeq, boolean visible, - boolean calculated, String colType, String colFormat, boolean groupBreak, - int orderBySeq, String orderByAscDesc, String displayTotal, String colOnChart, - int chartSeq, String drillDownType, String drillDownURL, String drillDownParams, - String semaphoreId, String comment) throws RaptorException { - DataColumnType dct = null; - dct = objFactory.createDataColumnType(); - - dct.setColId(colId); - dct.setTableId(tableId); - dct.setDbColName(dbColName); - if (nvl(crossTabValue).length() > 0) - dct.setCrossTabValue(crossTabValue); - dct.setColName(colName); - dct.setDisplayName(displayName); - if (displayWidth > 0) - dct.setDisplayWidth(displayWidth); - if (nvl(displayAlignment).length() > 0) - dct.setDisplayAlignment(displayAlignment); - if (orderSeq > 0) - dct.setOrderSeq(orderSeq); - else - dct.setOrderSeq(getAllColumns().size() + 1); - dct.setVisible(visible); - dct.setCalculated(calculated); - // dct.setColType(colType); - if (nvl(colFormat).length() > 0) - dct.setColFormat(colFormat); - dct.setGroupBreak(groupBreak); - if (orderBySeq > 0) - dct.setOrderBySeq(orderBySeq); - if (nvl(orderByAscDesc).length() > 0) - dct.setOrderByAscDesc(orderByAscDesc); - if (nvl(displayTotal).length() > 0) - dct.setDisplayTotal(displayTotal); - if (nvl(colOnChart).length() > 0) - dct.setColOnChart(colOnChart); - if (chartSeq > 0) - dct.setChartSeq(chartSeq); - if (nvl(drillDownType).length() > 0) - dct.setDrillDownType(drillDownType); - if (nvl(drillDownURL).length() > 0) - dct.setDrillDownURL(drillDownURL); - if (nvl(drillDownParams).length() > 0) - dct.setDrillDownParams(drillDownParams); - if (nvl(semaphoreId).length() > 0) - dct.setSemaphoreId(semaphoreId); - if (nvl(comment).length() > 0) - dct.setComment(comment); - - dct.setDbColType(colType); - adjustColumnType(dct); - - // ColFilterList colFilterList = objFactory.createColFilterList(); - // dct.setColFilterList(colFilterList); - - getTableById(tableId).getDataColumnList().getDataColumn().add(dct); - - resetCache(false); - - return dct; - } // addDataColumnType - - public void deleteDataColumnType(String colId) { - int colOrder = getColumnById(colId).getOrderSeq(); - - List dcList = getColumnTableById(colId).getDataColumnList().getDataColumn(); - for (Iterator iterC = dcList.iterator(); iterC.hasNext();) { - DataColumnType dct = (DataColumnType) iterC.next(); - - if (dct.getColId().equals(colId) && dct.getOrderSeq() == colOrder) - iterC.remove(); - else if (dct.getOrderSeq() > colOrder) - dct.setOrderSeq(dct.getOrderSeq() - 1); - } // for - - if (getFormFieldList() != null) - for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { - FormFieldType fft = (FormFieldType) iter.next(); - if (nvl(fft.getColId()).equals(colId)) { - fft.setColId(""); - fft.setFieldType(FormField.FFT_TEXT); - if (nvl(fft.getDefaultValue()).equals(AppConstants.FILTER_MAX_VALUE) - || nvl(fft.getDefaultValue()) - .equals(AppConstants.FILTER_MIN_VALUE)) - fft.setDefaultValue(""); - } // if - } // for - - resetCache(false); - resetColumnOrderValues(); - } // deleteDataColumnType - - public void shiftColumnOrderUp(String colId) { - List reportCols = getAllColumns(); - for (int i = 0; i < reportCols.size(); i++) { - DataColumnType dct = (DataColumnType) reportCols.get(i); - - if (dct.getColId().equals(colId) && (i > 0)) { - DataColumnType dctUp = (DataColumnType) reportCols.get(i - 1); - dctUp.setOrderSeq(dctUp.getOrderSeq() + 1); - dct.setOrderSeq(dct.getOrderSeq() - 1); - break; - } // if - } // for - - Collections.sort(reportCols, new OrderSeqComparator()); - resetCache(true); - resetColumnOrderValues(); - } // shiftColumnOrderUp - - public void shiftColumnOrderDown(String colId) { - List reportCols = getAllColumns(); - for (int i = 0; i < reportCols.size(); i++) { - DataColumnType dct = (DataColumnType) reportCols.get(i); - - if (dct.getColId().equals(colId) && (i < reportCols.size() - 1)) { - DataColumnType dctDown = (DataColumnType) reportCols.get(i + 1); - dctDown.setOrderSeq(dctDown.getOrderSeq() - 1); - dct.setOrderSeq(dct.getOrderSeq() + 1); - break; - } // if - } // for - - Collections.sort(reportCols, new OrderSeqComparator()); - resetCache(true); - resetColumnOrderValues(); - } // shiftColumnOrderDown - - public void resetColumnOrderValues() { - List reportCols = getAllColumns(); - - int colOrder = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - dct.setOrderSeq(++colOrder); - } // for - - Collections.sort(reportCols, new OrderSeqComparator()); - } // resetColumnOrderValues - - public void addColFilterType(ObjectFactory objFactory, String colId, // Column - // to - // which - // the - // new - // filter - // belongs - String joinCondition, String openBrackets, String expression, String argType, - String argValue, String closeBrackets, String comment) throws RaptorException { - ColFilterType cft = objFactory.createColFilterType(); - - cft.setColId(colId); - cft.setJoinCondition(nvl(joinCondition, "AND")); - if (nvl(openBrackets).length() > 0) - cft.setOpenBrackets(openBrackets); - cft.setExpression(expression); - if (nvl(argType).length() > 0) - cft.setArgType(argType); - if (nvl(argValue).length() > 0) - cft.setArgValue(argValue); - if (nvl(closeBrackets).length() > 0) - cft.setCloseBrackets(closeBrackets); - if (nvl(comment).length() > 0) - cft.setComment(comment); - - DataColumnType dct = getColumnById(colId); - if (dct != null) { - if (dct.getColFilterList() == null) - dct.setColFilterList(objFactory.createColFilterList()); - - cft.setFilterSeq(dct.getColFilterList().getColFilter().size()); - dct.getColFilterList().getColFilter().add(cft); - } // if - - resetCache(true); - } // addColFilterType - - public void removeColumnFilter(String colId, int filterPos) { - DataColumnType dct = getColumnById(colId); - - if (dct.getColFilterList() != null) - try { - dct.getColFilterList().getColFilter().remove(filterPos); - } catch (IndexOutOfBoundsException e) { - } - - resetCache(true); - } // removeColumnFilter - - public void addColumnSort(String colId, String ascDesc) { - addColumnSort(colId, ascDesc, -1); - } // addColumnSort - - public void addColumnSort(String colId, String ascDesc, int sortOrder) { - if (sortOrder <= 0) { - sortOrder = 1; - List reportCols = getAllColumns(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) - if (((DataColumnType) iter.next()).getOrderBySeq() > 0) - sortOrder++; - } // if - - DataColumnType dct = getColumnById(colId); - dct.setOrderBySeq(sortOrder); - dct.setOrderByAscDesc(ascDesc); - - resetCache(true); - } // addColumnSort - - public void removeColumnSort(String colId) { - DataColumnType dct = getColumnById(colId); - int sortOrder = dct.getOrderBySeq(); - - dct.setOrderBySeq(0); - dct.setOrderByAscDesc(null); - - if (sortOrder > 0) { - List reportCols = getAllColumns(); - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dct2 = (DataColumnType) iter.next(); - - if (dct2.getOrderBySeq() > sortOrder) - dct2.setOrderBySeq(dct2.getOrderBySeq() - 1); - } // for - } // if - - resetCache(true); - } // removeColumnSort - - public void shiftColumnSortUp(String colId) { - List reportCols = getAllColumns(); - Collections.sort(reportCols, new OrderBySeqComparator()); - - for (int i = 0; i < reportCols.size(); i++) { - DataColumnType dct = (DataColumnType) reportCols.get(i); - - if (dct.getColId().equals(colId) && (dct.getOrderBySeq() > 0)) { - DataColumnType dctUp = (DataColumnType) reportCols.get(i - 1); - if (dctUp.getOrderBySeq() > 0) - dctUp.setOrderBySeq(dctUp.getOrderBySeq() + 1); - dct.setOrderBySeq(dct.getOrderBySeq() - 1); - break; - } // if - } // for - - Collections.sort(reportCols, new OrderSeqComparator()); - resetCache(true); - } // shiftColumnSortUp - - public void shiftColumnSortDown(String colId) { - List reportCols = getAllColumns(); - Collections.sort(reportCols, new OrderBySeqComparator()); - - for (int i = 0; i < reportCols.size(); i++) { - DataColumnType dct = (DataColumnType) reportCols.get(i); - - if (dct.getColId().equals(colId) && (dct.getOrderBySeq() > 0)) { - DataColumnType dctDown = (DataColumnType) reportCols.get(i + 1); - if (dctDown.getOrderBySeq() > 0) - dctDown.setOrderBySeq(dctDown.getOrderBySeq() - 1); - dct.setOrderBySeq(dct.getOrderBySeq() + 1); - break; - } // if - } // for - - Collections.sort(reportCols, new OrderSeqComparator()); - resetCache(true); - } // shiftColumnSortDown - - /** ************************************************************************************************* */ - - public String generateNewSemaphoreId() { - if (getSemaphoreList() == null) - return "sem1"; - - String semaphoreId = null; - boolean idExists = true; - for (int i = 1; idExists; i++) { - semaphoreId = "sem" + i; - idExists = false; - for (Iterator iter = getSemaphoreList().getSemaphore().iterator(); iter.hasNext();) - if (semaphoreId.equals(((SemaphoreType) iter.next()).getSemaphoreId())) { - idExists = true; - break; - } - } // for - - return semaphoreId; - } // generateNewSemaphoreId - - public SemaphoreType addSemaphore(ObjectFactory objFactory, SemaphoreType semaphoreType) - throws RaptorException { - SemaphoreType sem = null; - try { - if (getSemaphoreList() == null) - setSemaphoreList(objFactory.createSemaphoreList()); - - String semaphoreName = null; - boolean nameExists = true; - for (int i = 1; nameExists; i++) { - semaphoreName = semaphoreType.getSemaphoreName() + ((i > 1) ? (" v" + i) : ""); - nameExists = false; - for (Iterator iter2 = getSemaphoreList().getSemaphore().iterator(); iter2 - .hasNext();) - if (semaphoreName.equals(((SemaphoreType) iter2.next()).getSemaphoreName())) { - nameExists = true; - break; - } - } // for - - sem = cloneSemaphoreType(objFactory, semaphoreType); - getSemaphoreList().getSemaphore().add(sem); - - sem.setSemaphoreId(generateNewSemaphoreId()); - sem.setSemaphoreName(semaphoreName); - } catch (JAXBException ex) { - throw new RaptorException(ex.getMessage(), ex.getCause()); - } - - return sem; - } // addSemaphore - - public SemaphoreType addSemaphoreType(ObjectFactory objFactory, String semaphoreName, - String semaphoreType, String comment) throws RaptorException { - SemaphoreType sem = null; - if (getSemaphoreList() == null) - setSemaphoreList(objFactory.createSemaphoreList()); - - sem = objFactory.createSemaphoreType(); - getSemaphoreList().getSemaphore().add(sem); - - sem.setSemaphoreId(generateNewSemaphoreId()); - sem.setSemaphoreName(semaphoreName); - sem.setSemaphoreType(nvl(semaphoreType)); - if (nvl(comment).length() > 0) - sem.setComment(comment); - - FormatList formatList = objFactory.createFormatList(); - sem.setFormatList(formatList); - return sem; - } // addSemaphoreType - - - public String getNextIdForJavaScriptElement (ObjectFactory objFactory, String fieldId) throws RaptorException { - String id = ""; - JavascriptItemType jit = null; - int incr = 0; - if (getJavascriptList() == null) { - setJavascriptList(objFactory.createJavascriptList()); - return fieldId + "|1"; - } else { - if(getJavascriptList().getJavascriptItem().iterator().hasNext()) { - for (Iterator iter = getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { - jit = (JavascriptItemType) iter.next(); - logger.debug(EELFLoggerDelegate.debugLogger, ("^^^^^JAVASCRIPTITEMTYPE " + jit.getFieldId() + " " + fieldId + " " + id)); - if(nvl(jit.getFieldId()).length()>0 && jit.getFieldId().equals(fieldId)) { - ++incr; - } - } // for - return fieldId + "|"+incr; - } else { - return fieldId + "|1"; - } - - } - //return null; - } - - public JavascriptItemType addJavascriptType(ObjectFactory objFactory, String id) throws RaptorException { - JavascriptItemType javascriptItemType = null; - int flag = 0; // checking whether id existing in the list - if (getJavascriptList() == null) { - setJavascriptList(objFactory.createJavascriptList()); - javascriptItemType = objFactory.createJavascriptItemType(); - getJavascriptList().getJavascriptItem().add(javascriptItemType); - return javascriptItemType; - } else { - - for (Iterator iter = getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { - javascriptItemType = (JavascriptItemType)iter.next(); - if(javascriptItemType.getId().equals(id) && !id.startsWith("-1")) { - flag = 1; - break; - } - } - if(flag == 1) return javascriptItemType; - else { - javascriptItemType = objFactory.createJavascriptItemType(); - getJavascriptList().getJavascriptItem().add(javascriptItemType); - return javascriptItemType; - } - } - - } // addSemaphoreType - - public boolean deleteJavascriptType(String id) throws RaptorException { - JavascriptItemType javascriptType = null; - if (getJavascriptList() == null) - return true; - for (Iterator iter = getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { - javascriptType = (JavascriptItemType)iter.next(); - if(javascriptType.getId().equals(id)) { - iter.remove(); - return true; - } - } - return false; - } // addSemaphoreType - - public static FormatType addEmptyFormatType(ObjectFactory objFactory, - SemaphoreType semaphore) throws RaptorException { - FormatType fmt = null; - fmt = objFactory.createFormatType(); - semaphore.getFormatList().getFormat().add(fmt); - - String formatId = null; - boolean idExists = true; - for (int i = 1; idExists; i++) { - formatId = semaphore.getSemaphoreId() + "_fmt" + i; - idExists = false; - for (Iterator iter = semaphore.getFormatList().getFormat().iterator(); iter - .hasNext();) - if (formatId.equals(((FormatType) iter.next()).getFormatId())) { - idExists = true; - break; - } - } // for - fmt.setFormatId(formatId); - return fmt; - } // addEmptyFormatType - - public static void deleteFormatType(SemaphoreType semaphore, String formatId) { - for (Iterator iter = semaphore.getFormatList().getFormat().iterator(); iter.hasNext();) - if (formatId.equals(((FormatType) iter.next()).getFormatId())) { - iter.remove(); - break; - } // if - } // deleteFormatType - - public FormFieldType addFormFieldType(ObjectFactory objFactory, String fieldName, - String colId, String fieldType, String validationType, String mandatory, - String defaultValue, String fieldSQL, String comment, Calendar rangeStartDate, Calendar rangeEndDate, - String rangeStartDateSQL, String rangeEndDateSQL) throws RaptorException { - FormFieldType fft = null; - fft = objFactory.createFormFieldType(); - - fft.setFieldName(fieldName); - fft.setColId(colId); - fft.setFieldType(fieldType); - fft.setValidationType(validationType); - fft.setMandatory(nvl(mandatory, "N")); - fft.setDefaultValue(nvl(defaultValue)); - fft.setOrderBySeq((getFormFieldList() == null) ? 1 : getFormFieldList().getFormField() - .size() + 1); - fft.setFieldSQL(fieldSQL); - //fft.setRangeStartDate(rangeStartDate); - //fft.setRangeEndDate(rangeEndDate); - - try { - fft.setRangeStartDate(DatatypeFactory.newInstance() - .newXMLGregorianCalendar(rangeStartDate.YEAR, rangeStartDate.MONTH, rangeStartDate.DAY_OF_WEEK, rangeStartDate.HOUR, rangeStartDate.MINUTE, rangeStartDate.SECOND, rangeStartDate.MILLISECOND, rangeStartDate.ZONE_OFFSET)); - fft.setRangeStartDate(DatatypeFactory.newInstance() - .newXMLGregorianCalendar(rangeEndDate.YEAR, rangeEndDate.MONTH, rangeEndDate.DAY_OF_WEEK, rangeEndDate.HOUR, rangeEndDate.MINUTE, rangeEndDate.SECOND, rangeEndDate.MILLISECOND, rangeEndDate.ZONE_OFFSET)); - /*currField.setRangeEndDate(DatatypeFactory.newInstance() - .newXMLGregorianCalendar(end));*/ - } catch (DatatypeConfigurationException ex) { - - } - - fft.setRangeStartDateSQL(rangeStartDateSQL); - fft.setRangeEndDateSQL(rangeEndDateSQL); - if (nvl(comment).length() > 0) - fft.setComment(comment); - - String fieldId = null; - boolean idExists = true; - for (int i = 1; idExists; i++) { - fieldId = "ff" + i; - idExists = false; - if (getFormFieldList() != null) - for (Iterator iter = getFormFieldList().getFormField().iterator(); iter - .hasNext();) - if (fieldId.equals(((FormFieldType) iter.next()).getFieldId())) { - idExists = true; - break; - } - } // for - fft.setFieldId(fieldId); - - if (getFormFieldList() == null) { - FormFieldList formFieldList = objFactory.createFormFieldList(); - setFormFieldList(formFieldList); - } - - getFormFieldList().getFormField().add(fft); - return fft; - } // addFormFieldType - - //addCustomizedTextForParameters - public void addCustomizedTextForParameters(String comment) throws RaptorException { - getFormFieldList().setComment(comment); - } - - public FormFieldType addFormFieldBlank(ObjectFactory objFactory) throws RaptorException { - FormFieldType fft = null; - fft = objFactory.createFormFieldType(); - - fft.setFieldName("BLANK"); - fft.setColId("bk"); - fft.setFieldType(FormField.FFT_BLANK); - fft.setOrderBySeq((getFormFieldList() == null) ? 1 : getFormFieldList().getFormField() - .size() + 1); - String fieldId = null; - boolean idExists = true; - for (int i = 1; idExists; i++) { - fieldId = "ff" + i; - idExists = false; - if (getFormFieldList() != null) - for (Iterator iter = getFormFieldList().getFormField().iterator(); iter - .hasNext();) - if (fieldId.equals(((FormFieldType) iter.next()).getFieldId())) { - idExists = true; - break; - } - } // for - fft.setFieldId(fieldId); - - if (getFormFieldList() == null) { - FormFieldList formFieldList = objFactory.createFormFieldList(); - setFormFieldList(formFieldList); - } - - getFormFieldList().getFormField().add(fft); - return fft; - } // addFormFieldBlank - - public void replaceFormFieldReferences(String fieldName, String replaceWith) { - if (fieldName.equals(replaceWith)) - return; - - for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) { - DataColumnType dct = (DataColumnType) iter.next(); - - if (dct.isCalculated() && dct.getColName().indexOf(fieldName) >= 0) - dct.setColName(Utils.replaceInString(dct.getColName(), fieldName, nvl( - replaceWith, "NULL"))); - - if (dct.getColFilterList() != null) - for (Iterator iter2 = dct.getColFilterList().getColFilter().iterator(); iter2 - .hasNext();) { - ColFilterType cft = (ColFilterType) iter2.next(); - - if (nvl(cft.getArgType()).equals(AppConstants.AT_FORM) - && nvl(cft.getArgValue()).equals(fieldName)) - cft.setArgValue(replaceWith); - } // for - } // for - } // replaceFormFieldReferences - - public void deleteFormField(String fieldId) { - String fieldDisplayName = null; - - int orderBySeq = Integer.MAX_VALUE; - if (getFormFieldList() != null) - for (Iterator iter = getFormFieldList().getFormField().iterator(); iter.hasNext();) { - FormFieldType fft = (FormFieldType) iter.next(); - - if (fieldId.equals(fft.getFieldId())) { - //orderBySeq = fft.getOrderBySeq(); - fieldDisplayName = getFormFieldDisplayName(fft); - iter.remove(); - } else if (fft.getOrderBySeq()!=null && (fft.getOrderBySeq().intValue() > orderBySeq)) - fft.setOrderBySeq(fft.getOrderBySeq() - 1); - } // for - - if (fieldDisplayName != null) - replaceFormFieldReferences(fieldDisplayName, ""); - } // deleteFormField - - public void shiftFormFieldUp(String fieldId) { - if (getFormFieldList() == null) - return; - - for (int i = 0; i < getFormFieldList().getFormField().size(); i++) { - FormFieldType fft = (FormFieldType) getFormFieldList().getFormField().get(i); - - if (fft.getFieldId().equals(fieldId) && (i > 0)) { - FormFieldType prevFft = (FormFieldType) getFormFieldList().getFormField().get( - i - 1); - prevFft.setOrderBySeq(prevFft.getOrderBySeq() + 1); - fft.setOrderBySeq((fft.getOrderBySeq() == null)?0:fft.getOrderBySeq() - 1); - - getFormFieldList().getFormField().remove(i); - getFormFieldList().getFormField().add(i - 1, fft); - return; - } // if - } // for - } // shiftFormFieldUp - - public void shiftFormFieldDown(String fieldId) { - if (getFormFieldList() == null) - return; - - for (int i = 0; i < getFormFieldList().getFormField().size(); i++) { - FormFieldType fft = (FormFieldType) getFormFieldList().getFormField().get(i); - - if (fft.getFieldId().equals(fieldId) - && (i < getFormFieldList().getFormField().size() - 1)) { - FormFieldType nextFft = (FormFieldType) getFormFieldList().getFormField().get( - i + 1); - nextFft.setOrderBySeq((nextFft.getOrderBySeq() == null)?0:nextFft.getOrderBySeq() - 1); - fft.setOrderBySeq((fft.getOrderBySeq() == null)?0:fft.getOrderBySeq() + 1); - - getFormFieldList().getFormField().remove(i + 1); - getFormFieldList().getFormField().add(i, nextFft); - return; - } // if - } // for - } // shiftFormFieldDown - - public static void addFormFieldPredefinedValue(ObjectFactory objFactory, - FormFieldType formField, String predefinedValue) throws RaptorException { - if (formField.getPredefinedValueList() == null) { - PredefinedValueList predefinedValueList = objFactory.createPredefinedValueList(); - formField.setPredefinedValueList(predefinedValueList); - } // if - - if (predefinedValue.length() > 0) { - formField.getPredefinedValueList().getPredefinedValue().add(predefinedValue); - Collections.sort(formField.getPredefinedValueList().getPredefinedValue()); - } // if - } // addFormFieldPredefinedValue - - public static void deleteFormFieldPredefinedValue(FormFieldType formField, - String predefinedValue) { - if (formField != null && formField.getPredefinedValueList() != null - && predefinedValue.length() > 0) - for (Iterator iter = formField.getPredefinedValueList().getPredefinedValue() - .iterator(); iter.hasNext();) - if (predefinedValue.equals((String) iter.next())) { - iter.remove(); - break; - } // if - } // deleteFormFieldPredefinedValue - - /** ************************************************************************************************* */ - - private int curSQLParsePos = 0; - - private String getNextSQLParseToken(String sql, boolean updateParsePos) { - int braketCount = 0; - boolean isInsideQuote = false; - StringBuffer nextToken = new StringBuffer(); - for (int idxNext = curSQLParsePos; idxNext < sql.length(); idxNext++) { - char ch = sql.charAt(idxNext); - - if (Character.isWhitespace(ch) || ch == ',') { - if (ch == ',') - nextToken.append(ch); - - if (nextToken.length() == 0) - continue; - else if (braketCount == 0 && (!isInsideQuote)) { - if (updateParsePos) - curSQLParsePos = idxNext + ((ch == ',') ? 1 : 0); - break; - } else if (ch != ',' && nextToken.charAt(nextToken.length() - 1) != ' ') - nextToken.append(' '); - } else { - nextToken.append(ch); - - if (ch == '(' || ch == '[') - braketCount++; - else if (ch == ')' || ch == ']') - braketCount--; - else if (ch == '\''/* ||ch=='\"' */) - isInsideQuote = (!isInsideQuote); - } // else - } // for - - return nextToken.toString(); - } // getNextSQLParseToken - - private boolean isParseSQLColID(String token) { - if (nvl(token).length() == 0) - return false; - - for (int i = 0; i < token.length(); i++) { - char ch = token.charAt(i); - - if (i == 0 && ch == '_') - return false; - - if (!(Character.isLetterOrDigit(ch) || ch == '_')) - return false; - } // for - - return true; - } // isParseSQLColID - - private DataColumnType getParseSQLDataColumn(String sqlExpression, String colId, - StringBuffer parsedSQL, Vector updatedReportCols, boolean isCYMBALScript) throws RaptorException { - DataColumnType dct = null; - - if (colId != null) { - if (!isParseSQLColID(colId)) - throw new org.openecomp.portalsdk.analytics.error.ValidationException( - "[" - + colId - + "] must either be a valid column id consisting only of letters, numbers, and underscores, or there must be a comma in front of it."); - - dct = getColumnById(colId); - } else { - // Getting unique column id - colId = ""; - int colIdN = 0; - for (int i = 0; (i < sqlExpression.length()) && (colIdN < 2); i++) - if (Character.isLetter(sqlExpression.charAt(i))) { - colId += sqlExpression.toLowerCase().charAt(i); - colIdN++; - } // if - - colIdN = getAllColumns().size() + updatedReportCols.size(); - for (boolean idAlreadyUsed = true; idAlreadyUsed; colIdN++) { - String newColId = colId + colIdN; - idAlreadyUsed = false; - - for (Iterator iter = getAllColumns().iterator(); iter.hasNext();) - if (newColId.equals(((DataColumnType) iter.next()).getColId())) { - idAlreadyUsed = true; - break; - } - - if (!idAlreadyUsed) - for (Iterator iter = updatedReportCols.iterator(); iter.hasNext();) - if (newColId.equals(((DataColumnType) iter.next()).getColId())) { - idAlreadyUsed = true; - break; - } - } // for - - colId += (colIdN - 1); - } // else - - if (dct == null) { - dct = (new ObjectFactory()).createDataColumnType(); - dct.setColId(colId); - dct.setDisplayWidth(10); - dct.setDisplayAlignment("Left"); - dct.setVisible(true); - dct.setGroupBreak(false); // ??? - if(!isCYMBALScript) { - boolean isValidIdentifier = Character.isLetterOrDigit(sqlExpression.charAt(0)); - for (int i = 0; i < sqlExpression.length(); i++) - if (!(Character.isLetterOrDigit(sqlExpression.charAt(i)) - || (sqlExpression.charAt(i) == '_') || (sqlExpression.charAt(i) == '$'))) { - isValidIdentifier = false; - break; - } // if - - if (isValidIdentifier) { - dct.setDisplayName(sqlExpression); - } else { - dct.setDisplayName(colId); - } // else - } else dct.setDisplayName(colId); - } // if - if(!isCYMBALScript) - sqlExpression = sqlExpression.replaceAll(", '", ",'"); - dct.setDbColName(sqlExpression); - dct.setColName(sqlExpression); - dct.setCalculated(true); - dct.setColType(AppConstants.CT_CHAR); - dct.setDbColType(AppConstants.CT_CHAR); - adjustColumnType(dct); // ??? - if(!isCYMBALScript) { - if (parsedSQL.toString().equals("SELECT ") - || parsedSQL.toString().equals("SELECT DISTINCT ")) - parsedSQL.append("\n\t"); - else - parsedSQL.append(", \n\t"); - parsedSQL.append(sqlExpression); - parsedSQL.append(" "); - parsedSQL.append(colId); - } - - return dct; - } // getParseSQLDataColumn - - public void parseReportSQL(String sql) throws RaptorException { - StringBuffer parsedSQL = new StringBuffer(); - - Vector updatedReportCols = new Vector(); - - curSQLParsePos = 0; - int lastParsePos = curSQLParsePos; - String lastToken = null; - String nextToken = getNextSQLParseToken(sql, true); - - String dbInfo = getDBInfo(); - boolean isCYMBALScript = false; - if (!isNull(dbInfo) && (!dbInfo.equals(AppConstants.DB_LOCAL))) { - try { - org.openecomp.portalsdk.analytics.util.RemDbInfo remDbInfo = new org.openecomp.portalsdk.analytics.util.RemDbInfo(); - String dbType = remDbInfo.getDBType(dbInfo); - if (dbType.equals("DAYTONA") && !(nextToken.toUpperCase().equals("SELECT"))) { - isCYMBALScript = true; - } - } catch (Exception ex) { - throw new RaptorException(ex); - } - } - if ( isCYMBALScript == false ) { - while (nextToken.length() > 0) { - if (parsedSQL.length() == 0) { - if (nextToken.toUpperCase().equals("SELECT")) - parsedSQL.append("SELECT "); - else - throw new org.openecomp.portalsdk.analytics.error.ValidationException( - "The SQL must start with the SELECT keyword."); - } else if (nextToken.toUpperCase().equals("DISTINCT") - && parsedSQL.toString().equals("SELECT ")) { - parsedSQL.append("DISTINCT "); - } else if (nextToken.equals("*") - && (parsedSQL.toString().equals("SELECT ") || parsedSQL.toString().equals( - "SELECT DISTINCT "))) { - throw new org.openecomp.portalsdk.analytics.error.ValidationException( - "You cannot use \"SELECT *\". Please specify select columns/expressions."); - } else if (nextToken.toUpperCase().equals("FROM")) { - if (lastToken != null) { - updatedReportCols.add(getParseSQLDataColumn(lastToken, null, parsedSQL, - updatedReportCols, false)); - lastToken = null; - } - - parsedSQL.append(" \n"); - while (lastParsePos < sql.length() - && Character.isWhitespace(sql.charAt(lastParsePos))) - lastParsePos++; - parsedSQL.append(sql.substring(lastParsePos)); - break; - } else { - if (nextToken.charAt(nextToken.length() - 1) == ',') { - // The token ends with , - nextToken = nextToken.substring(0, nextToken.length() - 1); - - if (nextToken.length() == 0) { - if (lastToken != null) { - updatedReportCols.add(getParseSQLDataColumn(lastToken, null, - parsedSQL, updatedReportCols, false)); - lastToken = null; - } // else just comma => ignore it - } else { - if (lastToken != null) { - updatedReportCols.add(getParseSQLDataColumn(lastToken, nextToken, - parsedSQL, updatedReportCols, false)); - lastToken = null; - } else - updatedReportCols.add(getParseSQLDataColumn(nextToken, null, - parsedSQL, updatedReportCols, false)); - } - } else { - // The token doesn't end with , - if (lastToken == null) - lastToken = nextToken; - else { - String token = getNextSQLParseToken(sql, false); - if (!token.toUpperCase().equals("FROM")) - throw new org.openecomp.portalsdk.analytics.error.ValidationException( - "|FROM keyword or a comma expected after [" + nextToken - + "]."); - - updatedReportCols.add(getParseSQLDataColumn(lastToken, nextToken, - parsedSQL, updatedReportCols, false)); - lastToken = null; - } // else - } // else - } // else - - lastParsePos = curSQLParsePos; - nextToken = getNextSQLParseToken(sql, true); - } // while - } else { // if CYMBAL Script - curSQLParsePos = 0; - Pattern re = null; - Matcher matcher = null; - String extracted = null; - nextToken = getNextCYMBALSQLParseToken(sql,true); - while (nextToken.length() > 0) { - if (lastToken == null) lastToken = nextToken; - - if( lastToken.toUpperCase().startsWith("DO DISPLAY")) { - re = Pattern.compile("each(.*)\\[.(.*?)\\]"); //\\[(.*?)\\] - matcher = re.matcher(nextToken); - if (matcher.find()) { - extracted = matcher.group(); - re = Pattern.compile("\\[(.*?)\\]"); - matcher = re.matcher(nextToken); - if(matcher.find()) { - extracted = matcher.group(); - extracted = extracted.substring(1,extracted.length()-1); - StringTokenizer sToken = new StringTokenizer(extracted, ","); - while(sToken.hasMoreTokens()) { - String str1 = sToken.nextToken().trim().substring(1); - updatedReportCols.add(getParseSQLDataColumn("", str1, - new StringBuffer(""), updatedReportCols, true)); - } - } - - } - - } - lastToken = nextToken; - nextToken = getNextCYMBALSQLParseToken(sql, true); - } - - } - if (updatedReportCols.size() == 0) - throw new org.openecomp.portalsdk.analytics.error.ValidationException( - "The SQL statement must have at least one column in the SELECT clause."); - if (getDataSourceList().getDataSource().size() == 0) - addDataSourceType(new ObjectFactory(), "du0", "DUAL", "", "DUAL", null, null, null); - DataSourceType dst = (DataSourceType) getDataSourceList().getDataSource().get(0); - dst.getDataColumnList().getDataColumn().clear(); - - for (int i = 0; i < updatedReportCols.size(); i++) { - DataColumnType dct = (DataColumnType) updatedReportCols.get(i); - dct.setTableId(dst.getTableId()); - dct.setOrderSeq(i + 1); - dst.getDataColumnList().getDataColumn().add(dct); - } // for - setReportSQL(parsedSQL.toString()); - resetCache(false); - } // parseReportSQL - - private String getNextCYMBALSQLParseToken(String sql, boolean updateParsePos) { - int braketCount = 0; - boolean isInsideQuote = false; - StringBuffer nextToken = new StringBuffer(); - for (int idxNext = curSQLParsePos; idxNext < sql.length(); idxNext++) { - char ch = sql.charAt(idxNext); - - if (ch!='\n') { - nextToken.append(ch); - if (updateParsePos) - curSQLParsePos = idxNext; - } - else { - curSQLParsePos = idxNext+1; - break; - } - } // for - - return nextToken.toString(); - } // getNextSQLParseToken - - public void addChartAdditionalOptions(ObjectFactory objFactory) throws RaptorException { - ChartAdditionalOptions chartOptions = objFactory.createChartAdditionalOptions(); - cr.setChartAdditionalOptions(chartOptions); - } - - public void addChartDrillOptions(ObjectFactory objFactory) throws RaptorException { - ChartDrillOptions chartOptions = objFactory.createChartDrillOptions(); - cr.setChartDrillOptions(chartOptions); -} - - public void addDataminingOptions(ObjectFactory objFactory) throws RaptorException { - DataminingOptions dataminingOptions = objFactory.createDataminingOptions(); - cr.setDataminingOptions(dataminingOptions); - } - /*public void addChartAdditionalOptions(ObjectFactory objFactory, String chartType, String chartMultiplePieOrder, String chartMultiplePieLabelDisplay, - String chartOrientation, String secondaryChartRenderer, String chartDisplay, String legendPosition, - String labelAngle) throws RaptorException { - try { - ChartAdditionalOptions chartOptions = objFactory.createChartAdditionalOptions(); - - if (nvl(chartMultiplePieOrder).length() > 0) - chartOptions.setChartMultiplePieOrder(chartMultiplePieOrder); - if (nvl(chartMultiplePieLabelDisplay).length() > 0) - chartOptions.setChartMultiplePieLabelDisplay(chartMultiplePieLabelDisplay); - if (nvl(chartOrientation).length() > 0) - chartOptions.setChartOrientation(chartOrientation); - if (nvl(secondaryChartRenderer).length() > 0) - chartOptions.setSecondaryChartRenderer(secondaryChartRenderer); - if (nvl(chartDisplay).length() > 0) - chartOptions.setChartDisplay(chartDisplay); - if (nvl(legendPosition).length() > 0) - chartOptions.setLegendPosition(legendPosition); - if (nvl(labelAngle).length() > 0) - chartOptions.setLabelAngle(labelAngle); - - cr.setChartAdditionalOptions(chartOptions); - } catch (JAXBException ex) { - throw new RaptorException(ex.getMessage(), ex.getCause()); - } - } // addChartAdditionalOptions*/ - - -} // ReportDefinition diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportMap.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportMap.java deleted file mode 100644 index 450349c7..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/ReportMap.java +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.definition; - -import java.util.ArrayList; -import java.util.List; - -import org.openecomp.portalsdk.analytics.RaptorObject; - -public class ReportMap extends RaptorObject { - String markerColor = ""; - String addressColumn = ""; - String dataColumn = ""; - String isMapAllowedYN = ""; - String addAddressInDataYN = ""; - List markers = new ArrayList(); - - public String getIsMapAllowedYN() { - return isMapAllowedYN; - } - public void setIsMapAllowedYN(String isMapAllowedYN) { - this.isMapAllowedYN = isMapAllowedYN; - } - public ReportMap(String markerColor, String addressColumn, String dataColumn, String isMapAllowed, String addAddressInDataYN){ - this.setMarkerColor(markerColor); - this.setAddressColumn(addressColumn); - this.setDataColumn(dataColumn); - this.setIsMapAllowedYN(isMapAllowed); - this.setAddAddressInDataYN(addAddressInDataYN); - } - public String getAddressColumn() { - return addressColumn; - } - public void setAddressColumn(String addressColumn) { - this.addressColumn = addressColumn; - } - public String getDataColumn() { - return dataColumn; - } - public void setDataColumn(String dataColumn) { - this.dataColumn = dataColumn; - } - public String getMarkerColor() { - return markerColor; - } - public void setMarkerColor(String markerColor) { - this.markerColor = markerColor; - } - public List getMarkers() { - return markers; - } - public void setMarkers(List markers) { - this.markers = markers; - } - public String getAddAddressInDataYN() { - return addAddressInDataYN; - } - public void setAddAddressInDataYN(String addAddressInDataYN) { - this.addAddressInDataYN = addAddressInDataYN; - } - - - - -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/SecurityEntry.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/SecurityEntry.java deleted file mode 100644 index 4feddd6e..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/definition/SecurityEntry.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.definition; - -import org.openecomp.portalsdk.analytics.model.base.IdNameValue; - -public class SecurityEntry extends IdNameValue { - private boolean readOnly = true; - - public SecurityEntry() { - super(); - } - - public SecurityEntry(String id, String name, boolean readOnly) { - super(id, name); - setReadOnly(readOnly); - } // SecurityEntry - - public boolean isReadOnly() { - return readOnly; - } - - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - -} // SecurityEntry diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PageEvent.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PageEvent.java deleted file mode 100644 index 34e38062..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PageEvent.java +++ /dev/null @@ -1,256 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.pdf; - -import java.awt.Color; -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; - -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.Globals; - -import com.lowagie.text.BadElementException; -import com.lowagie.text.Cell; -import com.lowagie.text.Document; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Font; -import com.lowagie.text.FontFactory; -import com.lowagie.text.Image; -import com.lowagie.text.Paragraph; -import com.lowagie.text.Rectangle; -import com.lowagie.text.pdf.PdfContentByte; -import com.lowagie.text.pdf.PdfDestination; -import com.lowagie.text.pdf.PdfOutline; -import com.lowagie.text.pdf.PdfPCell; -import com.lowagie.text.pdf.PdfPTable; -import com.lowagie.text.pdf.PdfPageEventHelper; -import com.lowagie.text.pdf.PdfWriter; - -class PageEvent extends PdfPageEventHelper { - private PdfBean pb; - private int pageNo = 0; - private int omit_page_count = 0; - private int DEFAULT_LOGO_SIZE = 100; - - public PageEvent(PdfBean pb) { - this.pb = pb; - } - - private int getWidthEntries(int howManyLogos){ - int widthEntries = 0; - - if(howManyLogos == 2) - widthEntries = 3; - else - if(howManyLogos == 1) - widthEntries = 2; - else - widthEntries = 0; - - return widthEntries; - } - - private int getHowManyLogos(){ - int howManyLogos = 0; - - if(AppUtils.isNotEmpty(pb.getLogo1Url()) && !pb.getLogo1Url().equalsIgnoreCase("")) - howManyLogos ++; - - if(AppUtils.isNotEmpty(pb.getLogo2Url()) && !pb.getLogo2Url().equalsIgnoreCase("")) - howManyLogos ++; - - return howManyLogos; - } - - private float[] fillWidthsArray(int howManyLogos){ - float[] widthsArray = new float[howManyLogos + 1]; - - //If one logo, we will need two columns in the header[left log, spacer] - if(howManyLogos == 1){ - widthsArray = new float[2]; - widthsArray[0] = 0.1f; - widthsArray[1] = 0.1f; - } - //If two logs, we will need three columns in the header [left log, spacer, right log] - else - if(howManyLogos == 2){ - widthsArray = new float[3]; - widthsArray[0] = 0.1f; - widthsArray[1] = 0.5f; - widthsArray[2] = 0.1f; - } - - return widthsArray; - } - public void onStartPage(PdfWriter writer, Document document) { - - Font font = FontFactory.getFont(Globals.getFooterFontFamily(), Globals.getFooterFontSize(), Font.NORMAL, Color.BLACK); - int howManyLogos = getHowManyLogos(); - - //No need to draw anything in the header if no logo was set in the report. - if(howManyLogos == 0) - return; - - float[] widths = fillWidthsArray(howManyLogos); - - PdfPTable foot = new PdfPTable(widths); - - if(AppUtils.isNotEmpty(pb.getLogo1Url()) && !pb.getLogo1Url().equalsIgnoreCase("")) - addLogo(foot, font, pb.getLogo1Url().substring(pb.getLogo1Url().indexOf("|") + 1).trim(), Cell.ALIGN_LEFT, pb.getLogo1Size() == null ? DEFAULT_LOGO_SIZE : pb.getLogo1Size()); - - PdfPCell spacingCell = new PdfPCell(); - spacingCell.setBorderColor(Color.WHITE); - foot.addCell(spacingCell); - - //Using logo1 size for now - use logo2 size if it is required to deal it separately. - if(AppUtils.isNotEmpty(pb.getLogo2Url()) && !pb.getLogo2Url().equalsIgnoreCase("")) - addLogo(foot, font, pb.getLogo2Url().substring(pb.getLogo2Url().indexOf("|") + 1).trim(), Cell.ALIGN_RIGHT, pb.getLogo2Size() == null ? DEFAULT_LOGO_SIZE : pb.getLogo2Size()); - - foot.setTotalWidth(getPageWidth(document)); - foot.writeSelectedRows(0, -1, 36, 600, writer.getDirectContent()); - } - - public void onEndPage(PdfWriter writer, Document document) { - - Font font = FontFactory.getFont(Globals.getFooterFontFamily(), Globals.getFooterFontSize(), Font.NORMAL, Color.BLACK); - - try { - - // footer - float[] f = { 1f, 0.4f, 1f }; - PdfPTable foot = new PdfPTable(f); - foot.getDefaultCell().setBorderWidth(0); - foot.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - foot.getDefaultCell().setVerticalAlignment(Rectangle.ALIGN_BOTTOM); - - foot.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_LEFT); - addLeftFooter(foot, font); - - foot.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - addPageNumber(foot, font, pb.isPageNumberAtFooter(), document.getPageNumber()); - - foot.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_RIGHT); - foot.getDefaultCell().setNoWrap(true); - - foot.addCell(new Paragraph(" " + PdfReportHandler.currentTime(pb.getTimestampPattern()), font)); - - foot.setTotalWidth(getPageWidth(document)); - foot.writeSelectedRows(0, -1, document.leftMargin(), document.bottomMargin(), writer.getDirectContent()); - - // bookmark - pageNo++; - PdfContentByte cb = writer.getDirectContent(); - PdfDestination destination = new PdfDestination(PdfDestination.FITH); - String bookmark = "Data Page " + (pageNo - omit_page_count); - if (pageNo == 1) { - if (pb.isCoverPageIncluded()) { - bookmark = "Cover Page"; - omit_page_count++; - } else if (pb.isDisplayChart()) { - bookmark = "Chart"; - omit_page_count++; - } - } - if (pageNo == 2 && pb.isCoverPageIncluded() && pb.isDisplayChart()) { - bookmark = "Chart"; - omit_page_count++; - } - - PdfOutline outline = new PdfOutline(cb.getRootOutline(), destination, bookmark); - - } catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - private void addPageNumber(PdfPTable table, Font font, boolean isAdd, int pageNum) { - if (isAdd) - table.addCell(new Paragraph(Globals.getWordBeforePageNumber() + " " + pageNum + " " + Globals.getWordAfterPageNumber(), font)); - else - table.addCell(""); - } - - private void addLeftFooter(PdfPTable table, Font font) { - Font font1 = new Font(font); - font1.setSize(Globals.getAttProprieraryFontSize()); - - if (isEmpty(pb.getLeftFooter())) - table.addCell(new Paragraph(" " + Globals.getAttProprietary(), font1)); - else - table.addCell(new Paragraph(pb.getLeftFooter(), font)); - } - - private void addHeaderDummy(PdfPTable table, Font font) { - Font font1 = new Font(font); - font1.setSize(Globals.getAttProprieraryFontSize()); - - table.addCell(new Paragraph("Header row", font1)); - } - - private void addLogo(PdfPTable table, Font font, String imgSrc, int alignment, int absoluteSize) { - - Image img = null; - try { - img = Image.getInstance(pb.getFullWebContextPath() + AppUtils.getImgFolderURL() + File.separator + imgSrc); - } catch (BadElementException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - img = null; - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - img = null; - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - - } - if(img == null){ - //log that the input file couldnt be loaded - - } - else{ - //img.scaleAbsolute(absoluteSize, absoluteSize); - img.scalePercent(absoluteSize, absoluteSize); - PdfPCell cell = new PdfPCell(img); - cell.setBorderColor(Color.WHITE); - cell.setHorizontalAlignment(alignment); - table.addCell(cell); - } - - } - - public static float getPageWidth(Document doc) { - return doc.getPageSize().width() - doc.leftMargin() - doc.rightMargin(); - } - - public static float getPageHeight(Document doc) { - return doc.getPageSize().height() - doc.topMargin() - doc.bottomMargin(); - } - - private float getHeadTopMargin(Document doc, PdfPTable table) { - return doc.getPageSize().height() - doc.topMargin() + table.getTotalHeight(); - } - - private boolean isEmpty(String str) { - return str == null || str.trim().length() == 0; - } - -} // PageEvent diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfReportHandler.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfReportHandler.java deleted file mode 100644 index deac806d..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/pdf/PdfReportHandler.java +++ /dev/null @@ -1,1890 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -/* =========================================================================================== - - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) - * Raptor : This tool is used to generate different kinds of reports with lot of utilities - * =========================================================================================== - * - * ------------------------------------------------------------------------------------------- - * PdfReportHandler.java - This class is used to generate reports in PDF using iText - * ------------------------------------------------------------------------------------------- - * - * - * Changes - * ------- - * 14-Jul-2009 : Version 8.4 (Sundar);
          - *
        • Dashboard reports can be downloaded with each report occupying separate page including its charts.
        • - *
        - * - */ -package org.openecomp.portalsdk.analytics.model.pdf; - -import java.awt.Color; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.io.StringReader; -import java.net.MalformedURLException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TimeZone; -import java.util.TreeMap; -import java.util.Vector; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.error.ReportSQLException; -import org.openecomp.portalsdk.analytics.model.ReportHandler; -import org.openecomp.portalsdk.analytics.model.ReportLoader; -import org.openecomp.portalsdk.analytics.model.base.IdNameValue; -import org.openecomp.portalsdk.analytics.model.definition.ReportDefinition; -import org.openecomp.portalsdk.analytics.model.runtime.ReportRuntime; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.ConnectionUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.HtmlStripper; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.analytics.view.ColumnHeader; -import org.openecomp.portalsdk.analytics.view.ColumnHeaderRow; -import org.openecomp.portalsdk.analytics.view.DataRow; -import org.openecomp.portalsdk.analytics.view.DataValue; -import org.openecomp.portalsdk.analytics.view.HtmlFormatter; -import org.openecomp.portalsdk.analytics.view.ReportData; -import org.openecomp.portalsdk.analytics.view.RowHeader; -import org.openecomp.portalsdk.analytics.view.RowHeaderCol; -import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; - -import com.lowagie.text.BadElementException; -import com.lowagie.text.Chunk; -import com.lowagie.text.Document; -import com.lowagie.text.DocumentException; -import com.lowagie.text.Element; -import com.lowagie.text.ElementTags; -import com.lowagie.text.Font; -import com.lowagie.text.FontFactory; -import com.lowagie.text.Image; -import com.lowagie.text.PageSize; -import com.lowagie.text.Paragraph; -import com.lowagie.text.Phrase; -import com.lowagie.text.Rectangle; -import com.lowagie.text.html.simpleparser.HTMLWorker; -import com.lowagie.text.html.simpleparser.StyleSheet; -import com.lowagie.text.pdf.PdfPCell; -import com.lowagie.text.pdf.PdfPTable; -import com.lowagie.text.pdf.PdfWriter; - - -public class PdfReportHandler extends org.openecomp.portalsdk.analytics.RaptorObject{ - - /** - * - */ - private PdfBean pb; - private HtmlStripper strip = new HtmlStripper(); - private static final int RetryCreateNewImage = 3; - private int retryCreateNewImageCount=0; - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PdfReportHandler.class); - - private String FONT_FAMILY = "Arial"; - private int FONT_SIZE = 9; - - public PdfReportHandler() { } - - public void createPdfFileContent(HttpServletRequest request, HttpServletResponse response, int type) throws IOException, RaptorException { - - Document document = new Document(); - ReportHandler rh = new ReportHandler(); - String formattedDate = new SimpleDateFormat("MMddyyyyHHmm").format(new Date()); - String pdfFName = ""; - String user_id = AppUtils.getUserID(request); - response.reset(); - response.setContentType("application/pdf"); - OutputStream outStream = response.getOutputStream(); - - String formattedReportName = ""; - PdfWriter writer = null; - ReportRuntime firstReportRuntimeObj = null; - int returnValue = 0; - - ReportRuntime rr = null; - if(rr==null) rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); - - boolean isDashboard = false; - if ((request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)!=null) && ( ((String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID)).equals(rr.getReportID())) ) { - isDashboard = true; - } - if(isDashboard) { - try { - String reportID = (String) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REP_ID); - ReportRuntime rrDash = rh.loadReportRuntime(request, reportID, true, 1); - pb = preparePdfBean(request,rrDash); - - // Setting pb Values - document.setPageSize(PageSize.getRectangle(pb.getPagesize())); - if(!pb.isPortrait()) // get this from properties file - document.setPageSize(document.getPageSize().rotate()); - - // - writer = PdfWriter.getInstance(document, response.getOutputStream()); - writer.setPageEvent(new PageEvent(pb));//header,footer,bookmark - document.open(); - - formattedReportName = new HtmlStripper().stripSpecialCharacters(rrDash.getReportName()); - if(pb.isAttachmentOfEmail()) - response.setHeader("Content-disposition", "inline"); - else - response.setHeader("Content-disposition", "attachment;filename="+ formattedReportName+formattedDate+user_id+".pdf"); - - pdfFName = "dashboard"+formattedReportName+formattedDate+user_id+".pdf"; - Map reportRuntimeMap = null; - Map reportDataMap = null; - Map reportDisplayTypeMap = null; - - reportRuntimeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); - reportDataMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); - reportDisplayTypeMap = (TreeMap) request.getSession().getAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); - - if(reportRuntimeMap!=null) { - //ServletOutputStream sos = response.getOutputStream(); - Set setReportRuntime = reportRuntimeMap.entrySet(); - Set setReportDataMap = reportDataMap.entrySet(); - Set setReportDisplayTypeMap = reportDisplayTypeMap.entrySet(); - - Iterator iter2 = setReportDataMap.iterator(); - Iterator iter3 = setReportDisplayTypeMap.iterator(); - int count = 0; - for(Iterator iter = setReportRuntime.iterator(); iter.hasNext(); ) { - count++; - Map.Entry entryData = (Entry) iter2.next(); - Map.Entry entry = (Entry) iter.next(); - Map.Entry entryCheckChart = (Entry) iter3.next(); - //String rep_id = (String) entry.getKey(); - ReportRuntime rrDashRep = (ReportRuntime) entry.getValue(); - - if(count == 1) { - firstReportRuntimeObj = (ReportRuntime) entry.getValue(); - if(pb.isCoverPageIncluded()) { - document = paintDashboardCoverPage(document, rrDash, firstReportRuntimeObj, request); - } - } - ReportData rdDashRep = (ReportData) entryData.getValue(); - int col = 0; - //pb.setDisplayChart(nvl(rr.getChartType()).trim().length()>0 && rr.getDisplayChart()); - if( ((rrDashRep.getChartType()).trim().length()>0 && rrDashRep.getDisplayChart()) && entryCheckChart.getValue().toString().equals("c")) { - document.newPage(); - pb.setTitle(nvl(rrDashRep.getReportTitle()).length()>0?rrDashRep.getReportTitle():rrDashRep.getReportName()); - paintPdfImage(request, document,AppUtils.getTempFolderPath()+"cr_"+ pb.getUserId()+"_"+request.getSession().getId()+"_"+rrDashRep.getReportID()+".png", rrDashRep); - } else { - document.newPage(); - pb.setTitle(nvl(rrDashRep.getReportTitle()).length()>0?rrDashRep.getReportTitle():rrDashRep.getReportName()); - paintPdfData(request, document,rdDashRep,rrDashRep, ""); - } - } - - } - } catch (DocumentException dex) {dex.printStackTrace();} - catch (RaptorException rex) {rex.printStackTrace();} - } else { - - //ReportRuntime rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); - //ReportData rd = (ReportData) request.getSession().getAttribute(AppConstants.RI_REPORT_DATA); - rr = null; - ReportData rd = null; - String parent = ""; - int parentFlag = 0; - if(!nvl(request.getParameter("parent"), "").equals("N")) parent = nvl(request.getParameter("parent"), ""); - if(parent.startsWith("parent_")) parentFlag = 1; - if(parentFlag == 1) { - rr = (ReportRuntime) request.getSession().getAttribute(parent+"_rr"); - rd = (ReportData) request.getSession().getAttribute(parent+"_rd"); - } - if(rr==null) rr = (ReportRuntime) request.getSession().getAttribute(AppConstants.SI_REPORT_RUNTIME); - if(rd==null) rd = (ReportData) request.getSession().getAttribute(AppConstants.RI_REPORT_DATA); - - pb = preparePdfBean(request,rr); - FONT_FAMILY = rr.getPDFFont(); - FONT_SIZE = rr.getPDFFontSize(); - //System.out.println(pb); - - formattedReportName = new HtmlStripper().stripSpecialCharacters(rr.getReportName()); - - - - response.setContentType("application/pdf"); - if(pb.isAttachmentOfEmail()) - response.setHeader("Content-disposition", "inline"); - else - response.setHeader("Content-disposition", "attachment;filename="+ formattedReportName+formattedDate+user_id+".pdf"); - - document.setPageSize(PageSize.getRectangle(pb.getPagesize())); - - if(!pb.isPortrait()) // get this from properties file - document.setPageSize(document.getPageSize().rotate()); - - try { - - writer = PdfWriter.getInstance(document, outStream); - writer.setPageEvent(new PageEvent(pb));//header,footer,bookmark - document.open(); - - //System.out.println("Document 1 " + document); - if(pb.isCoverPageIncluded()) { - document = paintCoverPage(document, rr, request); - } - - //boolean isImageRotate = false; - //System.out.println("Document 2 " + document); - - if(pb.isDisplayChart()) { - paintPdfImage(request, document,AppUtils.getTempFolderPath()+"cr_"+ pb.getUserId()+"_"+request.getSession().getId()+"_"+rr.getReportID()+".png", rr); - } - //System.out.println("Document 4" + document); - - document.newPage(); - if(type == 3 && rr.getSemaphoreList()==null && !(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) ) { //type = 3 is whole - String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); - returnValue = paintPdfData(request, document, rd, rr, sql_whole); - } else if(type == 2) { - returnValue = paintPdfData(request, document, rd, rr, ""); - } else { - //String sql_whole = (String) request.getAttribute(AppConstants.RI_REPORT_SQL_WHOLE); - int downloadLimit = (rr.getMaxRowsInExcelDownload()>0)?rr.getMaxRowsInExcelDownload():Globals.getDownloadLimit(); - String action = request.getParameter(AppConstants.RI_ACTION); - - if(!(rr.getReportType().equals(AppConstants.RT_CROSSTAB)) && !action.endsWith("session")) - rd = rr.loadReportData(-1, AppUtils.getUserID(request), downloadLimit,request, false /*download*/); - if(rr.getSemaphoreList()!=null) { - rd = rr.loadReportData(-1, AppUtils.getUserID(request), downloadLimit,request, true); - returnValue = paintPdfData(request, document, rd, rr, ""); - } else { - returnValue = paintPdfData(request, document, rd, rr, rr.getWholeSQL()); - } - - - } - - - //paintPdfData(document,rd,rr); - - - } catch (DocumentException de) { - de.printStackTrace(); - //System.err.println("document: " + de.getMessage()); - } - - } - document.close(); - int mb = 1024*1024; - Runtime runtime = Runtime.getRuntime(); - logger.debug(EELFLoggerDelegate.debugLogger, ("##### Heap utilization statistics [MB] #####")); - logger.debug(EELFLoggerDelegate.debugLogger, ("Used Memory:" - + (runtime.maxMemory() - runtime.freeMemory()) / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Free Memory:" - + runtime.freeMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Total Memory:" + runtime.totalMemory() / mb)); - logger.debug(EELFLoggerDelegate.debugLogger, ("Max Memory:" + runtime.maxMemory() / mb)); - - } - - private Document paintCoverPage(Document doc, ReportRuntime rr, HttpServletRequest request) throws IOException, DocumentException { - - //System.out.println("PDFREPORTHANDLER STARTED ... " ); - if(nvl(rr.getPdfImg()).length()>0) { - Image image1 = Image.getInstance(AppUtils.getExcelTemplatePath()+"../../"+AppUtils.getImgFolderURL()+rr.getPdfImg()); - image1.scalePercent(20f, 20f); - doc.add(image1); - } - float firstColumnSize = Globals.getCoverPageFirstColumnSize(); - float[] relativeWidths = {firstColumnSize,1f-firstColumnSize}; - PdfPTable table = new PdfPTable(relativeWidths); - table.getDefaultCell().setBorderWidth(0); - addEmptyRows(table,6); - HTMLWorker worker = new HTMLWorker(doc); - StyleSheet style = new StyleSheet(); - style.loadTagStyle("body", "leading", "16,0"); - StringBuffer reportDescrBuf = new StringBuffer(""); - ArrayList descr = HTMLWorker.parseToList(new StringReader(nvl(rr.getReportDescr())), style); - ArrayList paraList = null; - if(nvl(rr.getReportTitle()).length()>0) { - add2Cells(table,"Report Title : ",nvl(rr.getReportTitle())); - } else { - add2Cells(table,"Report Name : ",nvl(rr.getReportName())); - } - if((descr!=null && descr.size()>0)) { - paraList = (com.lowagie.text.Paragraph)descr.get(0); - for (int i=0 ; i0) { - String nameValue[] = Globals.getSessionInfoForTheCoverPage().split(","); - String name=nameValue[0]; - String value=nameValue[1]; - add2Cells(table,name+" : ",(AppUtils.getRequestNvlValue(request, value).length()>0?AppUtils.getRequestNvlValue(request, value):nvl((String)request.getSession().getAttribute(value)))); - } - - if(Globals.isCreatedOwnerInfoNeeded()) { - add2Cells(table,"Created By : ",nvl(AppUtils.getUserName(rr.getCreateID()))); - add2Cells(table,"Owner : ",nvl(AppUtils.getUserName(rr.getOwnerID()))); - } - if(Globals.displayLoginIdForDownloadedBy()) - add2Cells(table,"Downloaded by : ",nvl(AppUtils.getUserBackdoorLoginId(request))); - else - add2Cells(table,"Downloaded by : ",nvl(AppUtils.getUserName(AppUtils.getUserID(request)))); - - addEmptyRows(table,1); - - boolean isFirstRow = true; - ArrayList al = rr.getParamNameValuePairsforPDFExcel(request, 1); - if(al.size()<=0) { - al = (ArrayList) request.getSession().getAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); - } - - Iterator it = al.iterator(); - addEmptyRows(table,1); - //if(!Globals.customizeFormFieldInfo()) { - if(rr.getFormFieldComments(request).length()<=0) { - while(it.hasNext()) { - - if(isFirstRow) { - add2Cells(table, "Run-time Criteria : ", " "); - isFirstRow = false; - } - - IdNameValue value = (IdNameValue)it.next(); - if(!value.getId().trim().equals("BLANK")) - //System.out.println("PDFREPORTHANDLER " + value.getId()+" : "+value.getName()); - add2Cells(table, value.getId()+" : ",value.getName().replaceAll("~",",")); - //add2Cells(table, rr.getFormFieldComments(request), " "); - } - addEmptyRows(table,1); - doc.add(table); - - } else { - it = al.iterator(); - if(it.hasNext()) { - //add2Cells(table, "Run-time Criteria : ", " "); - addEmptyRows(table,1); - doc.add(table); - //com.lowagie.text.html.HtmlParser.parse(doc, new StringReader(rr.getFormFieldComments(request))); - ArrayList p = HTMLWorker.parseToList(new StringReader(rr.getFormFieldComments(request).replaceAll("~",",")), style); - - for (int k = 0; k < p.size(); ++k){ - doc.add((com.lowagie.text.Element)p.get(k)); - } - } - } - - return doc; - } - - - private Document paintDashboardCoverPage(Document doc, ReportRuntime rrDashRep, ReportRuntime firstReportRuntimeObj, HttpServletRequest request) throws IOException, DocumentException { - - //System.out.println("PDFREPORTHANDLER STARTED ... " ); - float firstColumnSize = Globals.getCoverPageFirstColumnSize(); - float[] relativeWidths = {firstColumnSize,1f-firstColumnSize}; - PdfPTable table = new PdfPTable(relativeWidths); - table.getDefaultCell().setBorderWidth(0); - addEmptyRows(table,6); - - add2Cells(table,"Report Name : ",rrDashRep.getReportName()); - add2Cells(table,"Description : ",rrDashRep.getReportDescr()); - if(Globals.getSessionInfoForTheCoverPage().length()>0) { - String nameValue[] = Globals.getSessionInfoForTheCoverPage().split(","); - String name=nameValue[0]; - String value=nameValue[1]; - add2Cells(table,name+" : ",(AppUtils.getRequestNvlValue(request, value).length()>0?AppUtils.getRequestNvlValue(request, value):nvl((String)request.getSession().getAttribute(value)))); - } - - if(Globals.isCreatedOwnerInfoNeeded()) { - add2Cells(table,"Created By : ",AppUtils.getUserName(rrDashRep.getCreateID())); - add2Cells(table,"Owner : ",AppUtils.getUserName(rrDashRep.getOwnerID())); - } - if(Globals.displayLoginIdForDownloadedBy()) - add2Cells(table,"Downloaded by : ",AppUtils.getUserBackdoorLoginId(request)); - else - add2Cells(table,"Downloaded by : ",AppUtils.getUserName(request)); - - addEmptyRows(table,1); - - boolean isFirstRow = true; - ArrayList al = firstReportRuntimeObj.getParamNameValuePairsforPDFExcel(request, 2); - Iterator it = al.iterator(); - addEmptyRows(table,1); - //if(!Globals.customizeFormFieldInfo()) { - if(firstReportRuntimeObj.getFormFieldComments(request).length()<=0) { - while(it.hasNext()) { - - if(isFirstRow) { - add2Cells(table, "Run-time Criteria : ", " "); - isFirstRow = false; - } - - IdNameValue value = (IdNameValue)it.next(); - if(!value.getId().trim().equals("BLANK")) - //System.out.println("PDFREPORTHANDLER " + value.getId()+" : "+value.getName()); - add2Cells(table, value.getId()+" : ",value.getName()); - //add2Cells(table, rr.getFormFieldComments(request), " "); - } - addEmptyRows(table,1); - doc.add(table); - - } else { - it = al.iterator(); - if(it.hasNext()) { - //add2Cells(table, "Run-time Criteria : ", " "); - addEmptyRows(table,1); - doc.add(table); - //com.lowagie.text.html.HtmlParser.parse(doc, new StringReader(rr.getFormFieldComments(request))); - HTMLWorker worker = new HTMLWorker(doc); - StyleSheet style = new StyleSheet(); - style.loadTagStyle("body", "leading", "16,0"); - ArrayList p = HTMLWorker.parseToList(new StringReader(firstReportRuntimeObj.getFormFieldComments(request)), style); - - for (int k = 0; k < p.size(); ++k){ - doc.add((com.lowagie.text.Element)p.get(k)); - } - } - } - - return doc; - } - - - public static void addEmptyRows(PdfPTable table, int rows) throws DocumentException { - for (int i=0; i0?AppUtils.getRequestNvlValue(request, "multiplePieOrder").equals("row"):rr.isMultiplePieOrderByRow())) ); - additionalChartOptionsMap.put("multiplePieLabelDisplay", AppUtils.getRequestNvlValue(request, "multiplePieLabelDisplay").length()>0? AppUtils.getRequestNvlValue(request, "multiplePieLabelDisplay"):rr.getMultiplePieLabelDisplay()); - additionalChartOptionsMap.put("chartDisplay", new Boolean(AppUtils.getRequestNvlValue(request, "chartDisplay").length()>0? AppUtils.getRequestNvlValue(request, "chartDisplay").equals("3D"):rr.isChartDisplayIn3D())); - } else if (chartType.equals(AppConstants.GT_BAR_3D)) { - additionalChartOptionsMap.put("chartOrientation", new Boolean((AppUtils.getRequestNvlValue(request, "chartOrientation").length()>0?AppUtils.getRequestNvlValue(request, "chartOrientation").equals("vertical"):rr.isVerticalOrientation())) ); - additionalChartOptionsMap.put("secondaryChartRenderer", AppUtils.getRequestNvlValue(request, "secondaryChartRenderer").length()>0? AppUtils.getRequestNvlValue(request, "secondaryChartRenderer"):rr.getSecondaryChartRenderer()); - additionalChartOptionsMap.put("chartDisplay", new Boolean(AppUtils.getRequestNvlValue(request, "chartDisplay").length()>0? AppUtils.getRequestNvlValue(request, "chartDisplay").equals("3D"):rr.isChartDisplayIn3D())); - additionalChartOptionsMap.put("lastSeriesALineChart", new Boolean(rr.isLastSeriesALineChart())); - } else if (chartType.equals(AppConstants.GT_LINE)) { - additionalChartOptionsMap.put("chartOrientation", new Boolean((AppUtils.getRequestNvlValue(request, "chartOrientation").length()>0?AppUtils.getRequestNvlValue(request, "chartOrientation").equals("vertical"):rr.isVerticalOrientation())) ); - //additionalChartOptionsMap.put("secondaryChartRenderer", AppUtils.getRequestNvlValue(request, "secondaryChartRenderer").length()>0? AppUtils.getRequestNvlValue(request, "secondaryChartRenderer"):rr.getSecondaryChartRenderer()); - additionalChartOptionsMap.put("chartDisplay", new Boolean(AppUtils.getRequestNvlValue(request, "chartDisplay").length()>0? AppUtils.getRequestNvlValue(request, "chartDisplay").equals("3D"):rr.isChartDisplayIn3D())); - additionalChartOptionsMap.put("lastSeriesABarChart", new Boolean(rr.isLastSeriesABarChart())); - } else if (chartType.equals(AppConstants.GT_TIME_DIFFERENCE_CHART)) { - additionalChartOptionsMap.put("intervalFromDate",AppUtils.getRequestNvlValue(request, "intervalFromDate").length()>0?AppUtils.getRequestNvlValue(request, "intervalFromDate"):rr.getIntervalFromdate()); - additionalChartOptionsMap.put("intervalToDate", AppUtils.getRequestNvlValue(request, "intervalToDate").length()>0? AppUtils.getRequestNvlValue(request, "intervalToDate"):rr.getIntervalTodate()); - additionalChartOptionsMap.put("intervalLabel", AppUtils.getRequestNvlValue(request, "intervalLabel").length()>0? AppUtils.getRequestNvlValue(request, "intervalLabel"):rr.getIntervalLabel()); - } else if (chartType.equals(AppConstants.GT_REGRESSION)) { - additionalChartOptionsMap.put("regressionType",AppUtils.getRequestNvlValue(request, "regressionType").length()>0?AppUtils.getRequestNvlValue(request, "regressionType"):rr.getLinearRegression()); - additionalChartOptionsMap.put("linearRegressionColor",nvl(rr.getLinearRegressionColor())); - additionalChartOptionsMap.put("expRegressionColor",nvl(rr.getExponentialRegressionColor())); - additionalChartOptionsMap.put("maxRegression",nvl(rr.getCustomizedRegressionPoint())); - } else if (chartType.equals(AppConstants.GT_STACK_BAR) ||chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR) || chartType.equals(AppConstants.GT_STACKED_HORIZ_BAR_LINES) - || chartType.equals(AppConstants.GT_STACKED_VERT_BAR) || chartType.equals(AppConstants.GT_STACKED_VERT_BAR_LINES) - ) { - additionalChartOptionsMap.put("overlayItemValue",new Boolean(nvl(rr.getOverlayItemValueOnStackBar()).equals("Y"))); - } - additionalChartOptionsMap.put("legendPosition", nvl(rr.getLegendPosition())); - additionalChartOptionsMap.put("hideToolTips", new Boolean(rr.hideChartToolTips())); - additionalChartOptionsMap.put("hideLegend", new Boolean(AppUtils.getRequestNvlValue(request, "hideLegend").length()>0? AppUtils.getRequestNvlValue(request, "hideLegend").equals("Y"):rr.hideChartLegend())); - additionalChartOptionsMap.put("labelAngle", nvl(rr.getLegendLabelAngle())); - additionalChartOptionsMap.put("maxLabelsInDomainAxis", nvl(rr.getMaxLabelsInDomainAxis())); - additionalChartOptionsMap.put("rangeAxisLowerLimit", nvl(rr.getRangeAxisLowerLimit())); - additionalChartOptionsMap.put("rangeAxisUpperLimit", nvl(rr.getRangeAxisUpperLimit())); - - - boolean totalOnChart = false; - totalOnChart = AppUtils.getRequestNvlValue(request, "totalOnChart").equals("Y"); - String filename = null; - ArrayList graphURL = new ArrayList(); - ArrayList chartNames = new ArrayList(); - ArrayList fileNames = new ArrayList(); - List l = rr.getAllColumns(); - List lGroups = rr.getAllChartGroups(); - HashMap mapYAxis = rr.getAllChartYAxis(rr.getReportParamValues()); - String chartLeftAxisLabel = rr.getFormFieldFilled(nvl(rr.getChartLeftAxisLabel())); - String chartRightAxisLabel = rr.getFormFieldFilled(nvl(rr.getChartRightAxisLabel())); - int displayTotalOnChart = 0; - HashMap formValues = Globals.getRequestParamtersMap(request, false); - - for (Iterator iterC = l.iterator(); iterC.hasNext();) { - DataColumnType dc = (DataColumnType) iterC.next(); - if(nvl(dc.getColName()).equals(AppConstants.RI_CHART_TOTAL_COL)) { - displayTotalOnChart = 1; - } - } - - String legendColumnName = (rr.getChartLegendColumn()!=null)?rr.getChartLegendColumn().getDisplayName():"Legend Column"; - - - - if(ds!=null) - { - if(rr.hasSeriesColumn() && chartType.equals(AppConstants.GT_TIME_SERIES) && (lGroups==null || lGroups.size() <= 0)) { /** Check whether Report has only category columns if so then all the columns will open in seperate chart - sundar**/ - for (int i=0; i0) - tempChartGroupCurrent = chartGroupOrg.substring(0,chartGroupOrg.lastIndexOf("|")); - if(i>0) tempChartGroupPrev = ((String) lGroups.get(i-1)).substring(0,((String) lGroups.get(i-1)).lastIndexOf("|")); - //System.out.println("TEMPCHARTGROUP " + tempChartGroupCurrent + " " + tempChartGroupPrev); - if(tempChartGroupCurrent.equals(tempChartGroupPrev)) continue; - //System.out.println("CHARTGROUPORG " + chartGroupOrg + " " + lGroups) ; - //String chartGroup = chartGroupOrg.substring(0,chartGroupOrg.lastIndexOf("|")); - String chartGroup = chartGroupOrg; - - //System.out.println("$$$$CHARTGROUP in JSP " +chartGroup+ " "+ chartGroupOrg ); - //System.out.println(" rr.getChartGroupDisplayNamesList(chartGroup) " + rr.getChartGroupDisplayNamesList(chartGroup)); - //System.out.println(" rr.getChartGroupColumnColorsList(chartGroup) " + rr.getChartGroupColumnColorsList(chartGroup)); - //System.out.println(" rr.getChartGroupColumnAxisList(chartGroup) " + rr.getChartGroupColumnAxisList(chartGroup)); - //System.out.println(" rr.getChartGroupValueColumnAxisList(chartGroupOrg) " + rr.getChartGroupValueColumnAxisList(chartGroupOrg)); - - downloadFileName = AppUtils.getTempFolderPath()+"cr_"+pb.getUserId()+"_"+request.getSession().getId()+"_"+rr.getReportID()+"_"+i+".png"; - String chartTitle = (Globals.getDisplayChartTitle()? (chartGroup!=null && chartGroup.indexOf("|") > 0 ?chartGroup.substring(0,chartGroup.lastIndexOf("|")):rr.getReportName()):""); - chartTitle = rr.getFormFieldFilled(chartTitle); - String leftAxisLabel = ""; - //if(!rr.isChartMultiSeries()) { - if(!rr.isMultiSeries()) { - leftAxisLabel = ((chartYAxis!=null && chartYAxis.indexOf("|") > 0) ? chartYAxis.substring(0,chartYAxis.lastIndexOf("|")): chartLeftAxisLabel ); - } else { - leftAxisLabel = chartLeftAxisLabel; - } - - filename = null;/*(String) ChartGen.generateChart( chartType, - request.getSession(), - ds, - legendColumnName, - leftAxisLabel, - chartRightAxisLabel, - ((chartType.indexOf("Stacked")>0 || chartType.equals(AppConstants.GT_PIE_MULTIPLE) || chartType.equals(AppConstants.GT_BAR_3D))?rr.getChartDisplayNamesList(AppConstants.CHART_ALL_COLUMNS, formValues):rr.getChartGroupDisplayNamesList(chartGroup, formValues)), - ((chartType.indexOf("Stacked")>0 || chartType.equals(AppConstants.GT_PIE_MULTIPLE) || chartType.equals(AppConstants.GT_BAR_3D))?rr.getChartColumnColorsList(AppConstants.CHART_ALL_COLUMNS, formValues):rr.getChartGroupColumnColorsList(chartGroup, formValues)), - ((chartType.indexOf("Stacked")>0 || chartType.equals(AppConstants.GT_PIE_MULTIPLE) || chartType.equals(AppConstants.GT_BAR_3D))?rr.getChartValueColumnAxisList(AppConstants.CHART_ALL_COLUMNS, formValues):rr.getChartGroupValueColumnAxisList(chartGroupOrg, formValues)), - "", - chartTitle, - null, - rr.getChartWidthAsInt(), - rr.getChartHeightAsInt(), - ((chartType.indexOf("Stacked")>0 || chartType.equals(AppConstants.GT_PIE_MULTIPLE))?rr.getChartValueColumnsList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues):rr.getChartGroupValueColumnAxisList(chartGroupOrg, formValues)), - rr.hasSeriesColumn(), - //rr.isChartMultiSeries(), - rr.isMultiSeries(), - rr.getAllColumns(), - downloadFileName, - totalOnChart, - AppConstants.WEB_VERSION deviceType, - additionalChartOptionsMap, - true - );*/ - try { - Image image = Image.getInstance(downloadFileName); - images.add(image); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - catch (BadElementException e) { - e.printStackTrace(); - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - if(!chartType.equals(AppConstants.GT_PIE_MULTIPLE)) { - for (int i=0; i 0))) { - - if(/*chartType.equals(AppConstants.GT_TIME_SERIES) && */rr.getChartDisplayNamesList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues)!=null && rr.getChartDisplayNamesList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues).size()>0) { - downloadFileName = AppUtils.getTempFolderPath()+"cr_"+ pb.getUserId()+"_"+request.getSession().getId()+"_"+rr.getReportID()+"_All.png"; - String chartTitle = Globals.getDisplayChartTitle()? rr.getReportName():""; - chartTitle = rr.getFormFieldFilled(chartTitle); - - filename = null;/*(String) ChartGen.generateChart( chartType, - request.getSession(), - ds, - legendColumnName, - chartLeftAxisLabel, - chartRightAxisLabel, - rr.getChartDisplayNamesList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues), - rr.getChartColumnColorsList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues), - rr.getChartValueColumnAxisList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues), - "", - chartTitle, - null, - rr.getChartWidthAsInt(), - rr.getChartHeightAsInt(), - rr.getChartValueColumnsList(AppConstants.CHART_WITHOUT_NEWCHART_COLUMNS, formValues), - rr.hasSeriesColumn(), - //rr.isChartMultiSeries(), - rr.isMultiSeries(), - rr.getAllColumns(), - downloadFileName, - totalOnChart, - AppConstants.WEB_VERSION, - additionalChartOptionsMap, - true - ); -*/ try { - Image image = Image.getInstance(downloadFileName); - images.add(image); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - catch (BadElementException e) { - e.printStackTrace(); - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } // Stacked Chart Check - } // else no Series Column - - }// if(ds!=null) - - }catch (Exception e) { - e.printStackTrace(); - } -// System.out.println("Total Images " + images.size()); - return images.size()>0?images:null; - - } - -/* - private boolean isImageRotate(Document doc, Image image) { - - System.out.println("image size="+image.getWidthPercentage()+ " "+ image.scaledWidth()+ - " "+image.scaledHeight()+" "+image.getXYRatio()); - System.out.println("page size = "+ doc.getPageSize().width() + " " +doc.getPageSize().height() +" "+ - doc.topMargin() + " " +doc.bottomMargin() + " " + doc.leftMargin() + " " + - doc.rightMargin()); - System.out.println(image.scaledWidth()/image.scaledHeight()); - System.out.println((PageEvent.getPageWidth(doc)/PageEvent.getPageHeight(doc))); -// System.out.println(doc.getPageSize().getRotation()); - - float image_w = image.scaledWidth(); - float image_h = image.scaledHeight(); - float image_ratio = image_w/image_h; - - float page_w = PageEvent.getPageWidth(doc); - float page_h = PageEvent.getPageHeight(doc); - float page_ratio = page_w/page_h; - - return (image_w > page_w && image_ratio > page_ratio) || - (image_h > page_h && image_ratio < page_ratio); - - } - -*/ - private final int DEFAULT_PDF_DISPLAY_WIDTH = 10; - private int paintPdfData(HttpServletRequest request, Document document, ReportData rd, ReportRuntime rr, String sql_whole) throws DocumentException, RaptorException, IOException { - - int mb = 1024*1024; - Runtime runtime = Runtime.getRuntime(); - int returnValue = 0; - sql_whole = rr.getWholeSQL(); - if(rd.getDataRowCount() >= rr.getReportDataSize()) { - sql_whole=""; - } - float f[] = getRelativeWidths(rd, rr.getReportType().equals(AppConstants.RT_CROSSTAB)); - PdfPTable table = new PdfPTable(f); - table.setWidthPercentage(100f); - table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - table.getDefaultCell().setVerticalAlignment(Rectangle.ALIGN_BOTTOM); - - ReportDefinition rdef = (new ReportHandler()).loadReportDefinition(request, rr.getReportID()); - - List allColumns = rdef.getAllColumns(); - - float[] repotWidths = new float[rdef.getVisibleColumnCount()]; - int columnIdx = 0; - float pdfDisplayWidth = 0; - for(Iterator iter = allColumns.iterator(); iter.hasNext();){ - DataColumnType dct = (DataColumnType) iter.next(); - if(dct.isVisible()) { - - if(dct.getPdfDisplayWidthInPxls() == null || dct.getPdfDisplayWidthInPxls().equals("") || dct.getPdfDisplayWidthInPxls().startsWith("null")) - pdfDisplayWidth = DEFAULT_PDF_DISPLAY_WIDTH; - else - pdfDisplayWidth = Float.parseFloat(dct.getPdfDisplayWidthInPxls()); - - repotWidths [columnIdx++] = pdfDisplayWidth; - } - } - - table.setWidths(repotWidths); - - //table.setH - - //TODO: check title and subtitle - HttpSession session = request.getSession(); - String drilldown_index = (String) session.getAttribute("drilldown_index"); - int index = 0; - try { - index = Integer.parseInt(drilldown_index); - } catch (NumberFormatException ex) { - index = 0; - } - String titleRep = (String) session.getAttribute("TITLE_"+index); - String subtitle = (String) session.getAttribute("SUBTITLE_"+index); - - if(nvl(titleRep).length()>0 && nvl(subtitle).length()>0) - table.setHeaderRows(3); - else if (nvl(titleRep).length()>0) - table.setHeaderRows(2); - else - table.setHeaderRows(1); - table = paintPdfReportHeader(request, document, table, rr, f); - paintPdfTableHeader(document, rd, table); - - int idx = 0; - int fragmentsize = 30; //for memory management - - ResultSet rs = null; - Connection conn = null; - Statement st = null; - ResultSetMetaData rsmd = null; - rd.reportDataRows.resetNext(); - DataRow dr = rd.reportDataRows.getNext(); - - //addRowHeader(table,dr,idx,rd); - - //addRowColumns(table,dr,idx); - if(nvl(sql_whole).length() >0 && rr.getReportType().equals(AppConstants.RT_LINEAR)) { - try { - conn = ConnectionUtils.getConnection(rr.getDbInfo()); - st = conn.createStatement(); - logger.debug(EELFLoggerDelegate.debugLogger, ("************* Map Whole SQL *************")); - logger.debug(EELFLoggerDelegate.debugLogger, (sql_whole)); - logger.debug(EELFLoggerDelegate.debugLogger, ("*****************************************")); - rs = st.executeQuery(sql_whole); - rsmd = rs.getMetaData(); - int numberOfColumns = rsmd.getColumnCount(); - HashMap colHash = new HashMap(); - dr = null; - int j = 0; - int rowCount = 0; - String title = ""; - while(rs.next()) { - -/* if(runtime.freeMemory()/mb <= ((runtime.maxMemory()/mb)*Globals.getMemoryThreshold()/100) ) { - returnValue = 1; - String cellValue = Globals.getUserDefinedMessageForMemoryLimitReached() + " "+ rowCount +" records out of " + rr.getReportDataSize() + " were downloaded to PDF."; - Font cellFont = FontFactory.getFont(Globals.getDataFontFamily(), - Globals.getDataFontSize(), - Font.NORMAL, Color.BLACK); - PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); - table.addCell(cell); - document.add(table); - return returnValue; - } -*/ rowCount++; - colHash = new HashMap(); - for (int i = 1; i <= numberOfColumns; i++) { - colHash.put(rsmd.getColumnName(i), rs.getString(i)); - } - rd.reportDataRows.resetNext(); - - dr = rd.reportDataRows.getNext(); - - j = 0; - /*if(rd.reportTotalRowHeaderCols!=null) { - - HtmlFormatter rfmt = dr.getRowFormatter(); - - Font cellFont = FontFactory.getFont(Globals.getDataFontFamily(), - Globals.getDataFontSize(), - Font.NORMAL, Color.BLACK); - if(rfmt != null) { - cellFormatterFont(rfmt,cellFont); - } - - String cellValue = new Integer(rowCount).toString(); - PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); - - //row background color can be overwritten by cell background color - cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); - - cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); - - if(rfmt != null) { - formatterCell(rfmt,cell); - } - table.addCell(cell); - }*/ - - for (dr.resetNext(); dr.hasNext();j++) { - DataValue dv = dr.getNext(); - /*if(j == 0) { - HtmlFormatter cfmt = dv.getCellFormatter(); - HtmlFormatter rfmt = dv.getRowFormatter(); - - Font cellFont = FontFactory.getFont(Globals.getDataFontFamily(), - Globals.getDataFontSize(), - Font.NORMAL, Color.BLACK); - if(cfmt!= null) { - cellFormatterFont(cfmt,cellFont); - } - else if(rfmt != null) { - cellFormatterFont(rfmt,cellFont); - } - else { - if(dv.isBold()) { - cellFont.setStyle(Font.BOLD); - } - } - - //String cellValue = strip.stripHtml(value.trim()); - PdfPCell cell = new PdfPCell(new Paragraph(rowCount+"",cellFont)); - - //row background color can be overwritten by cell background color - cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); - - if(nvl(dv.getAlignment()).trim().length()>0) - cell.setHorizontalAlignment(ElementTags.alignmentValue(dv.getAlignment())); - else - cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); - - if(cfmt!= null) { - formatterCell(cfmt,cell); - } - else if(rfmt != null) { - formatterCell(rfmt,cell); - } - table.addCell(cell); - }*/ - - //for (chr.resetNext(); chr.hasNext();) { - //ColumnHeader ch = chr.getNext(); - String value = nvl((String)colHash.get(dv.getColId().toUpperCase())); - if(dv.isVisible()) { - - HtmlFormatter cfmt = dv.getCellFormatter(); - HtmlFormatter rfmt = dv.getRowFormatter(); - - Font cellFont = FontFactory.getFont(FONT_FAMILY, - FONT_SIZE, - Font.NORMAL, Color.BLACK); - if(cfmt!= null) { - cellFormatterFont(cfmt,cellFont); - } - else if(rfmt != null) { - cellFormatterFont(rfmt,cellFont); - } - else { - if(dv.isBold()) { - cellFont.setStyle(Font.BOLD); - } - } - - String cellValue = strip.stripHtml(value.trim()); - PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); - - //row background color can be overwritten by cell background color - cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); - - if(nvl(dv.getAlignment()).trim().length()>0) - cell.setHorizontalAlignment(ElementTags.alignmentValue(dv.getAlignment())); - else - cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); - - if(cfmt!= null) { - formatterCell(cfmt,cell); - } - else if(rfmt != null) { - formatterCell(rfmt,cell); - } - - - - table.addCell(cell); - - }//if isVisible() - - - } - - } - if(rd.reportDataTotalRow!=null) { - for (rd.reportDataTotalRow.resetNext(); rd.reportDataTotalRow.hasNext();idx++) { - dr = rd.reportDataTotalRow.getNext(); - table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - Font rowHeaderFont = FontFactory.getFont(FONT_FAMILY, - FONT_SIZE, - Font.NORMAL, Color.BLACK); - rowHeaderFont.setStyle(Font.BOLD); - rowHeaderFont.setSize(FONT_SIZE+1f); - table.getDefaultCell().setBackgroundColor(getRowBackgroundColor(dr, idx)); - table.addCell(new Paragraph("Total",rowHeaderFont)); - - - addTotalRowColumns(table,dr,idx); - if (idx % fragmentsize == fragmentsize - 1) { - document.add(table); - table.deleteBodyRows(); - table.setSkipFirstHeader(true); - } - - } - } - } catch (SQLException ex) { - throw new RaptorException(ex); - } catch (ReportSQLException ex) { - throw new RaptorException(ex); - } catch (Exception ex) { - if(!(ex.getCause() instanceof java.net.SocketException) ) - throw new RaptorException (ex); - } finally { - try { - if(conn!=null) - conn.close(); - if(st!=null) - st.close(); - if(rs!=null) - rs.close(); - } catch (SQLException ex) { - throw new RaptorException(ex); - } - } - - -// if (idx % fragmentsize == fragmentsize - 1) { -// document.add(table); -// table.deleteBodyRows(); -// table.setSkipFirstHeader(true); -// } - - //document.add(table); - } else { - if(rr.getReportType().equals(AppConstants.RT_LINEAR)) { - int rowCount = 0; - for(rd.reportDataRows.resetNext();rd.reportDataRows.hasNext();idx++) - { - rowCount++; - - /*if(rd.reportTotalRowHeaderCols!=null) { - HtmlFormatter rfmt = dr.getRowFormatter(); - - Font cellFont = FontFactory.getFont(Globals.getDataFontFamily(), - Globals.getDataFontSize(), - Font.NORMAL, Color.BLACK); - if(rfmt != null) { - cellFormatterFont(rfmt,cellFont); - } - - //String cellValue = new Integer(rowCount).toString(); - //PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); - - //row background color can be overwritten by cell background color - //cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); - - //cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); - - //if(rfmt != null) { - //formatterCell(rfmt,cell); - //} - //table.addCell(cell); - }*/ - - - - if(runtime.freeMemory()/mb <= ((runtime.maxMemory()/mb)*Globals.getMemoryThreshold()/100) ) { - returnValue = 1; - } - - dr = rd.reportDataRows.getNext(); - - addRowHeader(table,dr,idx,rd); - - addRowColumns(table,dr,idx); - - if (idx % fragmentsize == fragmentsize - 1) { - document.add(table); - table.deleteBodyRows(); - table.setSkipFirstHeader(true); - } - } - - if(rd.reportDataTotalRow!=null) { - for (rd.reportDataTotalRow.resetNext(); rd.reportDataTotalRow.hasNext();idx++) { - dr = rd.reportDataTotalRow.getNext(); - table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - Font rowHeaderFont = FontFactory.getFont(FONT_FAMILY, - FONT_SIZE, - Font.NORMAL, Color.BLACK); - rowHeaderFont.setStyle(Font.BOLD); - rowHeaderFont.setSize(FONT_SIZE+1f); - table.getDefaultCell().setBackgroundColor(getRowBackgroundColor(dr, idx)); - table.addCell(new Paragraph("Total",rowHeaderFont)); - - - addTotalRowColumns(table,dr,idx); - if (idx % fragmentsize == fragmentsize - 1) { - document.add(table); - table.deleteBodyRows(); - table.setSkipFirstHeader(true); - } - - } - } - - } else if (rr.getReportType().equals(AppConstants.RT_CROSSTAB)) { - int rowCount = 0; - List l = rd.getReportDataList(); - boolean first = true; - for (int dataRow = 0; dataRow < l.size(); dataRow++) { - first = true; - rowCount++; - dr = (DataRow) l.get(dataRow); - Vector rowNames = dr.getRowValues(); - for(dr.resetNext(); dr.hasNext(); ) { - - if(first) { - HtmlFormatter rfmt = dr.getRowFormatter(); - - Font cellFont = FontFactory.getFont(FONT_FAMILY, - FONT_SIZE, - Font.NORMAL, Color.BLACK); - if(rfmt != null) { - cellFormatterFont(rfmt,cellFont); - } - String cellValue = ""; - PdfPCell cell = null; - //String cellValue = new Integer(rowCount).toString(); - //PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); - //row background color can be overwritten by cell background color - //cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); - - //cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); - - //if(rfmt != null) { - //formatterCell(rfmt,cell); - // } - //table.addCell(cell); - if(rowNames!=null) { - for(int i=0; i0) { - table.getDefaultCell().setColspan(rh.getColSpan()); - table.getDefaultCell().setBackgroundColor(getRowBackgroundColor(dr, idx)); - table.addCell(new Paragraph(strip.stripHtml(rh.getRowTitle()),rowHeaderFont)); - } - } - } - - private void addRowColumns(PdfPTable table, DataRow dr, int idx) { - - table.getDefaultCell().setColspan(1); - - for(dr.resetNext();dr.hasNext();) - { - DataValue dv = dr.getNext(); - //System.out.println(columnCount +" --> "+dv); - if(dv.isVisible()) { - HtmlFormatter cfmt = dv.getCellFormatter(); - HtmlFormatter rfmt = dv.getRowFormatter(); - - Font cellFont = FontFactory.getFont(FONT_FAMILY, - FONT_SIZE, - Font.NORMAL, Color.BLACK); - if(cfmt!= null) { - cellFormatterFont(cfmt,cellFont); - } - else if(rfmt != null) { - cellFormatterFont(rfmt,cellFont); - } - else { - if(dv.isBold()) { - cellFont.setStyle(Font.BOLD); - } - } - - String cellValue = strip.stripHtml(dv.getDisplayValue().trim()); - PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); - - //row background color can be overwritten by cell background color - cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); - - if(nvl(dv.getAlignment()).trim().length()>0) - cell.setHorizontalAlignment(ElementTags.alignmentValue(dv.getAlignment())); - else - cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); - - if(cfmt!= null) { - formatterCell(cfmt,cell); - } - else if(rfmt != null) { - formatterCell(rfmt,cell); - } - - table.addCell(cell); - - }//if isVisible() - } - } - - - private void addTotalRowColumns(PdfPTable table, DataRow dr, int idx) { - - table.getDefaultCell().setColspan(1); - dr.resetNext(); - dr.getNext(); - for(;dr.hasNext();) - { - DataValue dv = dr.getNext(); - //System.out.println(columnCount +" --> "+dv); - if(dv.isVisible()) { - HtmlFormatter cfmt = dv.getCellFormatter(); - HtmlFormatter rfmt = dv.getRowFormatter(); - - Font cellFont = FontFactory.getFont(FONT_FAMILY, - FONT_SIZE, - Font.NORMAL, Color.BLACK); - if(cfmt!= null) { - cellFormatterFont(cfmt,cellFont); - } - else if(rfmt != null) { - cellFormatterFont(rfmt,cellFont); - } - else { - if(dv.isBold()) { - cellFont.setStyle(Font.BOLD); - } - } - - String cellValue = strip.stripHtml(dv.getDisplayValue().trim()); - PdfPCell cell = new PdfPCell(new Paragraph(cellValue,cellFont)); - - //row background color can be overwritten by cell background color - cell.setBackgroundColor(getRowBackgroundColor(dr, idx)); - - if(nvl(dv.getAlignment()).trim().length()>0) - cell.setHorizontalAlignment(ElementTags.alignmentValue(dv.getAlignment())); - else - cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER); - - if(cfmt!= null) { - formatterCell(cfmt,cell); - } - else if(rfmt != null) { - formatterCell(rfmt,cell); - } - - table.addCell(cell); - - }//if isVisible() - } - } - - - private void formatterCell(HtmlFormatter fmt, PdfPCell cell) { - - if(nvl(fmt.getBgColor()).trim().length()>0) - cell.setBackgroundColor(Color.decode(fmt.getBgColor())); - if(nvl(fmt.getAlignment()).trim().length()>0) - cell.setHorizontalAlignment(ElementTags.alignmentValue(fmt.getAlignment())); - } - - private void cellFormatterFont(HtmlFormatter fmt, Font font) { - - if(fmt.isBold()) - font.setStyle(Font.BOLD); - if(fmt.isItalic()) - font.setStyle(Font.ITALIC); - if(fmt.isUnderline()) - font.setStyle(Font.UNDERLINE); - if(fmt.getFontColor().trim().length()>0) - font.setColor(Color.decode(fmt.getFontColor())); - if(fmt.getFontSize().trim().length()>0) - font.setSize(Float.parseFloat(fmt.getFontSize())-Globals.getDataFontSizeOffset()); -// if(fmt.getFontFace().trim().length()>0) -// cellFont.setFamily() - - } - - private Color getRowBackgroundColor(DataRow dr, int idx) { - - Color color = Color.decode(Globals.getDataDefaultBackgroundHexCode()); - - HtmlFormatter rhf = dr.getRowFormatter(); - if(rhf!=null && nvl(rhf.getBgColor()).trim().length()>0) - - color = Color.decode(rhf.getBgColor()); - - else if(pb.isAlternateColor() && idx%2==0) - - color = Color.decode(Globals.getDataBackgroundAlternateHexCode()); - - return color; - - } - - private int getTotalVisbleColumns(ReportData rd) { - - int totalVisbleColumn = rd.getTotalColumnCount(); - for(rd.reportDataRows.resetNext();rd.reportDataRows.hasNext();) - { - DataRow dr = rd.reportDataRows.getNext(); - for(dr.resetNext();dr.hasNext();) { - DataValue dv = dr.getNext(); - if(!dv.isVisible()) totalVisbleColumn--; - } - - break; - } - - return totalVisbleColumn; - } - - /* - private int getFirstRowIndex(ReportRuntime rr) { - return (pb.getCurrentPage()>0)?pb.getCurrentPage()*rr.getPageSize()+1 : 1; - } - */ - private float[] getRelativeWidths(ReportData rd, boolean crosstab){ - - int totalColumns = getTotalVisbleColumns(rd); - /*if(rd.reportTotalRowHeaderCols!=null) { - totalColumns += 1; - }*/ - if(crosstab) { - totalColumns += 1; - } - - if(totalColumns == 0 ) - totalColumns=1; - - float[] relativeWidths = new float[totalColumns]; - //initial widths are even - for(int i=0; i0) { - //PdfPTable table = new PdfPTable(1); - table.setWidthPercentage(100f); - table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - table.getDefaultCell().setVerticalAlignment(Rectangle.ALIGN_BOTTOM); - - - Font font = FontFactory.getFont(FONT_FAMILY, - FONT_SIZE-2f, - Font.BOLD, - Color.BLACK); - - //addEmptyRows(table,1); - table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - //table.getDefaultCell().setBackgroundColor(Color.decode(Globals.getDataTableHeaderBackgroundFontColor())); - title = Utils.replaceInString(title, "
        ", " "); - title = Utils.replaceInString(title, "
        ", " "); - title = Utils.replaceInString(title, "
        ", " "); - title = strip.stripHtml(nvl(title).trim()); - //subtitle = Utils.replaceInString(subtitle, "
        ", " "); - //subtitle = Utils.replaceInString(subtitle, "
        ", " "); - //subtitle = Utils.replaceInString(subtitle, "
        ", " "); - //subtitle = strip.stripHtml(nvl(subtitle).trim()); - StyleSheet styles = new StyleSheet(); - - HTMLWorker htmlWorker = new HTMLWorker(document); - ArrayList cc = new ArrayList(); - cc = htmlWorker.parseToList(new StringReader(subtitle), styles); - - Phrase p1 = new Phrase(); - for (int i = 0; i < cc.size(); i++){ - Element elem = (Element)cc.get(i); - ArrayList al = elem.getChunks(); - for (int j = 0; j < al.size(); j++) { - Chunk chunk = (Chunk) al.get(j); - chunk.font().setSize(6.0f); - } - p1.add(elem); - } - //cell = new PdfPCell(p1); - StyleSheet style = new StyleSheet(); - style.loadTagStyle("font", "font-size", "3"); - style.loadTagStyle("font", "size", "3"); - styles.loadStyle("pdfFont1", "size", "11px"); - styles.loadStyle("pdfFont1", "font-size", "11px"); - /*ArrayList p = HTMLWorker.parseToList(new StringReader(nvl(title)), style); - for (int k = 0; k < p.size(); ++k){ - document.add((com.lowagie.text.Element)p.get(k)); - }*/ - //p1.font().setSize(3.0f); - PdfPCell titleCell = new PdfPCell(new Phrase(title, font)); - titleCell.setColspan(rr.getVisibleColumnCount()); - PdfPCell subtitleCell = new PdfPCell(p1); - subtitleCell.setColspan(rr.getVisibleColumnCount()); - titleCell.setHorizontalAlignment(1); - subtitleCell.setHorizontalAlignment(1); - table.addCell(titleCell); - table.addCell(subtitleCell); - //document.add(table); - } - return table; - } - - - private void paintPdfReportFooter(HttpServletRequest request, Document document, ReportRuntime rr, float[] f) - throws DocumentException, IOException { - - HttpSession session = request.getSession(); - String drilldown_index = (String) session.getAttribute("drilldown_index"); - int index = 0; - try { - index = Integer.parseInt(drilldown_index); - } catch (NumberFormatException ex) { - index = 0; - } - - String title = (String) session.getAttribute("FOOTER_"+index); - if(nvl(title).length()>0) { - PdfPTable table = new PdfPTable(1); - table.setWidthPercentage(100f); - table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - table.getDefaultCell().setVerticalAlignment(Rectangle.ALIGN_BOTTOM); - - Font font = FontFactory.getFont(FONT_FAMILY, - FONT_SIZE-3f, - Font.BOLD, - Color.BLACK); - - - //addEmptyRows(table,1); - table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - //table.getDefaultCell().setBackgroundColor(Color.decode(Globals.getDataTableHeaderBackgroundFontColor())); - /*title = Utils.replaceInString(title, "
        ", " "); - title = Utils.replaceInString(title, "
        ", " "); - title = Utils.replaceInString(title, "
        ", " "); - title = strip.stripHtml(nvl(title).trim());*/ - StyleSheet style = new StyleSheet(); - - HTMLWorker htmlWorker = new HTMLWorker(document); - ArrayList cc = new ArrayList(); - cc = htmlWorker.parseToList(new StringReader(title), style); - - Phrase p1 = new Phrase(); - for (int i = 0; i < cc.size(); i++){ - Element elem = (Element)cc.get(i); - ArrayList al = elem.getChunks(); - for (int j = 0; j < al.size(); j++) { - Chunk chunk = (Chunk) al.get(j); - chunk.font().setSize(6.0f); - } - p1.add(elem); - } - -/* - HTMLWorker.parseToList(new StringReader(nvl(title)), style);*/ - PdfPCell titleCell = new PdfPCell(p1); - titleCell.setHorizontalAlignment(Element.ALIGN_LEFT); - table.addCell(titleCell); - //table. - document.add(table); - } - //return table; - } - - - private void paintPdfTableHeader(Document document, ReportData rd, PdfPTable table) - throws DocumentException { - - Font font = FontFactory.getFont(FONT_FAMILY, - FONT_SIZE+1f, - Font.BOLD, - Color.decode(Globals.getDataTableHeaderFontColor())); - //table.setHeaderRows(1); - table.getDefaultCell().setHorizontalAlignment(Rectangle.ALIGN_CENTER); - table.getDefaultCell().setBackgroundColor(Color.decode(Globals.getDataTableHeaderBackgroundFontColor())); - String title = ""; - - boolean firstPass = true; - - /*if(rd.reportTotalRowHeaderCols!=null) { - if(firstPass) { - table.addCell(new Paragraph("No.", font)); - firstPass = false; - } - }*/ - for (rd.reportColumnHeaderRows.resetNext(); rd.reportColumnHeaderRows.hasNext();) - { - if(firstPass) { - for(rd.reportRowHeaderCols.resetNext();rd.reportRowHeaderCols.hasNext();) { - /*if(firstPass) { - table.addCell(new Paragraph("No.", font)); - firstPass = false; - } else {*/ - RowHeaderCol rhc = rd.reportRowHeaderCols.getNext(); - title = rhc.getColumnTitle(); - title = Utils.replaceInString(title,"_nl_", " \n"); - table.addCell(new Paragraph(title,font)); - //} - } - } - - ColumnHeaderRow chr = rd.reportColumnHeaderRows.getNext(); - for (chr.resetNext(); chr.hasNext();) { - ColumnHeader ch = chr.getNext(); - //System.out.println(ch); - if(ch.isVisible()) { - title = ch.getColumnTitle(); - title = Utils.replaceInString(title,"_nl_", " \n"); - table.addCell(new Paragraph(title,font)); - } - } - } - } - - public static String currentTime(String pattern) { - try { - SimpleDateFormat oracleDateFormat = new SimpleDateFormat("MM/dd/yyyy kk:mm:ss"); - Date sysdate = oracleDateFormat.parse(ReportLoader.getSystemDateTime()); - SimpleDateFormat dtimestamp = new SimpleDateFormat(Globals.getScheduleDatePattern()); - return dtimestamp.format(sysdate)+" "+Globals.getTimeZone(); - //paramList.add(new IdNameValue("DATE", dtimestamp.format(sysdate)+" "+Globals.getTimeZone())); - } catch(Exception ex) {} - - SimpleDateFormat s = new SimpleDateFormat(pattern); - s.setTimeZone(TimeZone.getTimeZone(Globals.getTimeZone())); - //System.out.println("^^^^^^^^^^^^^^^^^^^^ " + Calendar.getInstance().getTime()); - //System.out.println("^^^^^^^^^^^^^^^^^^^^ " + s.format(Calendar.getInstance().getTime())); - return s.format(Calendar.getInstance().getTime()); - } - - private PdfBean preparePdfBean(HttpServletRequest request,ReportRuntime rr) { - PdfBean pb = new PdfBean(); - - pb.setUserId(AppUtils.getUserID(request)); - - pb.setWhereToShowPageNumber(Globals.getPageNumberPosition()); - pb.setAlternateColor(Globals.isDataAlternateColor()); - pb.setTimestampPattern(Globals.getDatePattern()); - - int temp = -1; - try { - temp = Integer.parseInt(request.getParameter(AppConstants.RI_NEXT_PAGE)); - } catch (NumberFormatException e) {} - pb.setCurrentPage(temp); - - //pb.setPortrait( trueORfalse(request.getParameter("isPortrait"),true)); - pb.setPortrait(trueORfalse(rr.getPDFOrientation() == "portait"?"true":"false", true)); - //pb.setCoverPageIncluded( trueORfalse(request.getParameter("isCoverPageIncluded"), true)); - //if(Globals.isCoverPageNeeded()) { - pb.setCoverPageIncluded(Globals.isCoverPageNeeded()?rr.isPDFCoverPage():false); - //} - pb.setTitle(nvl(request.getParameter("title"))); - pb.setPagesize(nvls(request.getParameter("pagesize"),"LETTER")); - - pb.setLogo1Url(rr.getPDFLogo1()); - pb.setLogo2Url(rr.getPDFLogo2()); - pb.setLogo1Size(rr.getPDFLogo1Size()); - pb.setLogo2Size(rr.getPDFLogo2Size()); - pb.setFullWebContextPath(request.getSession().getServletContext().getRealPath(File.separator)); - - - pb.setDisplayChart(nvl(rr.getChartType()).trim().length()>0 && rr.getDisplayChart()); - - String id = nvl(request.getParameter("pdfAttachmentKey")).trim(); - String log_id = nvl(request.getParameter("log_id")).trim(); - if(id.length()>0 && log_id.length()>0) - pb.setAttachmentOfEmail(true); - - return pb; - } - - private boolean trueORfalse(String str) { - return (str != null) && (str.equalsIgnoreCase("true")); - } - - private boolean trueORfalse(String str,boolean b_default) { - return str==null ? b_default : (str.equalsIgnoreCase("true")); - } - - -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartD3Helper.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartD3Helper.java deleted file mode 100644 index c46f48ac..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartD3Helper.java +++ /dev/null @@ -1,4064 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.runtime; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.apache.commons.lang.time.DateUtils; -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.model.ReportHandler; -import org.openecomp.portalsdk.analytics.model.base.ChartSeqComparator; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.ConnectionUtils; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.HtmlStripper; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.analytics.view.ReportData; -import org.openecomp.portalsdk.analytics.xmlobj.DataColumnType; -import org.openecomp.portalsdk.analytics.xmlobj.FormFieldType; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.web.support.UserUtils; - -public class ChartD3Helper { - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ChartD3Helper.class); - - - private ReportRuntime reportRuntime; - private String chartType; - - public static final long HOUR = 3600*1000; - public static final long DAY = 3600*1000*24; - public static final long MONTH = 3600*1000*24*31; - public static final long YEAR = 3600*1000*24*365; - - - public ChartD3Helper() { - - } - - /** - * @return the chartType - */ - public String getChartType() { - return chartType; - } - - /** - * @param chartType the chartType to set - */ - public void setChartType(String chartType) { - this.chartType = chartType; - } - - public ChartD3Helper(ReportRuntime rr) { - this.reportRuntime = rr; - } - - public String createVisualization(String reportID, HttpServletRequest request) throws RaptorException { - //From annotations chart - clearReportRuntimeBackup(request); - - //HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest(); - final Long user_id = new Long((long) UserUtils.getUserId(request)); - //String action = request.getParameter(AppConstants.RI_ACTION); - //String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); - - ReportHandler rh = new ReportHandler(); - ReportData reportData = null; - HashMap chartOptionsMap = new HashMap(); - try { - if(reportID !=null) { - reportRuntime = rh.loadReportRuntime(request, reportID, true, 1); - setChartType(reportRuntime.getChartType()); - reportData = reportRuntime.loadReportData(0, user_id.toString(), 10000,request, false); - } - - - - String rotateLabelsStr = ""; - rotateLabelsStr = AppUtils.nvl(reportRuntime.getLegendLabelAngle()); - if(rotateLabelsStr.toLowerCase().equals("standard")) { - rotateLabelsStr = "0"; - } else if (rotateLabelsStr.toLowerCase().equals("up45")) { - rotateLabelsStr = "45"; - } else if (rotateLabelsStr.toLowerCase().equals("down45")) { - rotateLabelsStr = "-45"; - } else if (rotateLabelsStr.toLowerCase().equals("up90")) { - rotateLabelsStr = "90"; - } else if (rotateLabelsStr.toLowerCase().equals("down90")) { - rotateLabelsStr = "-90"; - } else - rotateLabelsStr = "0"; - - String width = (AppUtils.getRequestNvlValue(request, "width").length()>0?AppUtils.getRequestNvlValue(request, "width"):(AppUtils.nvl(reportRuntime.getChartWidth()).length()>0?reportRuntime.getChartWidth():"700")); - String height = (AppUtils.getRequestNvlValue(request, "height").length()>0?AppUtils.getRequestNvlValue(request, "height"):(AppUtils.nvl(reportRuntime.getChartHeight()).length()>0?reportRuntime.getChartHeight():"300")); - String animationStr = (AppUtils.getRequestNvlValue(request, "animation").length()>0?AppUtils.getRequestNvlValue(request, "animation"):new Boolean(reportRuntime.isAnimateAnimatedChart()).toString()); - - String rotateLabels = (AppUtils.getRequestNvlValue(request, "rotateLabels").length()>0?AppUtils.getRequestNvlValue(request, "rotateLabels"):(rotateLabelsStr.length()>0?rotateLabelsStr:"0")); - String staggerLabelsStr = (AppUtils.getRequestNvlValue(request, "staggerLabels").length()>0?AppUtils.getRequestNvlValue(request, "staggerLabels"):"false"); - String showMaxMinStr = (AppUtils.getRequestNvlValue(request, "showMaxMin").length()>0?AppUtils.getRequestNvlValue(request, "showMaxMin"):"false"); - String showControlsStr = (AppUtils.getRequestNvlValue(request, "showControls").length()>0?AppUtils.getRequestNvlValue(request, "showControls"):new Boolean(reportRuntime.displayBarControls()).toString()); - String showLegendStr = (AppUtils.getRequestNvlValue(request, "showLegend").length()>0?AppUtils.getRequestNvlValue(request, "showLegend"):new Boolean(!new Boolean(reportRuntime.hideChartLegend())).toString()); - String topMarginStr = AppUtils.getRequestNvlValue(request, "topMargin"); - String topMargin = (AppUtils.nvl(topMarginStr).length()<=0)?(reportRuntime.getTopMargin()!=null?reportRuntime.getTopMargin().toString():"30"):topMarginStr; - String bottomMarginStr = AppUtils.getRequestNvlValue(request, "bottomMargin"); - String bottomMargin = (AppUtils.nvl(bottomMarginStr).length()<=0)?(reportRuntime.getBottomMargin()!=null?reportRuntime.getBottomMargin().toString():"50"):bottomMarginStr; - String leftMarginStr = AppUtils.getRequestNvlValue(request, "leftMargin"); - String leftMargin = (AppUtils.nvl(leftMarginStr).length()<=0)?(reportRuntime.getLeftMargin()!=null?reportRuntime.getLeftMargin().toString():"100"):leftMarginStr; - String rightMarginStr = AppUtils.getRequestNvlValue(request, "rightMargin"); - String rightMargin = (AppUtils.nvl(rightMarginStr).length()<=0)?(reportRuntime.getRightMargin()!=null?reportRuntime.getRightMargin().toString():"160"):rightMarginStr; - String showTitleStr = (AppUtils.getRequestNvlValue(request, "showTitle").length()>0?AppUtils.getRequestNvlValue(request, "showTitle"):new Boolean(reportRuntime.displayChartTitle()).toString()); - String subType = AppUtils.getRequestNvlValue(request, "subType").length()>0?AppUtils.getRequestNvlValue(request, "subType"):(AppUtils.nvl(reportRuntime.getTimeSeriesRender()).equals("area")?reportRuntime.getTimeSeriesRender():""); - String stackedStr = AppUtils.getRequestNvlValue(request, "stacked").length()>0?AppUtils.getRequestNvlValue(request, "stacked"):new Boolean(reportRuntime.isChartStacked()).toString(); - String horizontalBar = AppUtils.getRequestNvlValue(request, "horizontalBar").length()>0?AppUtils.getRequestNvlValue(request, "horizontalBar"):new Boolean(reportRuntime.isHorizontalOrientation()).toString(); - String barRealTimeAxis = AppUtils.getRequestNvlValue(request, "barRealTimeAxis"); - String barReduceXAxisLabels = AppUtils.getRequestNvlValue(request, "barReduceXAxisLabels").length()>0?AppUtils.getRequestNvlValue(request, "barReduceXAxisLabels"):new Boolean(reportRuntime.isLessXaxisTickers()).toString();; - String timeAxis = AppUtils.getRequestNvlValue(request, "timeAxis").length()>0?AppUtils.getRequestNvlValue(request, "timeAxis"):new Boolean(reportRuntime.isTimeAxis()).toString(); - String logScale = AppUtils.getRequestNvlValue(request, "logScale").length()>0?AppUtils.getRequestNvlValue(request, "logScale"):new Boolean(reportRuntime.isLogScale()).toString(); - String precision = AppUtils.getRequestNvlValue(request, "precision").length()>0?AppUtils.getRequestNvlValue(request, "precision"):"2"; - - - chartOptionsMap.put("width", width); - chartOptionsMap.put("height", height); - chartOptionsMap.put("animation", animationStr); - chartOptionsMap.put("rotateLabels", rotateLabels); - chartOptionsMap.put("staggerLabels", staggerLabelsStr); - chartOptionsMap.put("showMaxMin", showMaxMinStr); - chartOptionsMap.put("showControls", showControlsStr); - chartOptionsMap.put("showLegend", showLegendStr); - chartOptionsMap.put("topMargin", topMargin); - chartOptionsMap.put("bottomMargin", bottomMargin); - chartOptionsMap.put("leftMargin", leftMargin); - chartOptionsMap.put("rightMargin", rightMargin); - chartOptionsMap.put("showTitle", showTitleStr); - chartOptionsMap.put("subType", subType); - chartOptionsMap.put("stacked", stackedStr); - chartOptionsMap.put("horizontalBar", horizontalBar); - chartOptionsMap.put("timeAxis", timeAxis); - chartOptionsMap.put("barRealTimeAxis", barRealTimeAxis); - chartOptionsMap.put("barReduceXAxisLabels", barReduceXAxisLabels); - - chartOptionsMap.put("logScale", logScale); - chartOptionsMap.put("precision", precision); - - - } catch (RaptorException ex) { - ex.printStackTrace(); - } - return createVisualization(reportRuntime, chartOptionsMap, request); - } - - public String createVisualization(ReportRuntime reportRuntime, HttpServletRequest request) throws RaptorException { - - String rotateLabelsStr = ""; - rotateLabelsStr = AppUtils.nvl(reportRuntime.getLegendLabelAngle()); - if(rotateLabelsStr.toLowerCase().equals("standard")) { - rotateLabelsStr = "0"; - } else if (rotateLabelsStr.toLowerCase().equals("up45")) { - rotateLabelsStr = "45"; - } else if (rotateLabelsStr.toLowerCase().equals("down45")) { - rotateLabelsStr = "-45"; - } else if (rotateLabelsStr.toLowerCase().equals("up90")) { - rotateLabelsStr = "90"; - } else if (rotateLabelsStr.toLowerCase().equals("down90")) { - rotateLabelsStr = "-90"; - } else - rotateLabelsStr = "0"; - - HashMap chartOptionsMap = new HashMap(); - chartOptionsMap.put("width", reportRuntime.getChartWidth()); - chartOptionsMap.put("height", reportRuntime.getChartHeight()); - chartOptionsMap.put("animation", new Boolean(reportRuntime.isAnimateAnimatedChart()).toString()); - chartOptionsMap.put("rotateLabels", rotateLabelsStr); - chartOptionsMap.put("staggerLabels", "false"); - chartOptionsMap.put("showMaxMin", "false"); - chartOptionsMap.put("showControls", new Boolean(reportRuntime.displayBarControls()).toString()); - chartOptionsMap.put("showLegend", new Boolean(!reportRuntime.hideChartLegend()).toString()); - chartOptionsMap.put("topMargin", reportRuntime.getTopMargin()!=null?reportRuntime.getTopMargin().toString():"30"); - chartOptionsMap.put("bottomMargin", reportRuntime.getBottomMargin()!=null?reportRuntime.getBottomMargin().toString():"50"); - chartOptionsMap.put("leftMargin", reportRuntime.getLeftMargin()!=null?reportRuntime.getLeftMargin().toString():"100"); - chartOptionsMap.put("rightMargin", reportRuntime.getRightMargin()!=null?reportRuntime.getRightMargin().toString():"160"); - chartOptionsMap.put("showTitle", new Boolean(reportRuntime.displayChartTitle()).toString()); - chartOptionsMap.put("subType", (AppUtils.nvl(reportRuntime.getTimeSeriesRender()).equals("area")?reportRuntime.getTimeSeriesRender():"")); - chartOptionsMap.put("stacked", new Boolean(reportRuntime.isChartStacked()).toString()); - chartOptionsMap.put("horizontalBar", new Boolean(reportRuntime.isHorizontalOrientation()).toString()); - chartOptionsMap.put("timeAxis", new Boolean(reportRuntime.isTimeAxis()).toString()); - chartOptionsMap.put("barReduceXAxisLabels", new Boolean(reportRuntime.isLessXaxisTickers()).toString()); - - chartOptionsMap.put("logScale", new Boolean(reportRuntime.isLogScale()).toString()); - chartOptionsMap.put("precision", "2"); - - - - return createVisualization(reportRuntime, chartOptionsMap, request); - } - - public String createVisualization(ReportRuntime reportRuntime, HashMap chartOptionsMap, HttpServletRequest request) throws RaptorException { - - //String width, String height, boolean animation, String rotateLabels, boolean staggerLabels, boolean showMaxMin, boolean showLegend, boolean showControls, String topMargin, String bottomMargin, boolean showTitle, String subType - - String width = chartOptionsMap.get("width"); - String height = chartOptionsMap.get("height"); - boolean animation = getBooleanValue(chartOptionsMap.get("animation"), true); - String rotateLabels = chartOptionsMap.get("rotateLabels"); - boolean staggerLabels = getBooleanValue(chartOptionsMap.get("staggerLabels")); - boolean showMaxMin = getBooleanValue(chartOptionsMap.get("showMaxMin"), false); - boolean showLegend = getBooleanValue(chartOptionsMap.get("showLegend"), true); - boolean showControls = getBooleanValue(chartOptionsMap.get("showControls"), true); - String topMargin = chartOptionsMap.get("topMargin"); - String bottomMargin = chartOptionsMap.get("bottomMargin"); - String leftMargin = chartOptionsMap.get("leftMargin"); - String rightMargin = chartOptionsMap.get("rightMargin"); - boolean showTitle = getBooleanValue(chartOptionsMap.get("showTitle"), true); - String subType = chartOptionsMap.get("subType"); - boolean stacked = getBooleanValue(chartOptionsMap.get("stacked"), false); - boolean horizontalBar = getBooleanValue(chartOptionsMap.get("horizontalBar"), false); - boolean barRealTimeAxis = getBooleanValue(chartOptionsMap.get("barRealTimeAxis"), true); - boolean barReduceXAxisLabels= getBooleanValue(chartOptionsMap.get("barReduceXAxisLabels"), false); - boolean timeAxis = getBooleanValue(chartOptionsMap.get("timeAxis"), true); - - - boolean logScale = getBooleanValue(chartOptionsMap.get("logScale"), false); - - int precision = 2; - - try { - precision = Integer.parseInt(chartOptionsMap.get("precision")); - } catch (NumberFormatException ex) { - - } - - final Long user_id = new Long((long) UserUtils.getUserId(request)); - - HttpSession session = null; - session = request.getSession(); - - String chartType = reportRuntime.getChartType(); - List l = reportRuntime.getAllColumns(); - List lGroups = reportRuntime.getAllChartGroups(); - HashMap mapYAxis = reportRuntime.getAllChartYAxis(reportRuntime.getReportParamValues()); - //ReportParamValues reportParamValues = reportRuntime.getReportParamValues(); - String chartLeftAxisLabel = reportRuntime.getFormFieldFilled(nvl(reportRuntime.getChartLeftAxisLabel())); - String chartRightAxisLabel = reportRuntime.getFormFieldFilled(nvl(reportRuntime.getChartRightAxisLabel())); - - boolean multipleSeries = reportRuntime.isMultiSeries(); - - java.util.HashMap formValues = null; - formValues = getRequestParametersMap(reportRuntime, request); - - - String legendColumnName = (reportRuntime.getChartLegendColumn()!=null)?reportRuntime.getChartLegendColumn().getDisplayName():"Legend Column"; - boolean displayChart = (nvl(chartType).length()>0)&&reportRuntime.getDisplayChart(); - HashMap additionalChartOptionsMap = new HashMap(); - - StringBuffer wholeScript = new StringBuffer(""); - - String title = reportRuntime.getReportTitle(); - - title = parseTitle(title, formValues); - - if(displayChart) { - DataSet ds = null; - try { - if (!(chartType.equals(AppConstants.GT_HIERARCHICAL) || chartType.equals(AppConstants.GT_HIERARCHICAL_SUNBURST) || chartType.equals(AppConstants.GT_ANNOTATION_CHART))) { - ds = (DataSet) loadChartData(new Long(user_id).toString(), request); - } else if(chartType.equals(AppConstants.GT_ANNOTATION_CHART)) { - String reportSQL = reportRuntime.getWholeSQL(); - String dbInfo = reportRuntime.getDBInfo(); - ds = ConnectionUtils.getDataSet(reportSQL, dbInfo); - if(ds.getRowCount()<=0) { - logger.debug(EELFLoggerDelegate.debugLogger, ("********************************************************************************")); - logger.debug(EELFLoggerDelegate.debugLogger, (chartType.toUpperCase()+" - " + "Report ID : " + reportRuntime.getReportID() + " DATA IS EMPTY")); - logger.debug(EELFLoggerDelegate.debugLogger, ("QUERY - " + reportSQL)); - logger.debug(EELFLoggerDelegate.debugLogger, ("********************************************************************************")); - } - } else if(chartType.equals(AppConstants.GT_HIERARCHICAL)||chartType.equals(AppConstants.GT_HIERARCHICAL_SUNBURST)) { - String reportSQL = reportRuntime.getWholeSQL(); - String dbInfo = reportRuntime.getDBInfo(); - ds = ConnectionUtils.getDataSet(reportSQL, dbInfo); - } - } catch (RaptorException ex) { - //throw new RaptorException("Error while loading chart data", ex); - logger.error(EELFLoggerDelegate.debugLogger, ("********************************************************************************")); - logger.error(EELFLoggerDelegate.debugLogger, (chartType.toUpperCase()+" - " + "Report ID : " + reportRuntime.getReportID() + " ERROR THROWN FOR GIVEN QUERY ")); - logger.error(EELFLoggerDelegate.debugLogger, ("QUERY - " + reportRuntime.getWholeSQL())); - logger.error(EELFLoggerDelegate.debugLogger, ("ERROR STACK TRACE" + ex.getMessage())); - logger.error(EELFLoggerDelegate.debugLogger, ("********************************************************************************")); - - } - if(ds==null) { - //displayChart = false; - if(chartType.equals(AppConstants.GT_ANNOTATION_CHART)) - ds = new DataSet(); - else - displayChart = false; - } - if(displayChart) { - - if (chartType.equals(AppConstants.GT_BAR_3D)) { - - // get category if not give the column name for the data column use this to develop series. - boolean hasCategoryAxis = reportRuntime.hasSeriesColumn(); - - boolean hasCustomizedChartColor = false; - int flag = 0; - flag = hasCategoryAxis?1:0; - Object uniqueElements [] = null; - ArrayList uniqueElementsList = new ArrayList(); - Object uniqueXAxisElements[] = null; - ArrayList ts = new ArrayList(); - //Set ts1 = new HashSet(); - ArrayList ts1 = new ArrayList(); - HashMap columnMap = new HashMap(); - String uniqueXAxisStr = ""; - if(!timeAxis){ - for (int i = 0; i < ds.getRowCount(); i++) { - uniqueXAxisStr = ds.getString(i, 0); - ts1.add(uniqueXAxisStr); - } - } - uniqueElementsList.addAll(ts1); - uniqueXAxisElements = ts1.toArray(); - - if(flag == 1) { - StringBuffer catStr = new StringBuffer(""); - String color=""; - for (int i = 0; i < ds.getRowCount(); i++) { - catStr = new StringBuffer(""); - catStr.append(ds.getString(i, 2)); - try { - if(ds.getString(i, "chart_color")!=null) { - color = ds.getString(i, "chart_color"); - hasCustomizedChartColor = true; - catStr.append("|"+color); - } - } catch (ArrayIndexOutOfBoundsException ex) { - //System.out.println("No Chart Color"); - } - - if(catStr.length()>0) { - //duplicates are avoided - if(!ts.contains(catStr.toString())) - ts.add(catStr.toString()); - - } - /* Get Chart LeftAxis Label even from Range Axis definition. */ - DataColumnType dct = null; - for (Iterator iter = l.iterator(); iter.hasNext();) { - dct = (DataColumnType) iter.next(); - if(!(nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND))) { - if(nvl(chartLeftAxisLabel).length()<=0) { - chartLeftAxisLabel = nvl(dct.getYAxis()); - chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; - } - } - } - - } - //Object uniqueElements [] = ts.toArray(); - //SortedSet s = Collections.synchronizedSortedSet(ts); - uniqueElements = ts.toArray(); - } else { - DataColumnType dct = null; - List yTextSeries = reportRuntime.getChartDisplayNamesList(AppConstants.CHART_ALL_COLUMNS, formValues); - //if(columnValuesList.size() == 1) { - for (Iterator iter = l.iterator(); iter.hasNext();) { - dct = (DataColumnType) iter.next(); - - if(!(nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND))) { - if((dct.isChartSeries()!=null && dct.isChartSeries().booleanValue()) || (dct.getChartSeq()!=null && dct.getChartSeq()>0) ) { - - if(nvl(dct.getChartColor()).length()>0) hasCustomizedChartColor = true; - if(hasCustomizedChartColor) { - //duplicates are avoided - if(!ts.contains(dct.getDisplayName()+"|"+nvl(dct.getChartColor()))) - ts.add(dct.getDisplayName()+"|"+nvl(dct.getChartColor())); - } else { - //duplicates are avoided - if(!ts.contains(dct.getDisplayName())) - ts.add(dct.getDisplayName()); - } - if(nvl(chartLeftAxisLabel).length()<=0) { - chartLeftAxisLabel = nvl(dct.getYAxis()); - chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; - } - columnMap.put(dct.getDisplayName(), dct.getColId()); - /* - ts.add(dct.getDisplayName()); - if(nvl(chartLeftAxisLabel).length()<=0) { - chartLeftAxisLabel = nvl(dct.getYAxis()); - chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; - } - columnMap.put(dct.getDisplayName(), dct.getColId()); - */ - } - } - - } - //SortedSet s = Collections.synchronizedSortedSet(ts); - uniqueElements = ts.toArray(); - - } - - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - //wholeScript.append("") - wholeScript.append(" \n" ); - wholeScript.append(" \n"); - if(showTitle) - wholeScript.append("

        " + title +"

        "); - - wholeScript.append("
        \n"); - //js files - wholeScript.append(""); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - //wholeScript.append(" \n"); - //wholeScript.append(" \n"); - wholeScript.append(" \n"); - //json - wholeScript.append(" \n"); - - } else if (chartType.equals(AppConstants.GT_TIME_SERIES)) { - - // get category if not give the column name for the data column use this to develop series. - boolean hasCategoryAxis = reportRuntime.hasSeriesColumn(); - - - final int YEARFLAG = 1; - final int MONTHFLAG = 2; - final int DAYFLAG = 3; - final int HOURFLAG = 4; - final int MINFLAG = 5; - final int SECFLAG = 6; - final int MILLISECFLAG = 7; - final int DAYOFTHEWEEKFLAG = 8; - final int FLAGDATE = 9; - - int flag = 0; - flag = hasCategoryAxis?1:0; - String uniqueElements [] = null; - //TreeSet ts = new TreeSet(); - ArrayList ts = new ArrayList(); - HashMap columnMap = new HashMap(); - //check timeAxis - String dateStr = null; - java.util.Date date = null; - if( ds.getRowCount() > 0) { - dateStr = ds.getString(0, 1); - if(!timeAxis) { - date = getDateFromDateStr(dateStr); - if(date!=null) { - reportRuntime.setTimeAxis(true); - timeAxis = reportRuntime.isTimeAxis(); - - - } - } - } - - ArrayList ts1 = new ArrayList(); - ArrayList uniqueElementsList = new ArrayList(); - Object uniqueXAxisElements[] = null; - String uniqueXAxisStr = ""; - if(!timeAxis){ - for (int i = 0; i < ds.getRowCount(); i++) { - uniqueXAxisStr = ds.getString(i, 0); - ts1.add(uniqueXAxisStr); - } - } - uniqueElementsList.addAll(ts1); - uniqueXAxisElements = ts1.toArray(); - //test start - /* int TOTAL = 0; - int VALUE = 0; - int flagNull = 0; - String KEY = ""; - String COLOR = ""; - TreeSet colorList = new TreeSet(); - for (int i = 0; i < ds.getRowCount(); i++) { - VALUE = 0; - try { - VALUE = Integer.parseInt(ds.getString(i, 2)); - TOTAL = TOTAL+VALUE; - } catch (NumberFormatException ex) { - flagNull = 1; - } - KEY = ds.getString(i, 0); - try { - if(ds.getString(i, "chart_color")!=null) { - colorList.add(KEY+"|"+ds.getString(i, "chart_color")); - } - } catch (ArrayIndexOutOfBoundsException ex) { - System.out.println("No Chart Color"); - } - wholeScript.append("{ \""+ "key" +"\":\""+ KEY+"\", \""+ "y" +"\":"+VALUE+"}, \n"); - - } - StringBuffer color = new StringBuffer(""); - if(colorList.size()>0) { - SortedSet s = Collections.synchronizedSortedSet(colorList); - Object[] colorElements = (Object[]) s.toArray(); - - String element = ""; - - for (int i = 0; i < colorElements.length; i++) { - element = ((String)colorElements[i]); - color.append("'"+element.substring(element.indexOf("|")+1)+"',"); - } - color.deleteCharAt(color.length()-1); - }*/ - - //test end - boolean hasCustomizedChartColor = false; - if(flag == 1) { - StringBuffer catStr = new StringBuffer(""); - String color=""; - for (int i = 0; i < ds.getRowCount(); i++) { - catStr = new StringBuffer(""); - catStr.append(ds.getString(i, 2)); - try { - if(ds.getString(i, "chart_color")!=null) { - color = ds.getString(i, "chart_color"); - hasCustomizedChartColor = true; - catStr.append("|"+color); - } - } catch (ArrayIndexOutOfBoundsException ex) { - //System.out.println("No Chart Color"); - } - - if(catStr.length()>0) { - //duplicates are avoided - if(!ts.contains(catStr.toString())) - ts.add(catStr.toString()); - - } - } - //Object uniqueElements [] = ts.toArray(); - //SortedSet s = Collections.synchronizedSortedSet(ts); - //uniqueElements = (String[]) ts.toArray(); - DataColumnType dct = null; - List yTextSeries = reportRuntime.getChartDisplayNamesList(AppConstants.CHART_ALL_COLUMNS, formValues); - if(yTextSeries.size()==1) { - for (Iterator iter = l.iterator(); iter.hasNext();) { - dct = (DataColumnType) iter.next(); - //System.out.println(dct.getDisplayName() + " " + yText); - if(!(nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND))) { - if(nvl(chartLeftAxisLabel).length()<=0) { - chartLeftAxisLabel = nvl(dct.getYAxis()); - chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; - } - } - } - } - Object tempArray[] = ts.toArray(); - uniqueElements = Arrays.copyOf(tempArray, tempArray.length, String[].class); - - } else { - DataColumnType dct = null; - - List yTextSeries = reportRuntime.getChartDisplayNamesList(AppConstants.CHART_ALL_COLUMNS, formValues); - //if(columnValuesList.size() == 1) { - int dctIndex = 0; - for (Iterator iter = l.iterator(); iter.hasNext();) { - dct = (DataColumnType) iter.next(); - //System.out.println(dct.getDisplayName() + " " + yText); - if(!(nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND))) { - if(yTextSeries.contains((String)dct.getDisplayName())) { - if(nvl(dct.getChartColor()).length()>0) hasCustomizedChartColor = true; - if(hasCustomizedChartColor) { - //duplicates are avoided - if(!ts.contains(dct.getDisplayName()+"|"+nvl(dct.getChartColor()))) - ts.add(dct.getDisplayName()+"|"+nvl(dct.getChartColor())); - } else { - //duplicates are avoided - if(!ts.contains(dct.getDisplayName())) - ts.add(dct.getDisplayName()); - } - if(nvl(chartLeftAxisLabel).length()<=0) { - chartLeftAxisLabel = nvl(dct.getYAxis()); - chartLeftAxisLabel = (chartLeftAxisLabel.indexOf("|")!=-1)?chartLeftAxisLabel.substring(0,chartLeftAxisLabel.indexOf("|")):""; - } - if(nvl(chartRightAxisLabel).length()>0) { - String dctYAxis = nvl(dct.getYAxis()); - String yAxis = (dctYAxis.indexOf("|")!=-1)?dctYAxis.substring(0,dctYAxis.indexOf("|")):dctYAxis; - if(chartRightAxisLabel.equals(yAxis)) { - if(ts.contains(dct.getDisplayName())) { - if(hasCustomizedChartColor) { - ts.set(dctIndex, dct.getDisplayName()+"|R|"+nvl(dct.getChartColor())); - } else { - ts.set(dctIndex, dct.getDisplayName()+"|R"); - } - } - } - } - columnMap.put(dct.getDisplayName(), dct.getColId()); - } - dctIndex++; - } - - } - - //SortedSet s = Collections.synchronizedSortedSet(ts); - Object tempArray[] = ts.toArray(); - uniqueElements = Arrays.copyOf(tempArray, tempArray.length, String[].class); - //uniqueElements = (String[]) ts.toArray(); - - } - - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append(" \n" ); - - wholeScript.append(" \n"); - - if(showTitle) - wholeScript.append("

        " + title +"

        "); - - - wholeScript.append("
        \n"); - //js files - wholeScript.append("\n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - //wholeScript.append(" \n"); - //if(multipleSeries) - //wholeScript.append(" \n"); - - //json - wholeScript.append(" \n"); - - } else if (chartType.equals(AppConstants.GT_PIE) || chartType.equals(AppConstants.GT_PIE_3D)) { - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append(" \n" ); - wholeScript.append(" \n"); - - if(showTitle) - wholeScript.append("

        " + title +"

        "); - - wholeScript.append("
        "); - //"\n"); - //js files - wholeScript.append("\n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - - } else if (chartType.equals(AppConstants.GT_ANNOTATION_CHART) || chartType.equals(AppConstants.GT_FLEX_TIME_CHARTS)) { - - boolean timeCharts = chartType.equals(AppConstants.GT_FLEX_TIME_CHARTS); - - String dateStr = null; - java.util.Date date = null; - - final int YEARFLAG = 1; - final int MONTHFLAG = 2; - final int DAYFLAG = 3; - final int HOURFLAG = 4; - final int MINFLAG = 5; - final int SECFLAG = 6; - final int MILLISECFLAG = 7; - final int DAYOFTHEWEEKFLAG = 8; - final int FLAGDATE = 9; - - int flagNoDate = 0; - - int MAXNUM = 0; - int YAXISNUM = 0; - int flagNull = 0; - - double YAXISDOUBLENUM = 0.0; - double MAXDOUBLENUM = 0.0; - int MAXNUMDECIMALPLACES = 0; - - int formatFlag = 0; - - TreeSet dateStrList = new TreeSet(); - // added to store all date elements - SortedSet sortSet = new TreeSet(); - int count = 0; - - int flag = 0; - boolean hasCategoryAxis = reportRuntime.hasSeriesColumn(); - flag = hasCategoryAxis?1:0; - - - String anomalyText = ""; - - StringBuffer dataStrBuf = new StringBuffer(""); - StringBuffer annotationsStrBuf = new StringBuffer(""); - - String xAxisLabel = (reportRuntime.getChartLegendColumn()!=null)?reportRuntime.getChartLegendColumn().getDisplayName():""; - - //finding actual string - String actualText = ""; - DataColumnType dct = null; - for (Iterator iter = l.iterator(); iter.hasNext();) { - dct = (DataColumnType) iter.next(); - if((dct.getChartSeq()!=null && dct.getChartSeq() >=0) && !AppUtils.nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND)) { - //if(AppUtils.nvl(dct.getDisplayName()).toLowerCase().contains("actual")) { - actualText = dct.getDisplayName(); - break; - //} - } - } - - int anomalyRec = 0; - int columnIndex = 1; - ArrayList columnNames = new ArrayList(); - ArrayList columnValues = new ArrayList(); - Set set = null; - String columnName = ""; - String columnValue = ""; - long minDate = 0L; - long maxDate = 0L; - StringBuffer seriesBuffer = new StringBuffer(""); - - for (int i = 0; i < ds.getRowCount(); i++) { - columnNames = new ArrayList(); - columnValues = new ArrayList(); - columnName = ""; - columnValue = ""; - columnIndex = 1; - anomalyText = ""; - dateStr = ds.getString(i, 0); - date = getDateFromDateStr(dateStr); - if(date.getTime() > maxDate ) - maxDate = date.getTime(); - - formatFlag = getFlagFromDateStr(dateStr); - - - for (;columnIndex=0) && !AppUtils.nvl(dct.getColOnChart()).equals(AppConstants.GC_LEGEND)) { - if((!timeCharts && !AppUtils.nvl(dct.getColId()).toLowerCase().equals("anomaly_text")) && AppUtils.nvl(dct.getColId()).toLowerCase().equals(columnName.toLowerCase())) { - dataStrBuf.append(","+columnValue); - break; - } else if(timeCharts && AppUtils.nvl(dct.getColId()).toLowerCase().equals(columnName.toLowerCase())){ - dataStrBuf.append(","+columnValue); - //break; - } - } - } - } - - dataStrBuf.append("],\n"); - if(!timeCharts) { - if(AppUtils.nvl(anomalyText).length()>0) { - ++anomalyRec; - annotationsStrBuf.append("anns.push( {\n"); - annotationsStrBuf.append(" series: '"+actualText+"',\n"); - annotationsStrBuf.append(" x: moment(\""+dateStr+"\"),\n"); - annotationsStrBuf.append(" shortText: '"+ IntToLetter(anomalyRec).toUpperCase() +"',\n"); - annotationsStrBuf.append(" text: '"+ anomalyText + "'\n"); - annotationsStrBuf.append("});\n"); - //anomalyRec++; - } - - } - } - - //if(!timeCharts) - //anomalyRec = anomalyRec - 1; - - minDate = maxDate - (new Long(reportRuntime.getZoomIn()).longValue()*60*60*1000); - System.out.println(new java.util.Date(maxDate) + " " + new java.util.Date(minDate) + " " + reportRuntime.getZoomIn()); - if(dataStrBuf.lastIndexOf(",")!= -1) - dataStrBuf.deleteCharAt(dataStrBuf.lastIndexOf(",")); - - wholeScript = new StringBuffer(""); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append(" \n"); - //wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append("\n"); - - wholeScript.append("\n "); - wholeScript.append("\n"); - wholeScript.append("\n"); - wholeScript.append(" \n"); - -/* if(showTitle) - wholeScript.append("

        " + (AppUtils.nvl(reportRuntime.getReportTitle()).length()>0?reportRuntime.getReportTitle():reportRuntime.getReportName()) + "

        \n"); -*/ - wholeScript.append(" \n"); - if(showTitle) { - wholeScript.append(" \n "); - wholeScript.append(" \n "); - } - - wholeScript.append(" \n "); - - wholeScript.append(" \n "); - wholeScript.append(" \n "); - - wholeScript.append(" \n "); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - if(AppUtils.nvl(reportRuntime.getLegendPosition()).length()>=0 && reportRuntime.getLegendPosition().equals("right")) { - wholeScript.append(" \n"); - } - wholeScript.append(" \n"); - if(anomalyRec > 0) { - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - } - wholeScript.append("
        \n "); - wholeScript.append("
        "+title+"
        \n"); - wholeScript.append("
        \n "); - if(AppUtils.nvl(reportRuntime.getLegendPosition()).length()<=0 || reportRuntime.getLegendPosition().equals("top")) { - wholeScript.append("
        \n"); - } - wholeScript.append("
        \n"); - wholeScript.append("
        \n"); - - int heightInt = 0; - if(nvl(height).length() > 0) { - try { - heightInt = new Integer(height).intValue(); - heightInt -= 50; - } catch(Exception ex) { - if(height.endsWith("px")) { - try { - heightInt = new Integer(height.substring(0, height.indexOf("px"))); - heightInt -= 50; - } catch (Exception ex1) { - heightInt = 420; - } - } else { - heightInt = 420; - } - } - } else heightInt = 420; - if(AppUtils.nvl(reportRuntime.getLegendPosition()).length()>=0 && reportRuntime.getLegendPosition().equals("right")) { - wholeScript.append("
        \n"); - wholeScript.append("
        \n"); - wholeScript.append("
        \n"); - wholeScript.append("
        \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n" ); - wholeScript.append(" \n"); - wholeScript.append("
        Anomaly Description
        \n"); - wholeScript.append("
        \n"); - - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(""); - - - } else if (chartType.equals(AppConstants.GT_SCATTER)) { - - wholeScript.append("\n"); - wholeScript.append(" \n" ); - wholeScript.append(" \n"); - wholeScript.append("
        "); - //js files - wholeScript.append("\n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append(" \n"); - wholeScript.append("\n"); - } else if (chartType.equals(AppConstants.GT_HIERARCHICAL_SUNBURST)) { - - StringBuffer dataStr = new StringBuffer(""); - StringBuffer groupBuffer = new StringBuffer(""); - StringBuffer s = new StringBuffer(""); - dataStr.append("{"); - dataStr.append(" \"ss4262\":{\n"); - String mid = ""; - String mid_old = ""; - String level = "-1"; - String level_old = "-1"; - String eid = ""; - for (int i = 0; i < ds.getRowCount(); i++) { - mid = ds.getString(i, "mid"); - level = ds.getString(i, "level1"); - eid = ds.getString(i, "eid"); - if(mid.equals(mid_old)) { - dataStr.append("\""+ eid +"\": 9956,\n"); - } else { - if(dataStr.lastIndexOf(",")!= -1) - dataStr.deleteCharAt(dataStr.lastIndexOf(",")); - //if(Integer.parseInt(level_old)==Integer.parseInt(level)) - //dataStr.append("},\n"); - if (Integer.parseInt(level_old)0) { - /*sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( - paramValue, "NULL"));*/ - reportSQL = Utils.replaceInString(reportSQL, fieldDisplay, nvl( - paramValue, "NULL")); - } - /*sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( - paramValue, "NULL"));*/ - reportSQL = Utils.replaceInString(reportSQL, "'" + fieldDisplay + "'", nvl( - paramValue, "NULL")); - reportSQL = Utils.replaceInString(reportSQL, fieldDisplay , nvl( - paramValue, "NULL")); - } - } - logger.debug(EELFLoggerDelegate.debugLogger, ("SQL " + reportSQL)); - String legendCol = "1 a"; - // String valueCol = "1"; - StringBuffer groupCol = new StringBuffer(); - StringBuffer seriesCol = new StringBuffer(); - StringBuffer valueCols = new StringBuffer(); - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, request); - if (nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) - legendCol = getSelectExpr(dc, colName)+" " + dc.getColId(); - // if(dc.getChartSeq()>0) - // valueCol = "NVL("+colName+", 0) "+dc.getColId(); - if ((!nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND)) - && (dc.getChartSeq()!=null && dc.getChartSeq().intValue() <= 0) && dc.isGroupBreak()) { - groupCol.append(", "); - groupCol.append(colName + " " + dc.getColId()); - } - } // for - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if(dc.isChartSeries()!=null && dc.isChartSeries().booleanValue()) { - //System.out.println("*****************, "+ " " +getColumnSelectStr(dc, paramValues)+ " "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))); - seriesCol.append(", "+ getSelectExpr(dc,getColumnSelectStr(dc, request))+ " " + dc.getColId()); - } - } - - /*for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - if(!dc.isChartSeries() && !(nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND))) { - //System.out.println("*****************, "+ " " +getColumnSelectStr(dc, paramValues)+ " "+ getSelectExpr(dc,getColumnSelectStr(dc, paramValues))); - seriesCol.append(", "+ formatChartColumn(getSelectExpr(dc,getColumnSelectStr(dc, paramValues)))+ " " + dc.getColId()); - } - }*/ - - for (Iterator iter = chartValueCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, request); - String paramValue = ""; - if(AppUtils.nvl(colName).startsWith("[")) { - if (reportRuntime.getFormFieldList() != null) { - for (Iterator iterC = reportRuntime.getFormFieldList().getFormField().iterator(); iterC.hasNext();) { - FormFieldType fft = (FormFieldType) iterC.next(); - String fieldId = fft.getFieldId(); - String fieldDisplay = reportRuntime.getFormFieldDisplayName(fft); - String formfield_value = ""; - if(AppUtils.nvl(fieldDisplay).equals(colName)) { - formfield_value = AppUtils.getRequestNvlValue(request, fieldId); - paramValue = nvl(formfield_value); - } - } - - } - - seriesCol.append("," + (AppUtils.nvl(paramValue).length()>0? paramValue:"null") + " " + dc.getColId()); - } else { - //valueCols.append(", NVL(" + formatChartColumn(colName) + ",0) " + dc.getColId()); - seriesCol.append("," + (AppUtils.nvl(paramValue).length()>0? paramValue:formatChartColumn(colName)) + " " + dc.getColId()); - } - } // for - - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = dc.getDisplayName(); - String colValue = getColumnSelectStr(dc, request); - //String colName = getColumnSelectStr(dc, formGrid); - if(colName.equals(AppConstants.RI_CHART_TOTAL_COL)) - seriesCol.append(", " + AppConstants.RI_CHART_TOTAL_COL + " " + AppConstants.RI_CHART_TOTAL_COL ); - if (colName.equals(AppConstants.RI_CHART_COLOR)) - seriesCol.append(", " + colValue + " " + AppConstants.RI_CHART_COLOR ); - if(colName.equals(AppConstants.RI_CHART_MARKER_START)) - seriesCol.append(", " + AppConstants.RI_CHART_MARKER_START + " " + AppConstants.RI_CHART_MARKER_START ); - if(colName.equals(AppConstants.RI_CHART_MARKER_END)) - seriesCol.append(", " + AppConstants.RI_CHART_MARKER_END + " " + AppConstants.RI_CHART_MARKER_END ); - if(colName.equals(AppConstants.RI_CHART_MARKER_TEXT_LEFT)) - seriesCol.append(", " + AppConstants.RI_CHART_MARKER_TEXT_LEFT + " " + AppConstants.RI_CHART_MARKER_TEXT_LEFT ); - if(colName.equals(AppConstants.RI_CHART_MARKER_TEXT_RIGHT)) - seriesCol.append(", " + AppConstants.RI_CHART_MARKER_TEXT_RIGHT + " " + AppConstants.RI_CHART_MARKER_TEXT_RIGHT ); - //if(colName.equals(AppConstants.RI_ANOMALY_TEXT)) - //seriesCol.append(", " + AppConstants.RI_ANOMALY_TEXT + " " + AppConstants.RI_ANOMALY_TEXT ); - } - - //debugLogger.debug("ReportSQL Chart " + reportSQL ); - /*for (Iterator iter = chartValueCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, paramValues); - //valueCols.append(", NVL(" + formatChartColumn(colName) + ",0) " + dc.getColId()); - valueCols.append("," + formatChartColumn(colName) + " " + dc.getColId()); - } // for - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - DataColumnType dc = (DataColumnType) iter.next(); - String colName = getColumnSelectStr(dc, paramValues); - //if(colName.equals(AppConstants.RI_CHART_TOTAL_COL) || colName.equals(AppConstants.RI_CHART_COLOR)) { - if(colName.equals(AppConstants.RI_CHART_TOTAL_COL)) - valueCols.append(", " + AppConstants.RI_CHART_TOTAL_COL + " " + AppConstants.RI_CHART_TOTAL_COL ); - if (colName.equals(AppConstants.RI_CHART_COLOR)) - valueCols.append(", " + AppConstants.RI_CHART_COLOR + " " + AppConstants.RI_CHART_COLOR ); - if (colName.equals(AppConstants.RI_CHART_INCLUDE)) - valueCols.append(", " + AppConstants.RI_CHART_INCLUDE + " " + AppConstants.RI_CHART_INCLUDE ); - //} - }*/ - String final_sql = ""; - reportSQL = Utils.replaceInString(reportSQL, " from ", " FROM "); - reportSQL = Utils.replaceInString(reportSQL, " From ", " FROM "); - reportSQL = Utils.replaceInString(reportSQL, " select ", " SELECT "); - reportSQL = Utils.replaceInString(reportSQL, " union ", " UNION "); - //reportSQL = reportSQL.replaceAll("[\\s]*\\(", "("); -// if(reportSQL.indexOf("UNION") != -1) { -// if(reportSQL.indexOf("FROM(")!=-1) -// final_sql += " "+reportSQL.substring(reportSQL.indexOf("FROM(") ); -// else if (reportSQL.indexOf("FROM (")!=-1) -// final_sql += " "+reportSQL.substring(reportSQL.indexOf("FROM (") ); -// //TODO ELSE THROW ERROR -// } -// else { -// final_sql += " "+reportSQL.substring(reportSQL.toUpperCase().indexOf(" FROM ")); -// } - int pos = 0; - int pos_first_select = 0; - int pos_dup_select = 0; - int pos_prev_select = 0; - int pos_last_select = 0; - if (reportSQL.indexOf("FROM", pos)!=-1) { - pos = reportSQL.indexOf("FROM", pos); - pos_dup_select = reportSQL.lastIndexOf("SELECT",pos); - pos_first_select = reportSQL.indexOf("SELECT");//,pos); - logger.debug(EELFLoggerDelegate.debugLogger, ("pos_select " + pos_first_select + " " + pos_dup_select)); - if(pos_dup_select > pos_first_select) { - logger.debug(EELFLoggerDelegate.debugLogger, ("********pos_dup_select ********" + pos_dup_select)); - //pos_dup_select1 = pos_dup_select; - pos_prev_select = pos_first_select; - pos_last_select = pos_dup_select; - while (pos_last_select > pos_prev_select) { - logger.debug(EELFLoggerDelegate.debugLogger, ("pos_last , pos_prev " + pos_last_select + " " + pos_prev_select)); - pos = reportSQL.indexOf("FROM", pos+2); - pos_prev_select = pos_last_select; - pos_last_select = reportSQL.lastIndexOf("SELECT",pos); - logger.debug(EELFLoggerDelegate.debugLogger, ("in WHILE LOOP LAST " + pos_last_select)); - } - } - - } - final_sql += " "+reportSQL.substring(pos); - logger.debug(EELFLoggerDelegate.debugLogger, ("Final SQL " + final_sql)); - String sql = "SELECT " + legendCol + ", " + legendCol+"_1" + seriesCol.toString()+ nvl(valueCols.toString(), ", 1") - + groupCol.toString() - + final_sql; - logger.debug(EELFLoggerDelegate.debugLogger, ("Final sql in generateChartSQL " +sql)); - - return sql; - } // generateChartSQL - - private String getColumnSelectStr(DataColumnType dc, HttpServletRequest request) { - //String colName = dc.isCalculated() ? dc.getColName() - // : ((nvl(dc.getTableId()).length() > 0) ? (dc.getTableId() + "." + dc - // .getColName()) : dc.getColName()); - String colName = dc.getColName(); - String paramValue = null; - //if (dc.isCalculated()) { - if (reportRuntime.getFormFieldList() != null) { - for (Iterator iter = reportRuntime.getFormFieldList().getFormField().iterator(); iter.hasNext();) { - FormFieldType fft = (FormFieldType) iter.next(); - String fieldId = fft.getFieldId(); - String fieldDisplay = reportRuntime.getFormFieldDisplayName(fft); - String formfield_value = ""; - formfield_value = AppUtils.getRequestNvlValue(request, fieldId); - paramValue = nvl(formfield_value); - if(paramValue.length()>0) { - /*sql = Utils.replaceInString(sql, "'" + fieldDisplay + "'", nvl( - paramValue, "NULL"));*/ - colName = Utils.replaceInString(colName, "'" + fieldDisplay + "'", "'"+nvl( - paramValue, "NULL")+"'"); - colName = Utils.replaceInString(colName, fieldDisplay, nvl( - paramValue, "NULL")); - } - } - return colName; - } - //} - return colName; - } // getColumnSelectStr - - - - public String getSelectExpr(DataColumnType dct) { - // String colName = - // dct.isCalculated()?dct.getColName():((nvl(dct.getTableId()).length()>0)?(dct.getTableId()+"."+dct.getColName()):dct.getColName()); - return getSelectExpr(dct, dct.getColName() /* colName */); - } // getSelectExpr - - private String getSelectExpr(DataColumnType dct, String colName) { - String colType = dct.getColType(); - if (colType.equals(AppConstants.CT_CHAR) - || ((nvl(dct.getColFormat()).length() == 0) && (!colType - .equals(AppConstants.CT_DATE)))) - return colName; - else - return "DATE_FORMAT(" + colName + ", '" - + nvl(dct.getColFormat(), AppConstants.DEFAULT_DATE_FORMAT) + "')"; - } // getSelectExpr - - private String formatChartColumn(String colName) { - logger.debug(EELFLoggerDelegate.debugLogger, ("Format Chart Column Input colName " + colName)); - colName = colName.trim(); - colName = Utils.replaceInString(colName, "TO_CHAR", "to_char"); - colName = Utils.replaceInString(colName, "to_number", "TO_NUMBER"); - //reportSQL = reportSQL.replaceAll("[\\s]*\\(", "("); - colName = colName.replaceAll(",[\\s]*\\(", ",("); - StringBuffer colNameBuf = new StringBuffer(colName); - int pos = 0, posFormatStart = 0, posFormatEnd = 0; - String format = ""; - - if(colNameBuf.indexOf("999")==-1 && colNameBuf.indexOf("990")==-1) { - logger.debug(EELFLoggerDelegate.debugLogger, (" return colName " + colNameBuf.toString())); - return colNameBuf.toString(); - } - - while (colNameBuf.indexOf("to_char")!=-1) { - if(colNameBuf.indexOf("999")!=-1 || colNameBuf.indexOf("990")!=-1) { - pos = colNameBuf.indexOf("to_char"); - colNameBuf.insert(pos, " TO_NUMBER ( CR_RAPTOR.SAFE_TO_NUMBER ("); - pos = colNameBuf.indexOf("to_char"); - colNameBuf.replace(pos, pos+7, "TO_CHAR"); - //colName = Utils.replaceInString(colNameBuf.toString(), "to_char", " TO_NUMBER ( CR_RAPTOR.SAFE_TO_NUMBER ( TO_CHAR "); - logger.debug(EELFLoggerDelegate.debugLogger, ("After adding to_number " + colNameBuf.toString())); - //posFormatStart = colNameBuf.lastIndexOf(",'")+1; - posFormatStart = colNameBuf.indexOf(",'", pos)+1; - posFormatEnd = colNameBuf.indexOf(")",posFormatStart); - logger.debug(EELFLoggerDelegate.debugLogger, (posFormatStart + " " + posFormatEnd + " "+ pos)); - format = colNameBuf.substring(posFormatStart, posFormatEnd); - //posFormatEnd = colNameBuf.indexOf(")",posFormatEnd); - colNameBuf.insert(posFormatEnd+1, " ," + format + ") , "+ format + ")"); - logger.debug(EELFLoggerDelegate.debugLogger, ("colNameBuf " + colNameBuf.toString())); - } - } - logger.debug(EELFLoggerDelegate.debugLogger, (" return colName " + colNameBuf.toString())); - return colNameBuf.toString(); - } - - public List getChartValueColumnsList( int filter, HashMap formValues) { /*filter; all=0;create without new chart =1; createNewChart=2 */ - List reportCols = reportRuntime.getAllColumns(); - - ArrayList chartValueCols = new ArrayList(); - int flag = 0; - for (Iterator iter = reportCols.iterator(); iter.hasNext();) { - flag = 0; - DataColumnType dc = (DataColumnType) iter.next(); -// if(filter == 2 || filter == 1) { - flag = reportRuntime.getDependsOnFormFieldFlag(dc, formValues); - - if( (dc.getChartSeq()!=null && dc.getChartSeq()> 0) && flag == 0 && !(nvl(dc.getColOnChart()).equals(AppConstants.GC_LEGEND))) { - if(nvl(dc.getChartGroup()).length()<=0) { - if( filter == 2 && (dc.isCreateInNewChart()!=null && dc.isCreateInNewChart().booleanValue())) { - chartValueCols.add(dc); - } else if (filter == 1 && (dc.isCreateInNewChart()==null || !dc.isCreateInNewChart().booleanValue())) { - chartValueCols.add(dc); - } - else if(filter == 0) chartValueCols.add(dc); - } else chartValueCols.add(dc); - } -// } else -// chartValueCols.add(dc); - } // for - Collections.sort(chartValueCols, new ChartSeqComparator()); - return chartValueCols; - } // getChartValueColumnsList - - public String parseTitle(String title, HashMap formValues) { - Set set = formValues.entrySet(); - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - if(title.indexOf("["+ entry.getKey() + "]")!= -1) { - title = Utils.replaceInString(title, "["+entry.getKey()+"]", nvl( - (String) entry.getValue(), "")); - } - } - return title; - } - - public java.util.Date getDateFromDateStr(String dateStr) { - SimpleDateFormat MMDDYYYYFormat = new SimpleDateFormat("MM/dd/yyyy"); - SimpleDateFormat EEEMMDDYYYYFormat = new SimpleDateFormat("EEE, MM/dd/yyyy"); //2012-11-01 00:00:00 - SimpleDateFormat YYYYMMDDFormat = new SimpleDateFormat("yyyy/MM/dd"); - SimpleDateFormat MONYYYYFormat = new SimpleDateFormat("MMM yyyy"); - SimpleDateFormat MMYYYYFormat = new SimpleDateFormat("MM/yyyy"); - SimpleDateFormat MMMMMDDYYYYFormat = new SimpleDateFormat("MMMMM dd, yyyy"); - SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - SimpleDateFormat timestampHrFormat = new SimpleDateFormat("yyyy-MM-dd HH"); - SimpleDateFormat timestampDayFormat = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat DDMONYYYYFormat = new SimpleDateFormat("dd-MMM-yyyy"); - SimpleDateFormat MONTHYYYYFormat = new SimpleDateFormat("MMMMM, yyyy"); - SimpleDateFormat MMDDYYYYHHFormat = new SimpleDateFormat("MM/dd/yyyy HH"); - SimpleDateFormat MMDDYYYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); - SimpleDateFormat MMDDYYYYHHMMFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm"); - SimpleDateFormat YYYYMMDDHHMMSSFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - SimpleDateFormat YYYYMMDDHHMMFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); - SimpleDateFormat DDMONYYYYHHMMSSFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); - SimpleDateFormat DDMONYYYYHHMMFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); - SimpleDateFormat MMDDYYFormat = new SimpleDateFormat("MM/dd/yy"); - SimpleDateFormat MMDDYYHHMMFormat = new SimpleDateFormat("MM/dd/yy HH:mm"); - SimpleDateFormat MMDDYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); - SimpleDateFormat timestampFormat1 = new SimpleDateFormat("yyyy-M-d.HH.mm. s. S"); - SimpleDateFormat timestamp_W_dash = new SimpleDateFormat("yyyyMMddHHmmss"); - SimpleDateFormat MMDDYYYYHHMMZFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm z"); - SimpleDateFormat YYYYFormat = new SimpleDateFormat("yyyy"); - java.util.Date date = null; - - int formatFlag = 0; - - final int YEARFLAG = 1; - final int MONTHFLAG = 2; - final int DAYFLAG = 3; - final int HOURFLAG = 4; - final int MINFLAG = 5; - final int SECFLAG = 6; - final int MILLISECFLAG = 7; - final int DAYOFTHEWEEKFLAG = 8; - final int FLAGDATE = 9; - /*int yearFlag = 1; - int monthFlag = 2; - int dayFlag = 3; - int hourFlag = 4; - int minFlag = 5; - int secFlag = 6; - int milliSecFlag = 7; - int dayoftheweekFlag = 8; - int flagDate = 10; - */ - - date = MMDDYYYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - if(date==null) { - date = EEEMMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYOFTHEWEEKFLAG; - } - if(date==null) { - date = MMDDYYYYHHMMFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - if(date==null) { - //MMDDYYYYHHFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - date = MMDDYYYYHHFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = HOURFLAG; - } - if(date==null) { - date = MMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - if(date==null) { - date = YYYYMMDDFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - if(date==null) { - date = timestampFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - if(date==null) { - date = timestampHrFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = HOURFLAG; - } - if(date==null) { - date = timestampDayFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - - if(date==null) { - date = MONYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MONTHFLAG; - } - if(date==null) { - date = MMYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MONTHFLAG; - } - if(date==null) { - date = MMMMMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - if(date==null) { - date = MONTHYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MONTHFLAG; - } - - if(date==null) { - date = YYYYMMDDHHMMSSFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - - if(date==null) { - date = YYYYMMDDHHMMFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - - if(date==null) { - date = DDMONYYYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - - if(date==null) { - date = DDMONYYYYHHMMFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - - if(date==null) { - date = DDMONYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - - if(date==null) { - date = MMDDYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - - if(date==null) { - date = MMDDYYHHMMFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - - if(date==null) { - date = MMDDYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - - if(date==null) { - date = timestampFormat1.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - - if(date==null) { - date = MMDDYYYYHHMMZFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - - if(date==null) { - date = YYYYFormat.parse(dateStr, new ParsePosition(0)); - /* Some random numbers should not satisfy this year format. */ - if(dateStr.length()>4) date = null; - if(date!=null) formatFlag = YEARFLAG; - } - if(date==null) { - date = timestamp_W_dash.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - if(date==null) - date = null; - return date; - } - - public int getFlagFromDateStr(String dateStr) { - SimpleDateFormat MMDDYYYYFormat = new SimpleDateFormat("MM/dd/yyyy"); - SimpleDateFormat EEEMMDDYYYYFormat = new SimpleDateFormat("EEE, MM/dd/yyyy"); //2012-11-01 00:00:00 - SimpleDateFormat YYYYMMDDFormat = new SimpleDateFormat("yyyy/MM/dd"); - SimpleDateFormat MONYYYYFormat = new SimpleDateFormat("MMM yyyy"); - SimpleDateFormat MMYYYYFormat = new SimpleDateFormat("MM/yyyy"); - SimpleDateFormat MMMMMDDYYYYFormat = new SimpleDateFormat("MMMMM dd, yyyy"); - SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - SimpleDateFormat timestampHrFormat = new SimpleDateFormat("yyyy-MM-dd HH"); - SimpleDateFormat timestampDayFormat = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat DDMONYYYYFormat = new SimpleDateFormat("dd-MMM-yyyy"); - SimpleDateFormat MONTHYYYYFormat = new SimpleDateFormat("MMMMM, yyyy"); - SimpleDateFormat MMDDYYYYHHFormat = new SimpleDateFormat("MM/dd/yyyy HH"); - SimpleDateFormat MMDDYYYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); - SimpleDateFormat MMDDYYYYHHMMFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm"); - SimpleDateFormat YYYYMMDDHHMMSSFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - SimpleDateFormat YYYYMMDDHHMMFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); - SimpleDateFormat DDMONYYYYHHMMSSFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); - SimpleDateFormat DDMONYYYYHHMMFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); - SimpleDateFormat MMDDYYFormat = new SimpleDateFormat("MM/dd/yy"); - SimpleDateFormat MMDDYYHHMMFormat = new SimpleDateFormat("MM/dd/yy HH:mm"); - SimpleDateFormat MMDDYYHHMMSSFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); - SimpleDateFormat timestampFormat1 = new SimpleDateFormat("yyyy-M-d.HH.mm. s. S"); - SimpleDateFormat timestamp_W_dash = new SimpleDateFormat("yyyyMMddHHmmss"); - SimpleDateFormat MMDDYYYYHHMMZFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm z"); - SimpleDateFormat YYYYFormat = new SimpleDateFormat("yyyy"); - java.util.Date date = null; - - int formatFlag = 0; - - final int YEARFLAG = 1; - final int MONTHFLAG = 2; - final int DAYFLAG = 3; - final int HOURFLAG = 4; - final int MINFLAG = 5; - final int SECFLAG = 6; - final int MILLISECFLAG = 7; - final int DAYOFTHEWEEKFLAG = 8; - final int FLAGDATE = 9; - /*int yearFlag = 1; - int monthFlag = 2; - int dayFlag = 3; - int hourFlag = 4; - int minFlag = 5; - int secFlag = 6; - int milliSecFlag = 7; - int dayoftheweekFlag = 8; - int flagDate = 10; - */ - - date = MMDDYYYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - if(date==null) { - date = EEEMMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYOFTHEWEEKFLAG; - } - if(date==null) { - date = MMDDYYYYHHMMFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - if(date==null) { - //MMDDYYYYHHFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - date = MMDDYYYYHHFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = HOURFLAG; - } - if(date==null) { - date = MMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - if(date==null) { - date = YYYYMMDDFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - if(date==null) { - date = timestampFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - if(date==null) { - date = timestampHrFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = HOURFLAG; - } - if(date==null) { - date = timestampDayFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - if(date==null) { - date = MONYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MONTHFLAG; - } - if(date==null) { - date = MMYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MONTHFLAG; - } - if(date==null) { - date = MMMMMDDYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - if(date==null) { - date = MONTHYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MONTHFLAG; - } - - if(date==null) { - date = YYYYMMDDHHMMSSFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - - if(date==null) { - date = YYYYMMDDHHMMFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - - if(date==null) { - date = DDMONYYYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - - if(date==null) { - date = DDMONYYYYHHMMFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - - if(date==null) { - date = DDMONYYYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - - if(date==null) { - date = MMDDYYHHMMSSFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - - if(date==null) { - date = MMDDYYHHMMFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - - if(date==null) { - date = MMDDYYFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = DAYFLAG; - } - - if(date==null) { - date = timestampFormat1.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - - if(date==null) { - date = MMDDYYYYHHMMZFormat.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = MINFLAG; - } - - if(date==null) { - date = YYYYFormat.parse(dateStr, new ParsePosition(0)); - /* Some random numbers should not satisfy this year format. */ - if(dateStr.length()>4) date = null; - if(date!=null) formatFlag = YEARFLAG; - } - if(date==null) { - date = timestamp_W_dash.parse(dateStr, new ParsePosition(0)); - if(date!=null) formatFlag = SECFLAG; - } - if(date==null) - date = null; - return formatFlag; - } - - public static String[] reverse(String[] arr) { - List list = Arrays.asList(arr); - Collections.reverse(list); - return (String[])list.toArray(); - } - - public int getNumberOfDecimalPlaces(double num) { - Double d = num; - String[] splitter = d.toString().split("\\."); - splitter[0].length(); // Before Decimal Count - splitter[1].length(); // After Decimal Count - return splitter[1].length(); - } - - public boolean getBooleanValue(String s) { - return getBooleanValue(s,null); - } - - public boolean getBooleanValue(String s, Boolean defaultValue) { - s = nvl(s); - if(s.length()<=0 && defaultValue!=null) return defaultValue.booleanValue(); - else if(s.length()<=0) return false; - else { - if(s.toUpperCase().startsWith("Y") || s.toLowerCase().equals("true")) - return true; - else - return false; - } - } - - - public String IntToLetter(int Int) { - if (Int<27){ - return Character.toString((char)(Int+96)); - } else { - if (Int%26==0) { - return IntToLetter((Int/26)-1)+IntToLetter((Int%26)+1); - } else { - return IntToLetter(Int/26)+IntToLetter(Int%26); - } - } - } - - - - - private void clearReportRuntimeBackup(HttpServletRequest request) { - //Session sess = Sessions.getCurrent(true)getCurrent(); - //HttpSession session = (HttpSession)sess.getNativeSession(); - HttpSession session = request.getSession(); - session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); - request.removeAttribute(AppConstants.DRILLDOWN_INDEX); - session.removeAttribute(AppConstants.DRILLDOWN_INDEX); - request.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); - session.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); - Enumeration enum1 = session.getAttributeNames(); - String attributeName = ""; - while(enum1.hasMoreElements()) { - attributeName = enum1.nextElement(); - if(attributeName.startsWith("parent_")) { - session.removeAttribute(attributeName); - } - } - session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); - session.removeAttribute(AppConstants.SI_BACKUP_FOR_REP_ID); - session.removeAttribute(AppConstants.SI_COLUMN_LOOKUP); - session.removeAttribute(AppConstants.SI_DASHBOARD_REP_ID); - session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); - session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME); - session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); - session.removeAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP); - session.removeAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); - session.removeAttribute(AppConstants.SI_DATA_SIZE_FOR_TEXTFIELD_POPUP); - session.removeAttribute(AppConstants.SI_MAP); - session.removeAttribute(AppConstants.SI_MAP_OBJECT); - session.removeAttribute(AppConstants.SI_REPORT_DEFINITION); - session.removeAttribute(AppConstants.SI_REPORT_RUNTIME); - session.removeAttribute(AppConstants.SI_REPORT_RUN_BACKUP); - session.removeAttribute(AppConstants.SI_REPORT_SCHEDULE); - session.removeAttribute(AppConstants.RI_REPORT_DATA); - session.removeAttribute(AppConstants.RI_CHART_DATA); - session.removeAttribute(AppConstants.SI_FORMFIELD_INFO); - session.removeAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); - - } // clearReportRuntimeBackup - - - public static synchronized java.util.HashMap getRequestParametersMap(ReportRuntime rr, HttpServletRequest request) - { - HashMap valuesMap = new HashMap(); - - ReportFormFields rff = rr.getReportFormFields(); - - int idx = 0; - FormField ff = null; - - Map fieldNameMap = new HashMap(); - int countOfFields = 0 ; - - - for(rff.resetNext(); rff.hasNext(); idx++) { - ff = rff.getNext(); - fieldNameMap.put(ff.getFieldName(), ff.getFieldDisplayName()); - countOfFields++; - } - - List formParameter = new ArrayList(); - String formField = ""; - for(int i = 0 ; i < rff.size(); i++) { - ff = ((FormField)rff.getFormField(i)); - formField = ff.getFieldName(); - boolean isMultiValue = false; - isMultiValue = ff.getFieldType().equals(FormField.FFT_CHECK_BOX) - || ff.getFieldType().equals(FormField.FFT_LIST_MULTI); - boolean isTextArea = (ff.getFieldType().equals(FormField.FFT_TEXTAREA) && rr.getReportDefType() - .equals(AppConstants.RD_SQL_BASED)); - - if(request.getParameterValues(formField) != null && isMultiValue ) { - String[] vals = request.getParameterValues(formField); - StringBuffer value = new StringBuffer(""); - if(!AppUtils.getRequestFlag(request, AppConstants.RI_RESET_ACTION)) { - - if ( isMultiValue ) { - value.append("("); - } - for(int j = 0 ; j < vals.length; j++) { - if(isMultiValue) value.append("'"); - try { - if(vals[j] !=null && vals[j].length() > 0) { - vals[j] = Utils.oracleSafe(vals[j]); - value.append(java.net.URLDecoder.decode(vals[j], "UTF-8"));// + ","; - } - else - value.append(vals[j]); - } catch (UnsupportedEncodingException ex) {value.append(vals[j]);} - catch (IllegalArgumentException ex1){value.append(vals[j]);} - catch (Exception ex2){ - value.append(vals[j]); - } - - - if(isMultiValue) value.append("'"); - - if(j != vals.length -1) { - value.append(","); - } - } - if(vals.length > 0) { - value.append(")"); - } - } - - //value = value.substring(0 , value.length()); - - valuesMap.put(fieldNameMap.get(formField), value.toString()); - value = new StringBuffer(""); - } else if(request.getParameter(formField) != null) { - if(isTextArea) { - String value = ""; - value = request.getParameter(formField); - - value = Utils.oracleSafe(value); - value = "('" + Utils.replaceInString(value, ",", "'|'") + "')"; - value = Utils.replaceInString(value, "|", ","); - valuesMap.put(fieldNameMap.get(formField), value); - value = ""; - } else { - String value = ""; - if(!AppUtils.getRequestFlag(request, AppConstants.RI_RESET_ACTION)) - value = request.getParameter(formField); - valuesMap.put(fieldNameMap.get(formField), Utils.oracleSafe(value)); - } - - } else { - valuesMap.put(fieldNameMap.get(formField), "" ); - } - - } - - return valuesMap; - - } - -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartGen.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartGen.java deleted file mode 100644 index c395000e..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartGen.java +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.runtime; - -import java.io.PrintWriter; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.List; - -import javax.servlet.http.HttpSession; - -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.Log; - -public class ChartGen extends org.openecomp.portalsdk.analytics.RaptorObject { - - public static String generateChart(String chartType, HttpSession session, DataSet ds, - String xText, String yLabelLeftAxis, String yLabelRightAxis, List yTextSeries, - List yTextColor, List yTextSeriesAxis, String groupText, String chartTitle, - PrintWriter pw,List columnValuesList, boolean hasCategoryAxis, boolean isMultiSeries, - List allColumnsList, String downloadFileName, boolean totalOnlyChart, int deviceType, HashMap additionalChartOptionsMap) { - return generateChart(chartType, session, ds, xText, yLabelLeftAxis, yLabelRightAxis, - yTextSeries, yTextColor, yTextSeriesAxis, groupText, chartTitle, pw, Globals - .getDefaultChartWidth(), Globals.getDefaultChartHeight(), columnValuesList, hasCategoryAxis, isMultiSeries, allColumnsList, downloadFileName,totalOnlyChart, deviceType, additionalChartOptionsMap); - } // generateChart - - public static String generateChart(String chartType, HttpSession session, DataSet ds, - String xText, String yLabelLeftAxis, String yLabelRightAxis, List yTextSeries, - List yTextColor, List yTextSeriesAxis, String groupText, String chartTitle, - PrintWriter pw, int width, int height, List columnValuesList, boolean hasCategoryAxis, boolean isMultiSeries, - List allColumnsList, String downloadFileName,boolean totalOnlyChart, int deviceType, HashMap additionalChartOptionsMap) { - try { - Class chartGenClass = null; - - - Class[] argumentTypes = { String.class, HttpSession.class, DataSet.class, - String.class, String.class, String.class, List.class, List.class, - List.class, String.class, String.class, PrintWriter.class, int.class, - int.class, List.class, boolean.class, boolean.class, List.class, - String.class, boolean.class, int.class, HashMap.class }; - - Method method = chartGenClass.getMethod("generateChart", argumentTypes); - Object[] arguments = { chartType, session, ds, xText, yLabelLeftAxis, - yLabelRightAxis, yTextSeries, yTextColor, yTextSeriesAxis, groupText, - chartTitle, pw, new Integer(width), new Integer(height), columnValuesList, new Boolean(hasCategoryAxis), new Boolean(isMultiSeries), allColumnsList, downloadFileName, new Boolean(totalOnlyChart), new Integer(deviceType), additionalChartOptionsMap }; - - return (String) method.invoke(chartGenClass, arguments); - } catch (Exception e) { - e.printStackTrace(); - Log.write("ERROR [ChartGen.generateChart] " + e.getMessage()); - return null; - } - } // generateChart - -} // ChartGen diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSON.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSON.java deleted file mode 100644 index 85f8dc8a..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartJSON.java +++ /dev/null @@ -1,448 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.runtime; - -import java.util.ArrayList; - -class Row { - private String displayValue; - private String dataType; - private String colId; - //private boolean visible; - - - /*public boolean isVisible() { - return visible; - } - public void setVisible(boolean visible) { - this.visible = visible; - }*/ - public String getDisplayValue() { - return displayValue; - } - public void setDisplayValue(String displayValue) { - this.displayValue = displayValue; - } - public String getDataType() { - return dataType; - } - public void setDataType(String dataType) { - this.dataType = dataType; - } - public String getColId() { - return colId; - } - public void setColId(String colId) { - this.colId = colId; - } - - -} -class IndexValueJSON { - private int index; - private String value; - private String title; - public int getIndex() { - return index; - } - public void setIndex(int index) { - this.index = index; - } - public String getValue() { - return value; - } - public void setValue(String value) { - this.value = value; - } - public String getTitle() { - return title; - } - public void setTitle(String title) { - this.title = title; - } - -} - -class DomainAxisJSON extends IndexValueJSON {} - -class ChartColumnJSON extends IndexValueJSON {} - -class ChartTypeJSON extends IndexValueJSON {} - -class PieChartOptions { - -} - -public class ChartJSON { - - private String reportID; - private String reportName; - private String reportDescr; - private String reportTitle; - private String reportSubTitle; - private ArrayList formFieldList; - private ArrayList chartColumnJSONList; - private String formfield_comments; - private int totalRows; - private String chartSqlWhole; - private boolean chartAvailable; - private ChartTypeJSON chartTypeJSON; - private BarChartOptions barChartOptions; - private PieChartOptions pieChartOptions; - private TimeSeriesChartOptions timeSeriesChartOptions; - private FlexTimeSeriesChartOptions flexTimeSeriesChartOptions; - private CommonChartOptions commonChartOptions; - private String width; - private String height; - private boolean animation; - private String rotateLabels; - private boolean staggerLabels; - private boolean showTitle; - private DomainAxisJSON domainAxisJSON; - private CategoryAxisJSON categoryAxisJSON; - private boolean hasCategoryAxis; - - - public boolean isHasCategoryAxis() { - return hasCategoryAxis; - } - public void setHasCategoryAxis(boolean hasCategoryAxis) { - this.hasCategoryAxis = hasCategoryAxis; - } - private ArrayList rangeAxisList; - private ArrayList > wholeList; - - private String primaryAxisLabel; - private String secondaryAxisLabel; - private String minRange; - private String maxRange; - //private int topMargin; - //private int bottomMargin; - //private int leftMargin; - //private int rightMargin; - - /*private boolean showMaxMin; - private boolean showLegend; - private boolean showControls; - private String topMargin; - private String bottomMargin; - private String leftMargin; - private String rightMargin; - private String subType; - private boolean stacked; - private boolean horizontalBar; - private boolean barRealTimeAxis; - private boolean barReduceXAxisLabels; - private boolean timeAxis;*/ - - public String getReportID() { - return reportID; - } - public void setReportID(String reportID) { - this.reportID = reportID; - } - public String getReportName() { - return reportName; - } - public void setReportName(String reportName) { - this.reportName = reportName; - } - public String getReportDescr() { - return reportDescr; - } - public void setReportDescr(String reportDescr) { - this.reportDescr = reportDescr; - } - public String getReportTitle() { - return reportTitle; - } - public void setReportTitle(String reportTitle) { - this.reportTitle = reportTitle; - } - public String getReportSubTitle() { - return reportSubTitle; - } - public void setReportSubTitle(String reportSubTitle) { - this.reportSubTitle = reportSubTitle; - } - public ArrayList getFormFieldList() { - return formFieldList; - } - public void setFormFieldList(ArrayList formFieldList) { - this.formFieldList = formFieldList; - } - public String getFormfield_comments() { - return formfield_comments; - } - public void setFormfield_comments(String formfield_comments) { - this.formfield_comments = formfield_comments; - } - public int getTotalRows() { - return totalRows; - } - public void setTotalRows(int totalRows) { - this.totalRows = totalRows; - } - public String getChartSqlWhole() { - return chartSqlWhole; - } - public void setChartSqlWhole(String chartSqlWhole) { - this.chartSqlWhole = chartSqlWhole; - } - public boolean isChartAvailable() { - return chartAvailable; - } - public void setChartAvailable(boolean chartAvailable) { - this.chartAvailable = chartAvailable; - } - public String getWidth() { - return width; - } - public void setWidth(String width) { - this.width = width; - } - public String getHeight() { - return height; - } - public void setHeight(String height) { - this.height = height; - } - public boolean isAnimation() { - return animation; - } - public void setAnimation(boolean animation) { - this.animation = animation; - } - public String getRotateLabels() { - return rotateLabels; - } - public void setRotateLabels(String rotateLabels) { - this.rotateLabels = rotateLabels; - } - public boolean isStaggerLabels() { - return staggerLabels; - } - public void setStaggerLabels(boolean staggerLabels) { - this.staggerLabels = staggerLabels; - } - public boolean isShowTitle() { - return showTitle; - } - public void setShowTitle(boolean showTitle) { - this.showTitle = showTitle; - } - /*public boolean isShowMaxMin() { - return showMaxMin; - } - public void setShowMaxMin(boolean showMaxMin) { - this.showMaxMin = showMaxMin; - } - public boolean isShowLegend() { - return showLegend; - } - public void setShowLegend(boolean showLegend) { - this.showLegend = showLegend; - } - public boolean isShowControls() { - return showControls; - } - public void setShowControls(boolean showControls) { - this.showControls = showControls; - } - public String getTopMargin() { - return topMargin; - } - public void setTopMargin(String topMargin) { - this.topMargin = topMargin; - } - public String getBottomMargin() { - return bottomMargin; - } - public void setBottomMargin(String bottomMargin) { - this.bottomMargin = bottomMargin; - } - public String getLeftMargin() { - return leftMargin; - } - public void setLeftMargin(String leftMargin) { - this.leftMargin = leftMargin; - } - public String getRightMargin() { - return rightMargin; - } - public void setRightMargin(String rightMargin) { - this.rightMargin = rightMargin; - } - - public String getSubType() { - return subType; - } - public void setSubType(String subType) { - this.subType = subType; - } - public boolean isStacked() { - return stacked; - } - public void setStacked(boolean stacked) { - this.stacked = stacked; - } - public boolean isHorizontalBar() { - return horizontalBar; - } - public void setHorizontalBar(boolean horizontalBar) { - this.horizontalBar = horizontalBar; - } - public boolean isBarRealTimeAxis() { - return barRealTimeAxis; - } - public void setBarRealTimeAxis(boolean barRealTimeAxis) { - this.barRealTimeAxis = barRealTimeAxis; - } - public boolean isBarReduceXAxisLabels() { - return barReduceXAxisLabels; - } - public void setBarReduceXAxisLabels(boolean barReduceXAxisLabels) { - this.barReduceXAxisLabels = barReduceXAxisLabels; - } - public boolean isTimeAxis() { - return timeAxis; - } - public void setTimeAxis(boolean timeAxis) { - this.timeAxis = timeAxis; - }*/ - public ChartTypeJSON getChartTypeJSON() { - return chartTypeJSON; - } - public void setChartTypeJSON(ChartTypeJSON chartTypeJSON) { - this.chartTypeJSON = chartTypeJSON; - } - public String getChartType() { - return chartTypeJSON.getValue(); - } - public DomainAxisJSON getDomainAxisJSON() { - return domainAxisJSON; - } - public void setDomainAxisJSON(DomainAxisJSON domainAxisJSON) { - this.domainAxisJSON = domainAxisJSON; - } - public CategoryAxisJSON getCategoryAxisJSON() { - return categoryAxisJSON; - } - public void setCategoryAxisJSON(CategoryAxisJSON categoryAxisJSON) { - this.categoryAxisJSON = categoryAxisJSON; - } - public ArrayList getRangeAxisList() { - return rangeAxisList; - } - public void setRangeAxisList(ArrayList rangeAxisList) { - this.rangeAxisList = rangeAxisList; - } - public String getPrimaryAxisLabel() { - return primaryAxisLabel; - } - public void setPrimaryAxisLabel(String primaryAxisLabel) { - this.primaryAxisLabel = primaryAxisLabel; - } - public String getSecondaryAxisLabel() { - return secondaryAxisLabel; - } - public void setSecondaryAxisLabel(String secondaryAxisLabel) { - this.secondaryAxisLabel = secondaryAxisLabel; - } - public String getMinRange() { - return minRange; - } - public void setMinRange(String minRange) { - this.minRange = minRange; - } - public String getMaxRange() { - return maxRange; - } - public void setMaxRange(String maxRange) { - this.maxRange = maxRange; - } - /*public ArrayList getRowList() { - return rowList; - } - public void setRowList(ArrayList rowList) { - this.rowList = rowList; - }*/ - - public ArrayList> getWholeList() { - return wholeList; - } - public void setWholeList(ArrayList> wholeList) { - this.wholeList = wholeList; - } - //private ArrayList reportDataColumns; - //private ArrayList> reportDataRows; - public ArrayList getChartColumnJSONList() { - return chartColumnJSONList; - } - public void setChartColumnJSONList(ArrayList chartColumnJSONList) { - this.chartColumnJSONList = chartColumnJSONList; - } - - public BarChartOptions getBarChartOptions() { - return barChartOptions; - } - public void setBarChartOptions(BarChartOptions barChartOptions) { - this.barChartOptions = barChartOptions; - } - public PieChartOptions getPieChartOptions() { - return pieChartOptions; - } - public void setPieChartOptions(PieChartOptions pieChartOptions) { - this.pieChartOptions = pieChartOptions; - } - public TimeSeriesChartOptions getTimeSeriesChartOptions() { - return timeSeriesChartOptions; - } - public void setTimeSeriesChartOptions(TimeSeriesChartOptions timeSeriesChartOptions) { - this.timeSeriesChartOptions = timeSeriesChartOptions; - } - public FlexTimeSeriesChartOptions getFlexTimeSeriesChartOptions() { - return flexTimeSeriesChartOptions; - } - public void setFlexTimeSeriesChartOptions(FlexTimeSeriesChartOptions flexTimeSeriesChartOptions) { - this.flexTimeSeriesChartOptions = flexTimeSeriesChartOptions; - } - public CommonChartOptions getCommonChartOptions() { - return commonChartOptions; - } - public void setCommonChartOptions(CommonChartOptions commonChartOptions) { - this.commonChartOptions = commonChartOptions; - } - - public String getDomainAxis() { - if(getDomainAxisJSON() !=null) - return getDomainAxisJSON().getValue(); - else - return ""; - } - - public String getCategoryAxis() { - if(getCategoryAxisJSON()!=null) - return getCategoryAxisJSON().getValue(); - else - return ""; - } - -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartWebRuntime.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartWebRuntime.java deleted file mode 100644 index 3fb24402..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ChartWebRuntime.java +++ /dev/null @@ -1,420 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.runtime; - - - - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.openecomp.portalsdk.analytics.error.RaptorException; -import org.openecomp.portalsdk.analytics.model.ReportHandler; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.util.AppConstants; -import org.openecomp.portalsdk.analytics.view.ReportData; -import org.openecomp.portalsdk.core.web.support.UserUtils; - - -public class ChartWebRuntime implements Serializable { - - - // Not used - planned to use if Hibernate used as data access layer - private String runningDataQuery = ""; - private String runningCountQuery = ""; - //CONSTANTS FOR QUERY - public final String QRY_COUNT_REPORT = ""; - public final String QRY_DATA_REPORT = ""; - - // Not used planning to use when filter is used - private StringBuffer whereClause = new StringBuffer(""); - // request used to grab request parameters - private HttpServletRequest request; - - - public ReportRuntime reportRuntime; - public ReportData reportData; - - //Used to pass user information - private final Map params = new HashMap(); - - //from chart generator retrieves list of charts to render - public ArrayList chartList; - public ArrayList infoList; - - private String totalSql; - - - // - private String drilldown_index = "0"; - - public List getRolesCommaSeperated(HttpServletRequest request) { - HashMap roles = UserUtils.getRoles(request); - List roleList = null; - StringBuffer roleBuf = new StringBuffer(""); - int count = 0; - if( roles != null ) { - roleList = Arrays.asList(roles.keySet().toArray()); - } - - return roleList; - } - - - public String getUserId(HttpServletRequest request) { - return AppUtils.getUserID(request); - } - - public String generateChart(HttpServletRequest request) { - return generateChart(request, true); - } - - - public String generateChart(HttpServletRequest request, boolean showData) { - //wire variables - //processRecursive(this, this); - long currentTime = System.currentTimeMillis(); - HttpSession session = request.getSession(); - String action = nvl(request.getParameter(AppConstants.RI_ACTION), request.getParameter("action")); - boolean genReportData = (!action.equals("chart.json") || action.equals("chart.data.json")); - - - - final Long user_id = new Long((long) UserUtils.getUserId(request)); - - - boolean adminUser = false; - try { - adminUser = AppUtils.isAdminUser(request) || AppUtils.isSuperUser(request); - } catch (RaptorException ex) { - ex.printStackTrace(); - } - List roleList = getRolesCommaSeperated(request); - //final Map params = new HashMap(); - params.put("user_id", user_id); - params.put("role_list", roleList); - //params.put("public_yn", "Y"); - - //String action = request.getParameter(AppConstants.RI_ACTION); - String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); - - ReportHandler rh = new ReportHandler(); - ReportRuntime rr = null; - try { - if(reportID !=null) - rr = rh.loadReportRuntime(request, reportID, true, 1); - if(rr.getReportType().equals(AppConstants.RT_HIVE)) { - String sql = rr.getReportSQL(); - rr.setWholeSQL(sql); - //if(genReportData) - //reportData = rr.loadHiveLinearReportData(rr.getWholeSQL(),user_id.toString(), 10000,request); - } else { - //if(genReportData) - //reportData = rr.loadReportData(0, user_id.toString(), 10000,request, false /*download*/); - } - } catch (RaptorException ex) { - ex.printStackTrace(); - } - setReportRuntime(rr); - setReportData( reportData); - - reportRuntime = getReportRuntime(); - reportData = getReportData(); - - - HashMap chartOptionsMap = new HashMap(); - - String rotateLabelsStr = ""; - rotateLabelsStr = AppUtils.nvl(reportRuntime.getLegendLabelAngle()); - if(rotateLabelsStr.toLowerCase().equals("standard")) { - rotateLabelsStr = "0"; - } else if (rotateLabelsStr.toLowerCase().equals("up45")) { - rotateLabelsStr = "45"; - } else if (rotateLabelsStr.toLowerCase().equals("down45")) { - rotateLabelsStr = "-45"; - } else if (rotateLabelsStr.toLowerCase().equals("up90")) { - rotateLabelsStr = "90"; - } else if (rotateLabelsStr.toLowerCase().equals("down90")) { - rotateLabelsStr = "-90"; - } else - rotateLabelsStr = "0"; - - String width = (AppUtils.getRequestNvlValue(request, "width").length()>0?AppUtils.getRequestNvlValue(request, "width"):(AppUtils.nvl(reportRuntime.getChartWidth()).length()>0?reportRuntime.getChartWidth():"700")); - String height = (AppUtils.getRequestNvlValue(request, "height").length()>0?AppUtils.getRequestNvlValue(request, "height"):(AppUtils.nvl(reportRuntime.getChartHeight()).length()>0?reportRuntime.getChartHeight():"300")); - String animationStr = (AppUtils.getRequestNvlValue(request, "animation").length()>0?AppUtils.getRequestNvlValue(request, "animation"):new Boolean(reportRuntime.isAnimateAnimatedChart()).toString()); - - String rotateLabels = (AppUtils.getRequestNvlValue(request, "rotateLabels").length()>0?AppUtils.getRequestNvlValue(request, "rotateLabels"):(rotateLabelsStr.length()>0?rotateLabelsStr:"0")); - String staggerLabelsStr = (AppUtils.getRequestNvlValue(request, "staggerLabels").length()>0?AppUtils.getRequestNvlValue(request, "staggerLabels"):"false"); - String showMaxMinStr = (AppUtils.getRequestNvlValue(request, "showMaxMin").length()>0?AppUtils.getRequestNvlValue(request, "showMaxMin"):"false"); - String showControlsStr = (AppUtils.getRequestNvlValue(request, "showControls").length()>0?AppUtils.getRequestNvlValue(request, "showControls"):new Boolean(reportRuntime.displayBarControls()).toString()); - String showLegendStr = (AppUtils.getRequestNvlValue(request, "showLegend").length()>0?AppUtils.getRequestNvlValue(request, "showLegend"):new Boolean(!new Boolean(reportRuntime.hideChartLegend())).toString()); - String topMarginStr = AppUtils.getRequestNvlValue(request, "topMargin"); - String topMargin = (AppUtils.nvl(topMarginStr).length()<=0)?(reportRuntime.getTopMargin()!=null?reportRuntime.getTopMargin().toString():"30"):topMarginStr; - String bottomMarginStr = AppUtils.getRequestNvlValue(request, "bottomMargin"); - String bottomMargin = (AppUtils.nvl(bottomMarginStr).length()<=0)?(reportRuntime.getBottomMargin()!=null?reportRuntime.getBottomMargin().toString():"50"):bottomMarginStr; - String leftMarginStr = AppUtils.getRequestNvlValue(request, "leftMargin"); - String leftMargin = (AppUtils.nvl(leftMarginStr).length()<=0)?(reportRuntime.getLeftMargin()!=null?reportRuntime.getLeftMargin().toString():"100"):leftMarginStr; - String rightMarginStr = AppUtils.getRequestNvlValue(request, "rightMargin"); - String rightMargin = (AppUtils.nvl(rightMarginStr).length()<=0)?(reportRuntime.getRightMargin()!=null?reportRuntime.getRightMargin().toString():"160"):rightMarginStr; - String showTitleStr = (AppUtils.getRequestNvlValue(request, "showTitle").length()>0?AppUtils.getRequestNvlValue(request, "showTitle"):new Boolean(reportRuntime.displayChartTitle()).toString()); - String subType = AppUtils.getRequestNvlValue(request, "subType").length()>0?AppUtils.getRequestNvlValue(request, "subType"):(AppUtils.nvl(reportRuntime.getTimeSeriesRender()).equals("area")?reportRuntime.getTimeSeriesRender():""); - String stackedStr = AppUtils.getRequestNvlValue(request, "stacked").length()>0?AppUtils.getRequestNvlValue(request, "stacked"):new Boolean(reportRuntime.isChartStacked()).toString(); - String horizontalBar = AppUtils.getRequestNvlValue(request, "horizontalBar").length()>0?AppUtils.getRequestNvlValue(request, "horizontalBar"):new Boolean(reportRuntime.isHorizontalOrientation()).toString(); - String barRealTimeAxis = AppUtils.getRequestNvlValue(request, "barRealTimeAxis"); - String barReduceXAxisLabels = AppUtils.getRequestNvlValue(request, "barReduceXAxisLabels").length()>0?AppUtils.getRequestNvlValue(request, "barReduceXAxisLabels"):new Boolean(reportRuntime.isLessXaxisTickers()).toString();; - String timeAxis = AppUtils.getRequestNvlValue(request, "timeAxis").length()>0?AppUtils.getRequestNvlValue(request, "timeAxis"):new Boolean(reportRuntime.isTimeAxis()).toString(); - String logScale = AppUtils.getRequestNvlValue(request, "logScale").length()>0?AppUtils.getRequestNvlValue(request, "logScale"):new Boolean(reportRuntime.isLogScale()).toString(); - String precision = AppUtils.getRequestNvlValue(request, "precision").length()>0?AppUtils.getRequestNvlValue(request, "precision"):"2"; - - /* boolean animation = AppUtils.getRequestFlag(request, "animation"); - boolean staggerLabels = AppUtils.getRequestFlag(request, "staggerLabels"); - boolean showMaxMin = (showMaxMinStr.length()<=0)?false:Boolean.parseBoolean(showMaxMinStr); - boolean showControls = (showControlsStr.length()<=0)?true:Boolean.parseBoolean(showControlsStr); - boolean showLegend = (showLegendStr.length()<=0)?true:Boolean.parseBoolean(showLegendStr); - boolean showTitle = (showTitleStr.length()<=0)?true:Boolean.parseBoolean(showTitleStr); - boolean stacked = (stackedStr.length()<=0)?true:Boolean.parseBoolean(stackedStr); - */ - // Add all options to Map - chartOptionsMap.put("width", width); - chartOptionsMap.put("height", height); - chartOptionsMap.put("animation", animationStr); - chartOptionsMap.put("rotateLabels", rotateLabels); - chartOptionsMap.put("staggerLabels", staggerLabelsStr); - chartOptionsMap.put("showMaxMin", showMaxMinStr); - chartOptionsMap.put("showControls", showControlsStr); - chartOptionsMap.put("showLegend", showLegendStr); - chartOptionsMap.put("topMargin", topMargin); - chartOptionsMap.put("bottomMargin", bottomMargin); - chartOptionsMap.put("leftMargin", leftMargin); - chartOptionsMap.put("rightMargin", rightMargin); - chartOptionsMap.put("showTitle", showTitleStr); - chartOptionsMap.put("subType", subType); - chartOptionsMap.put("stacked", stackedStr); - chartOptionsMap.put("horizontalBar", horizontalBar); - chartOptionsMap.put("timeAxis", timeAxis); - chartOptionsMap.put("barRealTimeAxis", barRealTimeAxis); - chartOptionsMap.put("barReduceXAxisLabels", barReduceXAxisLabels); - - chartOptionsMap.put("logScale", logScale); - chartOptionsMap.put("precision", precision); - - - - if(reportRuntime!=null) { - StringBuffer title = new StringBuffer(""); - title.append(reportRuntime.getReportName()); - } - - if(! (action.equals("chart.json") || action.equals("chart.data.json"))) { - - - //Chart - String chartType = reportRuntime.getChartType(); - return drawD3Charts(chartOptionsMap, request); - //drawD3Charts(); - } else /*if (action.equals("chart.json"))*/ { - String chartType = reportRuntime.getChartType(); - return returnChartJSON(chartOptionsMap, request, showData); - - - } /*else { - - return ("Internal Error Occurred."); - }*/ - - } - - - public String nvl(String s) { - return (s == null) ? "" : s; - } - - /** - * @return the reportRuntime - */ - public ReportRuntime getReportRuntime() { - return reportRuntime; - } - - /** - * @param reportRuntime the reportRuntime to set - */ - public void setReportRuntime(ReportRuntime reportRuntime) { - this.reportRuntime = reportRuntime; - } - - /** - * @return the reportData - */ - public ReportData getReportData() { - return reportData; - } - - /** - * @param reportData the reportData to set - */ - public void setReportData(ReportData reportData) { - this.reportData = reportData; - } - - public boolean isNull(String a) { - if ((a == null) || (a.length() == 0) || a.equalsIgnoreCase("null")) - return true; - else - return false; - } - - - protected String nvl(String s, String sDefault) { - return nvl(s).equals("") ? sDefault : s; - } - - protected static String nvls(String s) { - return (s == null) ? "" : s; - } - - protected static String nvls(String s, String sDefault) { - return nvls(s).equals("") ? sDefault : s; - } - - protected boolean getFlagInBoolean(String s) { - return nvl(s).toUpperCase().startsWith("Y") || nvl(s).toLowerCase().equals("true"); - } - - - /** - * @return the chartList - */ - public ArrayList getChartList() { - return chartList; - } - - /** - * @param chartList the chartList to set - */ - public void setChartList(ArrayList chartList) { - this.chartList = chartList; - } - - /** - * @return the infoList - */ - public ArrayList getInfoList() { - return infoList; - } - - /** - * @param infoList the infoList to set - */ - public void setInfoList(ArrayList infoList) { - this.infoList = infoList; - } - - - - private void clearReportRuntimeBackup(HttpSession session, HttpServletRequest request) { - session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); - request.removeAttribute(AppConstants.DRILLDOWN_INDEX); - session.removeAttribute(AppConstants.DRILLDOWN_INDEX); - request.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); - session.removeAttribute(AppConstants.FORM_DRILLDOWN_INDEX); - Enumeration enum1 = session.getAttributeNames(); - String attributeName = ""; - while(enum1.hasMoreElements()) { - attributeName = enum1.nextElement(); - if(attributeName.startsWith("parent_")) { - session.removeAttribute(attributeName); - } - } - session.removeAttribute(AppConstants.DRILLDOWN_REPORTS_LIST); - session.removeAttribute(AppConstants.SI_BACKUP_FOR_REP_ID); - session.removeAttribute(AppConstants.SI_COLUMN_LOOKUP); - session.removeAttribute(AppConstants.SI_DASHBOARD_REP_ID); - session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME_MAP); - session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTRUNTIME); - session.removeAttribute(AppConstants.SI_DASHBOARD_REPORTDATA_MAP); - session.removeAttribute(AppConstants.SI_DASHBOARD_CHARTDATA_MAP); - session.removeAttribute(AppConstants.SI_DASHBOARD_DISPLAYTYPE_MAP); - session.removeAttribute(AppConstants.SI_DATA_SIZE_FOR_TEXTFIELD_POPUP); - session.removeAttribute(AppConstants.SI_MAP); - session.removeAttribute(AppConstants.SI_MAP_OBJECT); - session.removeAttribute(AppConstants.SI_REPORT_DEFINITION); - session.removeAttribute(AppConstants.SI_REPORT_RUNTIME); - session.removeAttribute(AppConstants.SI_REPORT_RUN_BACKUP); - session.removeAttribute(AppConstants.SI_REPORT_SCHEDULE); - session.removeAttribute(AppConstants.RI_REPORT_DATA); - session.removeAttribute(AppConstants.RI_CHART_DATA); - session.removeAttribute(AppConstants.SI_FORMFIELD_INFO); - session.removeAttribute(AppConstants.SI_FORMFIELD_DOWNLOAD_INFO); - } // clearReportRuntimeBackup - - - public String getTotalSql() { - return totalSql; - } - - public void setTotalSql(String totalSql) { - this.totalSql = totalSql; - } - - - - /* public void drawD3Charts(HashMap chartOptionsMap) { - drawD3Charts(chartOptionsMap); - - } - */ - - public String drawD3Charts(HashMap chartOptionsMap, HttpServletRequest request) { - - ChartD3Helper chartHelper = new ChartD3Helper(reportRuntime); - chartHelper.setChartType(reportRuntime.getChartType()); - try { - return chartHelper.createVisualization(reportRuntime, chartOptionsMap, request); - } catch(RaptorException ex) { - ex.printStackTrace(); - } - return ""; - - } - - public String returnChartJSON(HashMap chartOptionsMap, HttpServletRequest request, boolean showData) { - - ChartJSONHelper chartJSONHelper = new ChartJSONHelper(reportRuntime); - chartJSONHelper.setChartType(reportRuntime.getChartType()); - try { - return chartJSONHelper.generateJSON(reportRuntime, chartOptionsMap, request, showData); - } catch(RaptorException ex) { - ex.printStackTrace(); - } - return ""; - - } - - } - diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CommonChartOptions.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CommonChartOptions.java deleted file mode 100644 index e8ba2ee5..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/CommonChartOptions.java +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.runtime; - -public class CommonChartOptions { - - private String legendPosition = "top"; - private String legendLabelAngle = "up45"; - private boolean hideLegend = false; - private boolean animateAnimatedChart = true; - private int topMargin = 30; - private int bottomMargin = 50; - private int leftMargin = 100; - private int rightMargin = 60; - - public String getLegendPosition() { - return legendPosition; - } - public void setLegendPosition(String legendPosition) { - this.legendPosition = legendPosition; - } - public String getLegendLabelAngle() { - return legendLabelAngle; - } - public void setLegendLabelAngle(String legendLabelAngle) { - this.legendLabelAngle = legendLabelAngle; - } - public boolean isHideLegend() { - return hideLegend; - } - public void setHideLegend(boolean hideLegend) { - this.hideLegend = hideLegend; - } - public boolean isAnimateAnimatedChart() { - return animateAnimatedChart; - } - public void setAnimateAnimatedChart(boolean animateAnimatedChart) { - this.animateAnimatedChart = animateAnimatedChart; - } - public int getTopMargin() { - return topMargin; - } - public void setTopMargin(int topMargin) { - this.topMargin = topMargin; - } - public int getBottomMargin() { - return bottomMargin; - } - public void setBottomMargin(int bottomMargin) { - this.bottomMargin = bottomMargin; - } - public int getLeftMargin() { - return leftMargin; - } - public void setLeftMargin(int leftMargin) { - this.leftMargin = leftMargin; - } - public int getRightMargin() { - return rightMargin; - } - public void setRightMargin(int rightMargin) { - this.rightMargin = rightMargin; - } -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ErrorJSONRuntime.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ErrorJSONRuntime.java deleted file mode 100644 index d619c4e0..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/ErrorJSONRuntime.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.analytics.model.runtime; - -public class ErrorJSONRuntime { - - private String errormessage; - private String stacktrace; - - public String getErrormessage() { - return errormessage; - } - public void setErrormessage(String errormessage) { - this.errormessage = errormessage; - } - public String getStacktrace() { - return stacktrace; - } - public void setStacktrace(String stacktrace) { - this.stacktrace = stacktrace; - } - - - - -} diff --git a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormField.java b/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormField.java deleted file mode 100644 index ea215679..00000000 --- a/ecomp-sdk/sdk-analytics/src/main/java/org/openecomp/portalsdk/analytics/model/runtime/FormField.java +++ /dev/null @@ -1,2111 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -/* =========================================================================================== - * This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting) - * Raptor : This tool is used to generate different kinds of reports with lot of utilities - * =========================================================================================== - * - * ------------------------------------------------------------------------------------------- - * FormField.java - This class is used to generate all types of form field. - * ------------------------------------------------------------------------------------------- - * - * Created By : Stan Pishamanov - * Modified & Maintained By : Sundar Ramalingam - * - * Changes - * ------- - * 18-Aug-2009 : Version 8.5 (Sundar); Populating predefined formfields bug has been resolved. - * 13-Aug-2009 : Version 8.5 (RS); Form field chaining is supported even for hidden variables. - * 13-Aug-2009 : Version 8.5 (RS); Nothing changed just comment. - * 10-Aug-2009 : Version 9.0 (RS); required logic is added for Multiple Dropdown. - * 06-Aug-2009 : Version 9.0 (RS); B getAjaxHtml is added for converting form field chain from Iframe to AJAX. - * 08-Jun-2009 : Version 8.3 (RS); Hidden formfields now is displayed even when the sql is not provided. - * - */ -package org.openecomp.portalsdk.analytics.model.runtime; - -import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.openecomp.portalsdk.analytics.error.RaptorRuntimeException; -import org.openecomp.portalsdk.analytics.error.UserDefinedException; -import org.openecomp.portalsdk.analytics.model.base.IdNameList; -import org.openecomp.portalsdk.analytics.model.base.IdNameLookup; -import org.openecomp.portalsdk.analytics.model.base.IdNameSql; -import org.openecomp.portalsdk.analytics.model.base.IdNameValue; -import org.openecomp.portalsdk.analytics.system.AppUtils; -import org.openecomp.portalsdk.analytics.system.ConnectionUtils; -import org.openecomp.portalsdk.analytics.system.Globals; -import org.openecomp.portalsdk.analytics.util.DataSet; -import org.openecomp.portalsdk.analytics.util.Utils; -import org.openecomp.portalsdk.analytics.xmlobj.JavascriptItemType; - -public class FormField extends org.openecomp.portalsdk.analytics.RaptorObject implements Serializable { - private static final String HTML_FORM = "formd"; - - private String fieldName = null; - - private String fieldDisplayName = null; - - private String fieldType = FFT_TEXT_W_POPUP; - - private String validationType = VT_NONE; - - private boolean required = false; - - public boolean hasPredefinedList = false; - - private String defaultValue = null; - - private Calendar rangeStartDate = null; - - private Calendar rangeEndDate = null; - - private String rangeStartDateSQL = null; - - private String rangeEndDateSQL = null; - - private String fieldDefaultSQL = null; - - private String multiSelectListSize = null; - - private String helpText = null; - - private IdNameList lookupList = null; - - private String dbInfo = null; - - private String userId = null; - - private boolean visible = true; - - private String dependsOn = null; - - private boolean triggerOtherFormFields = false; - - private boolean triggerThisFormfield = false; - - // Form field types - public static final String FFT_TEXT_W_POPUP = "TEXT_WITH_POPUP"; - - public static final String FFT_TEXT = "TEXT"; - - public static final String FFT_TEXTAREA = "TEXTAREA"; - - public static final String FFT_COMBO_BOX = "COMBO_BOX"; - - public static final String FFT_LIST_BOX = "LIST_BOX"; - - public static final String FFT_RADIO_BTN = "RADIO_BTN"; - - public static final String FFT_CHECK_BOX = "CHECK_BOX"; - - public static final String FFT_LIST_MULTI = "LIST_MULTI_SELECT"; - - public static final String FFT_HIDDEN = "HIDDEN"; - - public static final String FFT_BLANK = "BLANK"; - - // Validation types - public static final String VT_NONE = "NONE"; - - public static final String VT_DATE = "DATE"; - - public static final String VT_TIMESTAMP_HR = "TIMESTAMP_HR"; - - public static final String VT_TIMESTAMP_MIN = "TIMESTAMP_MIN"; - - public static final String VT_TIMESTAMP_SEC = "TIMESTAMP_SEC"; - - public static final String VT_INT = "INTEGER"; - - public static final String VT_INT_POSITIVE = "POSITIVE_INTEGER"; - - public static final String VT_INT_NON_NEGATIVE = "NON_NEGATIVE_INTEGER"; - - public static final String VT_FLOAT = "FLOAT"; - - public static final String VT_FLOAT_POSITIVE = "POSITIVE_FLOAT"; - - public static final String VT_FLOAT_NON_NEGATIVE = "NON_NEGATIVE_FLOAT"; - - private FormField(String fieldName, String fieldDisplayName, String fieldType, - String validationType, boolean required, String defaultValue, String helpText, boolean visible, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, - String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize ) { - //super(); - this (fieldName,fieldDisplayName,fieldType,validationType,required,defaultValue,helpText, dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); - setVisible(visible); - } // FormField - - private FormField(String fieldName, String fieldDisplayName, String fieldType, - String validationType, boolean required, String defaultValue, String helpText, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, - String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize ) { - super(); - setFieldName(fieldName); - setFieldDisplayName(fieldDisplayName); - setFieldType(nvl(fieldType, FFT_TEXT)); - setValidationType(validationType); - setRequired(required); - setDefaultValue(defaultValue); - setHelpText(helpText); - setDependsOn(dependsOn); - setRangeStartDate(rangeStartDate); - setRangeEndDate(rangeEndDate); - setRangeStartDateSQL(rangeStartDateSQL); - setRangeEndDateSQL(rangeEndDateSQL); - setMultiSelectListSize(multiSelectListSize); - } - public FormField(String fieldName, String fieldDisplayName, String fieldType, - String validationType, boolean required, String defaultValue, String helpText, - List predefinedValues, boolean visible, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, - String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize) { - this(fieldName, fieldDisplayName, fieldType, validationType, required, defaultValue, - helpText,visible, dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); - if (predefinedValues != null) - setPredefinedListLookup(predefinedValues); - } // FormField - - public FormField(String fieldName, String fieldDisplayName, String fieldType, - String validationType, boolean required, String defaultValue, String helpText, - String lookupSql, boolean visible, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, - String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize ) { - this(fieldName, fieldDisplayName, fieldType, validationType, required, defaultValue, - helpText,visible, dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); - if (defaultValue!=null && defaultValue.length()>10 && defaultValue.substring(0,10).trim().toLowerCase().startsWith("select")) { - setFieldDefaultSQL(defaultValue); - setDefaultValue(""); - } - setLookupList(new IdNameSql(lookupSql,defaultValue)); - } // FormField - - public FormField(String fieldName, String fieldDisplayName, String fieldType, - String validationType, boolean required, String defaultValue, String helpText, - String dbTableName, String dbIdField, String dbNameField, String dbSortByField, boolean visible, String dependsOn, Calendar rangeStartDate, Calendar rangeEndDate, - String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize) { - this(fieldName, fieldDisplayName, fieldType, validationType, required, defaultValue, - helpText,dbTableName,dbIdField,dbNameField,dbSortByField, dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); - setVisible(visible); - } - - public FormField(String fieldName, String fieldDisplayName, String fieldType, - String validationType, boolean required, String defaultValue, String helpText, - String dbTableName, String dbIdField, String dbNameField, String dbSortByField, String dependsOn, - Calendar rangeStartDate, Calendar rangeEndDate, - String rangeStartDateSQL, String rangeEndDateSQL, String multiSelectListSize ) { - this(fieldName, fieldDisplayName, fieldType, validationType, required, defaultValue, - helpText,dependsOn, rangeStartDate, rangeEndDate, rangeStartDateSQL, rangeEndDateSQL, multiSelectListSize); - //if(dependsOn !=null){ this.dependsOn = dependsOn; }else { this.dependsOn = "" - if (defaultValue!=null && defaultValue.length()>10 && defaultValue.substring(0,10).trim().toLowerCase().startsWith("select")) { - setFieldDefaultSQL(defaultValue); - setDefaultValue(""); - if(fieldType.equals(FFT_TEXT)) - setLookupList(new IdNameLookup(dbTableName, dbIdField, dbNameField, dbSortByField,defaultValue,true)); - else - setLookupList(new IdNameLookup(dbTableName, dbIdField, dbNameField, dbSortByField,defaultValue,false)); - } - else { - if(fieldType.equals(FFT_TEXT)) - setLookupList(new IdNameLookup(dbTableName, dbIdField, dbNameField, dbSortByField, true)); - else - setLookupList(new IdNameLookup(dbTableName, dbIdField, dbNameField, dbSortByField, false)); - } - - this.setRangeStartDate(rangeStartDate); - this.setRangeEndDate(rangeEndDate); - this.setRangeStartDateSQL(rangeStartDateSQL); - this.setRangeEndDateSQL(rangeEndDateSQL); - - } // FormField - - - private void setPredefinedListLookup(List predefinedValues) { - IdNameList lookup = new IdNameList(); - for (Iterator iter = predefinedValues.iterator(); iter.hasNext();) { - String value = (String) iter.next(); - lookup.addValue(value, value); - } // for - setHasPredefinedList(true); - setLookupList(lookup); - } // setPredefinedListLookup - - public String getFieldName() { - return fieldName; - } - - public String getFieldDisplayName() { - return fieldDisplayName; - } - - public String getFieldType() { - return fieldType; - } - - public String getValidationType() { - return validationType; - } - - public boolean isRequired() { - return required; - } - - public String getDefaultValue() { - return defaultValue; - } - - public String getHelpText() { - return helpText; - } - - public IdNameList getLookupList() { - return lookupList; - } - - public void setFieldName(String fieldName) { - this.fieldName = fieldName; - } - - public void setFieldDisplayName(String fieldDisplayName) { - this.fieldDisplayName = fieldDisplayName; - } - - public void setFieldType(String fieldType) { - this.fieldType = fieldType; - } - - public void setValidationType(String validationType) { - this.validationType = nvl(validationType, VT_NONE); - } - - public void setRequired(boolean required) { - this.required = required; - } - - public void setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - } - - public void setHelpText(String helpText) { - this.helpText = helpText; - } - - public void setLookupList(IdNameList lookupList) { - this.lookupList = lookupList; - } - - public void setDefaultList(IdNameList lookupList) { - this.lookupList = lookupList; - } - - public String getBaseSQL() { - return (lookupList == null) ? null : lookupList.getBaseSQL(); - } // getBaseSQL - - public String getBaseWholeSQL() { - return (lookupList == null) ? null : lookupList.getBaseWholeSQL(); - } // getBaseWholeSQL - - public String getBaseWholeReadonlySQL() { - return (lookupList == null) ? null : lookupList.getBaseWholeReadonlySQL(); - } // getBaseWholeReadonlySQL - - public String getBaseSQLForPDFExcel() { - return (lookupList == null) ? null : lookupList.getBaseSQLForPDFExcel(getFieldType().equals(FFT_LIST_MULTI)||getFieldType().equals(FFT_CHECK_BOX)?true:false); - } // getBaseSQLForPDFExcel - - public String getDisplayNameHtml() { - if (nvl(helpText).length() > 0) - return "" + fieldDisplayName + ""; - else - return fieldDisplayName; - } // getDisplayNameHtml - - /*public String getHtml() throws RaptorRuntimeException { - return getHtml("" , null, null, false); - } // getHtml*/ - - public String getHtml(String fieldValue, HashMap formValues, ReportRuntime rr)throws RaptorRuntimeException { - return getHtml(fieldValue,formValues, rr, false); - } - - public String getHelpLink(String fieldName) { - //return "\"\""; - return ((getHelpText()!=null && getHelpText().length()>0)? "tooltipText=\""+ getHelpText()+"\">": ">"); - //return ((getHelpText()!=null && getHelpText().length()>0)? "": ""); - } - - - public String getCallableAfterChainingJavascript(String fieldName, ReportRuntime rr) { - JavascriptItemType javascriptItemType = null; - StringBuffer callJavascriptText = new StringBuffer(""); - if(rr.getJavascriptList()!=null) { - for (Iterator iter = rr.getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { - javascriptItemType = (JavascriptItemType)iter.next(); - if(javascriptItemType.getFieldId().equals(fieldName)) { - if(nvl(javascriptItemType.getCallText()).toLowerCase().startsWith("afterchaining")) - callJavascriptText.append(" "+javascriptItemType.getCallText()); - } - } - } - return callJavascriptText.toString()+" "; - } - public String getCallableJavascript(String fieldName, ReportRuntime rr) { - JavascriptItemType javascriptItemType = null; - StringBuffer callJavascriptText = new StringBuffer(""); - if(rr.getJavascriptList()!=null) { - for (Iterator iter = rr.getJavascriptList().getJavascriptItem().iterator(); iter.hasNext();) { - javascriptItemType = (JavascriptItemType)iter.next(); - if(javascriptItemType.getFieldId().equals(fieldName)) { - if(!nvl(javascriptItemType.getCallText()).toLowerCase().startsWith("afterchaining")) - callJavascriptText.append(" "+javascriptItemType.getCallText()); - } - } - } - return callJavascriptText.toString()+" "; - } - - public String getCallableOnChangeJavascript(String fieldName, ReportRuntime rr) { - String callText = getCallableJavascript(fieldName, rr); - if(callText != null && callText.trim().toLowerCase().indexOf("onchange")>=0) { - Pattern re1 = Pattern.compile("\\=(.*?)\\)"); - Matcher matcher = re1.matcher(callText); - while (matcher.find()) { - callText = matcher.group(); - if(callText!=null && callText.startsWith("=\"")) { - callText = callText.substring(2); - } else if (callText!=null) - callText = callText.substring(1); - } - callText = callText.replaceAll("this", "documentForm."+fieldName); - } else callText = null; - return callText; - } - - public String getAjaxHtml(String fieldValue, HashMap formValues, ReportRuntime rr, boolean inSchedule) throws RaptorRuntimeException { - fieldValue = nvl(fieldValue, defaultValue); - String readOnly = "ff_readonly"; - try { - if(fieldValue !=null && fieldValue.length() > 0) - fieldValue = java.net.URLDecoder.decode(fieldValue, "UTF-8"); - } catch (UnsupportedEncodingException ex) {} - catch (IllegalArgumentException ex1){} - catch (Exception ex2){} - if (fieldType.equals(FFT_COMBO_BOX)) { - StringBuffer sb = new StringBuffer(); - //System.out.println("COMBO BOX " + fieldName); - String oldSQL = ""; - if (!required) - sb.append("obj.options[obj.options.length] = new Option('-->select value<--','');"); - - IdNameList lookup = getLookupList(); - try { - if(!hasPredefinedList) { - //if(dependsOn != null && dependsOn != "") { - //if(dependsOn != null && dependsOn != "" ) { - IdNameSql lu = (IdNameSql) lookup; - String SQL = ""; - SQL = lu.getSql(); - /*if(nvl(fieldValue,"").length()<=0) - SQL = lu.getSql(); - else - SQL = lu.getBaseSQLForPDFExcel(false); - */ - //System.out.println("FORMFIELD 6666667 First" + ((IdNameSql)lookup).getSql()); - oldSQL = lu.getSql(); - //SQL = Utils.replaceInString(SQL, "[VALUE]", fieldValue); - if(formValues != null) { - Set set = formValues.entrySet(); - String value = ""; - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - value = (String) entry.getValue(); - if(inSchedule) { - try { - value = java.net.URLDecoder.decode(Utils.oracleSafe(value), "UTF-8"); - } catch (UnsupportedEncodingException ex) { - - } - } - if (value!=null && (value.length() <=0 || value.equals("NULL"))) { - value = "NULL"; - SQL = Utils.replaceInString(SQL, "'["+entry.getKey()+"]'", value); - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); - } else { - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); - } - } - lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); - } - //} - lookupList = lookup; - - //} - try { - lookup.loadUserData(0, "", getDbInfo(), getUserId()); - } catch (Exception e ){ e.printStackTrace(); //throw new RaptorRuntimeException(e); - } - } - lookup.trimToSize(); - - String selectedValue = ""; - int count = 0; - for (lookup.resetNext(); lookup.hasNext();) { - IdNameValue value = lookup.getNext(); - if(value != null && value.getId() != null && value.getName() != null ) { - /*if (count == 0 && required) { - selectedValue = value.getId(); - count++; - } else if (nvl(fieldValue).length()>0){ - if (fieldValue != null && fieldValue.equals(value.getId())){ - selectedValue = value.getId(); - } - count++; - } else { - count++; - } */ - if (count == 0) { - if(required){ - selectedValue = value.getId(); - } - count++; - } - sb.append("obj.options[obj.options.length] = new Option('" + Utils.singleQuoteEncode(value.getName())+"','"+Utils.singleQuoteEncode(value.getId())+"');"); - if ((fieldValue != null && fieldValue.equals(value.getId()))){ - sb.append("obj.options[obj.options.length-1].selected=true;"); - selectedValue = value.getId(); - } - if(value.isReadOnly()) - sb.append("obj.disabled=true;"); - else - sb.append("obj.disabled=false;"); - - } - } // for - if (formValues.containsKey(fieldDisplayName)){ - formValues.remove(fieldDisplayName); - } - formValues.put(fieldDisplayName, selectedValue); - } catch (Exception e) { - //throw new RaptorRuntimeException(e); - } - if(!hasPredefinedList) { - if(oldSQL != null && !oldSQL.equals("")) { - ((IdNameSql)lookup).setSQL(oldSQL); - } - } - //System.out.println("FORMFIELD 6666667 " + ((IdNameSql)lookup).getSql()); - if( isVisible()) - return sb.toString(); - else return ""; - } else if (fieldType.equals(FFT_LIST_MULTI)) { - StringBuffer sb = new StringBuffer(); - String oldSQL = ""; - - fieldValue = '|' + fieldValue + '|'; - IdNameList lookup = getLookupList(); - try { - if(!hasPredefinedList) { - //if(dependsOn != null && dependsOn != "") { - //if(dependsOn != null && dependsOn != "" ) { - IdNameSql lu = (IdNameSql) lookup; - String SQL = ""; - SQL = lu.getSql(); - /*if(nvl(fieldValue,"").length()<=0) - SQL = lu.getSql(); - else - SQL = lu.getBaseSQLForPDFExcel(false); - SQL = Utils.replaceInString(SQL, "[VALUE]", fieldValue); - */ - oldSQL = lu.getSql(); - if(formValues != null) { - Set set = formValues.entrySet(); - String value = ""; - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - value = (String) entry.getValue(); - if(inSchedule) { //('1347') - try { - value = java.net.URLDecoder.decode(value, "UTF-8"); - } catch (UnsupportedEncodingException ex) { - - } - } - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); - } - lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); - } - //} - lookupList = lookup; - //} - - lookup.loadUserData(0, "", getDbInfo(),getUserId()); - } - - for (lookup.resetNext(); lookup.hasNext();) { - IdNameValue value = lookup.getNext(); - sb.append("obj.options[obj.options.length] = new Option('" + Utils.singleQuoteEncode(value.getName()) +"','"+Utils.singleQuoteEncode(value.getId())+"');"); - if (fieldValue.indexOf('|' + value.getId() + '|') >= 0) - sb.append("obj.options[obj.options.length-1].selected=true;"); - if(value.isReadOnly()) - sb.append("obj.disabled=true;"); - else - sb.append("obj.disabled=false;"); - - } // for - - // lookup.clearData(); - } catch (Exception e) { - //throw new RaptorRuntimeException(e); - } - if(!hasPredefinedList) { - if(oldSQL != null && !oldSQL.equals("")) { - ((IdNameSql)lookup).setSQL(oldSQL); - } - } - if(isVisible()) - return sb.toString(); - else - return ""; - } else if (fieldType.equals(FFT_TEXT_W_POPUP)) { - //System.out.println("TEXT POPUP " + fieldName); - String oldSQL = ""; - IdNameValue idNamevalue = null; - String fieldDefValue=""; - String fieldDefDisplay=""; - try { - IdNameList lookup = getLookupList(); - if(dependsOn != null && dependsOn != "" ) { - IdNameSql lu = (IdNameSql) lookup; - String SQL = getBaseWholeSQL(); - if(SQL.toLowerCase().indexOf(readOnly) != -1) { - SQL = getBaseWholeReadonlySQL(); - } - oldSQL = lu.getSql(); - if(formValues != null) { - Set set = formValues.entrySet(); - String value = ""; - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - value = (String) entry.getValue(); - if(inSchedule) { - try { - value = java.net.URLDecoder.decode(Utils.oracleSafe(value), "UTF-8"); - } catch (UnsupportedEncodingException ex) { - - } - } - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); -// if(SQL.indexOf("'"+"["+entry.getKey()+"]"+"'")!=-1) { - if(SQL.indexOf("'"+"["+entry.getKey()+"]"+"'")!=-1 || SQL.indexOf("'"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"'")!=-1 - || SQL.indexOf("'%"+"["+entry.getKey()+"]"+"%'")!=-1 || SQL.indexOf("'%"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"%'")!=-1 - || SQL.indexOf("'_"+"["+entry.getKey()+"]"+"_'")!=-1 || SQL.indexOf("'_"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"_'")!=-1 - || SQL.indexOf("'%_"+"["+entry.getKey()+"]"+"_%'")!=-1 || SQL.indexOf("'%_"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"_%'")!=-1) { - - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", nvl( - value, "NULL")); - } else { - // Added to prevent SQL Injection - if(SQL.indexOf("["+entry.getKey()+"]")!=-1) { - try { - double vD = Double.parseDouble(value); - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", nvl( - value, "NULL")); - } catch (NumberFormatException ex) { - throw new UserDefinedException("Expected number, Given String for the form field \"" + "["+entry.getKey()+"]"+"\""); - } - } - } - } - if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.trim().length()<=0)) - lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); - else - lookup = new IdNameSql(-1,SQL,null); - } - } - //lookupList = lookup; - - if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.trim().length()<=0)) { - lookup.loadUserData(0, "", getDbInfo(), getUserId()); - for (lookup.resetNext(); lookup.hasNext();) { - idNamevalue = lookup.getNext(); - break; - - } - fieldDefValue = nvl(idNamevalue.getId()); - fieldDefDisplay = nvl(idNamevalue.getName()); - } else { - try { - // -2 indicates to run the whole sql for matching value - lookup.loadUserData(-2, "", getDbInfo(), getUserId()); - lookup.trimToSize(); - for (lookup.resetNext(); lookup.hasNext();) { - IdNameValue value = lookup.getNext(); - if(value != null && value.getId() != null && value.getName() != null ) { - fieldDefValue = nvl(value.getId()); - if (fieldValue != null && fieldValue.equals(value.getId())) { - fieldDefDisplay = nvl(value.getName()); - break; - } - else { - fieldDefValue = ""; - fieldDefDisplay = ""; - } - } - } - if (fieldDefDisplay == null || fieldDefDisplay.length()<=0) { - fieldDefDisplay = nvl(fieldDefValue); - } - - if(oldSQL != null && !oldSQL.equals("")) { - ((IdNameSql)lookup).setSQL(oldSQL); - } - - } catch (Exception e) { - //throw new RaptorRuntimeException(e); - } - - - //----- END ---// - - - if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.length()<=0)) { - fieldDefValue = nvl((idNamevalue!=null)?idNamevalue.getId():""); - fieldDefDisplay = nvl((idNamevalue!=null)?idNamevalue.getName():""); - } else { - if(fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.length()<=0) fieldValue=""; - fieldDefValue = nvl(fieldDefValue); - fieldDefDisplay = nvl(fieldDefDisplay); - } - - } - }catch(Exception e) { //throw new RaptorRuntimeException(e); - } - if(isVisible()) { - /* return "\n" + "0 && (dependsOn == null || dependsOn.length()<=0)) { - sb.append((fieldValue!=null)?"obj.value=\""+nvl(fieldValue)+"\";":""); - } else if (lookup != null) { - lookup.loadUserData(0, "", getDbInfo(), getUserId()); - int iCnt = 0; - for (lookup.resetNext(); lookup.hasNext(); iCnt++) { - IdNameValue value = lookup.getNext(); - //System.out.println("HIDDEN " + value.getId() + " " + value.getName()); - sb.append((value!=null)?"obj.value=\""+nvl(value.getId())+"\";":""); - if(value.isReadOnly()) - sb.append("obj.disabled=true;"); - else - sb.append("obj.disabled=false;"); - break; - } // for - if(lookup.size()<=0) { - sb.append("obj.value=\"\""); - - } - } else { - sb.append((fieldValue!=null)?"obj.value=\""+Utils.singleQuoteEncode(nvl(fieldValue))+"\";":""); - } - if(oldSQL != null && !oldSQL.equals("")) { - ((IdNameSql)lookup).setSQL(oldSQL); - } - // lookup.clearData(); - } catch (Exception e) { - //throw new RaptorRuntimeException(e); - } - //if(isVisible()) - return sb.toString() ; - } else if (fieldType.equals(FFT_LIST_BOX)) { - StringBuffer sb = new StringBuffer(); - //System.out.println("COMBO BOX " + fieldName); - String oldSQL = ""; - if (!required) - sb.append("obj.options[obj.options.length] = new Option('-->select value<--','');"); - - IdNameList lookup = getLookupList(); - try { - if(!hasPredefinedList) { - //if(dependsOn != null && dependsOn != "") { - //if(dependsOn != null && dependsOn != "" ) { - IdNameSql lu = (IdNameSql) lookup; - String SQL = ""; - SQL = lu.getSql(); - /*if(nvl(fieldValue,"").length()<=0) - SQL = lu.getSql(); - else - SQL = lu.getBaseSQLForPDFExcel(false); - */ - //System.out.println("FORMFIELD 6666667 First" + ((IdNameSql)lookup).getSql()); - oldSQL = lu.getSql(); - //SQL = Utils.replaceInString(SQL, "[VALUE]", fieldValue); - if(formValues != null) { - Set set = formValues.entrySet(); - String value = ""; - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - value = (String) entry.getValue(); - if(inSchedule) { - try { - value = java.net.URLDecoder.decode(Utils.oracleSafe(value), "UTF-8"); - } catch (UnsupportedEncodingException ex) { - - } - } - if (value!=null && (value.length() <=0 || value.equals("NULL"))) { - value = "NULL"; - SQL = Utils.replaceInString(SQL, "'["+entry.getKey()+"]'", value); - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); - } else { - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); - } - } - lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); - } - //} - lookupList = lookup; - - //} - try { - lookup.loadUserData(0, "", getDbInfo(), getUserId()); - } catch (Exception e ){ e.printStackTrace(); //throw new RaptorRuntimeException(e); - } - } - lookup.trimToSize(); - - String selectedValue = ""; - int count = 0; - for (lookup.resetNext(); lookup.hasNext();) { - IdNameValue value = lookup.getNext(); - if(value != null && value.getId() != null && value.getName() != null ) { - /*if (count == 0 && required) { - selectedValue = value.getId(); - count++; - } else if (nvl(fieldValue).length()>0){ - if (fieldValue != null && fieldValue.equals(value.getId())){ - selectedValue = value.getId(); - } - count++; - } else { - count++; - } */ - if (count == 0) { - if(required){ - selectedValue = value.getId(); - } - count++; - } - sb.append("obj.options[obj.options.length] = new Option('" + Utils.singleQuoteEncode(value.getName())+"','"+Utils.singleQuoteEncode(value.getId())+"');"); - if ((fieldValue != null && fieldValue.equals(value.getId()))){ - sb.append("obj.options[obj.options.length-1].selected=true;"); - selectedValue = value.getId(); - } - if(value.isReadOnly()) - sb.append("obj.disabled=true;"); - else - sb.append("obj.disabled=false;"); - - } - } // for - if (formValues.containsKey(fieldDisplayName)){ - formValues.remove(fieldDisplayName); - } - formValues.put(fieldDisplayName, selectedValue); - } catch (Exception e) { - //throw new RaptorRuntimeException(e); - } - if(!hasPredefinedList) { - if(oldSQL != null && !oldSQL.equals("")) { - ((IdNameSql)lookup).setSQL(oldSQL); - } - } - //System.out.println("FORMFIELD 6666667 " + ((IdNameSql)lookup).getSql()); - if( isVisible()) - return sb.toString(); - else return ""; - } - - return ""; - } - - public String getHtml(String fieldValue, HashMap formValues, ReportRuntime rr, boolean inSchedule) throws RaptorRuntimeException { - fieldValue = nvl(fieldValue, defaultValue); - int MILLIS_IN_DAY = 1000 * 60 * 60 * 24; - String readOnlyInSql = "ff_readonly"; - boolean readOnly = false; - try { - if(fieldValue !=null && fieldValue.length() > 0) - fieldValue = java.net.URLDecoder.decode(fieldValue, "UTF-8"); - } catch (UnsupportedEncodingException ex) {} - catch (IllegalArgumentException ex1){} - catch (Exception ex2){} - //System.out.println(fieldName + " " + fieldType + " " + fieldValue); - if (fieldType.equals(FFT_TEXT_W_POPUP)) { - //System.out.println("TEXT POPUP " + fieldName); - String oldSQL = ""; - IdNameValue idNamevalue = null; - String fieldDefValue=""; - String fieldDefDisplay=""; - IdNameList lookup = null; - try { - lookup = getLookupList(); - if(!hasPredefinedList) { - if(dependsOn != null && dependsOn != "" ) { - IdNameSql lu = (IdNameSql) lookup; - String SQL = getBaseWholeSQL(); - if(SQL.toLowerCase().indexOf(readOnlyInSql) != -1) { - SQL = getBaseWholeReadonlySQL(); - } - oldSQL = lu.getSql(); - if(formValues != null) { - Set set = formValues.entrySet(); - String value = ""; - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - value = (String) entry.getValue(); - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", value); -// if(SQL.indexOf("'"+"["+entry.getKey()+"]"+"'")!=-1) { - if(SQL.indexOf("'"+"["+entry.getKey()+"]"+"'")!=-1 || SQL.indexOf("'"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"'")!=-1 - || SQL.indexOf("'%"+"["+entry.getKey()+"]"+"%'")!=-1 || SQL.indexOf("'%"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"%'")!=-1 - || SQL.indexOf("'_"+"["+entry.getKey()+"]"+"_'")!=-1 || SQL.indexOf("'_"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"_'")!=-1 - || SQL.indexOf("'%_"+"["+entry.getKey()+"]"+"_%'")!=-1 || SQL.indexOf("'%_"+"["+entry.getKey())!=-1 || SQL.indexOf(entry.getKey()+"]"+"_%'")!=-1) { - - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", nvl( - value, "NULL")); - } else { - // Added to prevent SQL Injection - if(SQL.indexOf("["+entry.getKey()+"]")!=-1) { - try { - double vD = Double.parseDouble(value); - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", nvl( - value, "NULL")); - } catch (NumberFormatException ex) { - throw new UserDefinedException("Expected number, Given String for the form field \"" + "["+entry.getKey()+"]"+"\""); - } - } - } - } - if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.trim().length()<=0)) - lookup = new IdNameSql(-1,SQL,lu.getDefaultSQL()); - else - lookup = new IdNameSql(-1,SQL,null); - } - } - //lookupList = lookup; - - if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.trim().length()<=0)) { - lookup.loadUserData(0, "", getDbInfo(), getUserId()); - for (lookup.resetNext(); lookup.hasNext();) { - idNamevalue = lookup.getNext(); - break; - - } - fieldDefValue = nvl(idNamevalue.getId()); - fieldDefDisplay = nvl(idNamevalue.getName()); - } else { - try { - // -2 indicates to run the whole sql for matching value - lookup.loadUserData(-2, "", getDbInfo(), getUserId()); - } catch (Exception e) { - //throw new RaptorRuntimeException(e); - } - - lookup.trimToSize(); - for (lookup.resetNext(); lookup.hasNext();) { - IdNameValue value = lookup.getNext(); - if(value != null && value.getId() != null && value.getName() != null ) { - fieldDefValue = nvl(value.getId()); - if (fieldValue != null && fieldValue.equals(value.getId())) { - fieldDefDisplay = nvl(value.getName()); - break; - } - else { - fieldDefValue = ""; - fieldDefDisplay = ""; - } - } - } - if (fieldDefDisplay == null || fieldDefDisplay.length()<=0) { - fieldDefDisplay = nvl(fieldDefValue); - } - - - - //----- END ---// - - - if(getFieldDefaultSQL()!=null && (fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.length()<=0)) { - fieldDefValue = nvl((idNamevalue!=null)?idNamevalue.getId():""); - fieldDefDisplay = nvl((idNamevalue!=null)?idNamevalue.getName():""); - } else { - if(fieldValue == null || fieldValue.trim().equalsIgnoreCase("null")|| fieldValue.length()<=0) fieldValue=""; - fieldDefValue = nvl(fieldDefValue); - fieldDefDisplay = nvl(fieldDefDisplay); - } - - } - } else { - lookup.trimToSize(); - for (lookup.resetNext(); lookup.hasNext();) { - IdNameValue value = lookup.getNext(); - if(value != null && value.getId() != null && value.getName() != null ) { - fieldDefValue = nvl(value.getId()); - if (fieldValue != null && fieldValue.equals(value.getId())) { - fieldDefDisplay = nvl(value.getName()); - break; - } - else { - fieldDefValue = ""; - fieldDefDisplay = ""; - } - } - } - if (fieldDefDisplay == null || fieldDefDisplay.length()<=0) { - fieldDefDisplay = nvl(fieldDefValue); - } - } - }catch(Exception e) { //throw new RaptorRuntimeException(e); - } - - if(!hasPredefinedList) { - if(oldSQL != null && !oldSQL.equals("")) { - ((IdNameSql)lookup).setSQL(oldSQL); - } - } - - if(isVisible()) { - /* return "\n" + " \"Loading,
        "; - - return progress+" \n  \n" - + " 0) { - valueSQL = lu.getSql(); - avail_ReadOnly = (valueSQL.toLowerCase().indexOf(readOnlyInSql)!=-1); - //System.out.println("OLD SQL TEXT" + valueSQL); - //oldSQL = lu.getSql(); - if(formValues != null) { - Set set = formValues.entrySet(); - String value1 = ""; - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - value1 = (String) entry.getValue(); - if (value1.length() <=0) { - value1 = "NULL"; - valueSQL = Utils.replaceInString(valueSQL, "'["+entry.getKey()+"]'", value1); - valueSQL = Utils.replaceInString(valueSQL, "["+entry.getKey()+"]", value1); - } else { - valueSQL = Utils.replaceInString(valueSQL, "["+entry.getKey()+"]", value1); - } - } - // should be value one. - //lookup = new IdNameSql(-1,valueSQL,lu.getDefaultSQL()); - } - } - //lookupList = lookup; - //System.out.println("8888888 88 " + valueSQL); - } - if(valueSQL!=null && valueSQL.length()>0) { - DataSet ds = ConnectionUtils.getDataSet(valueSQL.toString(), dbInfo); - strValue = ds.getString(0,1); - if(avail_ReadOnly) readOnly = ds.getString(0, 2).toUpperCase().startsWith("Y")||ds.getString(0, 2).toUpperCase().startsWith("T");; - } - }catch(Exception e) { //throw new RaptorRuntimeException(e); - } - String returnString = ""; - String timestamp ="", timestamphr = "", timestampmin = "", timestampsec = ""; - - returnString = "0 && (!(fieldValue.toUpperCase().indexOf("SELECT ")!= -1 && fieldValue.toUpperCase().indexOf("FROM")!= -1)) ) { - if(validationType.startsWith("TIMESTAMP")) { - returnString += nvl((fieldValue!=null)?fieldValue.split(" ")[0]:""); - if(fieldValue!=null && fieldValue.length()>0) { - timestamp = (fieldValue.split(" ").length > 1)?fieldValue.split(" ")[1]:""; - String timestampArr[] = timestamp.split(":"); - if((timestampArr.length == 1) || (timestampArr.length == 2) || (timestampArr.length == 3)) - timestamphr = timestampArr[0]; - if((timestampArr.length == 2) || (timestampArr.length == 3)) - timestampmin = timestampArr[1]; - if(timestampArr.length == 3) - timestampsec = timestampArr[2]; - } - - } else returnString += fieldValue; - - } else if(getFieldDefaultSQL()!=null) { - - if(validationType.startsWith("TIMESTAMP")) { - returnString += nvl((strValue.length()>0)?strValue.split(" ")[0]:""); - if(strValue.length()>0) { - timestamp = (strValue.split(" ").length > 1)?strValue.split(" ")[1]:""; - String timestampArr[] = timestamp.split(":"); - if((timestampArr.length == 1) || (timestampArr.length == 2) || (timestampArr.length == 3)) - timestamphr = timestampArr[0]; - if((timestampArr.length == 2) || (timestampArr.length == 3)) - timestampmin = timestampArr[1]; - if(timestampArr.length == 3) - timestampsec = timestampArr[2]; - } - - } else if (nvl(strValue).length()>0) { - returnString += strValue; - } else - returnString += nvl((value!=null)?value.getId():""); - } else if (nvl(strValue).length()>0) { - returnString += strValue; - } else - returnString += nvl((value!=null)?value.getId():""); - - - /*returnString += "\">" - + (validationType.equals(VT_DATE) ? "\n\t\t\t" - + "\n\t\t\t\t" - : ""); */ - - SimpleDateFormat dtf = new SimpleDateFormat("MM/dd/yyyy"); - String stRangeText = this.getRangeStartDate() == null ? null : dtf.format(this.getRangeStartDate().getTime()); - String endRangeText = this.getRangeEndDate() == null ? null : dtf.format(this.getRangeEndDate().getTime()); - ///////////////////////// - - //get the date sqls - - //System.out.println("////////////start range date before Start" + this.getRangeStartDateSQL()); - - if (this.getRangeStartDateSQL() != null && this.getRangeStartDateSQL().trim().toLowerCase().startsWith("select")){ - //System.out.println("////////////start range date Starting"); - String SQL = this.getRangeStartDateSQL(); - if(formValues != null) { - Set set = formValues.entrySet(); - String v = ""; - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - v = (String) entry.getValue(); - //System.out.println("///////// key is " + entry.getKey() + " = " + v); - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", v); - } - - } - //System.out.println("////////////start range date sql created" + SQL); - try{ - DataSet ds = ConnectionUtils.getDataSet(SQL.toString(), dbInfo); - //System.out.println("////////////start range date is : " + ds.get(0)); - dtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Calendar tStart = Calendar.getInstance(); - tStart.setTime(dtf.parse(ds.getString(0,0))); - dtf = new SimpleDateFormat("MM/dd/yyyy"); - stRangeText = dtf.format(tStart.getTime().getTime()-MILLIS_IN_DAY); - - }catch(Exception e){ - System.out.println("Exception////////// : start range date is : " + e); - } - } - - if (this.getRangeEndDateSQL() != null && this.getRangeEndDateSQL().trim().toLowerCase().startsWith("select")){ - //System.out.println("////////////end range date Starting"); - String SQL = this.getRangeEndDateSQL(); - if(formValues != null) { - Set set = formValues.entrySet(); - String v = ""; - for(Iterator iter = set.iterator(); iter.hasNext(); ) { - Map.Entry entry = (Entry) iter.next(); - v = (String) entry.getValue(); - SQL = Utils.replaceInString(SQL, "["+entry.getKey()+"]", v); - } - - } - try{ - DataSet ds = ConnectionUtils.getDataSet(SQL.toString(), dbInfo); - //System.out.println("////////////end range date is : " + ds.get(0)); - dtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Calendar tStart = Calendar.getInstance(); - tStart.setTime(dtf.parse(ds.getString(0,0))); - dtf = new SimpleDateFormat("MM/dd/yyyy"); - //endRangeText = dtf.format(tStart.getTime()); - endRangeText = dtf.format(tStart.getTime().getTime()+MILLIS_IN_DAY); - }catch(Exception e){ - System.out.println("Exception////////// : end range date is : " + e); - } - } - - - ////////////////////// - String calendarOnClickMethodCall = ""; - String timeStampStr = ""; - if (stRangeText == null || endRangeText == null) - calendarOnClickMethodCall = "'oCalendar.select(document." + HTML_FORM + "." + fieldName + ", event,\""+ Globals.getCalendarOutputDateFormat() +"\"); return false;'"; - else - calendarOnClickMethodCall = "'oCalendar=new CalendarPopup(\"calendarDiv\", \"calendarFrame\");oCalendar.setCssPrefix(\"raptor\");oCalendar.addDisabledDates(null, \"" + stRangeText + "\"); oCalendar.addDisabledDates(\"" + endRangeText + "\", null); oCalendar.select(document." + HTML_FORM + "." + fieldName + ", event,\""+ Globals.getCalendarOutputDateFormat() +"\"); return false;'"; - returnString += "\" " + getHelpLink(fieldName) - + (validationType.equals(VT_DATE) || validationType.equals(VT_TIMESTAMP_HR) || validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC) - ? "\n\t\t\t" - : ""); - if(validationType.equals(VT_TIMESTAMP_HR) || validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC) ) { - //Add Hours/Minutes and Seconds. - timeStampStr = " Hour "; - } - //Minutes - if( validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC) ) { - int minutes = 0; - int t_min = 0; - try { - minutes = Integer.parseInt(nvl(rr.getParamValue(fieldName+"_Min"),"0")); - if(minutes == 0) { - if(inSchedule) minutes = Integer.parseInt(nvl(((String)formValues.get(fieldName+"_Min")),"0")); - } - } catch (NumberFormatException ex) {minutes = 0;} - try { - t_min = Integer.parseInt(timestampmin); - } catch (NumberFormatException ex) { t_min = 0;} - - if(minutes <= 0) minutes = t_min; - /*if (formValues.containsKey(fieldDisplayName+"_Min")){ - formValues.remove(fieldDisplayName+"_Min"); - formValues.put(fieldDisplayName+"_Min", minutes); - } else - formValues.put(fieldDisplayName+"_Min", minutes); - */ - timeStampStr += " Min "; - } - //Seconds - if( validationType.equals(VT_TIMESTAMP_SEC) ) { - int seconds = 0; - int t_sec = 0; - try { - seconds = Integer.parseInt(nvl(rr.getParamValue(fieldName+"_Sec"),"0")); - if(seconds == 0) { - if(inSchedule) seconds = Integer.parseInt(nvl(((String)formValues.get(fieldName+"_Sec")),"0")); - } - } catch (NumberFormatException ex) {seconds = 0;} - try { - t_sec = Integer.parseInt(timestampsec); - } catch (NumberFormatException ex) { t_sec = 0;} - - if(seconds <= 0) seconds = t_sec; - /*if (formValues.containsKey(fieldDisplayName+"_Sec")){ - formValues.remove(fieldDisplayName+"_Sec"); - formValues.put(fieldDisplayName+"_Sec", seconds); - } else - formValues.put(fieldDisplayName+"_Sec", seconds); - */ - timeStampStr += " Sec "; - } - - returnString += timeStampStr; - String checkboxStr = ""; - if(inSchedule && (validationType.equals(VT_DATE) || validationType.equals(VT_TIMESTAMP_HR) || validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC)) ) { - if(!Globals.isScheduleDateParamAutoIncr()) { - checkboxStr = /*checkboxStr +" "+ */ ""; - } else { - checkboxStr = /*checkboxStr +" "+ */""; - } - /*if(validationType.equals(VT_TIMESTAMP_HR) || validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC)) { - checkboxStr = checkboxStr +" "+ ""; - } - if(validationType.equals(VT_TIMESTAMP_MIN) || validationType.equals(VT_TIMESTAMP_SEC)) { - checkboxStr = checkboxStr +" "+ ""; - } - if(validationType.equals(VT_TIMESTAMP_SEC)) { - checkboxStr = checkboxStr +" "+ ""; - }*/ - } - if(isVisible()) - return returnString+checkboxStr; - else return ""; - } else if (fieldType.equals(FFT_TEXTAREA)) { - - if(nvl(fieldValue).length()>0) { - fieldValue = Pattern.compile("(^[\r\n])|\\([\\']", Pattern.DOTALL).matcher(fieldValue).replaceAll(""); - fieldValue = Pattern.compile("[\\']\\)", Pattern.DOTALL).matcher(fieldValue).replaceAll(""); - fieldValue = fieldValue.replaceAll("','",","); // changed from "|" - fieldValue = fieldValue.replaceAll("' , '","\r\n"); - } - - if(isVisible()) - return " -

        ?E!@0MaQRVh4|dffmc(JoYXmc87H?BNNdu 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/3_wed.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/3_wed.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8c032879226ffe84f24d66a9c2e1746f0d9b59 GIT binary patch literal 24012 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 AIsgCw literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/4_thu.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/4_thu.png new file mode 100644 index 0000000000000000000000000000000000000000..750dca5d6623e093ad27d516fa5e5b7db0b3a8ca GIT binary patch literal 23902 zcmb?@c|4R~|Gu5FrK0TF%bJ~G7$Kr4l6~y^76#c(ic$z6``AKuvacokHVR`OyRnNw zhT(TlpXd2L&+GO3{{H*@QMd8B=iKL<`<(atdSBOdynU>rL3^3yG7%9G?E_6UJt87v zEbvd5iURnJbdyRC5s^9H12vVWFQ&FLC_h~{7>^)-a)qW|FsF<}Fh@vq-h<@H)5nIR zV+Mu{Picfoa;h40MEP$*RGviKR%Nm6(Y`Bw>y{|RhuiX+91)k66(1^w221O^`5E~5 z8O&y;?5yu94*Mf_HYDpd<{Ect*D}51AK$)y`SrcG{_<~Q!|r7RpGY$PUM|CR2%j#$ zh7|mB3qt?zo&UOUA@2~rmwg5E_wtwuM)>sa%WX0c;nV-s*#D!=e>Fz9Xr=d@$t3qb z5XiXxwEP9GdvR!q*O&A9-`?arqr)E+3!Bv=3yA72F3Kl@J^`I0Jo&13hT4_q*MPnd zo*+ntq%TS1KbG;}UK=muzhUMZj!ml*THckTLi}_4Ye-wkP=>_s)BGy8*?Y`;0n|ml zzCysr|8}8-7>^%24Z5)S)Fw7>^6%fiCkplmu|m3B0-i^h6LAvkI*3+lDt_a`{_jstViI;DJ`+Q_zTEi+lN!gpU=Olfy0lVh<5dd&ZGt zl5}rkzU4)2;cG`N={hiyk;Bx2pSmJqxC*@)6}sBn2T!#T*Dz!txX%C23v>#C>N7)3Tw?g2 zrW=oMiE0==IL_qMZVSP~*iQ^n&;3<&8XxNF#AiQHwR7B;dN6$F4Q7pz9K+m(=Z{1O z=|>GI=;qz0m7i&l{7?Uq!N^!U-Nftz3E`}A&2u%qq#J%=ll}U69{c4Cc*SveW~FB? zTgbNbof6|~>%}Bk%j2E@j1O81LAN-*!m>-=3pn1ogO7|!I6T$GWYKS=++uFvtKOP< z_y8jZigL>fwY=4ggfsHkutlFj*Fo8*cmR>{2({UG5lYWFlrqI6R(sFks%jOPi{ zxDPBjUvYya99QTUB_t@vJ==J^KUh*7B)KX403&}pC+oC7o=@9$C|zF3ye*_f$&{+# z6CblAb-D9X8vD?1W%5dPQP*XhuV0-fcgS=)5xyu79m`mm`AGSaIjRr5aD0W4^|6%M zfX-7_%h6(wZO7c_j0%MgqjgcVJlQ0DdDfJ}WW)ClPwwlR=Sp^LsdZA!aZ%0P8Lw$l z>Ux_K@>sWI^XIzF%-#>9=qM0Ej8z)KWXmLbp1Xdq(sAA?iIrZ$^}ZVGd_7lZ{}RjE z#t%&M_xRKEJl@`>{k{*khMQJdCW{AWlJRHNu7%LqeSCHudNp1ld8T1`h|f>7!MnEw z3(pLEUj6Wwn?2CFKx#U zs3Luu{R{=tEh5atap;AB3py0NpZ49PhW7wv0W5)kt%MASm;u6L;#LE_;w`-*y*=>$ z!EiEZFix{8hP~F8263?)dXbR3J#88iy11HVXK2FmpXGcF!$8?cF_A0QChWCQ^eq;V z;TaJ!r>Ghpa@+JAGCWbGzF*eZ*O)a|BlO>2ile}dIAmVBynl~&ndmO}H~GpHdKfzg zH4{dLWb0X(aG=1$TZBdWuO5Q+AZTUVH~9BwAN7|pzjU>eI>5V@5c(t8%g(5zfkdJI z+?oL~B**RSwkB{NFjQ+LE>GCRJ{T8kd*Mvu3qdJd2xNWTDL@AlcNWF`vkm@v!i~hF z2KS6*RH+NxHQ@9}E1K&jQnJ=Pu{nZPBy@Lgv;4n<%+4i@lap7Dzc;m6Td}b|lc>>S zK?n-GUbB07SZTU3D>MGye?_B4Qv~PwXfMfujn77pNHlBz_t(_gw3q+~S^M`ZMr;x_ zDan8SyZiKGM3HngM2s3glVVs4!t1}n%jj>PpXm07ao0V#);rPqKW`1##@Gt>lV*QC zTe{va--6LSar;ZL%1O+~xB%(n2v*_8%0DZ4{(IWFGUmt2lg|PUORfa}R>z-8kb{nX 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 literal 0 HcmV?d00001 diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/6_sat.png b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/static/fusion/sample/images/tunnels/6_sat.png new file mode 100644 index 0000000000000000000000000000000000000000..70323ea04fb0b967ca06bbb75376dab90fd9238e GIT binary patch literal 23674 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

        -
        -
        -
        - - -
        - -
        -
        - - -
        - -
        -
        - -
        - - -
        -
        -
        -
        -
        -
        -
        - -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/broadcast_list.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/broadcast_list.jsp deleted file mode 100644 index 2f6c68b5..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/broadcast_list.jsp +++ /dev/null @@ -1,201 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ page import="java.util.*" %> -<%@ page import="com.fasterxml.jackson.databind.ObjectMapper" %> -<%@ page import="org.json.JSONObject" %> -<%@ page import="java.io.StringWriter" %> -<%@ page import="org.openecomp.portalsdk.core.web.support.ControllerProperties" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> - - - - -
        -

        - Broadcast Messages -

        -
        - - <%-- Display a table for the broadcast messages of each message location --%> -
        - -
        - {{location.label}} Messages -
        - - - - - - - - - - - - - - - - - {{message.id}} - - - - - - - - - - - -
        No.Message TextStart DateEnd DateSort OrderServerActive?Delete?
        {{$index+1}}{{message.messageText}} - {{message.displayStartDate}} - {{message.displayEndDate}}{{message.sortOrder}}{{message.siteCd}} -
        - -
        -
        -
        -
        -
        - -


        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/collaborateList.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/collaborateList.jsp deleted file mode 100644 index b1fbfab1..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/collaborateList.jsp +++ /dev/null @@ -1,146 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> - -
        -
        -

        User List

        -
        - - - - - - - - - - - - - - - - - - - - - - -
        User IDLast NameFirst NameEmailUserIdOnline/Offline
        - Offline - Online -
        -
        -
        -
        - Rows Per Page: - -
        -
        - Current Page: - -
        -
        - Total Page(s): - -
        - - -
        - - - - - - - - - - - -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp deleted file mode 100644 index 5a33314f..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_footer.jsp +++ /dev/null @@ -1,46 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> - - - - - -
        -
        - -
        - -
        -
        -
        - - -
        -
        -
        -
        -
        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp deleted file mode 100644 index 05c07f0d..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/ebz_header.jsp +++ /dev/null @@ -1,799 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> -<%@ page isELIgnored="false"%> -<%@ page import="org.openecomp.portalsdk.core.util.SystemProperties"%> -<%@ page import="org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties"%> -<%@ page import="org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants"%> -<%@ page import="org.openecomp.portalsdk.core.domain.MenuData"%> - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" /> -" /> - -<% - String contactUsLink = SystemProperties.getProperty(SystemProperties.CONTACT_US_LINK); - String redirectUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); - String portalUrl = redirectUrl.substring(0, redirectUrl.lastIndexOf('/')) + "/processSingleSignOn"; - String getAccessLink = redirectUrl.substring(0, redirectUrl.lastIndexOf('/')) + "/get_access"; -%> - - - - -<%@include file="/WEB-INF/fusion/jsp/ebz/loginSnippet.html" %> - -
        -
        - -
        -
        -
        - - -
        -
        -
        -
        -
      • - - ECOMP Portal -
      • -
        -
        - -
        -
        - - -
        - - -
        -
        -
        -
      • - Unable to load menus -
      • -
        - -
        -
      • -
        - - -
        -
      • -
      •  
      • -
        - -
        -
        -
        -
        -
        -
        -
        - -
        -
        - - - -     {{app_name}} - -
        -
        -
        -
        - - - - - -
        -
        -
        -
        -
        -
        -
        -
        - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/loginSnippet.html b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/loginSnippet.html deleted file mode 100644 index 0f29ee77..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz/loginSnippet.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template.jsp deleted file mode 100644 index 59b61d19..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template.jsp +++ /dev/null @@ -1,45 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> - - - - - <%@ include file="/WEB-INF/fusion/jsp/meta.jsp" %> - - - -
        -
        - -
        -
        -
        -
        - -
        -
        -
        -
        - -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_noheader_nofooter.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_noheader_nofooter.jsp deleted file mode 100644 index 98dccb4c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_noheader_nofooter.jsp +++ /dev/null @@ -1,35 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> - - - <%@ include file="/WEB-INF/fusion/jsp/meta.jsp" %> - -
        - -
        -
        - -
        -
        - -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_report_embedded.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_report_embedded.jsp deleted file mode 100644 index 4281a063..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/ebz_template_report_embedded.jsp +++ /dev/null @@ -1,48 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> - - - <%@ include file="/WEB-INF/fusion/jsp/meta.jsp" %> - - - - - - - - - - - - - - - - - - -
        -
        - -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/es_search_demo.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/es_search_demo.jsp deleted file mode 100644 index eae5324b..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/es_search_demo.jsp +++ /dev/null @@ -1,97 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - - - -
        -
        Elastic Search - Corporate Location Data System
        -
        -
        - -   -
        - - - - - - - - - - - - - - - - - - - - - - - - -
        Customer NamePhoneStreetCityStateZIPCLLI
        {{options._source.name}}{{options._source.suggest.payload.tn}}{{options._source.suggest.payload.addr}}{{options._source.suggest.payload.city}}{{options._source.suggest.payload.st}}{{options._source.suggest.payload.zip}}{{options._source.suggest.payload.clli}}
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp deleted file mode 100644 index 05cfaf55..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/es_suggest_demo.jsp +++ /dev/null @@ -1,97 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - - - -
        -
        Elastic Search - Corporate Location Data System
        -
        -
        - -   -
        - - - - - - - - - - - - - - - - - - - - - - - - -
        Customer NamePhoneStreetCityStateZIPCLLI
        {{options.text}}{{options.payload.tn}}{{options.payload.addr}}{{options.payload.city}}{{options.payload.st}}{{options.payload.zip}}{{options.payload.clli}}
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/frame_insert.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/frame_insert.jsp deleted file mode 100644 index 5f550c68..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/frame_insert.jsp +++ /dev/null @@ -1,44 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/jcs_admin.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/jcs_admin.jsp deleted file mode 100644 index 845beac2..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/jcs_admin.jsp +++ /dev/null @@ -1,144 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%-- <%@ include file="/WEB-INF/fusion/jsp/include.jsp"%> --%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> - -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> - -
        -

        Cache Regions

        - These are the regions which are currently defined in the cache. 'Items' and 'Bytes' refer to the elements currently in memory (not spooled). - You can clear all items for a region by clicking on the Clear icon next to the desired region below. You can also clear all regions which - empties the entire cache.

        - -
        -
        -
        Cache Name
        -
        # of Items
        -
        Bytes
        -
        Status
        -
        Memory Hits
        -
        Aux Hits
        -
        Not Found Misses
        -
        Expired Misses
        -
        Clear?
        -
        Items
        -
        -
        -
        - -
        {{region.size}}
        -
        {{region.byteCount}}
        -
        {{region.status}}
        -
        {{region.hitCountRam}}
        -
        {{region.hitCountAux}}
        -
        {{region.missCountNotFound}}
        -
        {{region.missCountExpired}}
        -
        -
        -
        -
        -
        -
        - -
        Key
        -
        Eternal?
        -
        Created
        -
        Max Life
        -
        Expires
        -
        Clear?
        -
        -
        -
        - - -
        {{item.eternal}}
        -
        {{item.createTime}}
        -
        {{item.maxLifeSeconds}}
        -
        {{item.expiresInSeconds}}
        -
        -
        -
        -
        -
        -
        -
        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/meta.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/meta.jsp deleted file mode 100644 index 3c4ff52a..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/meta.jsp +++ /dev/null @@ -1,36 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - - - - - - - - - - - - - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/post_search.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/post_search.jsp deleted file mode 100644 index 94d4b0bf..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/post_search.jsp +++ /dev/null @@ -1,356 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ page import="java.util.*" %> -<%@ page import="com.fasterxml.jackson.databind.ObjectMapper" %> -<%@ page import="org.json.JSONObject" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal_rolefunction.html" %> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal_role.html" %> - - -
        - -

        WEBPHONE Search

        -
        - Please enter search criteria below:
        - -
        - Last Name:
        - -
        - -
        - First Name:
        - -
        - -
        - UserId:
        - -
        - -
        - Manager OrgUserId:
        - -
        -
        -
        - Organization:
        - -
        - -
        - Email:
        - -
        -
        - -
        - - - -
        -
        - {{noResultsString}} -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        NoNameOrgUserIdOrganizationPhoneEmailImport?
        - {{$index + 1}} - -
        - {{profile.lastName}}, {{profile.firstName}} -
        - - -
        - {{profile.orgUserId}} - - {{profile.orgCode}} - - {{profile.phone}} - - {{profile.email}} - -
        -
        - -
        -
        -
        - Exists -
        -
        -
        - Rows Per Page: - -
        -
        - Current Page: - -
        -
        - Total Page(s): - -
        - -
        - -
        - -
        - - - - -
        - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/profile.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/profile.jsp deleted file mode 100644 index b01fa6b8..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/profile.jsp +++ /dev/null @@ -1,442 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ page import="org.openecomp.portalsdk.core.domain.User"%> -<%@ page import="org.openecomp.portalsdk.core.web.support.UserUtils"%> - -<%@page import="org.openecomp.portalsdk.core.web.support.ControllerProperties"%> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> - - - -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> - -<%@ include file="/WEB-INF/fusion/jsp/include.jsp"%> - -
        -

        - - -

        Profile Edit

        -
        - -

        Profile Edit

        -
        -
        -

        -
        - -
        - - Please edit the profile details below: 

        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        -
        -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        -
        -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        -
        -
        -
        - -
        - -
        -
        -
        -
        - -
        -
        - -
        - -
        -
        -
        -
        -
        -
        -
        -
        -
        - -
        - -
        - -
        -
        - - - -
        - - - - - - - - - - - - - - - - -
        NameRemove?
        {{ role.name }} - -
        - - - -
        - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/profile_search.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/profile_search.jsp deleted file mode 100644 index 295faf03..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/profile_search.jsp +++ /dev/null @@ -1,104 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> -
        -
        -

        Profile Search

        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - -
        User IDLast NameFirst NameEmailOrgUserIdManager OrgUserIdEditActive?
        {{rowData.id}}{{rowData.lastName}}{{rowData.firstName}}{{rowData.email}}{{rowData.orgUserId}}{{rowData.managerId}} -
        - -
        -
        -
        -
        -
        - Rows Per Page: - -
        -
        - Current Page: - -
        -
        - Total Page(s): - -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role.jsp deleted file mode 100644 index d8e2a01b..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role.jsp +++ /dev/null @@ -1,286 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> - -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal_rolefunction.html" %> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal_role.html" %> - -
        - -
        -
        -

        - - -

        Role Edit

        -
        - -

        Role Create

        -
        -
        -

        -
        - -
        - -
        - Please edit the role details below: 
        - -
        -
        - -
        - -
        -
        - -
        - -
        - -
        - -
        -
        - - -
        - - - - - - - - - - - - - - -
        NameRemove?
        {{ roleFunction.name }} -
        -
        - Manage Role Functions

        - -
        - - -
        - - - - - - - - - - - - - - -
        NameRemove?
        {{ role.name }} -
        -
        - -
        - - - - - - - - - - - - - - -
        Role
        -
        - -
        -
        {{ availableRole.name }}
        -
        -
        - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role_function_list.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role_function_list.jsp deleted file mode 100644 index b957337c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role_function_list.jsp +++ /dev/null @@ -1,213 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - -<%-- <%@ include file="/WEB-INF/fusion/jsp/include.jsp" %> --%> - -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> - -<%@ include file="/WEB-INF/fusion/jsp/popup_modal_rolefunction.html" %> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> -
        -
        - -

        Role Functions

        - - -

        - -
        - -
        - Click on the edit icon to update a role function, the plus icon to add additional role functions, or the delete icon to remove them. -
        -
        - - - - - - - - - - - - - - - - - -
        NameCodeEdit?Delete?
        {{ availableRoleFunction.name }}{{ availableRoleFunction.code }} - -
        -
        - -
        -
        -
        - - - - - - -
        - -
        -
        - -
        -
        -
        -
        - -
        -
        - - -
        - -
        - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role_list.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role_list.jsp deleted file mode 100644 index c27c360b..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/role_list.jsp +++ /dev/null @@ -1,139 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - -<%-- <%@ include file="/WEB-INF/fusion/jsp/include.jsp" %> --%> - -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> - -
        -

        Roles

        -
        -
        -Click on a Role to view its details. - -
        -
        - - - - - - - - - - - - - - - - - - -
        NamePriorityActive?Delete?
        {{ availableRole.name }}{{ availableRole.priority }} -
        - -
        -
        -
        -
        -
        - -
        - -
        - -
        - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/usage_list.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/usage_list.jsp deleted file mode 100644 index 699c1ce6..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/usage_list.jsp +++ /dev/null @@ -1,87 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - -<%-- <%@ include file="/WEB-INF/fusion/jsp/include.jsp" %> --%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> - -
        -
        -

        - Usage -

        -
        -
        - The following shows all users currently logged into the application. Click the icon to expel a user from the application. - -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        Current User Sessions
        User IdUser NameEmailLast Access Time (minutes)Time Remaining (minutes)Expel?
        {{user.id}}{{user.lastName}}{{user.email}}{{user.lastAccess}}{{user.remaining}}
        Current Session
        -
        -
        -
        -
        - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/webrtc/collaboration.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/webrtc/collaboration.jsp deleted file mode 100644 index ff6c985e..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/jsp/webrtc/collaboration.jsp +++ /dev/null @@ -1,492 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> - - - - - - - - - - - - - - - -
        -
        - - - - - - - - - - - - - - - - - -
        - - - - -
        - -
        -
        - - -
        -
        -
        -
        - -
        -
        - -
        -
        -
        -
        -
        -
        - - - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_drill_down_report.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_drill_down_report.jsp deleted file mode 100644 index 53959482..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/popup_drill_down_report.jsp +++ /dev/null @@ -1,601 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ page import="java.util.*" %> - -<%@ page import="org.openecomp.portalsdk.analytics.xmlobj.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.model.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.model.definition.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.model.runtime.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.system.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.util.*" %> - -<% ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute(AppConstants.SI_REPORT_DEFINITION); - List reportCols = rdef.getAllColumns(); - List rFormFields = null; - if(rdef.getFormFieldList()!=null&&rdef.getFormFieldList().getFormField().size()>0) - rFormFields = rdef.getFormFieldList().getFormField(); - - ReportFormFields ddReportFormFields = (ReportFormFields) request.getAttribute(AppConstants.RI_FORM_FIELDS); - - String drillDownSuppress = AppUtils.getRequestNvlValue(request, "drillDownSuppress"); - String drillDownParams = AppUtils.getRequestNvlValue(request, "drillDownParams"); - String drillDownRequest = AppUtils.getRequestNvlValue(request, "drillDownRequest"); - - Hashtable paramDefinitions = new Hashtable(); - StringTokenizer st = new StringTokenizer(drillDownParams, "&"); - //Added for passing request parameters in Drill Down - String[] reqParameters = Globals.getRequestParams().split(","); - int icnt=0; - // - while(st.hasMoreTokens()) { - String param = st.nextToken(); - DrillDownParamDef paramDef = new DrillDownParamDef(param); - if(paramDef.getFieldName().length()>0) - paramDefinitions.put(paramDef.getFieldName(), paramDef); - } // while -%> - - - - Drill-down Parameters Configuration - - - - - - - -
        - - - - - -<% if(ddReportFormFields!=null) - for(ddReportFormFields.resetNext(); ddReportFormFields.hasNext(); ) { - FormField ff = ddReportFormFields.getNext(); - if(!ff.getFieldType().equals(FormField.FFT_BLANK)) { - - DrillDownParamDef paramDef = (DrillDownParamDef) paramDefinitions.get(ff.getFieldName()); - if(paramDef==null) - paramDef = new DrillDownParamDef(""); %> - - <% if (ff!=null && (ff.getValidationType().equals(FormField.VT_TIMESTAMP_HR) || ff.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || ff.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) ) { - %> - - - - - - - - - - - - - - - -<% if(rFormFields!=null) { %> - - - - - - - - -<% } // if - -%> - - <% - paramDef = (DrillDownParamDef) paramDefinitions.get(ff.getFieldName()+"_Hr"); - if(paramDef==null) - paramDef = new DrillDownParamDef(""); - %> - - - - - - - - - - - -<% - if (ff.getValidationType().equals(FormField.VT_TIMESTAMP_MIN) || ff.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { -%> - <% - paramDef = (DrillDownParamDef) paramDefinitions.get(ff.getFieldName()+"_Min"); - if(paramDef==null) - paramDef = new DrillDownParamDef(""); - %> - - - - - - - - - - - -<% - } - if(ff.getValidationType().equals(FormField.VT_TIMESTAMP_SEC)) { -%> - <% - paramDef = (DrillDownParamDef) paramDefinitions.get(ff.getFieldName()+"_Sec"); - if(paramDef==null) - paramDef = new DrillDownParamDef(""); - %> - - - - - - - - - - - -<% - - } - - } else { -%> - - - - - - - - - - - - - - - -<% if(rFormFields!=null) { %> - - - - - - - - -<% } // if - } // else - } // if BLANK - } // for -%> - - - - - - - - - - - - - - - - - <% if(!Globals.getPassRequestParamInDrilldown() && (!(reqParameters.length==1 && reqParameters[0].length()<=0))) { - %> - - - - - <% - icnt=0; - - for (int i = 0; i < reqParameters.length; i++) { - icnt++; - - %> - > - - - - - <% - } //for - %> - - <% - } // if requestParam - %> - - - - - - - -
        - DRILL-DOWN PARAMETERS CONFIGURATION -
        -  <%= ff.getFieldDisplayName() %> -
        -       - >No value - - Accept default -
        -       - >Fixed value - - " onChange="document.dataform.r_<%= ff.getFieldName() %>[1].click();"> -
        -       - >Value of column - - -
        -       - >Value of form field - - -
        -       - >Value set - - Pass the value of the selected column if not empty,
        - otherwise pass the value of the selected form field
        -
        -  <%= ff.getFieldDisplayName() %> (Hour) -
        -       - >No value - - Accept default -
        -       - >Value of column - - - - -
        -  <%= ff.getFieldDisplayName() %> (Minutes) -
        -       - >No value - - Accept default -
        -       - >Value of column - - - - -
        -  <%= ff.getFieldDisplayName() %> (Seconds) -
        -       - >No value - - Accept default -
        -       - >Value of column - - - - -
        -  <%= ff.getFieldDisplayName() %> -
        -       - >No value - - Accept default -
        -       - >Fixed value - - " onChange="document.dataform.r_<%= ff.getFieldName() %>[1].click();"> -
        -       - >Value of column - - -
        -       - >Value of form field - - -
        -       - >Value set - - Pass the value of the selected column if not empty,
        - otherwise pass the value of the selected form field
        -
         
        -  Parameter values not to be passed to the drill-down report
        -       - Suppress values - - -
        separate by | if multiple values
        -
         
        -  Request Parameter values to be passed to the drill-down report
        <%= reqParameters[i]%> - > -
        - Show Drilled Down Report In Popup Window: -
        -
        -

        - - - - -<%! private String nvl(String s) { return (s==null)?"":s; } - private String nvl(String s, String sDefault) { return nvl(s).equals("")?sDefault:s; } %> - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_import.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_import.jsp deleted file mode 100644 index 014f98ac..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_import.jsp +++ /dev/null @@ -1,69 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ page import="java.util.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.system.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.util.*" %> - - - - Import - - - - -

        - -
        - - - - - - - - - - - - - -
        - <%= Globals.getBaseTitle() %> > IMPORT REPORT XML -
        - - - -
        -
        - -
        - - - -
        - - - - - - -<%! private String nvl(String s) { return (s==null)?"":s; } - private String nvl(String s, String sDefault) { return nvl(s).equals("")?sDefault:s; } %> - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_wizard.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_wizard.jsp deleted file mode 100644 index cdfe943a..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/fusion/raptor/report_wizard.jsp +++ /dev/null @@ -1,309 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%-- - Name: report_wizard.jsp - Use : Master JSP which navigates to specific JSP when different tab is selected. Default it navigates to the wizard_definition.jsp - - Change Log - ========== - - 22-Jun-2009 : Version 8.4 (Sundar); - -
          -
        • Save button is suppressed from showing when wizard is in the last page (Run page).
        • -
        • width of the content_iframe is changed back to default one when navigated from >100% report's run page.
        • -
        ---%> -<%@ page import="java.util.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.xmlobj.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.model.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.model.base.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.model.definition.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.model.runtime.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.controller.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.system.*" %> -<%@ page import="org.openecomp.portalsdk.analytics.util.*" %> - -<%@ page errorPage="error_page.jsp" %> - - - - - - -<% ReportDefinition rdef = (ReportDefinition) request.getSession().getAttribute(AppConstants.SI_REPORT_DEFINITION); - - String reportID = rdef.getReportID(); - WizardSequence ws = rdef.getWizardSequence(); - - String curStep = ws.getCurrentStep(); - String curSubStep = ws.getCurrentSubStep(); - - String dbInfo = null; - dbInfo = rdef.getDBInfo(); - int sessionflag = 0; - if(dbInfo == null || dbInfo.length() == 0) { - dbInfo = (String) session.getAttribute("remoteDB"); - sessionflag = 1; - } - session.setAttribute("remoteDB", dbInfo); - if((dbInfo == null) && (request.getParameter("dataSource")!=null)) - session.setAttribute("remoteDB", request.getParameter("dataSource")); - - String title = (reportID.equals("-1")?"Create Report":"Edit Report"); - String navTitle = Globals.getBaseTitle()+" > " + title; - - boolean isCrossTab = rdef.getReportType().equals(AppConstants.RT_CROSSTAB); - boolean isSQLBased = rdef.getReportDefType().equals(AppConstants.RD_SQL_BASED); -%> - -<% - request.setAttribute(AppConstants.SI_REPORT_DEFINITION,rdef); -%> - - - - - - - - - - - - - -
        - -
        -
        -
        - -
        - - - - - - - - - - -
        - - -<% for(ws.resetNext(); ws.hasNext(); ) { - String sTab = ws.getNext(); %> - - - -<% } // for -%> - - -
        " width="9" height="24"> align="center" valign="middle"> - <% if(sTab.equals(curStep)) { %> -  <%= clearSpaces(sTab) %>  - <% } else if(reportID.equals("-1")) { %> -  <%= clearSpaces(sTab) %>  - <% } else { %> -  <%= clearSpaces(sTab) %>  - <% } %> - " width="9" height="24"> 
        -
        - - - - -
        <%= navTitle %>
        -
        <% if(curStep.equals(AppConstants.WS_DEFINITION)) { %> - <% if(sessionflag == 1) dbInfo = ""; %> - -<% } else if(curStep.equals(AppConstants.WS_SQL)) { %> - -<% } else if(curStep.equals(AppConstants.WS_TABLES)&&curSubStep.equals("")) { %> - -<% } else if(curStep.equals(AppConstants.WS_TABLES)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT))) { %> - -<% } else if(curStep.equals(AppConstants.WS_COLUMNS)&&curSubStep.equals("")) { %> - -<% } else if(curStep.equals(AppConstants.WS_COLUMNS)&&curSubStep.equals(AppConstants.WSS_ADD_MULTI)) { %> - -<% } else if(curStep.equals(AppConstants.WS_COLUMNS)&&curSubStep.equals(AppConstants.WSS_ORDER_ALL)) { %> - -<% } else if(curStep.equals(AppConstants.WS_COLUMNS)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT) ||curSubStep.equals(AppConstants.WA_MODIFY))) { %> - -<% } else if(curStep.equals(AppConstants.WS_FORM_FIELDS)&&curSubStep.equals("")||curSubStep.equals(AppConstants.WSS_ADD_BLANK)) { %> - -<% } else if(curStep.equals(AppConstants.WS_FORM_FIELDS)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT))) { %> - -<% } else if(curStep.equals(AppConstants.WS_FILTERS)&&curSubStep.equals("")) { %> - -<% } else if(curStep.equals(AppConstants.WS_FILTERS)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT))) { %> - -<% } else if(curStep.equals(AppConstants.WS_SORTING)&&curSubStep.equals("")) { %> - -<% } else if(curStep.equals(AppConstants.WS_SORTING)&&curSubStep.equals(AppConstants.WSS_ORDER_ALL)) { %> - -<% } else if(curStep.equals(AppConstants.WS_SORTING)&&(curSubStep.equals(AppConstants.WSS_ADD)||curSubStep.equals(AppConstants.WSS_EDIT))) { %> - -<% } else if(curStep.equals(AppConstants.WS_JAVASCRIPT)) { %> - -<% } else if(curStep.equals(AppConstants.WS_CHART)) { %> - -<% } else if(curStep.equals(AppConstants.WS_USER_ACCESS)) { %> - -<% } else if(curStep.equals(AppConstants.WS_SCHEDULE)) { %> - -<% } else if(curStep.equals(AppConstants.WS_REPORT_LOG)) { %> - -<% } else if(curStep.equals(AppConstants.WS_MAP)) { %> - -<% } else if(curStep.equals(AppConstants.WS_DATA_FORECASTING)) { %> - -<% } else { %> - -<% } %> - -
        - - - - - -
        -   - - <% if(! ws.isInitialStep()) { %> - - <% } %> - - <% if(! ws.isFinalStep()) { %> - - - <% } %> -
        -
        - -
        - - - - - -
        -
        -<%----%> - -<%! private String HTMLEncode(String value) { - StringBuffer sb = new StringBuffer(value); - - for(int i=0; i') - sb.replace(i, i+1, ">"); - else if(sb.charAt(i)=='"') - sb.replace(i, i+1, """); - - return sb.toString(); - } // HTMLEncode - - private String clearSpaces(String value) { - StringBuffer sb = new StringBuffer(value); - - for(int i=0; i - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/leafletMap.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/leafletMap.jsp deleted file mode 100644 index 77981f73..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/leafletMap.jsp +++ /dev/null @@ -1,288 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> - - - - - - - - - - - - - - - - - - -
        - - -
        - - - - - - - - - -
        SiteUsage
        - - - - - - - - - -
        LinkUsage
        -
        - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/login_external.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/login_external.jsp deleted file mode 100644 index b4e3c093..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/login_external.jsp +++ /dev/null @@ -1,154 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ page import="org.openecomp.portalsdk.core.util.SystemProperties" %> - -" /> - - - - - - - Login - - - - - - - - - - - - - - - - - - - - - - - - -
        -
        - -
        -
        - -

        ECOMP Portal

        - - -
        -
        - - -
        -
        -                - -
        -
        -
        -






        - -
        - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/user_profile.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/user_profile.jsp deleted file mode 100644 index cb5c4e3b..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/user_profile.jsp +++ /dev/null @@ -1,84 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ include file="/WEB-INF/fusion/jsp/popup_modal.html" %> -
        -
        -

        Profile Search

        -
        - - - - - - - - - - - - - - - - - - - - - - -
        User IDLast NameFirst NameEmailOrgUserIdManager OrgUserId
        {{rowData.id}}{{rowData.last_name}}{{rowData.first_name}}{{rowData.email}}{{rowData.orgUserId}}{{rowData.org_manager_userid}}
        -
        -
        -
        - Rows Per Page: - -
        -
        - Current Page: - -
        -
        - Total Page(s): - -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/welcome.jsp b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/welcome.jsp deleted file mode 100644 index a6096215..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/jsp/welcome.jsp +++ /dev/null @@ -1,630 +0,0 @@ -<%-- - ================================================================================ - eCOMP Portal SDK - ================================================================================ - Copyright (C) 2017 AT&T Intellectual Property - ================================================================================ - Licensed 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. - ================================================================================ - --%> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - -
        - Welcome ${sessionScope.user.firstName} ${sessionScope.user.lastName}  - (Last Login:  ${lastLogin}) -
        - -
        -
        -
        -
        -
        - -
        - - - - -
        - -
        -
        - -
        -
        -
        - -
        -
        - -
        - -
        - -
        - -
        - -
        - -
        -
        -
          -
        • {{Daytab.title}}
        • -
        -
        -
        -
        - - - - - - - -
        -
        - -
        -
        -
          -
        • {{TrafficTab.title}}
        • -
        -
        -
        -
        - - - - - -
        -
        - -
        - - - - - - - - - - - - - - - - - - -
        JQuery - -
        Animated Map - -
        Chat Session - -
        -
        -
        -
        -
        - -
        - - - - - - - - - -
        - -
        - - -
        - -
        -
        -
        -
        - -
        - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/web.xml b/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index fcbe8407..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - ecomp-sdk-app - - - - - - 7 - COOKIE - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-animate.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-animate.js deleted file mode 100644 index 2778fc56..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-animate.js +++ /dev/null @@ -1,4121 +0,0 @@ -/** - * @license AngularJS v1.5.0 - * (c) 2010-2016 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular, undefined) {'use strict'; - -/* jshint ignore:start */ -var noop = angular.noop; -var copy = angular.copy; -var extend = angular.extend; -var jqLite = angular.element; -var forEach = angular.forEach; -var isArray = angular.isArray; -var isString = angular.isString; -var isObject = angular.isObject; -var isUndefined = angular.isUndefined; -var isDefined = angular.isDefined; -var isFunction = angular.isFunction; -var isElement = angular.isElement; - -var ELEMENT_NODE = 1; -var COMMENT_NODE = 8; - -var ADD_CLASS_SUFFIX = '-add'; -var REMOVE_CLASS_SUFFIX = '-remove'; -var EVENT_CLASS_PREFIX = 'ng-'; -var ACTIVE_CLASS_SUFFIX = '-active'; -var PREPARE_CLASS_SUFFIX = '-prepare'; - -var NG_ANIMATE_CLASSNAME = 'ng-animate'; -var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren'; - -// Detect proper transitionend/animationend event names. -var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT; - -// If unprefixed events are not supported but webkit-prefixed are, use the latter. -// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them. -// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend` -// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`. -// Register both events in case `window.onanimationend` is not supported because of that, -// do the same for `transitionend` as Safari is likely to exhibit similar behavior. -// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit -// therefore there is no reason to test anymore for other vendor prefixes: -// http://caniuse.com/#search=transition -if (isUndefined(window.ontransitionend) && isDefined(window.onwebkittransitionend)) { - CSS_PREFIX = '-webkit-'; - TRANSITION_PROP = 'WebkitTransition'; - TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend'; -} else { - TRANSITION_PROP = 'transition'; - TRANSITIONEND_EVENT = 'transitionend'; -} - -if (isUndefined(window.onanimationend) && isDefined(window.onwebkitanimationend)) { - CSS_PREFIX = '-webkit-'; - ANIMATION_PROP = 'WebkitAnimation'; - ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend'; -} else { - ANIMATION_PROP = 'animation'; - ANIMATIONEND_EVENT = 'animationend'; -} - -var DURATION_KEY = 'Duration'; -var PROPERTY_KEY = 'Property'; -var DELAY_KEY = 'Delay'; -var TIMING_KEY = 'TimingFunction'; -var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount'; -var ANIMATION_PLAYSTATE_KEY = 'PlayState'; -var SAFE_FAST_FORWARD_DURATION_VALUE = 9999; - -var ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY; -var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY; -var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY; -var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY; - -var isPromiseLike = function(p) { - return p && p.then ? true : false; -}; - -var ngMinErr = angular.$$minErr('ng'); -function assertArg(arg, name, reason) { - if (!arg) { - throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required")); - } - return arg; -} - -function mergeClasses(a,b) { - if (!a && !b) return ''; - if (!a) return b; - if (!b) return a; - if (isArray(a)) a = a.join(' '); - if (isArray(b)) b = b.join(' '); - return a + ' ' + b; -} - -function packageStyles(options) { - var styles = {}; - if (options && (options.to || options.from)) { - styles.to = options.to; - styles.from = options.from; - } - return styles; -} - -function pendClasses(classes, fix, isPrefix) { - var className = ''; - classes = isArray(classes) - ? classes - : classes && isString(classes) && classes.length - ? classes.split(/\s+/) - : []; - forEach(classes, function(klass, i) { - if (klass && klass.length > 0) { - className += (i > 0) ? ' ' : ''; - className += isPrefix ? fix + klass - : klass + fix; - } - }); - return className; -} - -function removeFromArray(arr, val) { - var index = arr.indexOf(val); - if (val >= 0) { - arr.splice(index, 1); - } -} - -function stripCommentsFromElement(element) { - if (element instanceof jqLite) { - switch (element.length) { - case 0: - return []; - break; - - case 1: - // there is no point of stripping anything if the element - // is the only element within the jqLite wrapper. - // (it's important that we retain the element instance.) - if (element[0].nodeType === ELEMENT_NODE) { - return element; - } - break; - - default: - return jqLite(extractElementNode(element)); - break; - } - } - - if (element.nodeType === ELEMENT_NODE) { - return jqLite(element); - } -} - -function extractElementNode(element) { - if (!element[0]) return element; - for (var i = 0; i < element.length; i++) { - var elm = element[i]; - if (elm.nodeType == ELEMENT_NODE) { - return elm; - } - } -} - -function $$addClass($$jqLite, element, className) { - forEach(element, function(elm) { - $$jqLite.addClass(elm, className); - }); -} - -function $$removeClass($$jqLite, element, className) { - forEach(element, function(elm) { - $$jqLite.removeClass(elm, className); - }); -} - -function applyAnimationClassesFactory($$jqLite) { - return function(element, options) { - if (options.addClass) { - $$addClass($$jqLite, element, options.addClass); - options.addClass = null; - } - if (options.removeClass) { - $$removeClass($$jqLite, element, options.removeClass); - options.removeClass = null; - } - } -} - -function prepareAnimationOptions(options) { - options = options || {}; - if (!options.$$prepared) { - var domOperation = options.domOperation || noop; - options.domOperation = function() { - options.$$domOperationFired = true; - domOperation(); - domOperation = noop; - }; - options.$$prepared = true; - } - return options; -} - -function applyAnimationStyles(element, options) { - applyAnimationFromStyles(element, options); - applyAnimationToStyles(element, options); -} - -function applyAnimationFromStyles(element, options) { - if (options.from) { - element.css(options.from); - options.from = null; - } -} - -function applyAnimationToStyles(element, options) { - if (options.to) { - element.css(options.to); - options.to = null; - } -} - -function mergeAnimationDetails(element, oldAnimation, newAnimation) { - var target = oldAnimation.options || {}; - var newOptions = newAnimation.options || {}; - - var toAdd = (target.addClass || '') + ' ' + (newOptions.addClass || ''); - var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || ''); - var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove); - - if (newOptions.preparationClasses) { - target.preparationClasses = concatWithSpace(newOptions.preparationClasses, target.preparationClasses); - delete newOptions.preparationClasses; - } - - // noop is basically when there is no callback; otherwise something has been set - var realDomOperation = target.domOperation !== noop ? target.domOperation : null; - - extend(target, newOptions); - - // TODO(matsko or sreeramu): proper fix is to maintain all animation callback in array and call at last,but now only leave has the callback so no issue with this. - if (realDomOperation) { - target.domOperation = realDomOperation; - } - - if (classes.addClass) { - target.addClass = classes.addClass; - } else { - target.addClass = null; - } - - if (classes.removeClass) { - target.removeClass = classes.removeClass; - } else { - target.removeClass = null; - } - - oldAnimation.addClass = target.addClass; - oldAnimation.removeClass = target.removeClass; - - return target; -} - -function resolveElementClasses(existing, toAdd, toRemove) { - var ADD_CLASS = 1; - var REMOVE_CLASS = -1; - - var flags = {}; - existing = splitClassesToLookup(existing); - - toAdd = splitClassesToLookup(toAdd); - forEach(toAdd, function(value, key) { - flags[key] = ADD_CLASS; - }); - - toRemove = splitClassesToLookup(toRemove); - forEach(toRemove, function(value, key) { - flags[key] = flags[key] === ADD_CLASS ? null : REMOVE_CLASS; - }); - - var classes = { - addClass: '', - removeClass: '' - }; - - forEach(flags, function(val, klass) { - var prop, allow; - if (val === ADD_CLASS) { - prop = 'addClass'; - allow = !existing[klass]; - } else if (val === REMOVE_CLASS) { - prop = 'removeClass'; - allow = existing[klass]; - } - if (allow) { - if (classes[prop].length) { - classes[prop] += ' '; - } - classes[prop] += klass; - } - }); - - function splitClassesToLookup(classes) { - if (isString(classes)) { - classes = classes.split(' '); - } - - var obj = {}; - forEach(classes, function(klass) { - // sometimes the split leaves empty string values - // incase extra spaces were applied to the options - if (klass.length) { - obj[klass] = true; - } - }); - return obj; - } - - return classes; -} - -function getDomNode(element) { - return (element instanceof angular.element) ? element[0] : element; -} - -function applyGeneratedPreparationClasses(element, event, options) { - var classes = ''; - if (event) { - classes = pendClasses(event, EVENT_CLASS_PREFIX, true); - } - if (options.addClass) { - classes = concatWithSpace(classes, pendClasses(options.addClass, ADD_CLASS_SUFFIX)); - } - if (options.removeClass) { - classes = concatWithSpace(classes, pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX)); - } - if (classes.length) { - options.preparationClasses = classes; - element.addClass(classes); - } -} - -function clearGeneratedClasses(element, options) { - if (options.preparationClasses) { - element.removeClass(options.preparationClasses); - options.preparationClasses = null; - } - if (options.activeClasses) { - element.removeClass(options.activeClasses); - options.activeClasses = null; - } -} - -function blockTransitions(node, duration) { - // we use a negative delay value since it performs blocking - // yet it doesn't kill any existing transitions running on the - // same element which makes this safe for class-based animations - var value = duration ? '-' + duration + 's' : ''; - applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]); - return [TRANSITION_DELAY_PROP, value]; -} - -function blockKeyframeAnimations(node, applyBlock) { - var value = applyBlock ? 'paused' : ''; - var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY; - applyInlineStyle(node, [key, value]); - return [key, value]; -} - -function applyInlineStyle(node, styleTuple) { - var prop = styleTuple[0]; - var value = styleTuple[1]; - node.style[prop] = value; -} - -function concatWithSpace(a,b) { - if (!a) return b; - if (!b) return a; - return a + ' ' + b; -} - -var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) { - var queue, cancelFn; - - function scheduler(tasks) { - // we make a copy since RAFScheduler mutates the state - // of the passed in array variable and this would be difficult - // to track down on the outside code - queue = queue.concat(tasks); - nextTick(); - } - - queue = scheduler.queue = []; - - /* waitUntilQuiet does two things: - * 1. It will run the FINAL `fn` value only when an uncanceled RAF has passed through - * 2. It will delay the next wave of tasks from running until the quiet `fn` has run. - * - * The motivation here is that animation code can request more time from the scheduler - * before the next wave runs. This allows for certain DOM properties such as classes to - * be resolved in time for the next animation to run. - */ - scheduler.waitUntilQuiet = function(fn) { - if (cancelFn) cancelFn(); - - cancelFn = $$rAF(function() { - cancelFn = null; - fn(); - nextTick(); - }); - }; - - return scheduler; - - function nextTick() { - if (!queue.length) return; - - var items = queue.shift(); - for (var i = 0; i < items.length; i++) { - items[i](); - } - - if (!cancelFn) { - $$rAF(function() { - if (!cancelFn) nextTick(); - }); - } - } -}]; - -/** - * @ngdoc directive - * @name ngAnimateChildren - * @restrict AE - * @element ANY - * - * @description - * - * ngAnimateChildren allows you to specify that children of this element should animate even if any - * of the children's parents are currently animating. By default, when an element has an active `enter`, `leave`, or `move` - * (structural) animation, child elements that also have an active structural animation are not animated. - * - * Note that even if `ngAnimteChildren` is set, no child animations will run when the parent element is removed from the DOM (`leave` animation). - * - * - * @param {string} ngAnimateChildren If the value is empty, `true` or `on`, - * then child animations are allowed. If the value is `false`, child animations are not allowed. - * - * @example - * - -
        - - -
        -
        -
        - List of items: -
        Item {{item}}
        -
        -
        -
        -
        - - - .container.ng-enter, - .container.ng-leave { - transition: all ease 1.5s; - } - - .container.ng-enter, - .container.ng-leave-active { - opacity: 0; - } - - .container.ng-leave, - .container.ng-enter-active { - opacity: 1; - } - - .item { - background: firebrick; - color: #FFF; - margin-bottom: 10px; - } - - .item.ng-enter, - .item.ng-leave { - transition: transform 1.5s ease; - } - - .item.ng-enter { - transform: translateX(50px); - } - - .item.ng-enter-active { - transform: translateX(0); - } - - - angular.module('ngAnimateChildren', ['ngAnimate']) - .controller('mainController', function() { - this.animateChildren = false; - this.enterElement = false; - }); - -
        - */ -var $$AnimateChildrenDirective = ['$interpolate', function($interpolate) { - return { - link: function(scope, element, attrs) { - var val = attrs.ngAnimateChildren; - if (angular.isString(val) && val.length === 0) { //empty attribute - element.data(NG_ANIMATE_CHILDREN_DATA, true); - } else { - // Interpolate and set the value, so that it is available to - // animations that run right after compilation - setData($interpolate(val)(scope)); - attrs.$observe('ngAnimateChildren', setData); - } - - function setData(value) { - value = value === 'on' || value === 'true'; - element.data(NG_ANIMATE_CHILDREN_DATA, value); - } - } - }; -}]; - -var ANIMATE_TIMER_KEY = '$$animateCss'; - -/** - * @ngdoc service - * @name $animateCss - * @kind object - * - * @description - * The `$animateCss` service is a useful utility to trigger customized CSS-based transitions/keyframes - * from a JavaScript-based animation or directly from a directive. The purpose of `$animateCss` is NOT - * to side-step how `$animate` and ngAnimate work, but the goal is to allow pre-existing animations or - * directives to create more complex animations that can be purely driven using CSS code. - * - * Note that only browsers that support CSS transitions and/or keyframe animations are capable of - * rendering animations triggered via `$animateCss` (bad news for IE9 and lower). - * - * ## Usage - * Once again, `$animateCss` is designed to be used inside of a registered JavaScript animation that - * is powered by ngAnimate. It is possible to use `$animateCss` directly inside of a directive, however, - * any automatic control over cancelling animations and/or preventing animations from being run on - * child elements will not be handled by Angular. For this to work as expected, please use `$animate` to - * trigger the animation and then setup a JavaScript animation that injects `$animateCss` to trigger - * the CSS animation. - * - * The example below shows how we can create a folding animation on an element using `ng-if`: - * - * ```html - * - *
        - * This element will go BOOM - *
        - * - * ``` - * - * Now we create the **JavaScript animation** that will trigger the CSS transition: - * - * ```js - * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) { - * return { - * enter: function(element, doneFn) { - * var height = element[0].offsetHeight; - * return $animateCss(element, { - * from: { height:'0px' }, - * to: { height:height + 'px' }, - * duration: 1 // one second - * }); - * } - * } - * }]); - * ``` - * - * ## More Advanced Uses - * - * `$animateCss` is the underlying code that ngAnimate uses to power **CSS-based animations** behind the scenes. Therefore CSS hooks - * like `.ng-EVENT`, `.ng-EVENT-active`, `.ng-EVENT-stagger` are all features that can be triggered using `$animateCss` via JavaScript code. - * - * This also means that just about any combination of adding classes, removing classes, setting styles, dynamically setting a keyframe animation, - * applying a hardcoded duration or delay value, changing the animation easing or applying a stagger animation are all options that work with - * `$animateCss`. The service itself is smart enough to figure out the combination of options and examine the element styling properties in order - * to provide a working animation that will run in CSS. - * - * The example below showcases a more advanced version of the `.fold-animation` from the example above: - * - * ```js - * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) { - * return { - * enter: function(element, doneFn) { - * var height = element[0].offsetHeight; - * return $animateCss(element, { - * addClass: 'red large-text pulse-twice', - * easing: 'ease-out', - * from: { height:'0px' }, - * to: { height:height + 'px' }, - * duration: 1 // one second - * }); - * } - * } - * }]); - * ``` - * - * Since we're adding/removing CSS classes then the CSS transition will also pick those up: - * - * ```css - * /* since a hardcoded duration value of 1 was provided in the JavaScript animation code, - * the CSS classes below will be transitioned despite them being defined as regular CSS classes */ - * .red { background:red; } - * .large-text { font-size:20px; } - * - * /* we can also use a keyframe animation and $animateCss will make it work alongside the transition */ - * .pulse-twice { - * animation: 0.5s pulse linear 2; - * -webkit-animation: 0.5s pulse linear 2; - * } - * - * @keyframes pulse { - * from { transform: scale(0.5); } - * to { transform: scale(1.5); } - * } - * - * @-webkit-keyframes pulse { - * from { -webkit-transform: scale(0.5); } - * to { -webkit-transform: scale(1.5); } - * } - * ``` - * - * Given this complex combination of CSS classes, styles and options, `$animateCss` will figure everything out and make the animation happen. - * - * ## How the Options are handled - * - * `$animateCss` is very versatile and intelligent when it comes to figuring out what configurations to apply to the element to ensure the animation - * works with the options provided. Say for example we were adding a class that contained a keyframe value and we wanted to also animate some inline - * styles using the `from` and `to` properties. - * - * ```js - * var animator = $animateCss(element, { - * from: { background:'red' }, - * to: { background:'blue' } - * }); - * animator.start(); - * ``` - * - * ```css - * .rotating-animation { - * animation:0.5s rotate linear; - * -webkit-animation:0.5s rotate linear; - * } - * - * @keyframes rotate { - * from { transform: rotate(0deg); } - * to { transform: rotate(360deg); } - * } - * - * @-webkit-keyframes rotate { - * from { -webkit-transform: rotate(0deg); } - * to { -webkit-transform: rotate(360deg); } - * } - * ``` - * - * The missing pieces here are that we do not have a transition set (within the CSS code nor within the `$animateCss` options) and the duration of the animation is - * going to be detected from what the keyframe styles on the CSS class are. In this event, `$animateCss` will automatically create an inline transition - * style matching the duration detected from the keyframe style (which is present in the CSS class that is being added) and then prepare both the transition - * and keyframe animations to run in parallel on the element. Then when the animation is underway the provided `from` and `to` CSS styles will be applied - * and spread across the transition and keyframe animation. - * - * ## What is returned - * - * `$animateCss` works in two stages: a preparation phase and an animation phase. Therefore when `$animateCss` is first called it will NOT actually - * start the animation. All that is going on here is that the element is being prepared for the animation (which means that the generated CSS classes are - * added and removed on the element). Once `$animateCss` is called it will return an object with the following properties: - * - * ```js - * var animator = $animateCss(element, { ... }); - * ``` - * - * Now what do the contents of our `animator` variable look like: - * - * ```js - * { - * // starts the animation - * start: Function, - * - * // ends (aborts) the animation - * end: Function - * } - * ``` - * - * To actually start the animation we need to run `animation.start()` which will then return a promise that we can hook into to detect when the animation ends. - * If we choose not to run the animation then we MUST run `animation.end()` to perform a cleanup on the element (since some CSS classes and styles may have been - * applied to the element during the preparation phase). Note that all other properties such as duration, delay, transitions and keyframes are just properties - * and that changing them will not reconfigure the parameters of the animation. - * - * ### runner.done() vs runner.then() - * It is documented that `animation.start()` will return a promise object and this is true, however, there is also an additional method available on the - * runner called `.done(callbackFn)`. The done method works the same as `.finally(callbackFn)`, however, it does **not trigger a digest to occur**. - * Therefore, for performance reasons, it's always best to use `runner.done(callback)` instead of `runner.then()`, `runner.catch()` or `runner.finally()` - * unless you really need a digest to kick off afterwards. - * - * Keep in mind that, to make this easier, ngAnimate has tweaked the JS animations API to recognize when a runner instance is returned from $animateCss - * (so there is no need to call `runner.done(doneFn)` inside of your JavaScript animation code). - * Check the {@link ngAnimate.$animateCss#usage animation code above} to see how this works. - * - * @param {DOMElement} element the element that will be animated - * @param {object} options the animation-related options that will be applied during the animation - * - * * `event` - The DOM event (e.g. enter, leave, move). When used, a generated CSS class of `ng-EVENT` and `ng-EVENT-active` will be applied - * to the element during the animation. Multiple events can be provided when spaces are used as a separator. (Note that this will not perform any DOM operation.) - * * `structural` - Indicates that the `ng-` prefix will be added to the event class. Setting to `false` or omitting will turn `ng-EVENT` and - * `ng-EVENT-active` in `EVENT` and `EVENT-active`. Unused if `event` is omitted. - * * `easing` - The CSS easing value that will be applied to the transition or keyframe animation (or both). - * * `transitionStyle` - The raw CSS transition style that will be used (e.g. `1s linear all`). - * * `keyframeStyle` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`). - * * `from` - The starting CSS styles (a key/value object) that will be applied at the start of the animation. - * * `to` - The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition. - * * `addClass` - A space separated list of CSS classes that will be added to the element and spread across the animation. - * * `removeClass` - A space separated list of CSS classes that will be removed from the element and spread across the animation. - * * `duration` - A number value representing the total duration of the transition and/or keyframe (note that a value of 1 is 1000ms). If a value of `0` - * is provided then the animation will be skipped entirely. - * * `delay` - A number value representing the total delay of the transition and/or keyframe (note that a value of 1 is 1000ms). If a value of `true` is - * used then whatever delay value is detected from the CSS classes will be mirrored on the elements styles (e.g. by setting delay true then the style value - * of the element will be `transition-delay: DETECTED_VALUE`). Using `true` is useful when you want the CSS classes and inline styles to all share the same - * CSS delay value. - * * `stagger` - A numeric time value representing the delay between successively animated elements - * ({@link ngAnimate#css-staggering-animations Click here to learn how CSS-based staggering works in ngAnimate.}) - * * `staggerIndex` - The numeric index representing the stagger item (e.g. a value of 5 is equal to the sixth item in the stagger; therefore when a - * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`) - * * `applyClassesEarly` - Whether or not the classes being added or removed will be used when detecting the animation. This is set by `$animate` when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. (Note that this will prevent any transitions from occurring on the classes being added and removed.) - * * `cleanupStyles` - Whether or not the provided `from` and `to` styles will be removed once - * the animation is closed. This is useful for when the styles are used purely for the sake of - * the animation and do not have a lasting visual effect on the element (e.g. a collapse and open animation). - * By default this value is set to `false`. - * - * @return {object} an object with start and end methods and details about the animation. - * - * * `start` - The method to start the animation. This will return a `Promise` when called. - * * `end` - This method will cancel the animation and remove all applied CSS classes and styles. - */ -var ONE_SECOND = 1000; -var BASE_TEN = 10; - -var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3; -var CLOSING_TIME_BUFFER = 1.5; - -var DETECT_CSS_PROPERTIES = { - transitionDuration: TRANSITION_DURATION_PROP, - transitionDelay: TRANSITION_DELAY_PROP, - transitionProperty: TRANSITION_PROP + PROPERTY_KEY, - animationDuration: ANIMATION_DURATION_PROP, - animationDelay: ANIMATION_DELAY_PROP, - animationIterationCount: ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY -}; - -var DETECT_STAGGER_CSS_PROPERTIES = { - transitionDuration: TRANSITION_DURATION_PROP, - transitionDelay: TRANSITION_DELAY_PROP, - animationDuration: ANIMATION_DURATION_PROP, - animationDelay: ANIMATION_DELAY_PROP -}; - -function getCssKeyframeDurationStyle(duration) { - return [ANIMATION_DURATION_PROP, duration + 's']; -} - -function getCssDelayStyle(delay, isKeyframeAnimation) { - var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP; - return [prop, delay + 's']; -} - -function computeCssStyles($window, element, properties) { - var styles = Object.create(null); - var detectedStyles = $window.getComputedStyle(element) || {}; - forEach(properties, function(formalStyleName, actualStyleName) { - var val = detectedStyles[formalStyleName]; - if (val) { - var c = val.charAt(0); - - // only numerical-based values have a negative sign or digit as the first value - if (c === '-' || c === '+' || c >= 0) { - val = parseMaxTime(val); - } - - // by setting this to null in the event that the delay is not set or is set directly as 0 - // then we can still allow for negative values to be used later on and not mistake this - // value for being greater than any other negative value. - if (val === 0) { - val = null; - } - styles[actualStyleName] = val; - } - }); - - return styles; -} - -function parseMaxTime(str) { - var maxValue = 0; - var values = str.split(/\s*,\s*/); - forEach(values, function(value) { - // it's always safe to consider only second values and omit `ms` values since - // getComputedStyle will always handle the conversion for us - if (value.charAt(value.length - 1) == 's') { - value = value.substring(0, value.length - 1); - } - value = parseFloat(value) || 0; - maxValue = maxValue ? Math.max(value, maxValue) : value; - }); - return maxValue; -} - -function truthyTimingValue(val) { - return val === 0 || val != null; -} - -function getCssTransitionDurationStyle(duration, applyOnlyDuration) { - var style = TRANSITION_PROP; - var value = duration + 's'; - if (applyOnlyDuration) { - style += DURATION_KEY; - } else { - value += ' linear all'; - } - return [style, value]; -} - -function createLocalCacheLookup() { - var cache = Object.create(null); - return { - flush: function() { - cache = Object.create(null); - }, - - count: function(key) { - var entry = cache[key]; - return entry ? entry.total : 0; - }, - - get: function(key) { - var entry = cache[key]; - return entry && entry.value; - }, - - put: function(key, value) { - if (!cache[key]) { - cache[key] = { total: 1, value: value }; - } else { - cache[key].total++; - } - } - }; -} - -// we do not reassign an already present style value since -// if we detect the style property value again we may be -// detecting styles that were added via the `from` styles. -// We make use of `isDefined` here since an empty string -// or null value (which is what getPropertyValue will return -// for a non-existing style) will still be marked as a valid -// value for the style (a falsy value implies that the style -// is to be removed at the end of the animation). If we had a simple -// "OR" statement then it would not be enough to catch that. -function registerRestorableStyles(backup, node, properties) { - forEach(properties, function(prop) { - backup[prop] = isDefined(backup[prop]) - ? backup[prop] - : node.style.getPropertyValue(prop); - }); -} - -var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { - var gcsLookup = createLocalCacheLookup(); - var gcsStaggerLookup = createLocalCacheLookup(); - - this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout', - '$$forceReflow', '$sniffer', '$$rAFScheduler', '$$animateQueue', - function($window, $$jqLite, $$AnimateRunner, $timeout, - $$forceReflow, $sniffer, $$rAFScheduler, $$animateQueue) { - - var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); - - var parentCounter = 0; - function gcsHashFn(node, extraClasses) { - var KEY = "$$ngAnimateParentKey"; - var parentNode = node.parentNode; - var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter); - return parentID + '-' + node.getAttribute('class') + '-' + extraClasses; - } - - function computeCachedCssStyles(node, className, cacheKey, properties) { - var timings = gcsLookup.get(cacheKey); - - if (!timings) { - timings = computeCssStyles($window, node, properties); - if (timings.animationIterationCount === 'infinite') { - timings.animationIterationCount = 1; - } - } - - // we keep putting this in multiple times even though the value and the cacheKey are the same - // because we're keeping an internal tally of how many duplicate animations are detected. - gcsLookup.put(cacheKey, timings); - return timings; - } - - function computeCachedCssStaggerStyles(node, className, cacheKey, properties) { - var stagger; - - // if we have one or more existing matches of matching elements - // containing the same parent + CSS styles (which is how cacheKey works) - // then staggering is possible - if (gcsLookup.count(cacheKey) > 0) { - stagger = gcsStaggerLookup.get(cacheKey); - - if (!stagger) { - var staggerClassName = pendClasses(className, '-stagger'); - - $$jqLite.addClass(node, staggerClassName); - - stagger = computeCssStyles($window, node, properties); - - // force the conversion of a null value to zero incase not set - stagger.animationDuration = Math.max(stagger.animationDuration, 0); - stagger.transitionDuration = Math.max(stagger.transitionDuration, 0); - - $$jqLite.removeClass(node, staggerClassName); - - gcsStaggerLookup.put(cacheKey, stagger); - } - } - - return stagger || {}; - } - - var cancelLastRAFRequest; - var rafWaitQueue = []; - function waitUntilQuiet(callback) { - rafWaitQueue.push(callback); - $$rAFScheduler.waitUntilQuiet(function() { - gcsLookup.flush(); - gcsStaggerLookup.flush(); - - // DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable. - // PLEASE EXAMINE THE `$$forceReflow` service to understand why. - var pageWidth = $$forceReflow(); - - // we use a for loop to ensure that if the queue is changed - // during this looping then it will consider new requests - for (var i = 0; i < rafWaitQueue.length; i++) { - rafWaitQueue[i](pageWidth); - } - rafWaitQueue.length = 0; - }); - } - - function computeTimings(node, className, cacheKey) { - var timings = computeCachedCssStyles(node, className, cacheKey, DETECT_CSS_PROPERTIES); - var aD = timings.animationDelay; - var tD = timings.transitionDelay; - timings.maxDelay = aD && tD - ? Math.max(aD, tD) - : (aD || tD); - timings.maxDuration = Math.max( - timings.animationDuration * timings.animationIterationCount, - timings.transitionDuration); - - return timings; - } - - return function init(element, initialOptions) { - // all of the animation functions should create - // a copy of the options data, however, if a - // parent service has already created a copy then - // we should stick to using that - var options = initialOptions || {}; - if (!options.$$prepared) { - options = prepareAnimationOptions(copy(options)); - } - - var restoreStyles = {}; - var node = getDomNode(element); - if (!node - || !node.parentNode - || !$$animateQueue.enabled()) { - return closeAndReturnNoopAnimator(); - } - - var temporaryStyles = []; - var classes = element.attr('class'); - var styles = packageStyles(options); - var animationClosed; - var animationPaused; - var animationCompleted; - var runner; - var runnerHost; - var maxDelay; - var maxDelayTime; - var maxDuration; - var maxDurationTime; - var startTime; - var events = []; - - if (options.duration === 0 || (!$sniffer.animations && !$sniffer.transitions)) { - return closeAndReturnNoopAnimator(); - } - - var method = options.event && isArray(options.event) - ? options.event.join(' ') - : options.event; - - var isStructural = method && options.structural; - var structuralClassName = ''; - var addRemoveClassName = ''; - - if (isStructural) { - structuralClassName = pendClasses(method, EVENT_CLASS_PREFIX, true); - } else if (method) { - structuralClassName = method; - } - - if (options.addClass) { - addRemoveClassName += pendClasses(options.addClass, ADD_CLASS_SUFFIX); - } - - if (options.removeClass) { - if (addRemoveClassName.length) { - addRemoveClassName += ' '; - } - addRemoveClassName += pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX); - } - - // there may be a situation where a structural animation is combined together - // with CSS classes that need to resolve before the animation is computed. - // However this means that there is no explicit CSS code to block the animation - // from happening (by setting 0s none in the class name). If this is the case - // we need to apply the classes before the first rAF so we know to continue if - // there actually is a detected transition or keyframe animation - if (options.applyClassesEarly && addRemoveClassName.length) { - applyAnimationClasses(element, options); - } - - var preparationClasses = [structuralClassName, addRemoveClassName].join(' ').trim(); - var fullClassName = classes + ' ' + preparationClasses; - var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX); - var hasToStyles = styles.to && Object.keys(styles.to).length > 0; - var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0; - - // there is no way we can trigger an animation if no styles and - // no classes are being applied which would then trigger a transition, - // unless there a is raw keyframe value that is applied to the element. - if (!containsKeyframeAnimation - && !hasToStyles - && !preparationClasses) { - return closeAndReturnNoopAnimator(); - } - - var cacheKey, stagger; - if (options.stagger > 0) { - var staggerVal = parseFloat(options.stagger); - stagger = { - transitionDelay: staggerVal, - animationDelay: staggerVal, - transitionDuration: 0, - animationDuration: 0 - }; - } else { - cacheKey = gcsHashFn(node, fullClassName); - stagger = computeCachedCssStaggerStyles(node, preparationClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES); - } - - if (!options.$$skipPreparationClasses) { - $$jqLite.addClass(element, preparationClasses); - } - - var applyOnlyDuration; - - if (options.transitionStyle) { - var transitionStyle = [TRANSITION_PROP, options.transitionStyle]; - applyInlineStyle(node, transitionStyle); - temporaryStyles.push(transitionStyle); - } - - if (options.duration >= 0) { - applyOnlyDuration = node.style[TRANSITION_PROP].length > 0; - var durationStyle = getCssTransitionDurationStyle(options.duration, applyOnlyDuration); - - // we set the duration so that it will be picked up by getComputedStyle later - applyInlineStyle(node, durationStyle); - temporaryStyles.push(durationStyle); - } - - if (options.keyframeStyle) { - var keyframeStyle = [ANIMATION_PROP, options.keyframeStyle]; - applyInlineStyle(node, keyframeStyle); - temporaryStyles.push(keyframeStyle); - } - - var itemIndex = stagger - ? options.staggerIndex >= 0 - ? options.staggerIndex - : gcsLookup.count(cacheKey) - : 0; - - var isFirst = itemIndex === 0; - - // this is a pre-emptive way of forcing the setup classes to be added and applied INSTANTLY - // without causing any combination of transitions to kick in. By adding a negative delay value - // it forces the setup class' transition to end immediately. We later then remove the negative - // transition delay to allow for the transition to naturally do it's thing. The beauty here is - // that if there is no transition defined then nothing will happen and this will also allow - // other transitions to be stacked on top of each other without any chopping them out. - if (isFirst && !options.skipBlocking) { - blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE); - } - - var timings = computeTimings(node, fullClassName, cacheKey); - var relativeDelay = timings.maxDelay; - maxDelay = Math.max(relativeDelay, 0); - maxDuration = timings.maxDuration; - - var flags = {}; - flags.hasTransitions = timings.transitionDuration > 0; - flags.hasAnimations = timings.animationDuration > 0; - flags.hasTransitionAll = flags.hasTransitions && timings.transitionProperty == 'all'; - flags.applyTransitionDuration = hasToStyles && ( - (flags.hasTransitions && !flags.hasTransitionAll) - || (flags.hasAnimations && !flags.hasTransitions)); - flags.applyAnimationDuration = options.duration && flags.hasAnimations; - flags.applyTransitionDelay = truthyTimingValue(options.delay) && (flags.applyTransitionDuration || flags.hasTransitions); - flags.applyAnimationDelay = truthyTimingValue(options.delay) && flags.hasAnimations; - flags.recalculateTimingStyles = addRemoveClassName.length > 0; - - if (flags.applyTransitionDuration || flags.applyAnimationDuration) { - maxDuration = options.duration ? parseFloat(options.duration) : maxDuration; - - if (flags.applyTransitionDuration) { - flags.hasTransitions = true; - timings.transitionDuration = maxDuration; - applyOnlyDuration = node.style[TRANSITION_PROP + PROPERTY_KEY].length > 0; - temporaryStyles.push(getCssTransitionDurationStyle(maxDuration, applyOnlyDuration)); - } - - if (flags.applyAnimationDuration) { - flags.hasAnimations = true; - timings.animationDuration = maxDuration; - temporaryStyles.push(getCssKeyframeDurationStyle(maxDuration)); - } - } - - if (maxDuration === 0 && !flags.recalculateTimingStyles) { - return closeAndReturnNoopAnimator(); - } - - if (options.delay != null) { - var delayStyle; - if (typeof options.delay !== "boolean") { - delayStyle = parseFloat(options.delay); - // number in options.delay means we have to recalculate the delay for the closing timeout - maxDelay = Math.max(delayStyle, 0); - } - - if (flags.applyTransitionDelay) { - temporaryStyles.push(getCssDelayStyle(delayStyle)); - } - - if (flags.applyAnimationDelay) { - temporaryStyles.push(getCssDelayStyle(delayStyle, true)); - } - } - - // we need to recalculate the delay value since we used a pre-emptive negative - // delay value and the delay value is required for the final event checking. This - // property will ensure that this will happen after the RAF phase has passed. - if (options.duration == null && timings.transitionDuration > 0) { - flags.recalculateTimingStyles = flags.recalculateTimingStyles || isFirst; - } - - maxDelayTime = maxDelay * ONE_SECOND; - maxDurationTime = maxDuration * ONE_SECOND; - if (!options.skipBlocking) { - flags.blockTransition = timings.transitionDuration > 0; - flags.blockKeyframeAnimation = timings.animationDuration > 0 && - stagger.animationDelay > 0 && - stagger.animationDuration === 0; - } - - if (options.from) { - if (options.cleanupStyles) { - registerRestorableStyles(restoreStyles, node, Object.keys(options.from)); - } - applyAnimationFromStyles(element, options); - } - - if (flags.blockTransition || flags.blockKeyframeAnimation) { - applyBlocking(maxDuration); - } else if (!options.skipBlocking) { - blockTransitions(node, false); - } - - // TODO(matsko): for 1.5 change this code to have an animator object for better debugging - return { - $$willAnimate: true, - end: endFn, - start: function() { - if (animationClosed) return; - - runnerHost = { - end: endFn, - cancel: cancelFn, - resume: null, //this will be set during the start() phase - pause: null - }; - - runner = new $$AnimateRunner(runnerHost); - - waitUntilQuiet(start); - - // we don't have access to pause/resume the animation - // since it hasn't run yet. AnimateRunner will therefore - // set noop functions for resume and pause and they will - // later be overridden once the animation is triggered - return runner; - } - }; - - function endFn() { - close(); - } - - function cancelFn() { - close(true); - } - - function close(rejected) { // jshint ignore:line - // if the promise has been called already then we shouldn't close - // the animation again - if (animationClosed || (animationCompleted && animationPaused)) return; - animationClosed = true; - animationPaused = false; - - if (!options.$$skipPreparationClasses) { - $$jqLite.removeClass(element, preparationClasses); - } - $$jqLite.removeClass(element, activeClasses); - - blockKeyframeAnimations(node, false); - blockTransitions(node, false); - - forEach(temporaryStyles, function(entry) { - // There is only one way to remove inline style properties entirely from elements. - // By using `removeProperty` this works, but we need to convert camel-cased CSS - // styles down to hyphenated values. - node.style[entry[0]] = ''; - }); - - applyAnimationClasses(element, options); - applyAnimationStyles(element, options); - - if (Object.keys(restoreStyles).length) { - forEach(restoreStyles, function(value, prop) { - value ? node.style.setProperty(prop, value) - : node.style.removeProperty(prop); - }); - } - - // the reason why we have this option is to allow a synchronous closing callback - // that is fired as SOON as the animation ends (when the CSS is removed) or if - // the animation never takes off at all. A good example is a leave animation since - // the element must be removed just after the animation is over or else the element - // will appear on screen for one animation frame causing an overbearing flicker. - if (options.onDone) { - options.onDone(); - } - - if (events && events.length) { - // Remove the transitionend / animationend listener(s) - element.off(events.join(' '), onAnimationProgress); - } - - //Cancel the fallback closing timeout and remove the timer data - var animationTimerData = element.data(ANIMATE_TIMER_KEY); - if (animationTimerData) { - $timeout.cancel(animationTimerData[0].timer); - element.removeData(ANIMATE_TIMER_KEY); - } - - // if the preparation function fails then the promise is not setup - if (runner) { - runner.complete(!rejected); - } - } - - function applyBlocking(duration) { - if (flags.blockTransition) { - blockTransitions(node, duration); - } - - if (flags.blockKeyframeAnimation) { - blockKeyframeAnimations(node, !!duration); - } - } - - function closeAndReturnNoopAnimator() { - runner = new $$AnimateRunner({ - end: endFn, - cancel: cancelFn - }); - - // should flush the cache animation - waitUntilQuiet(noop); - close(); - - return { - $$willAnimate: false, - start: function() { - return runner; - }, - end: endFn - }; - } - - function onAnimationProgress(event) { - event.stopPropagation(); - var ev = event.originalEvent || event; - - // we now always use `Date.now()` due to the recent changes with - // event.timeStamp in Firefox, Webkit and Chrome (see #13494 for more info) - var timeStamp = ev.$manualTimeStamp || Date.now(); - - /* Firefox (or possibly just Gecko) likes to not round values up - * when a ms measurement is used for the animation */ - var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES)); - - /* $manualTimeStamp is a mocked timeStamp value which is set - * within browserTrigger(). This is only here so that tests can - * mock animations properly. Real events fallback to event.timeStamp, - * or, if they don't, then a timeStamp is automatically created for them. - * We're checking to see if the timeStamp surpasses the expected delay, - * but we're using elapsedTime instead of the timeStamp on the 2nd - * pre-condition since animationPauseds sometimes close off early */ - if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) { - // we set this flag to ensure that if the transition is paused then, when resumed, - // the animation will automatically close itself since transitions cannot be paused. - animationCompleted = true; - close(); - } - } - - function start() { - if (animationClosed) return; - if (!node.parentNode) { - close(); - return; - } - - // even though we only pause keyframe animations here the pause flag - // will still happen when transitions are used. Only the transition will - // not be paused since that is not possible. If the animation ends when - // paused then it will not complete until unpaused or cancelled. - var playPause = function(playAnimation) { - if (!animationCompleted) { - animationPaused = !playAnimation; - if (timings.animationDuration) { - var value = blockKeyframeAnimations(node, animationPaused); - animationPaused - ? temporaryStyles.push(value) - : removeFromArray(temporaryStyles, value); - } - } else if (animationPaused && playAnimation) { - animationPaused = false; - close(); - } - }; - - // checking the stagger duration prevents an accidentally cascade of the CSS delay style - // being inherited from the parent. If the transition duration is zero then we can safely - // rely that the delay value is an intentional stagger delay style. - var maxStagger = itemIndex > 0 - && ((timings.transitionDuration && stagger.transitionDuration === 0) || - (timings.animationDuration && stagger.animationDuration === 0)) - && Math.max(stagger.animationDelay, stagger.transitionDelay); - if (maxStagger) { - $timeout(triggerAnimationStart, - Math.floor(maxStagger * itemIndex * ONE_SECOND), - false); - } else { - triggerAnimationStart(); - } - - // this will decorate the existing promise runner with pause/resume methods - runnerHost.resume = function() { - playPause(true); - }; - - runnerHost.pause = function() { - playPause(false); - }; - - function triggerAnimationStart() { - // just incase a stagger animation kicks in when the animation - // itself was cancelled entirely - if (animationClosed) return; - - applyBlocking(false); - - forEach(temporaryStyles, function(entry) { - var key = entry[0]; - var value = entry[1]; - node.style[key] = value; - }); - - applyAnimationClasses(element, options); - $$jqLite.addClass(element, activeClasses); - - if (flags.recalculateTimingStyles) { - fullClassName = node.className + ' ' + preparationClasses; - cacheKey = gcsHashFn(node, fullClassName); - - timings = computeTimings(node, fullClassName, cacheKey); - relativeDelay = timings.maxDelay; - maxDelay = Math.max(relativeDelay, 0); - maxDuration = timings.maxDuration; - - if (maxDuration === 0) { - close(); - return; - } - - flags.hasTransitions = timings.transitionDuration > 0; - flags.hasAnimations = timings.animationDuration > 0; - } - - if (flags.applyAnimationDelay) { - relativeDelay = typeof options.delay !== "boolean" && truthyTimingValue(options.delay) - ? parseFloat(options.delay) - : relativeDelay; - - maxDelay = Math.max(relativeDelay, 0); - timings.animationDelay = relativeDelay; - delayStyle = getCssDelayStyle(relativeDelay, true); - temporaryStyles.push(delayStyle); - node.style[delayStyle[0]] = delayStyle[1]; - } - - maxDelayTime = maxDelay * ONE_SECOND; - maxDurationTime = maxDuration * ONE_SECOND; - - if (options.easing) { - var easeProp, easeVal = options.easing; - if (flags.hasTransitions) { - easeProp = TRANSITION_PROP + TIMING_KEY; - temporaryStyles.push([easeProp, easeVal]); - node.style[easeProp] = easeVal; - } - if (flags.hasAnimations) { - easeProp = ANIMATION_PROP + TIMING_KEY; - temporaryStyles.push([easeProp, easeVal]); - node.style[easeProp] = easeVal; - } - } - - if (timings.transitionDuration) { - events.push(TRANSITIONEND_EVENT); - } - - if (timings.animationDuration) { - events.push(ANIMATIONEND_EVENT); - } - - startTime = Date.now(); - var timerTime = maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime; - var endTime = startTime + timerTime; - - var animationsData = element.data(ANIMATE_TIMER_KEY) || []; - var setupFallbackTimer = true; - if (animationsData.length) { - var currentTimerData = animationsData[0]; - setupFallbackTimer = endTime > currentTimerData.expectedEndTime; - if (setupFallbackTimer) { - $timeout.cancel(currentTimerData.timer); - } else { - animationsData.push(close); - } - } - - if (setupFallbackTimer) { - var timer = $timeout(onAnimationExpired, timerTime, false); - animationsData[0] = { - timer: timer, - expectedEndTime: endTime - }; - animationsData.push(close); - element.data(ANIMATE_TIMER_KEY, animationsData); - } - - if (events.length) { - element.on(events.join(' '), onAnimationProgress); - } - - if (options.to) { - if (options.cleanupStyles) { - registerRestorableStyles(restoreStyles, node, Object.keys(options.to)); - } - applyAnimationToStyles(element, options); - } - } - - function onAnimationExpired() { - var animationsData = element.data(ANIMATE_TIMER_KEY); - - // this will be false in the event that the element was - // removed from the DOM (via a leave animation or something - // similar) - if (animationsData) { - for (var i = 1; i < animationsData.length; i++) { - animationsData[i](); - } - element.removeData(ANIMATE_TIMER_KEY); - } - } - } - }; - }]; -}]; - -var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationProvider) { - $$animationProvider.drivers.push('$$animateCssDriver'); - - var NG_ANIMATE_SHIM_CLASS_NAME = 'ng-animate-shim'; - var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-anchor'; - - var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out'; - var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in'; - - function isDocumentFragment(node) { - return node.parentNode && node.parentNode.nodeType === 11; - } - - this.$get = ['$animateCss', '$rootScope', '$$AnimateRunner', '$rootElement', '$sniffer', '$$jqLite', '$document', - function($animateCss, $rootScope, $$AnimateRunner, $rootElement, $sniffer, $$jqLite, $document) { - - // only browsers that support these properties can render animations - if (!$sniffer.animations && !$sniffer.transitions) return noop; - - var bodyNode = $document[0].body; - var rootNode = getDomNode($rootElement); - - var rootBodyElement = jqLite( - // this is to avoid using something that exists outside of the body - // we also special case the doc fragment case because our unit test code - // appends the $rootElement to the body after the app has been bootstrapped - isDocumentFragment(rootNode) || bodyNode.contains(rootNode) ? rootNode : bodyNode - ); - - var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); - - return function initDriverFn(animationDetails) { - return animationDetails.from && animationDetails.to - ? prepareFromToAnchorAnimation(animationDetails.from, - animationDetails.to, - animationDetails.classes, - animationDetails.anchors) - : prepareRegularAnimation(animationDetails); - }; - - function filterCssClasses(classes) { - //remove all the `ng-` stuff - return classes.replace(/\bng-\S+\b/g, ''); - } - - function getUniqueValues(a, b) { - if (isString(a)) a = a.split(' '); - if (isString(b)) b = b.split(' '); - return a.filter(function(val) { - return b.indexOf(val) === -1; - }).join(' '); - } - - function prepareAnchoredAnimation(classes, outAnchor, inAnchor) { - var clone = jqLite(getDomNode(outAnchor).cloneNode(true)); - var startingClasses = filterCssClasses(getClassVal(clone)); - - outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME); - inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME); - - clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME); - - rootBodyElement.append(clone); - - var animatorIn, animatorOut = prepareOutAnimation(); - - // the user may not end up using the `out` animation and - // only making use of the `in` animation or vice-versa. - // In either case we should allow this and not assume the - // animation is over unless both animations are not used. - if (!animatorOut) { - animatorIn = prepareInAnimation(); - if (!animatorIn) { - return end(); - } - } - - var startingAnimator = animatorOut || animatorIn; - - return { - start: function() { - var runner; - - var currentAnimation = startingAnimator.start(); - currentAnimation.done(function() { - currentAnimation = null; - if (!animatorIn) { - animatorIn = prepareInAnimation(); - if (animatorIn) { - currentAnimation = animatorIn.start(); - currentAnimation.done(function() { - currentAnimation = null; - end(); - runner.complete(); - }); - return currentAnimation; - } - } - // in the event that there is no `in` animation - end(); - runner.complete(); - }); - - runner = new $$AnimateRunner({ - end: endFn, - cancel: endFn - }); - - return runner; - - function endFn() { - if (currentAnimation) { - currentAnimation.end(); - } - } - } - }; - - function calculateAnchorStyles(anchor) { - var styles = {}; - - var coords = getDomNode(anchor).getBoundingClientRect(); - - // we iterate directly since safari messes up and doesn't return - // all the keys for the coords object when iterated - forEach(['width','height','top','left'], function(key) { - var value = coords[key]; - switch (key) { - case 'top': - value += bodyNode.scrollTop; - break; - case 'left': - value += bodyNode.scrollLeft; - break; - } - styles[key] = Math.floor(value) + 'px'; - }); - return styles; - } - - function prepareOutAnimation() { - var animator = $animateCss(clone, { - addClass: NG_OUT_ANCHOR_CLASS_NAME, - delay: true, - from: calculateAnchorStyles(outAnchor) - }); - - // read the comment within `prepareRegularAnimation` to understand - // why this check is necessary - return animator.$$willAnimate ? animator : null; - } - - function getClassVal(element) { - return element.attr('class') || ''; - } - - function prepareInAnimation() { - var endingClasses = filterCssClasses(getClassVal(inAnchor)); - var toAdd = getUniqueValues(endingClasses, startingClasses); - var toRemove = getUniqueValues(startingClasses, endingClasses); - - var animator = $animateCss(clone, { - to: calculateAnchorStyles(inAnchor), - addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + toAdd, - removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + toRemove, - delay: true - }); - - // read the comment within `prepareRegularAnimation` to understand - // why this check is necessary - return animator.$$willAnimate ? animator : null; - } - - function end() { - clone.remove(); - outAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME); - inAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME); - } - } - - function prepareFromToAnchorAnimation(from, to, classes, anchors) { - var fromAnimation = prepareRegularAnimation(from, noop); - var toAnimation = prepareRegularAnimation(to, noop); - - var anchorAnimations = []; - forEach(anchors, function(anchor) { - var outElement = anchor['out']; - var inElement = anchor['in']; - var animator = prepareAnchoredAnimation(classes, outElement, inElement); - if (animator) { - anchorAnimations.push(animator); - } - }); - - // no point in doing anything when there are no elements to animate - if (!fromAnimation && !toAnimation && anchorAnimations.length === 0) return; - - return { - start: function() { - var animationRunners = []; - - if (fromAnimation) { - animationRunners.push(fromAnimation.start()); - } - - if (toAnimation) { - animationRunners.push(toAnimation.start()); - } - - forEach(anchorAnimations, function(animation) { - animationRunners.push(animation.start()); - }); - - var runner = new $$AnimateRunner({ - end: endFn, - cancel: endFn // CSS-driven animations cannot be cancelled, only ended - }); - - $$AnimateRunner.all(animationRunners, function(status) { - runner.complete(status); - }); - - return runner; - - function endFn() { - forEach(animationRunners, function(runner) { - runner.end(); - }); - } - } - }; - } - - function prepareRegularAnimation(animationDetails) { - var element = animationDetails.element; - var options = animationDetails.options || {}; - - if (animationDetails.structural) { - options.event = animationDetails.event; - options.structural = true; - options.applyClassesEarly = true; - - // we special case the leave animation since we want to ensure that - // the element is removed as soon as the animation is over. Otherwise - // a flicker might appear or the element may not be removed at all - if (animationDetails.event === 'leave') { - options.onDone = options.domOperation; - } - } - - // We assign the preparationClasses as the actual animation event since - // the internals of $animateCss will just suffix the event token values - // with `-active` to trigger the animation. - if (options.preparationClasses) { - options.event = concatWithSpace(options.event, options.preparationClasses); - } - - var animator = $animateCss(element, options); - - // the driver lookup code inside of $$animation attempts to spawn a - // driver one by one until a driver returns a.$$willAnimate animator object. - // $animateCss will always return an object, however, it will pass in - // a flag as a hint as to whether an animation was detected or not - return animator.$$willAnimate ? animator : null; - } - }]; -}]; - -// TODO(matsko): use caching here to speed things up for detection -// TODO(matsko): add documentation -// by the time... - -var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) { - this.$get = ['$injector', '$$AnimateRunner', '$$jqLite', - function($injector, $$AnimateRunner, $$jqLite) { - - var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); - // $animateJs(element, 'enter'); - return function(element, event, classes, options) { - var animationClosed = false; - - // the `classes` argument is optional and if it is not used - // then the classes will be resolved from the element's className - // property as well as options.addClass/options.removeClass. - if (arguments.length === 3 && isObject(classes)) { - options = classes; - classes = null; - } - - options = prepareAnimationOptions(options); - if (!classes) { - classes = element.attr('class') || ''; - if (options.addClass) { - classes += ' ' + options.addClass; - } - if (options.removeClass) { - classes += ' ' + options.removeClass; - } - } - - var classesToAdd = options.addClass; - var classesToRemove = options.removeClass; - - // the lookupAnimations function returns a series of animation objects that are - // matched up with one or more of the CSS classes. These animation objects are - // defined via the module.animation factory function. If nothing is detected then - // we don't return anything which then makes $animation query the next driver. - var animations = lookupAnimations(classes); - var before, after; - if (animations.length) { - var afterFn, beforeFn; - if (event == 'leave') { - beforeFn = 'leave'; - afterFn = 'afterLeave'; // TODO(matsko): get rid of this - } else { - beforeFn = 'before' + event.charAt(0).toUpperCase() + event.substr(1); - afterFn = event; - } - - if (event !== 'enter' && event !== 'move') { - before = packageAnimations(element, event, options, animations, beforeFn); - } - after = packageAnimations(element, event, options, animations, afterFn); - } - - // no matching animations - if (!before && !after) return; - - function applyOptions() { - options.domOperation(); - applyAnimationClasses(element, options); - } - - function close() { - animationClosed = true; - applyOptions(); - applyAnimationStyles(element, options); - } - - var runner; - - return { - $$willAnimate: true, - end: function() { - if (runner) { - runner.end(); - } else { - close(); - runner = new $$AnimateRunner(); - runner.complete(true); - } - return runner; - }, - start: function() { - if (runner) { - return runner; - } - - runner = new $$AnimateRunner(); - var closeActiveAnimations; - var chain = []; - - if (before) { - chain.push(function(fn) { - closeActiveAnimations = before(fn); - }); - } - - if (chain.length) { - chain.push(function(fn) { - applyOptions(); - fn(true); - }); - } else { - applyOptions(); - } - - if (after) { - chain.push(function(fn) { - closeActiveAnimations = after(fn); - }); - } - - runner.setHost({ - end: function() { - endAnimations(); - }, - cancel: function() { - endAnimations(true); - } - }); - - $$AnimateRunner.chain(chain, onComplete); - return runner; - - function onComplete(success) { - close(success); - runner.complete(success); - } - - function endAnimations(cancelled) { - if (!animationClosed) { - (closeActiveAnimations || noop)(cancelled); - onComplete(cancelled); - } - } - } - }; - - function executeAnimationFn(fn, element, event, options, onDone) { - var args; - switch (event) { - case 'animate': - args = [element, options.from, options.to, onDone]; - break; - - case 'setClass': - args = [element, classesToAdd, classesToRemove, onDone]; - break; - - case 'addClass': - args = [element, classesToAdd, onDone]; - break; - - case 'removeClass': - args = [element, classesToRemove, onDone]; - break; - - default: - args = [element, onDone]; - break; - } - - args.push(options); - - var value = fn.apply(fn, args); - if (value) { - if (isFunction(value.start)) { - value = value.start(); - } - - if (value instanceof $$AnimateRunner) { - value.done(onDone); - } else if (isFunction(value)) { - // optional onEnd / onCancel callback - return value; - } - } - - return noop; - } - - function groupEventedAnimations(element, event, options, animations, fnName) { - var operations = []; - forEach(animations, function(ani) { - var animation = ani[fnName]; - if (!animation) return; - - // note that all of these animations will run in parallel - operations.push(function() { - var runner; - var endProgressCb; - - var resolved = false; - var onAnimationComplete = function(rejected) { - if (!resolved) { - resolved = true; - (endProgressCb || noop)(rejected); - runner.complete(!rejected); - } - }; - - runner = new $$AnimateRunner({ - end: function() { - onAnimationComplete(); - }, - cancel: function() { - onAnimationComplete(true); - } - }); - - endProgressCb = executeAnimationFn(animation, element, event, options, function(result) { - var cancelled = result === false; - onAnimationComplete(cancelled); - }); - - return runner; - }); - }); - - return operations; - } - - function packageAnimations(element, event, options, animations, fnName) { - var operations = groupEventedAnimations(element, event, options, animations, fnName); - if (operations.length === 0) { - var a,b; - if (fnName === 'beforeSetClass') { - a = groupEventedAnimations(element, 'removeClass', options, animations, 'beforeRemoveClass'); - b = groupEventedAnimations(element, 'addClass', options, animations, 'beforeAddClass'); - } else if (fnName === 'setClass') { - a = groupEventedAnimations(element, 'removeClass', options, animations, 'removeClass'); - b = groupEventedAnimations(element, 'addClass', options, animations, 'addClass'); - } - - if (a) { - operations = operations.concat(a); - } - if (b) { - operations = operations.concat(b); - } - } - - if (operations.length === 0) return; - - // TODO(matsko): add documentation - return function startAnimation(callback) { - var runners = []; - if (operations.length) { - forEach(operations, function(animateFn) { - runners.push(animateFn()); - }); - } - - runners.length ? $$AnimateRunner.all(runners, callback) : callback(); - - return function endFn(reject) { - forEach(runners, function(runner) { - reject ? runner.cancel() : runner.end(); - }); - }; - }; - } - }; - - function lookupAnimations(classes) { - classes = isArray(classes) ? classes : classes.split(' '); - var matches = [], flagMap = {}; - for (var i=0; i < classes.length; i++) { - var klass = classes[i], - animationFactory = $animateProvider.$$registeredAnimations[klass]; - if (animationFactory && !flagMap[klass]) { - matches.push($injector.get(animationFactory)); - flagMap[klass] = true; - } - } - return matches; - } - }]; -}]; - -var $$AnimateJsDriverProvider = ['$$animationProvider', function($$animationProvider) { - $$animationProvider.drivers.push('$$animateJsDriver'); - this.$get = ['$$animateJs', '$$AnimateRunner', function($$animateJs, $$AnimateRunner) { - return function initDriverFn(animationDetails) { - if (animationDetails.from && animationDetails.to) { - var fromAnimation = prepareAnimation(animationDetails.from); - var toAnimation = prepareAnimation(animationDetails.to); - if (!fromAnimation && !toAnimation) return; - - return { - start: function() { - var animationRunners = []; - - if (fromAnimation) { - animationRunners.push(fromAnimation.start()); - } - - if (toAnimation) { - animationRunners.push(toAnimation.start()); - } - - $$AnimateRunner.all(animationRunners, done); - - var runner = new $$AnimateRunner({ - end: endFnFactory(), - cancel: endFnFactory() - }); - - return runner; - - function endFnFactory() { - return function() { - forEach(animationRunners, function(runner) { - // at this point we cannot cancel animations for groups just yet. 1.5+ - runner.end(); - }); - }; - } - - function done(status) { - runner.complete(status); - } - } - }; - } else { - return prepareAnimation(animationDetails); - } - }; - - function prepareAnimation(animationDetails) { - // TODO(matsko): make sure to check for grouped animations and delegate down to normal animations - var element = animationDetails.element; - var event = animationDetails.event; - var options = animationDetails.options; - var classes = animationDetails.classes; - return $$animateJs(element, event, classes, options); - } - }]; -}]; - -var NG_ANIMATE_ATTR_NAME = 'data-ng-animate'; -var NG_ANIMATE_PIN_DATA = '$ngAnimatePin'; -var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { - var PRE_DIGEST_STATE = 1; - var RUNNING_STATE = 2; - var ONE_SPACE = ' '; - - var rules = this.rules = { - skip: [], - cancel: [], - join: [] - }; - - function makeTruthyCssClassMap(classString) { - if (!classString) { - return null; - } - - var keys = classString.split(ONE_SPACE); - var map = Object.create(null); - - forEach(keys, function(key) { - map[key] = true; - }); - return map; - } - - function hasMatchingClasses(newClassString, currentClassString) { - if (newClassString && currentClassString) { - var currentClassMap = makeTruthyCssClassMap(currentClassString); - return newClassString.split(ONE_SPACE).some(function(className) { - return currentClassMap[className]; - }); - } - } - - function isAllowed(ruleType, element, currentAnimation, previousAnimation) { - return rules[ruleType].some(function(fn) { - return fn(element, currentAnimation, previousAnimation); - }); - } - - function hasAnimationClasses(animation, and) { - var a = (animation.addClass || '').length > 0; - var b = (animation.removeClass || '').length > 0; - return and ? a && b : a || b; - } - - rules.join.push(function(element, newAnimation, currentAnimation) { - // if the new animation is class-based then we can just tack that on - return !newAnimation.structural && hasAnimationClasses(newAnimation); - }); - - rules.skip.push(function(element, newAnimation, currentAnimation) { - // there is no need to animate anything if no classes are being added and - // there is no structural animation that will be triggered - return !newAnimation.structural && !hasAnimationClasses(newAnimation); - }); - - rules.skip.push(function(element, newAnimation, currentAnimation) { - // why should we trigger a new structural animation if the element will - // be removed from the DOM anyway? - return currentAnimation.event == 'leave' && newAnimation.structural; - }); - - rules.skip.push(function(element, newAnimation, currentAnimation) { - // if there is an ongoing current animation then don't even bother running the class-based animation - return currentAnimation.structural && currentAnimation.state === RUNNING_STATE && !newAnimation.structural; - }); - - rules.cancel.push(function(element, newAnimation, currentAnimation) { - // there can never be two structural animations running at the same time - return currentAnimation.structural && newAnimation.structural; - }); - - rules.cancel.push(function(element, newAnimation, currentAnimation) { - // if the previous animation is already running, but the new animation will - // be triggered, but the new animation is structural - return currentAnimation.state === RUNNING_STATE && newAnimation.structural; - }); - - rules.cancel.push(function(element, newAnimation, currentAnimation) { - var nA = newAnimation.addClass; - var nR = newAnimation.removeClass; - var cA = currentAnimation.addClass; - var cR = currentAnimation.removeClass; - - // early detection to save the global CPU shortage :) - if ((isUndefined(nA) && isUndefined(nR)) || (isUndefined(cA) && isUndefined(cR))) { - return false; - } - - return hasMatchingClasses(nA, cR) || hasMatchingClasses(nR, cA); - }); - - this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap', - '$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite', '$$forceReflow', - function($$rAF, $rootScope, $rootElement, $document, $$HashMap, - $$animation, $$AnimateRunner, $templateRequest, $$jqLite, $$forceReflow) { - - var activeAnimationsLookup = new $$HashMap(); - var disabledElementsLookup = new $$HashMap(); - var animationsEnabled = null; - - function postDigestTaskFactory() { - var postDigestCalled = false; - return function(fn) { - // we only issue a call to postDigest before - // it has first passed. This prevents any callbacks - // from not firing once the animation has completed - // since it will be out of the digest cycle. - if (postDigestCalled) { - fn(); - } else { - $rootScope.$$postDigest(function() { - postDigestCalled = true; - fn(); - }); - } - }; - } - - // Wait until all directive and route-related templates are downloaded and - // compiled. The $templateRequest.totalPendingRequests variable keeps track of - // all of the remote templates being currently downloaded. If there are no - // templates currently downloading then the watcher will still fire anyway. - var deregisterWatch = $rootScope.$watch( - function() { return $templateRequest.totalPendingRequests === 0; }, - function(isEmpty) { - if (!isEmpty) return; - deregisterWatch(); - - // Now that all templates have been downloaded, $animate will wait until - // the post digest queue is empty before enabling animations. By having two - // calls to $postDigest calls we can ensure that the flag is enabled at the - // very end of the post digest queue. Since all of the animations in $animate - // use $postDigest, it's important that the code below executes at the end. - // This basically means that the page is fully downloaded and compiled before - // any animations are triggered. - $rootScope.$$postDigest(function() { - $rootScope.$$postDigest(function() { - // we check for null directly in the event that the application already called - // .enabled() with whatever arguments that it provided it with - if (animationsEnabled === null) { - animationsEnabled = true; - } - }); - }); - } - ); - - var callbackRegistry = {}; - - // remember that the classNameFilter is set during the provider/config - // stage therefore we can optimize here and setup a helper function - var classNameFilter = $animateProvider.classNameFilter(); - var isAnimatableClassName = !classNameFilter - ? function() { return true; } - : function(className) { - return classNameFilter.test(className); - }; - - var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); - - function normalizeAnimationDetails(element, animation) { - return mergeAnimationDetails(element, animation, {}); - } - - // IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259. - var contains = Node.prototype.contains || function(arg) { - // jshint bitwise: false - return this === arg || !!(this.compareDocumentPosition(arg) & 16); - // jshint bitwise: true - }; - - function findCallbacks(parent, element, event) { - var targetNode = getDomNode(element); - var targetParentNode = getDomNode(parent); - - var matches = []; - var entries = callbackRegistry[event]; - if (entries) { - forEach(entries, function(entry) { - if (contains.call(entry.node, targetNode)) { - matches.push(entry.callback); - } else if (event === 'leave' && contains.call(entry.node, targetParentNode)) { - matches.push(entry.callback); - } - }); - } - - return matches; - } - - return { - on: function(event, container, callback) { - var node = extractElementNode(container); - callbackRegistry[event] = callbackRegistry[event] || []; - callbackRegistry[event].push({ - node: node, - callback: callback - }); - }, - - off: function(event, container, callback) { - var entries = callbackRegistry[event]; - if (!entries) return; - - callbackRegistry[event] = arguments.length === 1 - ? null - : filterFromRegistry(entries, container, callback); - - function filterFromRegistry(list, matchContainer, matchCallback) { - var containerNode = extractElementNode(matchContainer); - return list.filter(function(entry) { - var isMatch = entry.node === containerNode && - (!matchCallback || entry.callback === matchCallback); - return !isMatch; - }); - } - }, - - pin: function(element, parentElement) { - assertArg(isElement(element), 'element', 'not an element'); - assertArg(isElement(parentElement), 'parentElement', 'not an element'); - element.data(NG_ANIMATE_PIN_DATA, parentElement); - }, - - push: function(element, event, options, domOperation) { - options = options || {}; - options.domOperation = domOperation; - return queueAnimation(element, event, options); - }, - - // this method has four signatures: - // () - global getter - // (bool) - global setter - // (element) - element getter - // (element, bool) - element setter - enabled: function(element, bool) { - var argCount = arguments.length; - - if (argCount === 0) { - // () - Global getter - bool = !!animationsEnabled; - } else { - var hasElement = isElement(element); - - if (!hasElement) { - // (bool) - Global setter - bool = animationsEnabled = !!element; - } else { - var node = getDomNode(element); - var recordExists = disabledElementsLookup.get(node); - - if (argCount === 1) { - // (element) - Element getter - bool = !recordExists; - } else { - // (element, bool) - Element setter - disabledElementsLookup.put(node, !bool); - } - } - } - - return bool; - } - }; - - function queueAnimation(element, event, initialOptions) { - // we always make a copy of the options since - // there should never be any side effects on - // the input data when running `$animateCss`. - var options = copy(initialOptions); - - var node, parent; - element = stripCommentsFromElement(element); - if (element) { - node = getDomNode(element); - parent = element.parent(); - } - - options = prepareAnimationOptions(options); - - // we create a fake runner with a working promise. - // These methods will become available after the digest has passed - var runner = new $$AnimateRunner(); - - // this is used to trigger callbacks in postDigest mode - var runInNextPostDigestOrNow = postDigestTaskFactory(); - - if (isArray(options.addClass)) { - options.addClass = options.addClass.join(' '); - } - - if (options.addClass && !isString(options.addClass)) { - options.addClass = null; - } - - if (isArray(options.removeClass)) { - options.removeClass = options.removeClass.join(' '); - } - - if (options.removeClass && !isString(options.removeClass)) { - options.removeClass = null; - } - - if (options.from && !isObject(options.from)) { - options.from = null; - } - - if (options.to && !isObject(options.to)) { - options.to = null; - } - - // there are situations where a directive issues an animation for - // a jqLite wrapper that contains only comment nodes... If this - // happens then there is no way we can perform an animation - if (!node) { - close(); - return runner; - } - - var className = [node.className, options.addClass, options.removeClass].join(' '); - if (!isAnimatableClassName(className)) { - close(); - return runner; - } - - var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0; - - // this is a hard disable of all animations for the application or on - // the element itself, therefore there is no need to continue further - // past this point if not enabled - // Animations are also disabled if the document is currently hidden (page is not visible - // to the user), because browsers slow down or do not flush calls to requestAnimationFrame - var skipAnimations = !animationsEnabled || $document[0].hidden || disabledElementsLookup.get(node); - var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {}; - var hasExistingAnimation = !!existingAnimation.state; - - // there is no point in traversing the same collection of parent ancestors if a followup - // animation will be run on the same element that already did all that checking work - if (!skipAnimations && (!hasExistingAnimation || existingAnimation.state != PRE_DIGEST_STATE)) { - skipAnimations = !areAnimationsAllowed(element, parent, event); - } - - if (skipAnimations) { - close(); - return runner; - } - - if (isStructural) { - closeChildAnimations(element); - } - - var newAnimation = { - structural: isStructural, - element: element, - event: event, - addClass: options.addClass, - removeClass: options.removeClass, - close: close, - options: options, - runner: runner - }; - - if (hasExistingAnimation) { - var skipAnimationFlag = isAllowed('skip', element, newAnimation, existingAnimation); - if (skipAnimationFlag) { - if (existingAnimation.state === RUNNING_STATE) { - close(); - return runner; - } else { - mergeAnimationDetails(element, existingAnimation, newAnimation); - return existingAnimation.runner; - } - } - var cancelAnimationFlag = isAllowed('cancel', element, newAnimation, existingAnimation); - if (cancelAnimationFlag) { - if (existingAnimation.state === RUNNING_STATE) { - // this will end the animation right away and it is safe - // to do so since the animation is already running and the - // runner callback code will run in async - existingAnimation.runner.end(); - } else if (existingAnimation.structural) { - // this means that the animation is queued into a digest, but - // hasn't started yet. Therefore it is safe to run the close - // method which will call the runner methods in async. - existingAnimation.close(); - } else { - // this will merge the new animation options into existing animation options - mergeAnimationDetails(element, existingAnimation, newAnimation); - - return existingAnimation.runner; - } - } else { - // a joined animation means that this animation will take over the existing one - // so an example would involve a leave animation taking over an enter. Then when - // the postDigest kicks in the enter will be ignored. - var joinAnimationFlag = isAllowed('join', element, newAnimation, existingAnimation); - if (joinAnimationFlag) { - if (existingAnimation.state === RUNNING_STATE) { - normalizeAnimationDetails(element, newAnimation); - } else { - applyGeneratedPreparationClasses(element, isStructural ? event : null, options); - - event = newAnimation.event = existingAnimation.event; - options = mergeAnimationDetails(element, existingAnimation, newAnimation); - - //we return the same runner since only the option values of this animation will - //be fed into the `existingAnimation`. - return existingAnimation.runner; - } - } - } - } else { - // normalization in this case means that it removes redundant CSS classes that - // already exist (addClass) or do not exist (removeClass) on the element - normalizeAnimationDetails(element, newAnimation); - } - - // when the options are merged and cleaned up we may end up not having to do - // an animation at all, therefore we should check this before issuing a post - // digest callback. Structural animations will always run no matter what. - var isValidAnimation = newAnimation.structural; - if (!isValidAnimation) { - // animate (from/to) can be quickly checked first, otherwise we check if any classes are present - isValidAnimation = (newAnimation.event === 'animate' && Object.keys(newAnimation.options.to || {}).length > 0) - || hasAnimationClasses(newAnimation); - } - - if (!isValidAnimation) { - close(); - clearElementAnimationState(element); - return runner; - } - - // the counter keeps track of cancelled animations - var counter = (existingAnimation.counter || 0) + 1; - newAnimation.counter = counter; - - markElementAnimationState(element, PRE_DIGEST_STATE, newAnimation); - - $rootScope.$$postDigest(function() { - var animationDetails = activeAnimationsLookup.get(node); - var animationCancelled = !animationDetails; - animationDetails = animationDetails || {}; - - // if addClass/removeClass is called before something like enter then the - // registered parent element may not be present. The code below will ensure - // that a final value for parent element is obtained - var parentElement = element.parent() || []; - - // animate/structural/class-based animations all have requirements. Otherwise there - // is no point in performing an animation. The parent node must also be set. - var isValidAnimation = parentElement.length > 0 - && (animationDetails.event === 'animate' - || animationDetails.structural - || hasAnimationClasses(animationDetails)); - - // this means that the previous animation was cancelled - // even if the follow-up animation is the same event - if (animationCancelled || animationDetails.counter !== counter || !isValidAnimation) { - // if another animation did not take over then we need - // to make sure that the domOperation and options are - // handled accordingly - if (animationCancelled) { - applyAnimationClasses(element, options); - applyAnimationStyles(element, options); - } - - // if the event changed from something like enter to leave then we do - // it, otherwise if it's the same then the end result will be the same too - if (animationCancelled || (isStructural && animationDetails.event !== event)) { - options.domOperation(); - runner.end(); - } - - // in the event that the element animation was not cancelled or a follow-up animation - // isn't allowed to animate from here then we need to clear the state of the element - // so that any future animations won't read the expired animation data. - if (!isValidAnimation) { - clearElementAnimationState(element); - } - - return; - } - - // this combined multiple class to addClass / removeClass into a setClass event - // so long as a structural event did not take over the animation - event = !animationDetails.structural && hasAnimationClasses(animationDetails, true) - ? 'setClass' - : animationDetails.event; - - markElementAnimationState(element, RUNNING_STATE); - var realRunner = $$animation(element, event, animationDetails.options); - - realRunner.done(function(status) { - close(!status); - var animationDetails = activeAnimationsLookup.get(node); - if (animationDetails && animationDetails.counter === counter) { - clearElementAnimationState(getDomNode(element)); - } - notifyProgress(runner, event, 'close', {}); - }); - - // this will update the runner's flow-control events based on - // the `realRunner` object. - runner.setHost(realRunner); - notifyProgress(runner, event, 'start', {}); - }); - - return runner; - - function notifyProgress(runner, event, phase, data) { - runInNextPostDigestOrNow(function() { - var callbacks = findCallbacks(parent, element, event); - if (callbacks.length) { - // do not optimize this call here to RAF because - // we don't know how heavy the callback code here will - // be and if this code is buffered then this can - // lead to a performance regression. - $$rAF(function() { - forEach(callbacks, function(callback) { - callback(element, phase, data); - }); - }); - } - }); - runner.progress(event, phase, data); - } - - function close(reject) { // jshint ignore:line - clearGeneratedClasses(element, options); - applyAnimationClasses(element, options); - applyAnimationStyles(element, options); - options.domOperation(); - runner.complete(!reject); - } - } - - function closeChildAnimations(element) { - var node = getDomNode(element); - var children = node.querySelectorAll('[' + NG_ANIMATE_ATTR_NAME + ']'); - forEach(children, function(child) { - var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME)); - var animationDetails = activeAnimationsLookup.get(child); - if (animationDetails) { - switch (state) { - case RUNNING_STATE: - animationDetails.runner.end(); - /* falls through */ - case PRE_DIGEST_STATE: - activeAnimationsLookup.remove(child); - break; - } - } - }); - } - - function clearElementAnimationState(element) { - var node = getDomNode(element); - node.removeAttribute(NG_ANIMATE_ATTR_NAME); - activeAnimationsLookup.remove(node); - } - - function isMatchingElement(nodeOrElmA, nodeOrElmB) { - return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB); - } - - /** - * This fn returns false if any of the following is true: - * a) animations on any parent element are disabled, and animations on the element aren't explicitly allowed - * b) a parent element has an ongoing structural animation, and animateChildren is false - * c) the element is not a child of the body - * d) the element is not a child of the $rootElement - */ - function areAnimationsAllowed(element, parentElement, event) { - var bodyElement = jqLite($document[0].body); - var bodyElementDetected = isMatchingElement(element, bodyElement) || element[0].nodeName === 'HTML'; - var rootElementDetected = isMatchingElement(element, $rootElement); - var parentAnimationDetected = false; - var animateChildren; - var elementDisabled = disabledElementsLookup.get(getDomNode(element)); - - var parentHost = element.data(NG_ANIMATE_PIN_DATA); - if (parentHost) { - parentElement = parentHost; - } - - while (parentElement && parentElement.length) { - if (!rootElementDetected) { - // angular doesn't want to attempt to animate elements outside of the application - // therefore we need to ensure that the rootElement is an ancestor of the current element - rootElementDetected = isMatchingElement(parentElement, $rootElement); - } - - var parentNode = parentElement[0]; - if (parentNode.nodeType !== ELEMENT_NODE) { - // no point in inspecting the #document element - break; - } - - var details = activeAnimationsLookup.get(parentNode) || {}; - // either an enter, leave or move animation will commence - // therefore we can't allow any animations to take place - // but if a parent animation is class-based then that's ok - if (!parentAnimationDetected) { - var parentElementDisabled = disabledElementsLookup.get(parentNode); - - if (parentElementDisabled === true && elementDisabled !== false) { - // disable animations if the user hasn't explicitly enabled animations on the - // current element - elementDisabled = true; - // element is disabled via parent element, no need to check anything else - break; - } else if (parentElementDisabled === false) { - elementDisabled = false; - } - parentAnimationDetected = details.structural; - } - - if (isUndefined(animateChildren) || animateChildren === true) { - var value = parentElement.data(NG_ANIMATE_CHILDREN_DATA); - if (isDefined(value)) { - animateChildren = value; - } - } - - // there is no need to continue traversing at this point - if (parentAnimationDetected && animateChildren === false) break; - - if (!bodyElementDetected) { - // we also need to ensure that the element is or will be a part of the body element - // otherwise it is pointless to even issue an animation to be rendered - bodyElementDetected = isMatchingElement(parentElement, bodyElement); - } - - if (bodyElementDetected && rootElementDetected) { - // If both body and root have been found, any other checks are pointless, - // as no animation data should live outside the application - break; - } - - if (!rootElementDetected) { - // If no rootElement is detected, check if the parentElement is pinned to another element - parentHost = parentElement.data(NG_ANIMATE_PIN_DATA); - if (parentHost) { - // The pin target element becomes the next parent element - parentElement = parentHost; - continue; - } - } - - parentElement = parentElement.parent(); - } - - var allowAnimation = (!parentAnimationDetected || animateChildren) && elementDisabled !== true; - return allowAnimation && rootElementDetected && bodyElementDetected; - } - - function markElementAnimationState(element, state, details) { - details = details || {}; - details.state = state; - - var node = getDomNode(element); - node.setAttribute(NG_ANIMATE_ATTR_NAME, state); - - var oldValue = activeAnimationsLookup.get(node); - var newValue = oldValue - ? extend(oldValue, details) - : details; - activeAnimationsLookup.put(node, newValue); - } - }]; -}]; - -var $$AnimationProvider = ['$animateProvider', function($animateProvider) { - var NG_ANIMATE_REF_ATTR = 'ng-animate-ref'; - - var drivers = this.drivers = []; - - var RUNNER_STORAGE_KEY = '$$animationRunner'; - - function setRunner(element, runner) { - element.data(RUNNER_STORAGE_KEY, runner); - } - - function removeRunner(element) { - element.removeData(RUNNER_STORAGE_KEY); - } - - function getRunner(element) { - return element.data(RUNNER_STORAGE_KEY); - } - - this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$HashMap', '$$rAFScheduler', - function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$HashMap, $$rAFScheduler) { - - var animationQueue = []; - var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); - - function sortAnimations(animations) { - var tree = { children: [] }; - var i, lookup = new $$HashMap(); - - // this is done first beforehand so that the hashmap - // is filled with a list of the elements that will be animated - for (i = 0; i < animations.length; i++) { - var animation = animations[i]; - lookup.put(animation.domNode, animations[i] = { - domNode: animation.domNode, - fn: animation.fn, - children: [] - }); - } - - for (i = 0; i < animations.length; i++) { - processNode(animations[i]); - } - - return flatten(tree); - - function processNode(entry) { - if (entry.processed) return entry; - entry.processed = true; - - var elementNode = entry.domNode; - var parentNode = elementNode.parentNode; - lookup.put(elementNode, entry); - - var parentEntry; - while (parentNode) { - parentEntry = lookup.get(parentNode); - if (parentEntry) { - if (!parentEntry.processed) { - parentEntry = processNode(parentEntry); - } - break; - } - parentNode = parentNode.parentNode; - } - - (parentEntry || tree).children.push(entry); - return entry; - } - - function flatten(tree) { - var result = []; - var queue = []; - var i; - - for (i = 0; i < tree.children.length; i++) { - queue.push(tree.children[i]); - } - - var remainingLevelEntries = queue.length; - var nextLevelEntries = 0; - var row = []; - - for (i = 0; i < queue.length; i++) { - var entry = queue[i]; - if (remainingLevelEntries <= 0) { - remainingLevelEntries = nextLevelEntries; - nextLevelEntries = 0; - result.push(row); - row = []; - } - row.push(entry.fn); - entry.children.forEach(function(childEntry) { - nextLevelEntries++; - queue.push(childEntry); - }); - remainingLevelEntries--; - } - - if (row.length) { - result.push(row); - } - - return result; - } - } - - // TODO(matsko): document the signature in a better way - return function(element, event, options) { - options = prepareAnimationOptions(options); - var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0; - - // there is no animation at the current moment, however - // these runner methods will get later updated with the - // methods leading into the driver's end/cancel methods - // for now they just stop the animation from starting - var runner = new $$AnimateRunner({ - end: function() { close(); }, - cancel: function() { close(true); } - }); - - if (!drivers.length) { - close(); - return runner; - } - - setRunner(element, runner); - - var classes = mergeClasses(element.attr('class'), mergeClasses(options.addClass, options.removeClass)); - var tempClasses = options.tempClasses; - if (tempClasses) { - classes += ' ' + tempClasses; - options.tempClasses = null; - } - - var prepareClassName; - if (isStructural) { - prepareClassName = 'ng-' + event + PREPARE_CLASS_SUFFIX; - $$jqLite.addClass(element, prepareClassName); - } - - animationQueue.push({ - // this data is used by the postDigest code and passed into - // the driver step function - element: element, - classes: classes, - event: event, - structural: isStructural, - options: options, - beforeStart: beforeStart, - close: close - }); - - element.on('$destroy', handleDestroyedElement); - - // we only want there to be one function called within the post digest - // block. This way we can group animations for all the animations that - // were apart of the same postDigest flush call. - if (animationQueue.length > 1) return runner; - - $rootScope.$$postDigest(function() { - var animations = []; - forEach(animationQueue, function(entry) { - // the element was destroyed early on which removed the runner - // form its storage. This means we can't animate this element - // at all and it already has been closed due to destruction. - if (getRunner(entry.element)) { - animations.push(entry); - } else { - entry.close(); - } - }); - - // now any future animations will be in another postDigest - animationQueue.length = 0; - - var groupedAnimations = groupAnimations(animations); - var toBeSortedAnimations = []; - - forEach(groupedAnimations, function(animationEntry) { - toBeSortedAnimations.push({ - domNode: getDomNode(animationEntry.from ? animationEntry.from.element : animationEntry.element), - fn: function triggerAnimationStart() { - // it's important that we apply the `ng-animate` CSS class and the - // temporary classes before we do any driver invoking since these - // CSS classes may be required for proper CSS detection. - animationEntry.beforeStart(); - - var startAnimationFn, closeFn = animationEntry.close; - - // in the event that the element was removed before the digest runs or - // during the RAF sequencing then we should not trigger the animation. - var targetElement = animationEntry.anchors - ? (animationEntry.from.element || animationEntry.to.element) - : animationEntry.element; - - if (getRunner(targetElement)) { - var operation = invokeFirstDriver(animationEntry); - if (operation) { - startAnimationFn = operation.start; - } - } - - if (!startAnimationFn) { - closeFn(); - } else { - var animationRunner = startAnimationFn(); - animationRunner.done(function(status) { - closeFn(!status); - }); - updateAnimationRunners(animationEntry, animationRunner); - } - } - }); - }); - - // we need to sort each of the animations in order of parent to child - // relationships. This ensures that the child classes are applied at the - // right time. - $$rAFScheduler(sortAnimations(toBeSortedAnimations)); - }); - - return runner; - - // TODO(matsko): change to reference nodes - function getAnchorNodes(node) { - var SELECTOR = '[' + NG_ANIMATE_REF_ATTR + ']'; - var items = node.hasAttribute(NG_ANIMATE_REF_ATTR) - ? [node] - : node.querySelectorAll(SELECTOR); - var anchors = []; - forEach(items, function(node) { - var attr = node.getAttribute(NG_ANIMATE_REF_ATTR); - if (attr && attr.length) { - anchors.push(node); - } - }); - return anchors; - } - - function groupAnimations(animations) { - var preparedAnimations = []; - var refLookup = {}; - forEach(animations, function(animation, index) { - var element = animation.element; - var node = getDomNode(element); - var event = animation.event; - var enterOrMove = ['enter', 'move'].indexOf(event) >= 0; - var anchorNodes = animation.structural ? getAnchorNodes(node) : []; - - if (anchorNodes.length) { - var direction = enterOrMove ? 'to' : 'from'; - - forEach(anchorNodes, function(anchor) { - var key = anchor.getAttribute(NG_ANIMATE_REF_ATTR); - refLookup[key] = refLookup[key] || {}; - refLookup[key][direction] = { - animationID: index, - element: jqLite(anchor) - }; - }); - } else { - preparedAnimations.push(animation); - } - }); - - var usedIndicesLookup = {}; - var anchorGroups = {}; - forEach(refLookup, function(operations, key) { - var from = operations.from; - var to = operations.to; - - if (!from || !to) { - // only one of these is set therefore we can't have an - // anchor animation since all three pieces are required - var index = from ? from.animationID : to.animationID; - var indexKey = index.toString(); - if (!usedIndicesLookup[indexKey]) { - usedIndicesLookup[indexKey] = true; - preparedAnimations.push(animations[index]); - } - return; - } - - var fromAnimation = animations[from.animationID]; - var toAnimation = animations[to.animationID]; - var lookupKey = from.animationID.toString(); - if (!anchorGroups[lookupKey]) { - var group = anchorGroups[lookupKey] = { - structural: true, - beforeStart: function() { - fromAnimation.beforeStart(); - toAnimation.beforeStart(); - }, - close: function() { - fromAnimation.close(); - toAnimation.close(); - }, - classes: cssClassesIntersection(fromAnimation.classes, toAnimation.classes), - from: fromAnimation, - to: toAnimation, - anchors: [] // TODO(matsko): change to reference nodes - }; - - // the anchor animations require that the from and to elements both have at least - // one shared CSS class which effectively marries the two elements together to use - // the same animation driver and to properly sequence the anchor animation. - if (group.classes.length) { - preparedAnimations.push(group); - } else { - preparedAnimations.push(fromAnimation); - preparedAnimations.push(toAnimation); - } - } - - anchorGroups[lookupKey].anchors.push({ - 'out': from.element, 'in': to.element - }); - }); - - return preparedAnimations; - } - - function cssClassesIntersection(a,b) { - a = a.split(' '); - b = b.split(' '); - var matches = []; - - for (var i = 0; i < a.length; i++) { - var aa = a[i]; - if (aa.substring(0,3) === 'ng-') continue; - - for (var j = 0; j < b.length; j++) { - if (aa === b[j]) { - matches.push(aa); - break; - } - } - } - - return matches.join(' '); - } - - function invokeFirstDriver(animationDetails) { - // we loop in reverse order since the more general drivers (like CSS and JS) - // may attempt more elements, but custom drivers are more particular - for (var i = drivers.length - 1; i >= 0; i--) { - var driverName = drivers[i]; - if (!$injector.has(driverName)) continue; // TODO(matsko): remove this check - - var factory = $injector.get(driverName); - var driver = factory(animationDetails); - if (driver) { - return driver; - } - } - } - - function beforeStart() { - element.addClass(NG_ANIMATE_CLASSNAME); - if (tempClasses) { - $$jqLite.addClass(element, tempClasses); - } - if (prepareClassName) { - $$jqLite.removeClass(element, prepareClassName); - prepareClassName = null; - } - } - - function updateAnimationRunners(animation, newRunner) { - if (animation.from && animation.to) { - update(animation.from.element); - update(animation.to.element); - } else { - update(animation.element); - } - - function update(element) { - getRunner(element).setHost(newRunner); - } - } - - function handleDestroyedElement() { - var runner = getRunner(element); - if (runner && (event !== 'leave' || !options.$$domOperationFired)) { - runner.end(); - } - } - - function close(rejected) { // jshint ignore:line - element.off('$destroy', handleDestroyedElement); - removeRunner(element); - - applyAnimationClasses(element, options); - applyAnimationStyles(element, options); - options.domOperation(); - - if (tempClasses) { - $$jqLite.removeClass(element, tempClasses); - } - - element.removeClass(NG_ANIMATE_CLASSNAME); - runner.complete(!rejected); - } - }; - }]; -}]; - -/** - * @ngdoc directive - * @name ngAnimateSwap - * @restrict A - * @scope - * - * @description - * - * ngAnimateSwap is a animation-oriented directive that allows for the container to - * be removed and entered in whenever the associated expression changes. A - * common usecase for this directive is a rotating banner component which - * contains one image being present at a time. When the active image changes - * then the old image will perform a `leave` animation and the new element - * will be inserted via an `enter` animation. - * - * @example - * - * - *
        - *
        - * {{ number }} - *
        - *
        - *
        - * - * angular.module('ngAnimateSwapExample', ['ngAnimate']) - * .controller('AppCtrl', ['$scope', '$interval', function($scope, $interval) { - * $scope.number = 0; - * $interval(function() { - * $scope.number++; - * }, 1000); - * - * var colors = ['red','blue','green','yellow','orange']; - * $scope.colorClass = function(number) { - * return colors[number % colors.length]; - * }; - * }]); - * - * - * .container { - * height:250px; - * width:250px; - * position:relative; - * overflow:hidden; - * border:2px solid black; - * } - * .container .cell { - * font-size:150px; - * text-align:center; - * line-height:250px; - * position:absolute; - * top:0; - * left:0; - * right:0; - * border-bottom:2px solid black; - * } - * .swap-animation.ng-enter, .swap-animation.ng-leave { - * transition:0.5s linear all; - * } - * .swap-animation.ng-enter { - * top:-250px; - * } - * .swap-animation.ng-enter-active { - * top:0px; - * } - * .swap-animation.ng-leave { - * top:0px; - * } - * .swap-animation.ng-leave-active { - * top:250px; - * } - * .red { background:red; } - * .green { background:green; } - * .blue { background:blue; } - * .yellow { background:yellow; } - * .orange { background:orange; } - * - *
        - */ -var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $rootScope) { - return { - restrict: 'A', - transclude: 'element', - terminal: true, - priority: 600, // we use 600 here to ensure that the directive is caught before others - link: function(scope, $element, attrs, ctrl, $transclude) { - var previousElement, previousScope; - scope.$watchCollection(attrs.ngAnimateSwap || attrs['for'], function(value) { - if (previousElement) { - $animate.leave(previousElement); - } - if (previousScope) { - previousScope.$destroy(); - previousScope = null; - } - if (value || value === 0) { - previousScope = scope.$new(); - $transclude(previousScope, function(element) { - previousElement = element; - $animate.enter(element, null, $element); - }); - } - }); - } - }; -}]; - -/* global angularAnimateModule: true, - - ngAnimateSwapDirective, - $$AnimateAsyncRunFactory, - $$rAFSchedulerFactory, - $$AnimateChildrenDirective, - $$AnimateQueueProvider, - $$AnimationProvider, - $AnimateCssProvider, - $$AnimateCssDriverProvider, - $$AnimateJsProvider, - $$AnimateJsDriverProvider, -*/ - -/** - * @ngdoc module - * @name ngAnimate - * @description - * - * The `ngAnimate` module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via - * callback hooks. Animations are not enabled by default, however, by including `ngAnimate` the animation hooks are enabled for an Angular app. - * - *
        - * - * # Usage - * Simply put, there are two ways to make use of animations when ngAnimate is used: by using **CSS** and **JavaScript**. The former works purely based - * using CSS (by using matching CSS selectors/styles) and the latter triggers animations that are registered via `module.animation()`. For - * both CSS and JS animations the sole requirement is to have a matching `CSS class` that exists both in the registered animation and within - * the HTML element that the animation will be triggered on. - * - * ## Directive Support - * The following directives are "animation aware": - * - * | Directive | Supported Animations | - * |----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------| - * | {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave and move | - * | {@link ngRoute.directive:ngView#animations ngView} | enter and leave | - * | {@link ng.directive:ngInclude#animations ngInclude} | enter and leave | - * | {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave | - * | {@link ng.directive:ngIf#animations ngIf} | enter and leave | - * | {@link ng.directive:ngClass#animations ngClass} | add and remove (the CSS class(es) present) | - * | {@link ng.directive:ngShow#animations ngShow} & {@link ng.directive:ngHide#animations ngHide} | add and remove (the ng-hide class value) | - * | {@link ng.directive:form#animation-hooks form} & {@link ng.directive:ngModel#animation-hooks ngModel} | add and remove (dirty, pristine, valid, invalid & all other validations) | - * | {@link module:ngMessages#animations ngMessages} | add and remove (ng-active & ng-inactive) | - * | {@link module:ngMessages#animations ngMessage} | enter and leave | - * - * (More information can be found by visiting each the documentation associated with each directive.) - * - * ## CSS-based Animations - * - * CSS-based animations with ngAnimate are unique since they require no JavaScript code at all. By using a CSS class that we reference between our HTML - * and CSS code we can create an animation that will be picked up by Angular when an the underlying directive performs an operation. - * - * The example below shows how an `enter` animation can be made possible on an element using `ng-if`: - * - * ```html - *
        - * Fade me in out - *
        - * - * - * ``` - * - * Notice the CSS class **fade**? We can now create the CSS transition code that references this class: - * - * ```css - * /* The starting CSS styles for the enter animation */ - * .fade.ng-enter { - * transition:0.5s linear all; - * opacity:0; - * } - * - * /* The finishing CSS styles for the enter animation */ - * .fade.ng-enter.ng-enter-active { - * opacity:1; - * } - * ``` - * - * The key thing to remember here is that, depending on the animation event (which each of the directives above trigger depending on what's going on) two - * generated CSS classes will be applied to the element; in the example above we have `.ng-enter` and `.ng-enter-active`. For CSS transitions, the transition - * code **must** be defined within the starting CSS class (in this case `.ng-enter`). The destination class is what the transition will animate towards. - * - * If for example we wanted to create animations for `leave` and `move` (ngRepeat triggers move) then we can do so using the same CSS naming conventions: - * - * ```css - * /* now the element will fade out before it is removed from the DOM */ - * .fade.ng-leave { - * transition:0.5s linear all; - * opacity:1; - * } - * .fade.ng-leave.ng-leave-active { - * opacity:0; - * } - * ``` - * - * We can also make use of **CSS Keyframes** by referencing the keyframe animation within the starting CSS class: - * - * ```css - * /* there is no need to define anything inside of the destination - * CSS class since the keyframe will take charge of the animation */ - * .fade.ng-leave { - * animation: my_fade_animation 0.5s linear; - * -webkit-animation: my_fade_animation 0.5s linear; - * } - * - * @keyframes my_fade_animation { - * from { opacity:1; } - * to { opacity:0; } - * } - * - * @-webkit-keyframes my_fade_animation { - * from { opacity:1; } - * to { opacity:0; } - * } - * ``` - * - * Feel free also mix transitions and keyframes together as well as any other CSS classes on the same element. - * - * ### CSS Class-based Animations - * - * Class-based animations (animations that are triggered via `ngClass`, `ngShow`, `ngHide` and some other directives) have a slightly different - * naming convention. Class-based animations are basic enough that a standard transition or keyframe can be referenced on the class being added - * and removed. - * - * For example if we wanted to do a CSS animation for `ngHide` then we place an animation on the `.ng-hide` CSS class: - * - * ```html - *
        - * Show and hide me - *
        - * - * - * - * ``` - * - * All that is going on here with ngShow/ngHide behind the scenes is the `.ng-hide` class is added/removed (when the hidden state is valid). Since - * ngShow and ngHide are animation aware then we can match up a transition and ngAnimate handles the rest. - * - * In addition the addition and removal of the CSS class, ngAnimate also provides two helper methods that we can use to further decorate the animation - * with CSS styles. - * - * ```html - *
        - * Highlight this box - *
        - * - * - * - * ``` - * - * We can also make use of CSS keyframes by placing them within the CSS classes. - * - * - * ### CSS Staggering Animations - * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a - * curtain-like effect. The ngAnimate module (versions >=1.2) supports staggering animations and the stagger effect can be - * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for - * the animation. The style property expected within the stagger class can either be a **transition-delay** or an - * **animation-delay** property (or both if your animation contains both transitions and keyframe animations). - * - * ```css - * .my-animation.ng-enter { - * /* standard transition code */ - * transition: 1s linear all; - * opacity:0; - * } - * .my-animation.ng-enter-stagger { - * /* this will have a 100ms delay between each successive leave animation */ - * transition-delay: 0.1s; - * - * /* As of 1.4.4, this must always be set: it signals ngAnimate - * to not accidentally inherit a delay property from another CSS class */ - * transition-duration: 0s; - * } - * .my-animation.ng-enter.ng-enter-active { - * /* standard transition styles */ - * opacity:1; - * } - * ``` - * - * Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations - * on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this - * are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation - * will also be reset if one or more animation frames have passed since the multiple calls to `$animate` were fired. - * - * The following code will issue the **ng-leave-stagger** event on the element provided: - * - * ```js - * var kids = parent.children(); - * - * $animate.leave(kids[0]); //stagger index=0 - * $animate.leave(kids[1]); //stagger index=1 - * $animate.leave(kids[2]); //stagger index=2 - * $animate.leave(kids[3]); //stagger index=3 - * $animate.leave(kids[4]); //stagger index=4 - * - * window.requestAnimationFrame(function() { - * //stagger has reset itself - * $animate.leave(kids[5]); //stagger index=0 - * $animate.leave(kids[6]); //stagger index=1 - * - * $scope.$digest(); - * }); - * ``` - * - * Stagger animations are currently only supported within CSS-defined animations. - * - * ### The `ng-animate` CSS class - * - * When ngAnimate is animating an element it will apply the `ng-animate` CSS class to the element for the duration of the animation. - * This is a temporary CSS class and it will be removed once the animation is over (for both JavaScript and CSS-based animations). - * - * Therefore, animations can be applied to an element using this temporary class directly via CSS. - * - * ```css - * .zipper.ng-animate { - * transition:0.5s linear all; - * } - * .zipper.ng-enter { - * opacity:0; - * } - * .zipper.ng-enter.ng-enter-active { - * opacity:1; - * } - * .zipper.ng-leave { - * opacity:1; - * } - * .zipper.ng-leave.ng-leave-active { - * opacity:0; - * } - * ``` - * - * (Note that the `ng-animate` CSS class is reserved and it cannot be applied on an element directly since ngAnimate will always remove - * the CSS class once an animation has completed.) - * - * - * ### The `ng-[event]-prepare` class - * - * This is a special class that can be used to prevent unwanted flickering / flash of content before - * the actual animation starts. The class is added as soon as an animation is initialized, but removed - * before the actual animation starts (after waiting for a $digest). - * It is also only added for *structural* animations (`enter`, `move`, and `leave`). - * - * In practice, flickering can appear when nesting elements with structural animations such as `ngIf` - * into elements that have class-based animations such as `ngClass`. - * - * ```html - *
        - *
        - *
        - *
        - *
        - * ``` - * - * It is possible that during the `enter` animation, the `.message` div will be briefly visible before it starts animating. - * In that case, you can add styles to the CSS that make sure the element stays hidden before the animation starts: - * - * ```css - * .message.ng-enter-prepare { - * opacity: 0; - * } - * - * ``` - * - * ## JavaScript-based Animations - * - * ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared - * CSS class that is referenced in our HTML code) but in addition we need to register the JavaScript animation on the module. By making use of the - * `module.animation()` module function we can register the animation. - * - * Let's see an example of a enter/leave animation using `ngRepeat`: - * - * ```html - *
        - * {{ item }} - *
        - * ``` - * - * See the **slide** CSS class? Let's use that class to define an animation that we'll structure in our module code by using `module.animation`: - * - * ```js - * myModule.animation('.slide', [function() { - * return { - * // make note that other events (like addClass/removeClass) - * // have different function input parameters - * enter: function(element, doneFn) { - * jQuery(element).fadeIn(1000, doneFn); - * - * // remember to call doneFn so that angular - * // knows that the animation has concluded - * }, - * - * move: function(element, doneFn) { - * jQuery(element).fadeIn(1000, doneFn); - * }, - * - * leave: function(element, doneFn) { - * jQuery(element).fadeOut(1000, doneFn); - * } - * } - * }]); - * ``` - * - * The nice thing about JS-based animations is that we can inject other services and make use of advanced animation libraries such as - * greensock.js and velocity.js. - * - * If our animation code class-based (meaning that something like `ngClass`, `ngHide` and `ngShow` triggers it) then we can still define - * our animations inside of the same registered animation, however, the function input arguments are a bit different: - * - * ```html - *
        - * this box is moody - *
        - * - * - * - * ``` - * - * ```js - * myModule.animation('.colorful', [function() { - * return { - * addClass: function(element, className, doneFn) { - * // do some cool animation and call the doneFn - * }, - * removeClass: function(element, className, doneFn) { - * // do some cool animation and call the doneFn - * }, - * setClass: function(element, addedClass, removedClass, doneFn) { - * // do some cool animation and call the doneFn - * } - * } - * }]); - * ``` - * - * ## CSS + JS Animations Together - * - * AngularJS 1.4 and higher has taken steps to make the amalgamation of CSS and JS animations more flexible. However, unlike earlier versions of Angular, - * defining CSS and JS animations to work off of the same CSS class will not work anymore. Therefore the example below will only result in **JS animations taking - * charge of the animation**: - * - * ```html - *
        - * Slide in and out - *
        - * ``` - * - * ```js - * myModule.animation('.slide', [function() { - * return { - * enter: function(element, doneFn) { - * jQuery(element).slideIn(1000, doneFn); - * } - * } - * }]); - * ``` - * - * ```css - * .slide.ng-enter { - * transition:0.5s linear all; - * transform:translateY(-100px); - * } - * .slide.ng-enter.ng-enter-active { - * transform:translateY(0); - * } - * ``` - * - * Does this mean that CSS and JS animations cannot be used together? Do JS-based animations always have higher priority? We can make up for the - * lack of CSS animations by using the `$animateCss` service to trigger our own tweaked-out, CSS-based animations directly from - * our own JS-based animation code: - * - * ```js - * myModule.animation('.slide', ['$animateCss', function($animateCss) { - * return { - * enter: function(element) { -* // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`. - * return $animateCss(element, { - * event: 'enter', - * structural: true - * }); - * } - * } - * }]); - * ``` - * - * The nice thing here is that we can save bandwidth by sticking to our CSS-based animation code and we don't need to rely on a 3rd-party animation framework. - * - * The `$animateCss` service is very powerful since we can feed in all kinds of extra properties that will be evaluated and fed into a CSS transition or - * keyframe animation. For example if we wanted to animate the height of an element while adding and removing classes then we can do so by providing that - * data into `$animateCss` directly: - * - * ```js - * myModule.animation('.slide', ['$animateCss', function($animateCss) { - * return { - * enter: function(element) { - * return $animateCss(element, { - * event: 'enter', - * structural: true, - * addClass: 'maroon-setting', - * from: { height:0 }, - * to: { height: 200 } - * }); - * } - * } - * }]); - * ``` - * - * Now we can fill in the rest via our transition CSS code: - * - * ```css - * /* the transition tells ngAnimate to make the animation happen */ - * .slide.ng-enter { transition:0.5s linear all; } - * - * /* this extra CSS class will be absorbed into the transition - * since the $animateCss code is adding the class */ - * .maroon-setting { background:red; } - * ``` - * - * And `$animateCss` will figure out the rest. Just make sure to have the `done()` callback fire the `doneFn` function to signal when the animation is over. - * - * To learn more about what's possible be sure to visit the {@link ngAnimate.$animateCss $animateCss service}. - * - * ## Animation Anchoring (via `ng-animate-ref`) - * - * ngAnimate in AngularJS 1.4 comes packed with the ability to cross-animate elements between - * structural areas of an application (like views) by pairing up elements using an attribute - * called `ng-animate-ref`. - * - * Let's say for example we have two views that are managed by `ng-view` and we want to show - * that there is a relationship between two components situated in within these views. By using the - * `ng-animate-ref` attribute we can identify that the two components are paired together and we - * can then attach an animation, which is triggered when the view changes. - * - * Say for example we have the following template code: - * - * ```html - * - *
        - *
        - * - * - * - * - * - * - * - * - * ``` - * - * Now, when the view changes (once the link is clicked), ngAnimate will examine the - * HTML contents to see if there is a match reference between any components in the view - * that is leaving and the view that is entering. It will scan both the view which is being - * removed (leave) and inserted (enter) to see if there are any paired DOM elements that - * contain a matching ref value. - * - * The two images match since they share the same ref value. ngAnimate will now create a - * transport element (which is a clone of the first image element) and it will then attempt - * to animate to the position of the second image element in the next view. For the animation to - * work a special CSS class called `ng-anchor` will be added to the transported element. - * - * We can now attach a transition onto the `.banner.ng-anchor` CSS class and then - * ngAnimate will handle the entire transition for us as well as the addition and removal of - * any changes of CSS classes between the elements: - * - * ```css - * .banner.ng-anchor { - * /* this animation will last for 1 second since there are - * two phases to the animation (an `in` and an `out` phase) */ - * transition:0.5s linear all; - * } - * ``` - * - * We also **must** include animations for the views that are being entered and removed - * (otherwise anchoring wouldn't be possible since the new view would be inserted right away). - * - * ```css - * .view-animation.ng-enter, .view-animation.ng-leave { - * transition:0.5s linear all; - * position:fixed; - * left:0; - * top:0; - * width:100%; - * } - * .view-animation.ng-enter { - * transform:translateX(100%); - * } - * .view-animation.ng-leave, - * .view-animation.ng-enter.ng-enter-active { - * transform:translateX(0%); - * } - * .view-animation.ng-leave.ng-leave-active { - * transform:translateX(-100%); - * } - * ``` - * - * Now we can jump back to the anchor animation. When the animation happens, there are two stages that occur: - * an `out` and an `in` stage. The `out` stage happens first and that is when the element is animated away - * from its origin. Once that animation is over then the `in` stage occurs which animates the - * element to its destination. The reason why there are two animations is to give enough time - * for the enter animation on the new element to be ready. - * - * The example above sets up a transition for both the in and out phases, but we can also target the out or - * in phases directly via `ng-anchor-out` and `ng-anchor-in`. - * - * ```css - * .banner.ng-anchor-out { - * transition: 0.5s linear all; - * - * /* the scale will be applied during the out animation, - * but will be animated away when the in animation runs */ - * transform: scale(1.2); - * } - * - * .banner.ng-anchor-in { - * transition: 1s linear all; - * } - * ``` - * - * - * - * - * ### Anchoring Demo - * - - - Home -
        -
        -
        -
        -
        - - angular.module('anchoringExample', ['ngAnimate', 'ngRoute']) - .config(['$routeProvider', function($routeProvider) { - $routeProvider.when('/', { - templateUrl: 'home.html', - controller: 'HomeController as home' - }); - $routeProvider.when('/profile/:id', { - templateUrl: 'profile.html', - controller: 'ProfileController as profile' - }); - }]) - .run(['$rootScope', function($rootScope) { - $rootScope.records = [ - { id:1, title: "Miss Beulah Roob" }, - { id:2, title: "Trent Morissette" }, - { id:3, title: "Miss Ava Pouros" }, - { id:4, title: "Rod Pouros" }, - { id:5, title: "Abdul Rice" }, - { id:6, title: "Laurie Rutherford Sr." }, - { id:7, title: "Nakia McLaughlin" }, - { id:8, title: "Jordon Blanda DVM" }, - { id:9, title: "Rhoda Hand" }, - { id:10, title: "Alexandrea Sauer" } - ]; - }]) - .controller('HomeController', [function() { - //empty - }]) - .controller('ProfileController', ['$rootScope', '$routeParams', function($rootScope, $routeParams) { - var index = parseInt($routeParams.id, 10); - var record = $rootScope.records[index - 1]; - - this.title = record.title; - this.id = record.id; - }]); - - -

        Welcome to the home page

        -

        Please click on an element

        - - {{ record.title }} - -
        - -
        - {{ profile.title }} -
        -
        - - .record { - display:block; - font-size:20px; - } - .profile { - background:black; - color:white; - font-size:100px; - } - .view-container { - position:relative; - } - .view-container > .view.ng-animate { - position:absolute; - top:0; - left:0; - width:100%; - min-height:500px; - } - .view.ng-enter, .view.ng-leave, - .record.ng-anchor { - transition:0.5s linear all; - } - .view.ng-enter { - transform:translateX(100%); - } - .view.ng-enter.ng-enter-active, .view.ng-leave { - transform:translateX(0%); - } - .view.ng-leave.ng-leave-active { - transform:translateX(-100%); - } - .record.ng-anchor-out { - background:red; - } - -
        - * - * ### How is the element transported? - * - * When an anchor animation occurs, ngAnimate will clone the starting element and position it exactly where the starting - * element is located on screen via absolute positioning. The cloned element will be placed inside of the root element - * of the application (where ng-app was defined) and all of the CSS classes of the starting element will be applied. The - * element will then animate into the `out` and `in` animations and will eventually reach the coordinates and match - * the dimensions of the destination element. During the entire animation a CSS class of `.ng-animate-shim` will be applied - * to both the starting and destination elements in order to hide them from being visible (the CSS styling for the class - * is: `visibility:hidden`). Once the anchor reaches its destination then it will be removed and the destination element - * will become visible since the shim class will be removed. - * - * ### How is the morphing handled? - * - * CSS Anchoring relies on transitions and keyframes and the internal code is intelligent enough to figure out - * what CSS classes differ between the starting element and the destination element. These different CSS classes - * will be added/removed on the anchor element and a transition will be applied (the transition that is provided - * in the anchor class). Long story short, ngAnimate will figure out what classes to add and remove which will - * make the transition of the element as smooth and automatic as possible. Be sure to use simple CSS classes that - * do not rely on DOM nesting structure so that the anchor element appears the same as the starting element (since - * the cloned element is placed inside of root element which is likely close to the body element). - * - * Note that if the root element is on the `` element then the cloned node will be placed inside of body. - * - * - * ## Using $animate in your directive code - * - * So far we've explored how to feed in animations into an Angular application, but how do we trigger animations within our own directives in our application? - * By injecting the `$animate` service into our directive code, we can trigger structural and class-based hooks which can then be consumed by animations. Let's - * imagine we have a greeting box that shows and hides itself when the data changes - * - * ```html - * Hi there - * ``` - * - * ```js - * ngModule.directive('greetingBox', ['$animate', function($animate) { - * return function(scope, element, attrs) { - * attrs.$observe('active', function(value) { - * value ? $animate.addClass(element, 'on') : $animate.removeClass(element, 'on'); - * }); - * }); - * }]); - * ``` - * - * Now the `on` CSS class is added and removed on the greeting box component. Now if we add a CSS class on top of the greeting box element - * in our HTML code then we can trigger a CSS or JS animation to happen. - * - * ```css - * /* normally we would create a CSS class to reference on the element */ - * greeting-box.on { transition:0.5s linear all; background:green; color:white; } - * ``` - * - * The `$animate` service contains a variety of other methods like `enter`, `leave`, `animate` and `setClass`. To learn more about what's - * possible be sure to visit the {@link ng.$animate $animate service API page}. - * - * - * ### Preventing Collisions With Third Party Libraries - * - * Some third-party frameworks place animation duration defaults across many element or className - * selectors in order to make their code small and reuseable. This can lead to issues with ngAnimate, which - * is expecting actual animations on these elements and has to wait for their completion. - * - * You can prevent this unwanted behavior by using a prefix on all your animation classes: - * - * ```css - * /* prefixed with animate- */ - * .animate-fade-add.animate-fade-add-active { - * transition:1s linear all; - * opacity:0; - * } - * ``` - * - * You then configure `$animate` to enforce this prefix: - * - * ```js - * $animateProvider.classNameFilter(/animate-/); - * ``` - * - * This also may provide your application with a speed boost since only specific elements containing CSS class prefix - * will be evaluated for animation when any DOM changes occur in the application. - * - * ## Callbacks and Promises - * - * When `$animate` is called it returns a promise that can be used to capture when the animation has ended. Therefore if we were to trigger - * an animation (within our directive code) then we can continue performing directive and scope related activities after the animation has - * ended by chaining onto the returned promise that animation method returns. - * - * ```js - * // somewhere within the depths of the directive - * $animate.enter(element, parent).then(function() { - * //the animation has completed - * }); - * ``` - * - * (Note that earlier versions of Angular prior to v1.4 required the promise code to be wrapped using `$scope.$apply(...)`. This is not the case - * anymore.) - * - * In addition to the animation promise, we can also make use of animation-related callbacks within our directives and controller code by registering - * an event listener using the `$animate` service. Let's say for example that an animation was triggered on our view - * routing controller to hook into that: - * - * ```js - * ngModule.controller('HomePageController', ['$animate', function($animate) { - * $animate.on('enter', ngViewElement, function(element) { - * // the animation for this route has completed - * }]); - * }]) - * ``` - * - * (Note that you will need to trigger a digest within the callback to get angular to notice any scope-related changes.) - */ - -/** - * @ngdoc service - * @name $animate - * @kind object - * - * @description - * The ngAnimate `$animate` service documentation is the same for the core `$animate` service. - * - * Click here {@link ng.$animate to learn more about animations with `$animate`}. - */ -angular.module('ngAnimate', []) - .directive('ngAnimateSwap', ngAnimateSwapDirective) - - .directive('ngAnimateChildren', $$AnimateChildrenDirective) - .factory('$$rAFScheduler', $$rAFSchedulerFactory) - - .provider('$$animateQueue', $$AnimateQueueProvider) - .provider('$$animation', $$AnimationProvider) - - .provider('$animateCss', $AnimateCssProvider) - .provider('$$animateCssDriver', $$AnimateCssDriverProvider) - - .provider('$$animateJs', $$AnimateJsProvider) - .provider('$$animateJsDriver', $$AnimateJsDriverProvider); - - -})(window, window.angular); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-animate.min.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-animate.min.js deleted file mode 100644 index 8e8e41df..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-animate.min.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - AngularJS v1.5.0 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(D,r,Va){'use strict';function ya(a,b,c){if(!a)throw Ka("areq",b||"?",c||"required");return a}function za(a,b){if(!a&&!b)return"";if(!a)return b;if(!b)return a;ba(a)&&(a=a.join(" "));ba(b)&&(b=b.join(" "));return a+" "+b}function La(a){var b={};a&&(a.to||a.from)&&(b.to=a.to,b.from=a.from);return b}function X(a,b,c){var d="";a=ba(a)?a:a&&R(a)&&a.length?a.split(/\s+/):[];s(a,function(a,g){a&&0=a&&(a=e,e=0,b.push(t),t=[]);t.push(g.fn);g.children.forEach(function(a){e++; -c.push(a)});a--}t.length&&b.push(t);return b}(c)}var M=[],r=U(a);return function(u,A,v){function z(a){a=a.hasAttribute("ng-animate-ref")?[a]:a.querySelectorAll("[ng-animate-ref]");var b=[];s(a,function(a){var c=a.getAttribute("ng-animate-ref");c&&c.length&&b.push(a)});return b}function K(a){var b=[],c={};s(a,function(a,f){var d=G(a.element),h=0<=["enter","move"].indexOf(a.event),d=a.structural?z(d):[];if(d.length){var e=h?"to":"from";s(d,function(a){var b=a.getAttribute("ng-animate-ref");c[b]=c[b]|| -{};c[b][e]={animationID:f,element:I(a)}})}else b.push(a)});var d={},h={};s(c,function(c,e){var l=c.from,t=c.to;if(l&&t){var g=a[l.animationID],E=a[t.animationID],k=l.animationID.toString();if(!h[k]){var z=h[k]={structural:!0,beforeStart:function(){g.beforeStart();E.beforeStart()},close:function(){g.close();E.close()},classes:J(g.classes,E.classes),from:g,to:E,anchors:[]};z.classes.length?b.push(z):(b.push(g),b.push(E))}h[k].anchors.push({out:l.element,"in":t.element})}else l=l?l.animationID:t.animationID, -t=l.toString(),d[t]||(d[t]=!0,b.push(a[l]))});return b}function J(a,b){a=a.split(" ");b=b.split(" ");for(var c=[],d=0;d=P&&b>=O&&(wa=!0,q())}function L(){function b(){if(!A){t(!1);s(m, -function(a){l.style[a[0]]=a[1]});z(a,f);e.addClass(a,ca);if(p.recalculateTimingStyles){ja=l.className+" "+da;ga=r(l,ja);F=v(l,ja,ga);$=F.maxDelay;n=Math.max($,0);O=F.maxDuration;if(0===O){q();return}p.hasTransitions=0B.expectedEndTime)?H.cancel(B.timer):g.push(q)}L&&(k=H(c,k,!1),g[0]={timer:k,expectedEndTime:d},g.push(q),a.data("$$animateCss",g));if(ea.length)a.on(ea.join(" "),E);f.to&&(f.cleanupStyles&&Ga(x,l,Object.keys(f.to)),Ba(a, -f))}}function c(){var b=a.data("$$animateCss");if(b){for(var d=1;dARIA](http://www.w3.org/TR/wai-aria/) - * attributes that convey state or semantic information about the application for users - * of assistive technologies, such as screen readers. - * - *
        - * - * ## Usage - * - * For ngAria to do its magic, simply include the module `ngAria` as a dependency. The following - * directives are supported: - * `ngModel`, `ngChecked`, `ngRequired`, `ngValue`, `ngDisabled`, `ngShow`, `ngHide`, `ngClick`, - * `ngDblClick`, and `ngMessages`. - * - * Below is a more detailed breakdown of the attributes handled by ngAria: - * - * | Directive | Supported Attributes | - * |---------------------------------------------|----------------------------------------------------------------------------------------| - * | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles | - * | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled | - * | {@link ng.directive:ngRequired ngRequired} | aria-required | - * | {@link ng.directive:ngChecked ngChecked} | aria-checked | - * | {@link ng.directive:ngValue ngValue} | aria-checked | - * | {@link ng.directive:ngShow ngShow} | aria-hidden | - * | {@link ng.directive:ngHide ngHide} | aria-hidden | - * | {@link ng.directive:ngDblclick ngDblclick} | tabindex | - * | {@link module:ngMessages ngMessages} | aria-live | - * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role | - * - * Find out more information about each directive by reading the - * {@link guide/accessibility ngAria Developer Guide}. - * - * ##Example - * Using ngDisabled with ngAria: - * ```html - * - * ``` - * Becomes: - * ```html - * - * ``` - * - * ##Disabling Attributes - * It's possible to disable individual attributes added by ngAria with the - * {@link ngAria.$ariaProvider#config config} method. For more details, see the - * {@link guide/accessibility Developer Guide}. - */ - /* global -ngAriaModule */ -var ngAriaModule = angular.module('ngAria', ['ng']). - provider('$aria', $AriaProvider); - -/** -* Internal Utilities -*/ -var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA', 'SELECT', 'DETAILS', 'SUMMARY']; - -var isNodeOneOf = function(elem, nodeTypeArray) { - if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) { - return true; - } -}; -/** - * @ngdoc provider - * @name $ariaProvider - * - * @description - * - * Used for configuring the ARIA attributes injected and managed by ngAria. - * - * ```js - * angular.module('myApp', ['ngAria'], function config($ariaProvider) { - * $ariaProvider.config({ - * ariaValue: true, - * tabindex: false - * }); - * }); - *``` - * - * ## Dependencies - * Requires the {@link ngAria} module to be installed. - * - */ -function $AriaProvider() { - var config = { - ariaHidden: true, - ariaChecked: true, - ariaDisabled: true, - ariaRequired: true, - ariaInvalid: true, - ariaValue: true, - tabindex: true, - bindKeypress: true, - bindRoleForClick: true - }; - - /** - * @ngdoc method - * @name $ariaProvider#config - * - * @param {object} config object to enable/disable specific ARIA attributes - * - * - **ariaHidden** – `{boolean}` – Enables/disables aria-hidden tags - * - **ariaChecked** – `{boolean}` – Enables/disables aria-checked tags - * - **ariaDisabled** – `{boolean}` – Enables/disables aria-disabled tags - * - **ariaRequired** – `{boolean}` – Enables/disables aria-required tags - * - **ariaInvalid** – `{boolean}` – Enables/disables aria-invalid tags - * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags - * - **tabindex** – `{boolean}` – Enables/disables tabindex tags - * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on `div` and - * `li` elements with ng-click - * - **bindRoleForClick** – `{boolean}` – Adds role=button to non-interactive elements like `div` - * using ng-click, making them more accessible to users of assistive technologies - * - * @description - * Enables/disables various ARIA attributes - */ - this.config = function(newConfig) { - config = angular.extend(config, newConfig); - }; - - function watchExpr(attrName, ariaAttr, nodeBlackList, negate) { - return function(scope, elem, attr) { - var ariaCamelName = attr.$normalize(ariaAttr); - if (config[ariaCamelName] && !isNodeOneOf(elem, nodeBlackList) && !attr[ariaCamelName]) { - scope.$watch(attr[attrName], function(boolVal) { - // ensure boolean value - boolVal = negate ? !boolVal : !!boolVal; - elem.attr(ariaAttr, boolVal); - }); - } - }; - } - /** - * @ngdoc service - * @name $aria - * - * @description - * @priority 200 - * - * The $aria service contains helper methods for applying common - * [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives. - * - * ngAria injects common accessibility attributes that tell assistive technologies when HTML - * elements are enabled, selected, hidden, and more. To see how this is performed with ngAria, - * let's review a code snippet from ngAria itself: - * - *```js - * ngAriaModule.directive('ngDisabled', ['$aria', function($aria) { - * return $aria.$$watchExpr('ngDisabled', 'aria-disabled', nodeBlackList, false); - * }]) - *``` - * Shown above, the ngAria module creates a directive with the same signature as the - * traditional `ng-disabled` directive. But this ngAria version is dedicated to - * solely managing accessibility attributes on custom elements. The internal `$aria` service is - * used to watch the boolean attribute `ngDisabled`. If it has not been explicitly set by the - * developer, `aria-disabled` is injected as an attribute with its value synchronized to the - * value in `ngDisabled`. - * - * Because ngAria hooks into the `ng-disabled` directive, developers do not have to do - * anything to enable this feature. The `aria-disabled` attribute is automatically managed - * simply as a silent side-effect of using `ng-disabled` with the ngAria module. - * - * The full list of directives that interface with ngAria: - * * **ngModel** - * * **ngChecked** - * * **ngRequired** - * * **ngDisabled** - * * **ngValue** - * * **ngShow** - * * **ngHide** - * * **ngClick** - * * **ngDblclick** - * * **ngMessages** - * - * Read the {@link guide/accessibility ngAria Developer Guide} for a thorough explanation of each - * directive. - * - * - * ## Dependencies - * Requires the {@link ngAria} module to be installed. - */ - this.$get = function() { - return { - config: function(key) { - return config[key]; - }, - $$watchExpr: watchExpr - }; - }; -} - - -ngAriaModule.directive('ngShow', ['$aria', function($aria) { - return $aria.$$watchExpr('ngShow', 'aria-hidden', [], true); -}]) -.directive('ngHide', ['$aria', function($aria) { - return $aria.$$watchExpr('ngHide', 'aria-hidden', [], false); -}]) -.directive('ngValue', ['$aria', function($aria) { - return $aria.$$watchExpr('ngValue', 'aria-checked', nodeBlackList, false); -}]) -.directive('ngChecked', ['$aria', function($aria) { - return $aria.$$watchExpr('ngChecked', 'aria-checked', nodeBlackList, false); -}]) -.directive('ngRequired', ['$aria', function($aria) { - return $aria.$$watchExpr('ngRequired', 'aria-required', nodeBlackList, false); -}]) -.directive('ngModel', ['$aria', function($aria) { - - function shouldAttachAttr(attr, normalizedAttr, elem, allowBlacklistEls) { - return $aria.config(normalizedAttr) && !elem.attr(attr) && (allowBlacklistEls || !isNodeOneOf(elem, nodeBlackList)); - } - - function shouldAttachRole(role, elem) { - // if element does not have role attribute - // AND element type is equal to role (if custom element has a type equaling shape) <-- remove? - // AND element is not INPUT - return !elem.attr('role') && (elem.attr('type') === role) && (elem[0].nodeName !== 'INPUT'); - } - - function getShape(attr, elem) { - var type = attr.type, - role = attr.role; - - return ((type || role) === 'checkbox' || role === 'menuitemcheckbox') ? 'checkbox' : - ((type || role) === 'radio' || role === 'menuitemradio') ? 'radio' : - (type === 'range' || role === 'progressbar' || role === 'slider') ? 'range' : ''; - } - - return { - restrict: 'A', - require: 'ngModel', - priority: 200, //Make sure watches are fired after any other directives that affect the ngModel value - compile: function(elem, attr) { - var shape = getShape(attr, elem); - - return { - pre: function(scope, elem, attr, ngModel) { - if (shape === 'checkbox') { - //Use the input[checkbox] $isEmpty implementation for elements with checkbox roles - ngModel.$isEmpty = function(value) { - return value === false; - }; - } - }, - post: function(scope, elem, attr, ngModel) { - var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem, false); - - function ngAriaWatchModelValue() { - return ngModel.$modelValue; - } - - function getRadioReaction(newVal) { - var boolVal = (attr.value == ngModel.$viewValue); - elem.attr('aria-checked', boolVal); - } - - function getCheckboxReaction() { - elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue)); - } - - switch (shape) { - case 'radio': - case 'checkbox': - if (shouldAttachRole(shape, elem)) { - elem.attr('role', shape); - } - if (shouldAttachAttr('aria-checked', 'ariaChecked', elem, false)) { - scope.$watch(ngAriaWatchModelValue, shape === 'radio' ? - getRadioReaction : getCheckboxReaction); - } - if (needsTabIndex) { - elem.attr('tabindex', 0); - } - break; - case 'range': - if (shouldAttachRole(shape, elem)) { - elem.attr('role', 'slider'); - } - if ($aria.config('ariaValue')) { - var needsAriaValuemin = !elem.attr('aria-valuemin') && - (attr.hasOwnProperty('min') || attr.hasOwnProperty('ngMin')); - var needsAriaValuemax = !elem.attr('aria-valuemax') && - (attr.hasOwnProperty('max') || attr.hasOwnProperty('ngMax')); - var needsAriaValuenow = !elem.attr('aria-valuenow'); - - if (needsAriaValuemin) { - attr.$observe('min', function ngAriaValueMinReaction(newVal) { - elem.attr('aria-valuemin', newVal); - }); - } - if (needsAriaValuemax) { - attr.$observe('max', function ngAriaValueMinReaction(newVal) { - elem.attr('aria-valuemax', newVal); - }); - } - if (needsAriaValuenow) { - scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) { - elem.attr('aria-valuenow', newVal); - }); - } - } - if (needsTabIndex) { - elem.attr('tabindex', 0); - } - break; - } - - if (!attr.hasOwnProperty('ngRequired') && ngModel.$validators.required - && shouldAttachAttr('aria-required', 'ariaRequired', elem, false)) { - // ngModel.$error.required is undefined on custom controls - attr.$observe('required', function() { - elem.attr('aria-required', !!attr['required']); - }); - } - - if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem, true)) { - scope.$watch(function ngAriaInvalidWatch() { - return ngModel.$invalid; - }, function ngAriaInvalidReaction(newVal) { - elem.attr('aria-invalid', !!newVal); - }); - } - } - }; - } - }; -}]) -.directive('ngDisabled', ['$aria', function($aria) { - return $aria.$$watchExpr('ngDisabled', 'aria-disabled', nodeBlackList, false); -}]) -.directive('ngMessages', function() { - return { - restrict: 'A', - require: '?ngMessages', - link: function(scope, elem, attr, ngMessages) { - if (!elem.attr('aria-live')) { - elem.attr('aria-live', 'assertive'); - } - } - }; -}) -.directive('ngClick',['$aria', '$parse', function($aria, $parse) { - return { - restrict: 'A', - compile: function(elem, attr) { - var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true); - return function(scope, elem, attr) { - - if (!isNodeOneOf(elem, nodeBlackList)) { - - if ($aria.config('bindRoleForClick') && !elem.attr('role')) { - elem.attr('role', 'button'); - } - - if ($aria.config('tabindex') && !elem.attr('tabindex')) { - elem.attr('tabindex', 0); - } - - if ($aria.config('bindKeypress') && !attr.ngKeypress) { - elem.on('keypress', function(event) { - var keyCode = event.which || event.keyCode; - if (keyCode === 32 || keyCode === 13) { - scope.$apply(callback); - } - - function callback() { - fn(scope, { $event: event }); - } - }); - } - } - }; - } - }; -}]) -.directive('ngDblclick', ['$aria', function($aria) { - return function(scope, elem, attr) { - if ($aria.config('tabindex') && !elem.attr('tabindex') && !isNodeOneOf(elem, nodeBlackList)) { - elem.attr('tabindex', 0); - } - }; -}]); - - -})(window, window.angular); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-aria.min.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-aria.min.js deleted file mode 100644 index cf0fd742..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-aria.min.js +++ /dev/null @@ -1,14 +0,0 @@ -/* - AngularJS v1.5.0 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(s,q,t){'use strict';var f="BUTTON A INPUT TEXTAREA SELECT DETAILS SUMMARY".split(" "),l=function(a,c){if(-1!==c.indexOf(a[0].nodeName))return!0};q.module("ngAria",["ng"]).provider("$aria",function(){function a(a,h,p,n){return function(d,e,b){var g=b.$normalize(h);!c[g]||l(e,p)||b[g]||d.$watch(b[a],function(b){b=n?!b:!!b;e.attr(h,b)})}}var c={ariaHidden:!0,ariaChecked:!0,ariaDisabled:!0,ariaRequired:!0,ariaInvalid:!0,ariaValue:!0,tabindex:!0,bindKeypress:!0,bindRoleForClick:!0};this.config= -function(a){c=q.extend(c,a)};this.$get=function(){return{config:function(a){return c[a]},$$watchExpr:a}}}).directive("ngShow",["$aria",function(a){return a.$$watchExpr("ngShow","aria-hidden",[],!0)}]).directive("ngHide",["$aria",function(a){return a.$$watchExpr("ngHide","aria-hidden",[],!1)}]).directive("ngValue",["$aria",function(a){return a.$$watchExpr("ngValue","aria-checked",f,!1)}]).directive("ngChecked",["$aria",function(a){return a.$$watchExpr("ngChecked","aria-checked",f,!1)}]).directive("ngRequired", -["$aria",function(a){return a.$$watchExpr("ngRequired","aria-required",f,!1)}]).directive("ngModel",["$aria",function(a){function c(c,n,d,e){return a.config(n)&&!d.attr(c)&&(e||!l(d,f))}function m(a,c){return!c.attr("role")&&c.attr("type")===a&&"INPUT"!==c[0].nodeName}function h(a,c){var d=a.type,e=a.role;return"checkbox"===(d||e)||"menuitemcheckbox"===e?"checkbox":"radio"===(d||e)||"menuitemradio"===e?"radio":"range"===d||"progressbar"===e||"slider"===e?"range":""}return{restrict:"A",require:"ngModel", -priority:200,compile:function(f,n){var d=h(n,f);return{pre:function(a,b,c,k){"checkbox"===d&&(k.$isEmpty=function(a){return!1===a})},post:function(e,b,g,k){function f(){return k.$modelValue}function h(a){b.attr("aria-checked",g.value==k.$viewValue)}function n(){b.attr("aria-checked",!k.$isEmpty(k.$viewValue))}var l=c("tabindex","tabindex",b,!1);switch(d){case "radio":case "checkbox":m(d,b)&&b.attr("role",d);c("aria-checked","ariaChecked",b,!1)&&e.$watch(f,"radio"===d?h:n);l&&b.attr("tabindex",0); -break;case "range":m(d,b)&&b.attr("role","slider");if(a.config("ariaValue")){var p=!b.attr("aria-valuemin")&&(g.hasOwnProperty("min")||g.hasOwnProperty("ngMin")),q=!b.attr("aria-valuemax")&&(g.hasOwnProperty("max")||g.hasOwnProperty("ngMax")),r=!b.attr("aria-valuenow");p&&g.$observe("min",function(a){b.attr("aria-valuemin",a)});q&&g.$observe("max",function(a){b.attr("aria-valuemax",a)});r&&e.$watch(f,function(a){b.attr("aria-valuenow",a)})}l&&b.attr("tabindex",0)}!g.hasOwnProperty("ngRequired")&& -k.$validators.required&&c("aria-required","ariaRequired",b,!1)&&g.$observe("required",function(){b.attr("aria-required",!!g.required)});c("aria-invalid","ariaInvalid",b,!0)&&e.$watch(function(){return k.$invalid},function(a){b.attr("aria-invalid",!!a)})}}}}}]).directive("ngDisabled",["$aria",function(a){return a.$$watchExpr("ngDisabled","aria-disabled",f,!1)}]).directive("ngMessages",function(){return{restrict:"A",require:"?ngMessages",link:function(a,c,f,h){c.attr("aria-live")||c.attr("aria-live", -"assertive")}}}).directive("ngClick",["$aria","$parse",function(a,c){return{restrict:"A",compile:function(m,h){var p=c(h.ngClick,null,!0);return function(c,d,e){if(!l(d,f)&&(a.config("bindRoleForClick")&&!d.attr("role")&&d.attr("role","button"),a.config("tabindex")&&!d.attr("tabindex")&&d.attr("tabindex",0),a.config("bindKeypress")&&!e.ngKeypress))d.on("keypress",function(a){function d(){p(c,{$event:a})}var e=a.which||a.keyCode;32!==e&&13!==e||c.$apply(d)})}}}}]).directive("ngDblclick",["$aria",function(a){return function(c, -m,h){!a.config("tabindex")||m.attr("tabindex")||l(m,f)||m.attr("tabindex",0)}}])})(window,window.angular); -//# sourceMappingURL=angular-aria.min.js.map diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-aria.min.js.map b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-aria.min.js.map deleted file mode 100644 index b1db15b5..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-aria.min.js.map +++ /dev/null @@ -1,8 +0,0 @@ -{ -"version":3, -"file":"angular-aria.min.js", -"lineCount":13, -"mappings":"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", -"sources":["angular-aria.js"], -"names":["window","angular","undefined","nodeBlackList","isNodeOneOf","elem","nodeTypeArray","indexOf","nodeName","module","provider","ngAriaModule","$AriaProvider","watchExpr","attrName","ariaAttr","negate","scope","attr","ariaCamelName","$normalize","config","$watch","boolVal","ariaHidden","ariaChecked","ariaDisabled","ariaRequired","ariaInvalid","ariaValue","tabindex","bindKeypress","bindRoleForClick","this.config","newConfig","extend","$get","this.$get","key","$$watchExpr","directive","$aria","shouldAttachAttr","normalizedAttr","allowBlacklistEls","shouldAttachRole","role","getShape","type","restrict","require","priority","compile","shape","pre","ngModel","$isEmpty","ngModel.$isEmpty","value","post","ngAriaWatchModelValue","$modelValue","getRadioReaction","newVal","$viewValue","getCheckboxReaction","needsTabIndex","needsAriaValuemin","hasOwnProperty","needsAriaValuemax","needsAriaValuenow","$observe","ngAriaValueMinReaction","ngAriaValueNowReaction","$validators","required","ngAriaInvalidWatch","$invalid","ngAriaInvalidReaction","link","ngMessages","$parse","fn","ngClick","ngKeypress","on","event","callback","$event","keyCode","which","$apply"] -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.js deleted file mode 100644 index 2157ef03..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.js +++ /dev/null @@ -1,322 +0,0 @@ -/** - * @license AngularJS v1.5.0 - * (c) 2010-2016 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular, undefined) {'use strict'; - -/** - * @ngdoc module - * @name ngCookies - * @description - * - * # ngCookies - * - * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies. - * - * - *
        - * - * See {@link ngCookies.$cookies `$cookies`} for usage. - */ - - -angular.module('ngCookies', ['ng']). - /** - * @ngdoc provider - * @name $cookiesProvider - * @description - * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service. - * */ - provider('$cookies', [function $CookiesProvider() { - /** - * @ngdoc property - * @name $cookiesProvider#defaults - * @description - * - * Object containing default options to pass when setting cookies. - * - * The object may have following properties: - * - * - **path** - `{string}` - The cookie will be available only for this path and its - * sub-paths. By default, this is the URL that appears in your `` tag. - * - **domain** - `{string}` - The cookie will be available only for this domain and - * its sub-domains. For security reasons the user agent will not accept the cookie - * if the current domain is not a sub-domain of this domain or equal to it. - * - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT" - * or a Date object indicating the exact date/time this cookie will expire. - * - **secure** - `{boolean}` - If `true`, then the cookie will only be available through a - * secured connection. - * - * Note: By default, the address that appears in your `` tag will be used as the path. - * This is important so that cookies will be visible for all routes when html5mode is enabled. - * - **/ - var defaults = this.defaults = {}; - - function calcOptions(options) { - return options ? angular.extend({}, defaults, options) : defaults; - } - - /** - * @ngdoc service - * @name $cookies - * - * @description - * Provides read/write access to browser's cookies. - * - *
        - * Up until Angular 1.3, `$cookies` exposed properties that represented the - * current browser cookie values. In version 1.4, this behavior has changed, and - * `$cookies` now provides a standard api of getters, setters etc. - *
        - * - * Requires the {@link ngCookies `ngCookies`} module to be installed. - * - * @example - * - * ```js - * angular.module('cookiesExample', ['ngCookies']) - * .controller('ExampleController', ['$cookies', function($cookies) { - * // Retrieving a cookie - * var favoriteCookie = $cookies.get('myFavorite'); - * // Setting a cookie - * $cookies.put('myFavorite', 'oatmeal'); - * }]); - * ``` - */ - this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) { - return { - /** - * @ngdoc method - * @name $cookies#get - * - * @description - * Returns the value of given cookie key - * - * @param {string} key Id to use for lookup. - * @returns {string} Raw cookie value. - */ - get: function(key) { - return $$cookieReader()[key]; - }, - - /** - * @ngdoc method - * @name $cookies#getObject - * - * @description - * Returns the deserialized value of given cookie key - * - * @param {string} key Id to use for lookup. - * @returns {Object} Deserialized cookie value. - */ - getObject: function(key) { - var value = this.get(key); - return value ? angular.fromJson(value) : value; - }, - - /** - * @ngdoc method - * @name $cookies#getAll - * - * @description - * Returns a key value object with all the cookies - * - * @returns {Object} All cookies - */ - getAll: function() { - return $$cookieReader(); - }, - - /** - * @ngdoc method - * @name $cookies#put - * - * @description - * Sets a value for given cookie key - * - * @param {string} key Id for the `value`. - * @param {string} value Raw value to be stored. - * @param {Object=} options Options object. - * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults} - */ - put: function(key, value, options) { - $$cookieWriter(key, value, calcOptions(options)); - }, - - /** - * @ngdoc method - * @name $cookies#putObject - * - * @description - * Serializes and sets a value for given cookie key - * - * @param {string} key Id for the `value`. - * @param {Object} value Value to be stored. - * @param {Object=} options Options object. - * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults} - */ - putObject: function(key, value, options) { - this.put(key, angular.toJson(value), options); - }, - - /** - * @ngdoc method - * @name $cookies#remove - * - * @description - * Remove given cookie - * - * @param {string} key Id of the key-value pair to delete. - * @param {Object=} options Options object. - * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults} - */ - remove: function(key, options) { - $$cookieWriter(key, undefined, calcOptions(options)); - } - }; - }]; - }]); - -angular.module('ngCookies'). -/** - * @ngdoc service - * @name $cookieStore - * @deprecated - * @requires $cookies - * - * @description - * Provides a key-value (string-object) storage, that is backed by session cookies. - * Objects put or retrieved from this storage are automatically serialized or - * deserialized by angular's toJson/fromJson. - * - * Requires the {@link ngCookies `ngCookies`} module to be installed. - * - *
        - * **Note:** The $cookieStore service is **deprecated**. - * Please use the {@link ngCookies.$cookies `$cookies`} service instead. - *
        - * - * @example - * - * ```js - * angular.module('cookieStoreExample', ['ngCookies']) - * .controller('ExampleController', ['$cookieStore', function($cookieStore) { - * // Put cookie - * $cookieStore.put('myFavorite','oatmeal'); - * // Get cookie - * var favoriteCookie = $cookieStore.get('myFavorite'); - * // Removing a cookie - * $cookieStore.remove('myFavorite'); - * }]); - * ``` - */ - factory('$cookieStore', ['$cookies', function($cookies) { - - return { - /** - * @ngdoc method - * @name $cookieStore#get - * - * @description - * Returns the value of given cookie key - * - * @param {string} key Id to use for lookup. - * @returns {Object} Deserialized cookie value, undefined if the cookie does not exist. - */ - get: function(key) { - return $cookies.getObject(key); - }, - - /** - * @ngdoc method - * @name $cookieStore#put - * - * @description - * Sets a value for given cookie key - * - * @param {string} key Id for the `value`. - * @param {Object} value Value to be stored. - */ - put: function(key, value) { - $cookies.putObject(key, value); - }, - - /** - * @ngdoc method - * @name $cookieStore#remove - * - * @description - * Remove given cookie - * - * @param {string} key Id of the key-value pair to delete. - */ - remove: function(key) { - $cookies.remove(key); - } - }; - - }]); - -/** - * @name $$cookieWriter - * @requires $document - * - * @description - * This is a private service for writing cookies - * - * @param {string} name Cookie name - * @param {string=} value Cookie value (if undefined, cookie will be deleted) - * @param {Object=} options Object with options that need to be stored for the cookie. - */ -function $$CookieWriter($document, $log, $browser) { - var cookiePath = $browser.baseHref(); - var rawDocument = $document[0]; - - function buildCookieString(name, value, options) { - var path, expires; - options = options || {}; - expires = options.expires; - path = angular.isDefined(options.path) ? options.path : cookiePath; - if (angular.isUndefined(value)) { - expires = 'Thu, 01 Jan 1970 00:00:00 GMT'; - value = ''; - } - if (angular.isString(expires)) { - expires = new Date(expires); - } - - var str = encodeURIComponent(name) + '=' + encodeURIComponent(value); - str += path ? ';path=' + path : ''; - str += options.domain ? ';domain=' + options.domain : ''; - str += expires ? ';expires=' + expires.toUTCString() : ''; - str += options.secure ? ';secure' : ''; - - // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum: - // - 300 cookies - // - 20 cookies per unique domain - // - 4096 bytes per cookie - var cookieLength = str.length + 1; - if (cookieLength > 4096) { - $log.warn("Cookie '" + name + - "' possibly not set or overflowed because it was too large (" + - cookieLength + " > 4096 bytes)!"); - } - - return str; - } - - return function(name, value, options) { - rawDocument.cookie = buildCookieString(name, value, options); - }; -} - -$$CookieWriter.$inject = ['$document', '$log', '$browser']; - -angular.module('ngCookies').provider('$$cookieWriter', function $$CookieWriterProvider() { - this.$get = $$CookieWriter; -}); - - -})(window, window.angular); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.min.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.min.js deleted file mode 100644 index d0f126a9..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - AngularJS v1.5.0 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(p,c,n){'use strict';function l(b,a,g){var d=g.baseHref(),k=b[0];return function(b,e,f){var g,h;f=f||{};h=f.expires;g=c.isDefined(f.path)?f.path:d;c.isUndefined(e)&&(h="Thu, 01 Jan 1970 00:00:00 GMT",e="");c.isString(h)&&(h=new Date(h));e=encodeURIComponent(b)+"="+encodeURIComponent(e);e=e+(g?";path="+g:"")+(f.domain?";domain="+f.domain:"");e+=h?";expires="+h.toUTCString():"";e+=f.secure?";secure":"";f=e.length+1;4096 4096 bytes)!");k.cookie=e}}c.module("ngCookies",["ng"]).provider("$cookies",[function(){var b=this.defaults={};this.$get=["$$cookieReader","$$cookieWriter",function(a,g){return{get:function(d){return a()[d]},getObject:function(d){return(d=this.get(d))?c.fromJson(d):d},getAll:function(){return a()},put:function(d,a,m){g(d,a,m?c.extend({},b,m):b)},putObject:function(d,b,a){this.put(d,c.toJson(b),a)},remove:function(a,k){g(a,n,k?c.extend({},b,k):b)}}}]}]);c.module("ngCookies").factory("$cookieStore", -["$cookies",function(b){return{get:function(a){return b.getObject(a)},put:function(a,c){b.putObject(a,c)},remove:function(a){b.remove(a)}}}]);l.$inject=["$document","$log","$browser"];c.module("ngCookies").provider("$$cookieWriter",function(){this.$get=l})})(window,window.angular); -//# sourceMappingURL=angular-cookies.min.js.map diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.min.js.map b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.min.js.map deleted file mode 100644 index 555b5103..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-cookies.min.js.map +++ /dev/null @@ -1,8 +0,0 @@ -{ -"version":3, -"file":"angular-cookies.min.js", -"lineCount":8, -"mappings":"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", -"sources":["angular-cookies.js"], -"names":["window","angular","undefined","$$CookieWriter","$document","$log","$browser","cookiePath","baseHref","rawDocument","name","value","options","path","expires","isDefined","isUndefined","isString","Date","str","encodeURIComponent","domain","toUTCString","secure","cookieLength","length","warn","cookie","module","provider","$CookiesProvider","defaults","$get","$$cookieReader","$$cookieWriter","get","key","getObject","fromJson","getAll","put","extend","putObject","toJson","remove","factory","$cookies","$inject","$$CookieWriterProvider"] -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-csp.css b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-csp.css deleted file mode 100644 index 23134fdf..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-csp.css +++ /dev/null @@ -1,20 +0,0 @@ - -@charset "UTF-8"; - -[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], -.ng-cloak, .x-ng-cloak, -.ng-hide:not(.ng-hide-animate) { - display: none !important; -} - -ng\:form { - display: block; -} - -.ng-animate-shim { - visibility:hidden; -} - -.ng-anchor { - position:absolute; -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-loader.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-loader.js deleted file mode 100644 index 77948fd5..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-loader.js +++ /dev/null @@ -1,484 +0,0 @@ -/** - * @license AngularJS v1.5.0 - * (c) 2010-2016 Google, Inc. http://angularjs.org - * License: MIT - */ - -(function() {'use strict'; - function isFunction(value) {return typeof value === 'function';}; - -/* global: toDebugString: true */ - -function serializeObject(obj) { - var seen = []; - - return JSON.stringify(obj, function(key, val) { - val = toJsonReplacer(key, val); - if (isObject(val)) { - - if (seen.indexOf(val) >= 0) return '...'; - - seen.push(val); - } - return val; - }); -} - -function toDebugString(obj) { - if (typeof obj === 'function') { - return obj.toString().replace(/ \{[\s\S]*$/, ''); - } else if (isUndefined(obj)) { - return 'undefined'; - } else if (typeof obj !== 'string') { - return serializeObject(obj); - } - return obj; -} - -/** - * @description - * - * This object provides a utility for producing rich Error messages within - * Angular. It can be called as follows: - * - * var exampleMinErr = minErr('example'); - * throw exampleMinErr('one', 'This {0} is {1}', foo, bar); - * - * The above creates an instance of minErr in the example namespace. The - * resulting error will have a namespaced error code of example.one. The - * resulting error will replace {0} with the value of foo, and {1} with the - * value of bar. The object is not restricted in the number of arguments it can - * take. - * - * If fewer arguments are specified than necessary for interpolation, the extra - * interpolation markers will be preserved in the final string. - * - * Since data will be parsed statically during a build step, some restrictions - * are applied with respect to how minErr instances are created and called. - * Instances should have names of the form namespaceMinErr for a minErr created - * using minErr('namespace') . Error codes, namespaces and template strings - * should all be static strings, not variables or general expressions. - * - * @param {string} module The namespace to use for the new minErr instance. - * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning - * error from returned function, for cases when a particular type of error is useful. - * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance - */ - -function minErr(module, ErrorConstructor) { - ErrorConstructor = ErrorConstructor || Error; - return function() { - var SKIP_INDEXES = 2; - - var templateArgs = arguments, - code = templateArgs[0], - message = '[' + (module ? module + ':' : '') + code + '] ', - template = templateArgs[1], - paramPrefix, i; - - message += template.replace(/\{\d+\}/g, function(match) { - var index = +match.slice(1, -1), - shiftedIndex = index + SKIP_INDEXES; - - if (shiftedIndex < templateArgs.length) { - return toDebugString(templateArgs[shiftedIndex]); - } - - return match; - }); - - message += '\nhttp://errors.angularjs.org/1.5.0/' + - (module ? module + '/' : '') + code; - - for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') { - message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' + - encodeURIComponent(toDebugString(templateArgs[i])); - } - - return new ErrorConstructor(message); - }; -} - -/** - * @ngdoc type - * @name angular.Module - * @module ng - * @description - * - * Interface for configuring angular {@link angular.module modules}. - */ - -function setupModuleLoader(window) { - - var $injectorMinErr = minErr('$injector'); - var ngMinErr = minErr('ng'); - - function ensure(obj, name, factory) { - return obj[name] || (obj[name] = factory()); - } - - var angular = ensure(window, 'angular', Object); - - // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap - angular.$$minErr = angular.$$minErr || minErr; - - return ensure(angular, 'module', function() { - /** @type {Object.} */ - var modules = {}; - - /** - * @ngdoc function - * @name angular.module - * @module ng - * @description - * - * The `angular.module` is a global place for creating, registering and retrieving Angular - * modules. - * All modules (angular core or 3rd party) that should be available to an application must be - * registered using this mechanism. - * - * Passing one argument retrieves an existing {@link angular.Module}, - * whereas passing more than one argument creates a new {@link angular.Module} - * - * - * # Module - * - * A module is a collection of services, directives, controllers, filters, and configuration information. - * `angular.module` is used to configure the {@link auto.$injector $injector}. - * - * ```js - * // Create a new module - * var myModule = angular.module('myModule', []); - * - * // register a new service - * myModule.value('appName', 'MyCoolApp'); - * - * // configure existing services inside initialization blocks. - * myModule.config(['$locationProvider', function($locationProvider) { - * // Configure existing providers - * $locationProvider.hashPrefix('!'); - * }]); - * ``` - * - * Then you can create an injector and load your modules like this: - * - * ```js - * var injector = angular.injector(['ng', 'myModule']) - * ``` - * - * However it's more likely that you'll just use - * {@link ng.directive:ngApp ngApp} or - * {@link angular.bootstrap} to simplify this process for you. - * - * @param {!string} name The name of the module to create or retrieve. - * @param {!Array.=} requires If specified then new module is being created. If - * unspecified then the module is being retrieved for further configuration. - * @param {Function=} configFn Optional configuration function for the module. Same as - * {@link angular.Module#config Module#config()}. - * @returns {angular.Module} new module with the {@link angular.Module} api. - */ - return function module(name, requires, configFn) { - var assertNotHasOwnProperty = function(name, context) { - if (name === 'hasOwnProperty') { - throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); - } - }; - - assertNotHasOwnProperty(name, 'module'); - if (requires && modules.hasOwnProperty(name)) { - modules[name] = null; - } - return ensure(modules, name, function() { - if (!requires) { - throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " + - "the module name or forgot to load it. If registering a module ensure that you " + - "specify the dependencies as the second argument.", name); - } - - /** @type {!Array.>} */ - var invokeQueue = []; - - /** @type {!Array.} */ - var configBlocks = []; - - /** @type {!Array.} */ - var runBlocks = []; - - var config = invokeLater('$injector', 'invoke', 'push', configBlocks); - - /** @type {angular.Module} */ - var moduleInstance = { - // Private state - _invokeQueue: invokeQueue, - _configBlocks: configBlocks, - _runBlocks: runBlocks, - - /** - * @ngdoc property - * @name angular.Module#requires - * @module ng - * - * @description - * Holds the list of modules which the injector will load before the current module is - * loaded. - */ - requires: requires, - - /** - * @ngdoc property - * @name angular.Module#name - * @module ng - * - * @description - * Name of the module. - */ - name: name, - - - /** - * @ngdoc method - * @name angular.Module#provider - * @module ng - * @param {string} name service name - * @param {Function} providerType Construction function for creating new instance of the - * service. - * @description - * See {@link auto.$provide#provider $provide.provider()}. - */ - provider: invokeLaterAndSetModuleName('$provide', 'provider'), - - /** - * @ngdoc method - * @name angular.Module#factory - * @module ng - * @param {string} name service name - * @param {Function} providerFunction Function for creating new instance of the service. - * @description - * See {@link auto.$provide#factory $provide.factory()}. - */ - factory: invokeLaterAndSetModuleName('$provide', 'factory'), - - /** - * @ngdoc method - * @name angular.Module#service - * @module ng - * @param {string} name service name - * @param {Function} constructor A constructor function that will be instantiated. - * @description - * See {@link auto.$provide#service $provide.service()}. - */ - service: invokeLaterAndSetModuleName('$provide', 'service'), - - /** - * @ngdoc method - * @name angular.Module#value - * @module ng - * @param {string} name service name - * @param {*} object Service instance object. - * @description - * See {@link auto.$provide#value $provide.value()}. - */ - value: invokeLater('$provide', 'value'), - - /** - * @ngdoc method - * @name angular.Module#constant - * @module ng - * @param {string} name constant name - * @param {*} object Constant value. - * @description - * Because the constants are fixed, they get applied before other provide methods. - * See {@link auto.$provide#constant $provide.constant()}. - */ - constant: invokeLater('$provide', 'constant', 'unshift'), - - /** - * @ngdoc method - * @name angular.Module#decorator - * @module ng - * @param {string} The name of the service to decorate. - * @param {Function} This function will be invoked when the service needs to be - * instantiated and should return the decorated service instance. - * @description - * See {@link auto.$provide#decorator $provide.decorator()}. - */ - decorator: invokeLaterAndSetModuleName('$provide', 'decorator'), - - /** - * @ngdoc method - * @name angular.Module#animation - * @module ng - * @param {string} name animation name - * @param {Function} animationFactory Factory function for creating new instance of an - * animation. - * @description - * - * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. - * - * - * Defines an animation hook that can be later used with - * {@link $animate $animate} service and directives that use this service. - * - * ```js - * module.animation('.animation-name', function($inject1, $inject2) { - * return { - * eventName : function(element, done) { - * //code to run the animation - * //once complete, then run done() - * return function cancellationFunction(element) { - * //code to cancel the animation - * } - * } - * } - * }) - * ``` - * - * See {@link ng.$animateProvider#register $animateProvider.register()} and - * {@link ngAnimate ngAnimate module} for more information. - */ - animation: invokeLaterAndSetModuleName('$animateProvider', 'register'), - - /** - * @ngdoc method - * @name angular.Module#filter - * @module ng - * @param {string} name Filter name - this must be a valid angular expression identifier - * @param {Function} filterFactory Factory function for creating new instance of filter. - * @description - * See {@link ng.$filterProvider#register $filterProvider.register()}. - * - *
        - * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`. - * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace - * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores - * (`myapp_subsection_filterx`). - *
        - */ - filter: invokeLaterAndSetModuleName('$filterProvider', 'register'), - - /** - * @ngdoc method - * @name angular.Module#controller - * @module ng - * @param {string|Object} name Controller name, or an object map of controllers where the - * keys are the names and the values are the constructors. - * @param {Function} constructor Controller constructor function. - * @description - * See {@link ng.$controllerProvider#register $controllerProvider.register()}. - */ - controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'), - - /** - * @ngdoc method - * @name angular.Module#directive - * @module ng - * @param {string|Object} name Directive name, or an object map of directives where the - * keys are the names and the values are the factories. - * @param {Function} directiveFactory Factory function for creating new instance of - * directives. - * @description - * See {@link ng.$compileProvider#directive $compileProvider.directive()}. - */ - directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'), - - /** - * @ngdoc method - * @name angular.Module#component - * @module ng - * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp) - * @param {Object} options Component definition object (a simplified - * {@link ng.$compile#directive-definition-object directive definition object}) - * - * @description - * See {@link ng.$compileProvider#component $compileProvider.component()}. - */ - component: invokeLaterAndSetModuleName('$compileProvider', 'component'), - - /** - * @ngdoc method - * @name angular.Module#config - * @module ng - * @param {Function} configFn Execute this function on module load. Useful for service - * configuration. - * @description - * Use this method to register work which needs to be performed on module loading. - * For more about how to configure services, see - * {@link providers#provider-recipe Provider Recipe}. - */ - config: config, - - /** - * @ngdoc method - * @name angular.Module#run - * @module ng - * @param {Function} initializationFn Execute this function after injector creation. - * Useful for application initialization. - * @description - * Use this method to register work which should be performed when the injector is done - * loading all modules. - */ - run: function(block) { - runBlocks.push(block); - return this; - } - }; - - if (configFn) { - config(configFn); - } - - return moduleInstance; - - /** - * @param {string} provider - * @param {string} method - * @param {String=} insertMethod - * @returns {angular.Module} - */ - function invokeLater(provider, method, insertMethod, queue) { - if (!queue) queue = invokeQueue; - return function() { - queue[insertMethod || 'push']([provider, method, arguments]); - return moduleInstance; - }; - } - - /** - * @param {string} provider - * @param {string} method - * @returns {angular.Module} - */ - function invokeLaterAndSetModuleName(provider, method) { - return function(recipeName, factoryFunction) { - if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name; - invokeQueue.push([provider, method, arguments]); - return moduleInstance; - }; - } - }); - }; - }); - -} - -setupModuleLoader(window); -})(window); - -/** - * Closure compiler type information - * - * @typedef { { - * requires: !Array., - * invokeQueue: !Array.>, - * - * service: function(string, Function):angular.Module, - * factory: function(string, Function):angular.Module, - * value: function(string, *):angular.Module, - * - * filter: function(string, Function):angular.Module, - * - * init: function(Function):angular.Module - * } } - */ -angular.Module; - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-loader.min.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-loader.min.js deleted file mode 100644 index 316ee26e..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-loader.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - AngularJS v1.5.0 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(){'use strict';function d(b){return function(){var a=arguments[0],e;e="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.5.0/"+(b?b+"/":"")+a;for(a=1;a= line.length) { - index -= line.length; - } else { - return { line: i + 1, column: index + 1 }; - } - } -} -var PARSE_CACHE_FOR_TEXT_LITERALS = Object.create(null); - -function parseTextLiteral(text) { - var cachedFn = PARSE_CACHE_FOR_TEXT_LITERALS[text]; - if (cachedFn != null) { - return cachedFn; - } - function parsedFn(context) { return text; } - parsedFn['$$watchDelegate'] = function watchDelegate(scope, listener, objectEquality) { - var unwatch = scope['$watch'](noop, - function textLiteralWatcher() { - if (isFunction(listener)) { listener.call(null, text, text, scope); } - unwatch(); - }, - objectEquality); - return unwatch; - }; - PARSE_CACHE_FOR_TEXT_LITERALS[text] = parsedFn; - parsedFn['exp'] = text; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - parsedFn['expressions'] = []; // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. - return parsedFn; -} - -function subtractOffset(expressionFn, offset) { - if (offset === 0) { - return expressionFn; - } - function minusOffset(value) { - return (value == void 0) ? value : value - offset; - } - function parsedFn(context) { return minusOffset(expressionFn(context)); } - var unwatch; - parsedFn['$$watchDelegate'] = function watchDelegate(scope, listener, objectEquality) { - unwatch = scope['$watch'](expressionFn, - function pluralExpressionWatchListener(newValue, oldValue) { - if (isFunction(listener)) { listener.call(null, minusOffset(newValue), minusOffset(oldValue), scope); } - }, - objectEquality); - return unwatch; - }; - return parsedFn; -} - -// NOTE: ADVANCED_OPTIMIZATIONS mode. -// -// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using -// constructs incompatible with that mode. - -/* global $interpolateMinErr: false */ -/* global isFunction: false */ -/* global noop: false */ - -/** - * @constructor - * @private - */ -function MessageSelectorBase(expressionFn, choices) { - var self = this; - this.expressionFn = expressionFn; - this.choices = choices; - if (choices["other"] === void 0) { - throw $interpolateMinErr('reqother', '“other” is a required option.'); - } - this.parsedFn = function(context) { return self.getResult(context); }; - this.parsedFn['$$watchDelegate'] = function $$watchDelegate(scope, listener, objectEquality) { - return self.watchDelegate(scope, listener, objectEquality); - }; - this.parsedFn['exp'] = expressionFn['exp']; - this.parsedFn['expressions'] = expressionFn['expressions']; -} - -MessageSelectorBase.prototype.getMessageFn = function getMessageFn(value) { - return this.choices[this.categorizeValue(value)]; -}; - -MessageSelectorBase.prototype.getResult = function getResult(context) { - return this.getMessageFn(this.expressionFn(context))(context); -}; - -MessageSelectorBase.prototype.watchDelegate = function watchDelegate(scope, listener, objectEquality) { - var watchers = new MessageSelectorWatchers(this, scope, listener, objectEquality); - return function() { watchers.cancelWatch(); }; -}; - -/** - * @constructor - * @private - */ -function MessageSelectorWatchers(msgSelector, scope, listener, objectEquality) { - var self = this; - this.scope = scope; - this.msgSelector = msgSelector; - this.listener = listener; - this.objectEquality = objectEquality; - this.lastMessage = void 0; - this.messageFnWatcher = noop; - var expressionFnListener = function(newValue, oldValue) { return self.expressionFnListener(newValue, oldValue); }; - this.expressionFnWatcher = scope['$watch'](msgSelector.expressionFn, expressionFnListener, objectEquality); -} - -MessageSelectorWatchers.prototype.expressionFnListener = function expressionFnListener(newValue, oldValue) { - var self = this; - this.messageFnWatcher(); - var messageFnListener = function(newMessage, oldMessage) { return self.messageFnListener(newMessage, oldMessage); }; - var messageFn = this.msgSelector.getMessageFn(newValue); - this.messageFnWatcher = this.scope['$watch'](messageFn, messageFnListener, this.objectEquality); -}; - -MessageSelectorWatchers.prototype.messageFnListener = function messageFnListener(newMessage, oldMessage) { - if (isFunction(this.listener)) { - this.listener.call(null, newMessage, newMessage === oldMessage ? newMessage : this.lastMessage, this.scope); - } - this.lastMessage = newMessage; -}; - -MessageSelectorWatchers.prototype.cancelWatch = function cancelWatch() { - this.expressionFnWatcher(); - this.messageFnWatcher(); -}; - -/** - * @constructor - * @extends MessageSelectorBase - * @private - */ -function SelectMessage(expressionFn, choices) { - MessageSelectorBase.call(this, expressionFn, choices); -} - -function SelectMessageProto() {} -SelectMessageProto.prototype = MessageSelectorBase.prototype; - -SelectMessage.prototype = new SelectMessageProto(); -SelectMessage.prototype.categorizeValue = function categorizeSelectValue(value) { - return (this.choices[value] !== void 0) ? value : "other"; -}; - -/** - * @constructor - * @extends MessageSelectorBase - * @private - */ -function PluralMessage(expressionFn, choices, offset, pluralCat) { - MessageSelectorBase.call(this, expressionFn, choices); - this.offset = offset; - this.pluralCat = pluralCat; -} - -function PluralMessageProto() {} -PluralMessageProto.prototype = MessageSelectorBase.prototype; - -PluralMessage.prototype = new PluralMessageProto(); -PluralMessage.prototype.categorizeValue = function categorizePluralValue(value) { - if (isNaN(value)) { - return "other"; - } else if (this.choices[value] !== void 0) { - return value; - } else { - var category = this.pluralCat(value - this.offset); - return (this.choices[category] !== void 0) ? category : "other"; - } -}; - -// NOTE: ADVANCED_OPTIMIZATIONS mode. -// -// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using -// constructs incompatible with that mode. - -/* global $interpolateMinErr: false */ -/* global isFunction: false */ -/* global parseTextLiteral: false */ - -/** - * @constructor - * @private - */ -function InterpolationParts(trustedContext, allOrNothing) { - this.trustedContext = trustedContext; - this.allOrNothing = allOrNothing; - this.textParts = []; - this.expressionFns = []; - this.expressionIndices = []; - this.partialText = ''; - this.concatParts = null; -} - -InterpolationParts.prototype.flushPartialText = function flushPartialText() { - if (this.partialText) { - if (this.concatParts == null) { - this.textParts.push(this.partialText); - } else { - this.textParts.push(this.concatParts.join('')); - this.concatParts = null; - } - this.partialText = ''; - } -}; - -InterpolationParts.prototype.addText = function addText(text) { - if (text.length) { - if (!this.partialText) { - this.partialText = text; - } else if (this.concatParts) { - this.concatParts.push(text); - } else { - this.concatParts = [this.partialText, text]; - } - } -}; - -InterpolationParts.prototype.addExpressionFn = function addExpressionFn(expressionFn) { - this.flushPartialText(); - this.expressionIndices.push(this.textParts.length); - this.expressionFns.push(expressionFn); - this.textParts.push(''); -}; - -InterpolationParts.prototype.getExpressionValues = function getExpressionValues(context) { - var expressionValues = new Array(this.expressionFns.length); - for (var i = 0; i < this.expressionFns.length; i++) { - expressionValues[i] = this.expressionFns[i](context); - } - return expressionValues; -}; - -InterpolationParts.prototype.getResult = function getResult(expressionValues) { - for (var i = 0; i < this.expressionIndices.length; i++) { - var expressionValue = expressionValues[i]; - if (this.allOrNothing && expressionValue === void 0) return; - this.textParts[this.expressionIndices[i]] = expressionValue; - } - return this.textParts.join(''); -}; - - -InterpolationParts.prototype.toParsedFn = function toParsedFn(mustHaveExpression, originalText) { - var self = this; - this.flushPartialText(); - if (mustHaveExpression && this.expressionFns.length === 0) { - return void 0; - } - if (this.textParts.length === 0) { - return parseTextLiteral(''); - } - if (this.trustedContext && this.textParts.length > 1) { - $interpolateMinErr['throwNoconcat'](originalText); - } - if (this.expressionFns.length === 0) { - if (this.textParts.length != 1) { this.errorInParseLogic(); } - return parseTextLiteral(this.textParts[0]); - } - var parsedFn = function(context) { - return self.getResult(self.getExpressionValues(context)); - }; - parsedFn['$$watchDelegate'] = function $$watchDelegate(scope, listener, objectEquality) { - return self.watchDelegate(scope, listener, objectEquality); - }; - - parsedFn['exp'] = originalText; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - parsedFn['expressions'] = new Array(this.expressionFns.length); // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. - for (var i = 0; i < this.expressionFns.length; i++) { - parsedFn['expressions'][i] = this.expressionFns[i]['exp']; - } - - return parsedFn; -}; - -InterpolationParts.prototype.watchDelegate = function watchDelegate(scope, listener, objectEquality) { - var watcher = new InterpolationPartsWatcher(this, scope, listener, objectEquality); - return function() { watcher.cancelWatch(); }; -}; - -function InterpolationPartsWatcher(interpolationParts, scope, listener, objectEquality) { - this.interpolationParts = interpolationParts; - this.scope = scope; - this.previousResult = (void 0); - this.listener = listener; - var self = this; - this.expressionFnsWatcher = scope['$watchGroup'](interpolationParts.expressionFns, function(newExpressionValues, oldExpressionValues) { - self.watchListener(newExpressionValues, oldExpressionValues); - }); -} - -InterpolationPartsWatcher.prototype.watchListener = function watchListener(newExpressionValues, oldExpressionValues) { - var result = this.interpolationParts.getResult(newExpressionValues); - if (isFunction(this.listener)) { - this.listener.call(null, result, newExpressionValues === oldExpressionValues ? result : this.previousResult, this.scope); - } - this.previousResult = result; -}; - -InterpolationPartsWatcher.prototype.cancelWatch = function cancelWatch() { - this.expressionFnsWatcher(); -}; - -// NOTE: ADVANCED_OPTIMIZATIONS mode. -// -// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using -// constructs incompatible with that mode. - -/* global $interpolateMinErr: false */ -/* global indexToLineAndColumn: false */ -/* global InterpolationParts: false */ -/* global PluralMessage: false */ -/* global SelectMessage: false */ -/* global subtractOffset: false */ - -// The params src and dst are exactly one of two types: NestedParserState or MessageFormatParser. -// This function is fully optimized by V8. (inspect via IRHydra or --trace-deopt.) -// The idea behind writing it this way is to avoid repeating oneself. This is the ONE place where -// the parser state that is saved/restored when parsing nested mustaches is specified. -function copyNestedParserState(src, dst) { - dst.expressionFn = src.expressionFn; - dst.expressionMinusOffsetFn = src.expressionMinusOffsetFn; - dst.pluralOffset = src.pluralOffset; - dst.choices = src.choices; - dst.choiceKey = src.choiceKey; - dst.interpolationParts = src.interpolationParts; - dst.ruleChoiceKeyword = src.ruleChoiceKeyword; - dst.msgStartIndex = src.msgStartIndex; - dst.expressionStartIndex = src.expressionStartIndex; -} - -function NestedParserState(parser) { - copyNestedParserState(parser, this); -} - -/** - * @constructor - * @private - */ -function MessageFormatParser(text, startIndex, $parse, pluralCat, stringifier, - mustHaveExpression, trustedContext, allOrNothing) { - this.text = text; - this.index = startIndex || 0; - this.$parse = $parse; - this.pluralCat = pluralCat; - this.stringifier = stringifier; - this.mustHaveExpression = !!mustHaveExpression; - this.trustedContext = trustedContext; - this.allOrNothing = !!allOrNothing; - this.expressionFn = null; - this.expressionMinusOffsetFn = null; - this.pluralOffset = null; - this.choices = null; - this.choiceKey = null; - this.interpolationParts = null; - this.msgStartIndex = null; - this.nestedStateStack = []; - this.parsedFn = null; - this.rule = null; - this.ruleStack = null; - this.ruleChoiceKeyword = null; - this.interpNestLevel = null; - this.expressionStartIndex = null; - this.stringStartIndex = null; - this.stringQuote = null; - this.stringInterestsRe = null; - this.angularOperatorStack = null; - this.textPart = null; -} - -// preserve v8 optimization. -var EMPTY_STATE = new NestedParserState(new MessageFormatParser( - /* text= */ '', /* startIndex= */ 0, /* $parse= */ null, /* pluralCat= */ null, /* stringifier= */ null, - /* mustHaveExpression= */ false, /* trustedContext= */ null, /* allOrNothing */ false)); - -MessageFormatParser.prototype.pushState = function pushState() { - this.nestedStateStack.push(new NestedParserState(this)); - copyNestedParserState(EMPTY_STATE, this); -}; - -MessageFormatParser.prototype.popState = function popState() { - if (this.nestedStateStack.length === 0) { - this.errorInParseLogic(); - } - var previousState = this.nestedStateStack.pop(); - copyNestedParserState(previousState, this); -}; - -// Oh my JavaScript! Who knew you couldn't match a regex at a specific -// location in a string but will always search forward?! -// Apparently you'll be growing this ability via the sticky flag (y) in -// ES6. I'll just to work around you for now. -MessageFormatParser.prototype.matchRe = function matchRe(re, search) { - re.lastIndex = this.index; - var match = re.exec(this.text); - if (match != null && (search === true || (match.index == this.index))) { - this.index = re.lastIndex; - return match; - } - return null; -}; - -MessageFormatParser.prototype.searchRe = function searchRe(re) { - return this.matchRe(re, true); -}; - - -MessageFormatParser.prototype.consumeRe = function consumeRe(re) { - // Without the sticky flag, we can't use the .test() method to consume a - // match at the current index. Instead, we'll use the slower .exec() method - // and verify match.index. - return !!this.matchRe(re); -}; - -// Run through our grammar avoiding deeply nested function call chains. -MessageFormatParser.prototype.run = function run(initialRule) { - this.ruleStack = [initialRule]; - do { - this.rule = this.ruleStack.pop(); - while (this.rule) { - this.rule(); - } - this.assertRuleOrNull(this.rule); - } while (this.ruleStack.length > 0); -}; - -MessageFormatParser.prototype.errorInParseLogic = function errorInParseLogic() { - throw $interpolateMinErr('logicbug', - 'The messageformat parser has encountered an internal error. Please file a github issue against the AngularJS project and provide this message text that triggers the bug. Text: “{0}”', - this.text); -}; - -MessageFormatParser.prototype.assertRuleOrNull = function assertRuleOrNull(rule) { - if (rule === void 0) { - this.errorInParseLogic(); - } -}; - -var NEXT_WORD_RE = /\s*(\w+)\s*/g; -MessageFormatParser.prototype.errorExpecting = function errorExpecting() { - // What was wrong with the syntax? Unsupported type, missing comma, or something else? - var match = this.matchRe(NEXT_WORD_RE), position; - if (match == null) { - position = indexToLineAndColumn(this.text, this.index); - throw $interpolateMinErr('reqarg', - 'Expected one of “plural” or “select” at line {0}, column {1} of text “{2}”', - position.line, position.column, this.text); - } - var word = match[1]; - if (word == "select" || word == "plural") { - position = indexToLineAndColumn(this.text, this.index); - throw $interpolateMinErr('reqcomma', - 'Expected a comma after the keyword “{0}” at line {1}, column {2} of text “{3}”', - word, position.line, position.column, this.text); - } else { - position = indexToLineAndColumn(this.text, this.index); - throw $interpolateMinErr('unknarg', - 'Unsupported keyword “{0}” at line {0}, column {1}. Only “plural” and “select” are currently supported. Text: “{3}”', - word, position.line, position.column, this.text); - } -}; - -var STRING_START_RE = /['"]/g; -MessageFormatParser.prototype.ruleString = function ruleString() { - var match = this.matchRe(STRING_START_RE); - if (match == null) { - var position = indexToLineAndColumn(this.text, this.index); - throw $interpolateMinErr('wantstring', - 'Expected the beginning of a string at line {0}, column {1} in text “{2}”', - position.line, position.column, this.text); - } - this.startStringAtMatch(match); -}; - -MessageFormatParser.prototype.startStringAtMatch = function startStringAtMatch(match) { - this.stringStartIndex = match.index; - this.stringQuote = match[0]; - this.stringInterestsRe = this.stringQuote == "'" ? SQUOTED_STRING_INTEREST_RE : DQUOTED_STRING_INTEREST_RE; - this.rule = this.ruleInsideString; -}; - -var SQUOTED_STRING_INTEREST_RE = /\\(?:\\|'|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}|[0-7]{3}|\r\n|\n|[\s\S])|'/g; -var DQUOTED_STRING_INTEREST_RE = /\\(?:\\|"|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}|[0-7]{3}|\r\n|\n|[\s\S])|"/g; -MessageFormatParser.prototype.ruleInsideString = function ruleInsideString() { - var match = this.searchRe(this.stringInterestsRe); - if (match == null) { - var position = indexToLineAndColumn(this.text, this.stringStartIndex); - throw $interpolateMinErr('untermstr', - 'The string beginning at line {0}, column {1} is unterminated in text “{2}”', - position.line, position.column, this.text); - } - var chars = match[0]; - if (match == this.stringQuote) { - this.rule = null; - } -}; - -var PLURAL_OR_SELECT_ARG_TYPE_RE = /\s*(plural|select)\s*,\s*/g; -MessageFormatParser.prototype.rulePluralOrSelect = function rulePluralOrSelect() { - var match = this.searchRe(PLURAL_OR_SELECT_ARG_TYPE_RE); - if (match == null) { - this.errorExpecting(); - } - var argType = match[1]; - switch (argType) { - case "plural": this.rule = this.rulePluralStyle; break; - case "select": this.rule = this.ruleSelectStyle; break; - default: this.errorInParseLogic(); - } -}; - -MessageFormatParser.prototype.rulePluralStyle = function rulePluralStyle() { - this.choices = Object.create(null); - this.ruleChoiceKeyword = this.rulePluralValueOrKeyword; - this.rule = this.rulePluralOffset; -}; - -MessageFormatParser.prototype.ruleSelectStyle = function ruleSelectStyle() { - this.choices = Object.create(null); - this.ruleChoiceKeyword = this.ruleSelectKeyword; - this.rule = this.ruleSelectKeyword; -}; - -var NUMBER_RE = /[0]|(?:[1-9][0-9]*)/g; -var PLURAL_OFFSET_RE = new RegExp("\\s*offset\\s*:\\s*(" + NUMBER_RE.source + ")", "g"); - -MessageFormatParser.prototype.rulePluralOffset = function rulePluralOffset() { - var match = this.matchRe(PLURAL_OFFSET_RE); - this.pluralOffset = (match == null) ? 0 : parseInt(match[1], 10); - this.expressionMinusOffsetFn = subtractOffset(this.expressionFn, this.pluralOffset); - this.rule = this.rulePluralValueOrKeyword; -}; - -MessageFormatParser.prototype.assertChoiceKeyIsNew = function assertChoiceKeyIsNew(choiceKey, index) { - if (this.choices[choiceKey] !== void 0) { - var position = indexToLineAndColumn(this.text, index); - throw $interpolateMinErr('dupvalue', - 'The choice “{0}” is specified more than once. Duplicate key is at line {1}, column {2} in text “{3}”', - choiceKey, position.line, position.column, this.text); - } -}; - -var SELECT_KEYWORD = /\s*(\w+)/g; -MessageFormatParser.prototype.ruleSelectKeyword = function ruleSelectKeyword() { - var match = this.matchRe(SELECT_KEYWORD); - if (match == null) { - this.parsedFn = new SelectMessage(this.expressionFn, this.choices).parsedFn; - this.rule = null; - return; - } - this.choiceKey = match[1]; - this.assertChoiceKeyIsNew(this.choiceKey, match.index); - this.rule = this.ruleMessageText; -}; - -var EXPLICIT_VALUE_OR_KEYWORD_RE = new RegExp("\\s*(?:(?:=(" + NUMBER_RE.source + "))|(\\w+))", "g"); -MessageFormatParser.prototype.rulePluralValueOrKeyword = function rulePluralValueOrKeyword() { - var match = this.matchRe(EXPLICIT_VALUE_OR_KEYWORD_RE); - if (match == null) { - this.parsedFn = new PluralMessage(this.expressionFn, this.choices, this.pluralOffset, this.pluralCat).parsedFn; - this.rule = null; - return; - } - if (match[1] != null) { - this.choiceKey = parseInt(match[1], 10); - } else { - this.choiceKey = match[2]; - } - this.assertChoiceKeyIsNew(this.choiceKey, match.index); - this.rule = this.ruleMessageText; -}; - -var BRACE_OPEN_RE = /\s*{/g; -var BRACE_CLOSE_RE = /}/g; -MessageFormatParser.prototype.ruleMessageText = function ruleMessageText() { - if (!this.consumeRe(BRACE_OPEN_RE)) { - var position = indexToLineAndColumn(this.text, this.index); - throw $interpolateMinErr('reqopenbrace', - 'The plural choice “{0}” must be followed by a message in braces at line {1}, column {2} in text “{3}”', - this.choiceKey, position.line, position.column, this.text); - } - this.msgStartIndex = this.index; - this.interpolationParts = new InterpolationParts(this.trustedContext, this.allOrNothing); - this.rule = this.ruleInInterpolationOrMessageText; -}; - -// Note: Since "\" is used as an escape character, don't allow it to be part of the -// startSymbol/endSymbol when I add the feature to allow them to be redefined. -var INTERP_OR_END_MESSAGE_RE = /\\.|{{|}/g; -var INTERP_OR_PLURALVALUE_OR_END_MESSAGE_RE = /\\.|{{|#|}/g; -var ESCAPE_OR_MUSTACHE_BEGIN_RE = /\\.|{{/g; -MessageFormatParser.prototype.advanceInInterpolationOrMessageText = function advanceInInterpolationOrMessageText() { - var currentIndex = this.index, match, re; - if (this.ruleChoiceKeyword == null) { // interpolation - match = this.searchRe(ESCAPE_OR_MUSTACHE_BEGIN_RE); - if (match == null) { // End of interpolation text. Nothing more to process. - this.textPart = this.text.substring(currentIndex); - this.index = this.text.length; - return null; - } - } else { - match = this.searchRe(this.ruleChoiceKeyword == this.rulePluralValueOrKeyword ? - INTERP_OR_PLURALVALUE_OR_END_MESSAGE_RE : INTERP_OR_END_MESSAGE_RE); - if (match == null) { - var position = indexToLineAndColumn(this.text, this.msgStartIndex); - throw $interpolateMinErr('reqendbrace', - 'The plural/select choice “{0}” message starting at line {1}, column {2} does not have an ending closing brace. Text “{3}”', - this.choiceKey, position.line, position.column, this.text); - } - } - // match is non-null. - var token = match[0]; - this.textPart = this.text.substring(currentIndex, match.index); - return token; -}; - -MessageFormatParser.prototype.ruleInInterpolationOrMessageText = function ruleInInterpolationOrMessageText() { - var currentIndex = this.index; - var token = this.advanceInInterpolationOrMessageText(); - if (token == null) { - // End of interpolation text. Nothing more to process. - this.index = this.text.length; - this.interpolationParts.addText(this.text.substring(currentIndex)); - this.rule = null; - return; - } - if (token[0] == "\\") { - // unescape next character and continue - this.interpolationParts.addText(this.textPart + token[1]); - return; - } - this.interpolationParts.addText(this.textPart); - if (token == "{{") { - this.pushState(); - this.ruleStack.push(this.ruleEndMustacheInInterpolationOrMessage); - this.rule = this.ruleEnteredMustache; - } else if (token == "}") { - this.choices[this.choiceKey] = this.interpolationParts.toParsedFn(/*mustHaveExpression=*/false, this.text); - this.rule = this.ruleChoiceKeyword; - } else if (token == "#") { - this.interpolationParts.addExpressionFn(this.expressionMinusOffsetFn); - } else { - this.errorInParseLogic(); - } -}; - -MessageFormatParser.prototype.ruleInterpolate = function ruleInterpolate() { - this.interpolationParts = new InterpolationParts(this.trustedContext, this.allOrNothing); - this.rule = this.ruleInInterpolation; -}; - -MessageFormatParser.prototype.ruleInInterpolation = function ruleInInterpolation() { - var currentIndex = this.index; - var match = this.searchRe(ESCAPE_OR_MUSTACHE_BEGIN_RE); - if (match == null) { - // End of interpolation text. Nothing more to process. - this.index = this.text.length; - this.interpolationParts.addText(this.text.substring(currentIndex)); - this.parsedFn = this.interpolationParts.toParsedFn(this.mustHaveExpression, this.text); - this.rule = null; - return; - } - var token = match[0]; - if (token[0] == "\\") { - // unescape next character and continue - this.interpolationParts.addText(this.text.substring(currentIndex, match.index) + token[1]); - return; - } - this.interpolationParts.addText(this.text.substring(currentIndex, match.index)); - this.pushState(); - this.ruleStack.push(this.ruleInterpolationEndMustache); - this.rule = this.ruleEnteredMustache; -}; - -MessageFormatParser.prototype.ruleInterpolationEndMustache = function ruleInterpolationEndMustache() { - var expressionFn = this.parsedFn; - this.popState(); - this.interpolationParts.addExpressionFn(expressionFn); - this.rule = this.ruleInInterpolation; -}; - -MessageFormatParser.prototype.ruleEnteredMustache = function ruleEnteredMustache() { - this.parsedFn = null; - this.ruleStack.push(this.ruleEndMustache); - this.rule = this.ruleAngularExpression; -}; - -MessageFormatParser.prototype.ruleEndMustacheInInterpolationOrMessage = function ruleEndMustacheInInterpolationOrMessage() { - var expressionFn = this.parsedFn; - this.popState(); - this.interpolationParts.addExpressionFn(expressionFn); - this.rule = this.ruleInInterpolationOrMessageText; -}; - - - -var INTERP_END_RE = /\s*}}/g; -MessageFormatParser.prototype.ruleEndMustache = function ruleEndMustache() { - var match = this.matchRe(INTERP_END_RE); - if (match == null) { - var position = indexToLineAndColumn(this.text, this.index); - throw $interpolateMinErr('reqendinterp', - 'Expecting end of interpolation symbol, “{0}”, at line {1}, column {2} in text “{3}”', - '}}', position.line, position.column, this.text); - } - if (this.parsedFn == null) { - // If we parsed a MessageFormat extension, (e.g. select/plural today, maybe more some other - // day), then the result *has* to be a string and those rules would have already set - // this.parsedFn. If there was no MessageFormat extension, then there is no requirement to - // stringify the result and parsedFn isn't set. We set it here. While we could have set it - // unconditionally when exiting the Angular expression, I intend for us to not just replace - // $interpolate, but also to replace $parse in a future version (so ng-bind can work), and in - // such a case we do not want to unnecessarily stringify something if it's not going to be used - // in a string context. - this.parsedFn = this.$parse(this.expressionFn, this.stringifier); - this.parsedFn['exp'] = this.expressionFn['exp']; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - this.parsedFn['expressions'] = this.expressionFn['expressions']; // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. - } - this.rule = null; -}; - -MessageFormatParser.prototype.ruleAngularExpression = function ruleAngularExpression() { - this.angularOperatorStack = []; - this.expressionStartIndex = this.index; - this.rule = this.ruleInAngularExpression; -}; - -function getEndOperator(opBegin) { - switch (opBegin) { - case "{": return "}"; - case "[": return "]"; - case "(": return ")"; - default: return null; - } -} - -function getBeginOperator(opEnd) { - switch (opEnd) { - case "}": return "{"; - case "]": return "["; - case ")": return "("; - default: return null; - } -} - -// TODO(chirayu): The interpolation endSymbol must also be accounted for. It -// just so happens that "}" is an operator so it's in the list below. But we -// should support any other type of start/end interpolation symbol. -var INTERESTING_OPERATORS_RE = /[[\]{}()'",]/g; -MessageFormatParser.prototype.ruleInAngularExpression = function ruleInAngularExpression() { - var startIndex = this.index; - var match = this.searchRe(INTERESTING_OPERATORS_RE); - var position; - if (match == null) { - if (this.angularOperatorStack.length === 0) { - // This is the end of the Angular expression so this is actually a - // success. Note that when inside an interpolation, this means we even - // consumed the closing interpolation symbols if they were curlies. This - // is NOT an error at this point but will become an error further up the - // stack when the part that saw the opening curlies is unable to find the - // closing ones. - this.index = this.text.length; - this.expressionFn = this.$parse(this.text.substring(this.expressionStartIndex, this.index)); - // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - this.expressionFn['exp'] = this.text.substring(this.expressionStartIndex, this.index); - this.expressionFn['expressions'] = this.expressionFn['expressions']; - this.rule = null; - return; - } - var innermostOperator = this.angularOperatorStack[0]; - throw $interpolateMinErr('badexpr', - 'Unexpected end of Angular expression. Expecting operator “{0}” at the end of the text “{1}”', - this.getEndOperator(innermostOperator), this.text); - } - var operator = match[0]; - if (operator == "'" || operator == '"') { - this.ruleStack.push(this.ruleInAngularExpression); - this.startStringAtMatch(match); - return; - } - if (operator == ",") { - if (this.trustedContext) { - position = indexToLineAndColumn(this.text, this.index); - throw $interpolateMinErr('unsafe', - 'Use of select/plural MessageFormat syntax is currently disallowed in a secure context ({0}). At line {1}, column {2} of text “{3}”', - this.trustedContext, position.line, position.column, this.text); - } - // only the top level comma has relevance. - if (this.angularOperatorStack.length === 0) { - // todo: does this need to be trimmed? - this.expressionFn = this.$parse(this.text.substring(this.expressionStartIndex, match.index)); - // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - this.expressionFn['exp'] = this.text.substring(this.expressionStartIndex, match.index); - this.expressionFn['expressions'] = this.expressionFn['expressions']; - this.rule = null; - this.rule = this.rulePluralOrSelect; - } - return; - } - if (getEndOperator(operator) != null) { - this.angularOperatorStack.unshift(operator); - return; - } - var beginOperator = getBeginOperator(operator); - if (beginOperator == null) { - this.errorInParseLogic(); - } - if (this.angularOperatorStack.length > 0) { - if (beginOperator == this.angularOperatorStack[0]) { - this.angularOperatorStack.shift(); - return; - } - position = indexToLineAndColumn(this.text, this.index); - throw $interpolateMinErr('badexpr', - 'Unexpected operator “{0}” at line {1}, column {2} in text. Was expecting “{3}”. Text: “{4}”', - operator, position.line, position.column, getEndOperator(this.angularOperatorStack[0]), this.text); - } - // We are trying to pop off the operator stack but there really isn't anything to pop off. - this.index = match.index; - this.expressionFn = this.$parse(this.text.substring(this.expressionStartIndex, this.index)); - // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - this.expressionFn['exp'] = this.text.substring(this.expressionStartIndex, this.index); - this.expressionFn['expressions'] = this.expressionFn['expressions']; - this.rule = null; -}; - -// NOTE: ADVANCED_OPTIMIZATIONS mode. -// -// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using -// constructs incompatible with that mode. - -/* global $interpolateMinErr: false */ -/* global MessageFormatParser: false */ -/* global stringify: false */ - -/** - * @ngdoc service - * @name $$messageFormat - * - * @description - * Angular internal service to recognize MessageFormat extensions in interpolation expressions. - * For more information, see: - * https://docs.google.com/a/google.com/document/d/1pbtW2yvtmFBikfRrJd8VAsabiFkKezmYZ_PbgdjQOVU/edit - * - * ## Example - * - * - * - *
        - *
        - * {{recipients.length, plural, offset:1 - * =0 {{{sender.name}} gave no gifts (\#=#)} - * =1 {{{sender.name}} gave one gift to {{recipients[0].name}} (\#=#)} - * one {{{sender.name}} gave {{recipients[0].name}} and one other person a gift (\#=#)} - * other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\#=#)} - * }} - *
        - *
        - * - * - * function Person(name, gender) { - * this.name = name; - * this.gender = gender; - * } - * - * var alice = new Person("Alice", "female"), - * bob = new Person("Bob", "male"), - * charlie = new Person("Charlie", "male"), - * harry = new Person("Harry Potter", "male"); - * - * angular.module('msgFmtExample', ['ngMessageFormat']) - * .controller('AppController', ['$scope', function($scope) { - * $scope.recipients = [alice, bob, charlie]; - * $scope.sender = harry; - * $scope.decreaseRecipients = function() { - * --$scope.recipients.length; - * }; - * }]); - * - * - * - * describe('MessageFormat plural', function() { - * it('should pluralize initial values', function() { - * var messageElem = element(by.binding('recipients.length')), decreaseRecipientsBtn = element(by.id('decreaseRecipients')); - * expect(messageElem.getText()).toEqual('Harry Potter gave Alice and 2 other people a gift (#=2)'); - * decreaseRecipientsBtn.click(); - * expect(messageElem.getText()).toEqual('Harry Potter gave Alice and one other person a gift (#=1)'); - * decreaseRecipientsBtn.click(); - * expect(messageElem.getText()).toEqual('Harry Potter gave one gift to Alice (#=0)'); - * decreaseRecipientsBtn.click(); - * expect(messageElem.getText()).toEqual('Harry Potter gave no gifts (#=-1)'); - * }); - * }); - * - *
        - */ -var $$MessageFormatFactory = ['$parse', '$locale', '$sce', '$exceptionHandler', function $$messageFormat( - $parse, $locale, $sce, $exceptionHandler) { - - function getStringifier(trustedContext, allOrNothing, text) { - return function stringifier(value) { - try { - value = trustedContext ? $sce['getTrusted'](trustedContext, value) : $sce['valueOf'](value); - return allOrNothing && (value === void 0) ? value : stringify(value); - } catch (err) { - $exceptionHandler($interpolateMinErr['interr'](text, err)); - } - }; - } - - function interpolate(text, mustHaveExpression, trustedContext, allOrNothing) { - var stringifier = getStringifier(trustedContext, allOrNothing, text); - var parser = new MessageFormatParser(text, 0, $parse, $locale['pluralCat'], stringifier, - mustHaveExpression, trustedContext, allOrNothing); - parser.run(parser.ruleInterpolate); - return parser.parsedFn; - } - - return { - 'interpolate': interpolate - }; -}]; - -var $$interpolateDecorator = ['$$messageFormat', '$delegate', function $$interpolateDecorator($$messageFormat, $interpolate) { - if ($interpolate['startSymbol']() != "{{" || $interpolate['endSymbol']() != "}}") { - throw $interpolateMinErr('nochgmustache', 'angular-message-format.js currently does not allow you to use custom start and end symbols for interpolation.'); - } - var interpolate = $$messageFormat['interpolate']; - interpolate['startSymbol'] = $interpolate['startSymbol']; - interpolate['endSymbol'] = $interpolate['endSymbol']; - return interpolate; -}]; - - -/** - * @ngdoc module - * @name ngMessageFormat - * @packageName angular-message-format - * @description - */ -var module = window['angular']['module']('ngMessageFormat', ['ng']); -module['factory']('$$messageFormat', $$MessageFormatFactory); -module['config'](['$provide', function($provide) { - $provide['decorator']('$interpolate', $$interpolateDecorator); -}]); - - -})(window, window.angular); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-message-format.min.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-message-format.min.js deleted file mode 100644 index f85a5876..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-message-format.min.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - AngularJS v1.5.0 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(h){'use strict';function C(a){if(null==a)return"";switch(typeof a){case "string":return a;case "number":return""+a;default:return D(a)}}function f(a,b){for(var d=a.split(/\n/g),k=0;k=c.length)b-=c.length;else return{h:k+1,f:b+1}}}function t(a){function b(){return a}var d=u[a];if(null!=d)return d;b.$$watchDelegate=function(b,d,c){var e=b.$watch(v,function(){m(d)&&d.call(null,a,a,b);e()},c);return e};u[a]=b;b.exp=a;b.expressions=[];return b}function F(a,b){function d(a){return void 0== -a?a:a-b}function c(b){return d(a(b))}if(0===b)return a;var e;c.$$watchDelegate=function(b,c,k){return e=b.$watch(a,function(a,k){m(c)&&c.call(null,d(a),d(k),b)},k)};return c}function l(a,b){var d=this;this.b=a;this.e=b;if(void 0===b.other)throw e("reqother");this.d=function(a){return d.D(a)};this.d.$$watchDelegate=function(a,b,c){return d.P(a,b,c)};this.d.exp=a.exp;this.d.expressions=a.expressions}function n(a,b,d,c){var e=this;this.scope=b;this.oa=a;this.v=d;this.qa=c;this.U=void 0;this.K=v;this.ka= -b.$watch(a.b,function(a){return e.ja(a)},c)}function p(a,b){l.call(this,a,b)}function w(){}function q(a,b,d,c){l.call(this,a,b);this.offset=d;this.M=c}function x(){}function g(a,b){this.u=a;this.B=b;this.i=[];this.g=[];this.J=[];this.s="";this.q=null}function r(a,b,d){this.c=a;this.scope=b;this.W=void 0;this.v=d;var c=this;this.la=b.$watchGroup(a.g,function(a,b){c.Ea(a,b)})}function s(a,b){b.b=a.b;b.C=a.C;b.w=a.w;b.e=a.e;b.k=a.k;b.c=a.c;b.n=a.n;b.F=a.F;b.l=a.l}function y(a){s(a,this)}function c(a, -b,d,c,e,E,f,g){this.text=a;this.index=b||0;this.A=d;this.M=c;this.Da=e;this.pa=!!E;this.u=f;this.B=!!g;this.F=this.c=this.k=this.e=this.w=this.C=this.b=null;this.L=[];this.G=this.j=this.ca=this.O=this.da=this.l=this.n=this.o=this.a=this.d=null}function z(a){switch(a){case "{":return"}";case "[":return"]";case "(":return")";default:return null}}function G(a){switch(a){case "}":return"{";case "]":return"[";case ")":return"(";default:return null}}var e=h.angular.$interpolateMinErr,v=h.angular.noop,m= -h.angular.isFunction,D=h.angular.toJson,u=Object.create(null);l.prototype.T=function(a){return this.e[this.R(a)]};l.prototype.D=function(a){return this.T(this.b(a))(a)};l.prototype.P=function(a,b,d){var c=new n(this,a,b,d);return function(){c.I()}};n.prototype.ja=function(a){var b=this;this.K();a=this.oa.T(a);this.K=this.scope.$watch(a,function(a,c){return b.na(a,c)},this.qa)};n.prototype.na=function(a,b){m(this.v)&&this.v.call(null,a,a===b?a:this.U,this.scope);this.U=a};n.prototype.I=function(){this.ka(); -this.K()};w.prototype=l.prototype;p.prototype=new w;p.prototype.R=function(a){return void 0!==this.e[a]?a:"other"};x.prototype=l.prototype;q.prototype=new x;q.prototype.R=function(a){if(isNaN(a))return"other";if(void 0!==this.e[a])return a;a=this.M(a-this.offset);return void 0!==this.e[a]?a:"other"};g.prototype.S=function(){this.s&&(null==this.q?this.i.push(this.s):(this.i.push(this.q.join("")),this.q=null),this.s="")};g.prototype.p=function(a){a.length&&(this.s?this.q?this.q.push(a):this.q=[this.s, -a]:this.s=a)};g.prototype.H=function(a){this.S();this.J.push(this.i.length);this.g.push(a);this.i.push("")};g.prototype.ma=function(a){for(var b=Array(this.g.length),d=0;d - * - *
        - *
        You did not enter a field
        - *
        - * Your email must be between 5 and 100 characters long - *
        - *
        - * - * ``` - * - * Now whatever key/value entries are present within the provided object (in this case `$error`) then - * the ngMessages directive will render the inner first ngMessage directive (depending if the key values - * match the attribute value present on each ngMessage directive). In other words, if your errors - * object contains the following data: - * - * ```javascript - * - * myField.$error = { minlength : true, required : true }; - * ``` - * - * Then the `required` message will be displayed first. When required is false then the `minlength` message - * will be displayed right after (since these messages are ordered this way in the template HTML code). - * The prioritization of each message is determined by what order they're present in the DOM. - * Therefore, instead of having custom JavaScript code determine the priority of what errors are - * present before others, the presentation of the errors are handled within the template. - * - * By default, ngMessages will only display one error at a time. However, if you wish to display all - * messages then the `ng-messages-multiple` attribute flag can be used on the element containing the - * ngMessages directive to make this happen. - * - * ```html - * - *
        ...
        - * - * - * ... - * ``` - * - * ## Reusing and Overriding Messages - * In addition to prioritization, ngMessages also allows for including messages from a remote or an inline - * template. This allows for generic collection of messages to be reused across multiple parts of an - * application. - * - * ```html - * - * - *
        - *
        - *
        - * ``` - * - * However, including generic messages may not be useful enough to match all input fields, therefore, - * `ngMessages` provides the ability to override messages defined in the remote template by redefining - * them within the directive container. - * - * ```html - * - * - * - *
        - * - * - *
        - * - *
        You did not enter your email address
        - * - * - *
        Your email address is invalid
        - * - * - *
        - *
        - *
        - * ``` - * - * In the example HTML code above the message that is set on required will override the corresponding - * required message defined within the remote template. Therefore, with particular input fields (such - * email addresses, date fields, autocomplete inputs, etc...), specialized error messages can be applied - * while more generic messages can be used to handle other, more general input errors. - * - * ## Dynamic Messaging - * ngMessages also supports using expressions to dynamically change key values. Using arrays and - * repeaters to list messages is also supported. This means that the code below will be able to - * fully adapt itself and display the appropriate message when any of the expression data changes: - * - * ```html - *
        - * - *
        - *
        You did not enter your email address
        - *
        - * - *
        {{ errorMessage.text }}
        - *
        - *
        - *
        - * ``` - * - * The `errorMessage.type` expression can be a string value or it can be an array so - * that multiple errors can be associated with a single error message: - * - * ```html - * - *
        - *
        You did not enter your email address
        - *
        - * Your email must be between 5 and 100 characters long - *
        - *
        - * ``` - * - * Feel free to use other structural directives such as ng-if and ng-switch to further control - * what messages are active and when. Be careful, if you place ng-message on the same element - * as these structural directives, Angular may not be able to determine if a message is active - * or not. Therefore it is best to place the ng-message on a child element of the structural - * directive. - * - * ```html - *
        - *
        - *
        Please enter something
        - *
        - *
        - * ``` - * - * ## Animations - * If the `ngAnimate` module is active within the application then the `ngMessages`, `ngMessage` and - * `ngMessageExp` directives will trigger animations whenever any messages are added and removed from - * the DOM by the `ngMessages` directive. - * - * Whenever the `ngMessages` directive contains one or more visible messages then the `.ng-active` CSS - * class will be added to the element. The `.ng-inactive` CSS class will be applied when there are no - * messages present. Therefore, CSS transitions and keyframes as well as JavaScript animations can - * hook into the animations whenever these classes are added/removed. - * - * Let's say that our HTML code for our messages container looks like so: - * - * ```html - * - * ``` - * - * Then the CSS animation code for the message container looks like so: - * - * ```css - * .my-messages { - * transition:1s linear all; - * } - * .my-messages.ng-active { - * // messages are visible - * } - * .my-messages.ng-inactive { - * // messages are hidden - * } - * ``` - * - * Whenever an inner message is attached (becomes visible) or removed (becomes hidden) then the enter - * and leave animation is triggered for each particular element bound to the `ngMessage` directive. - * - * Therefore, the CSS code for the inner messages looks like so: - * - * ```css - * .some-message { - * transition:1s linear all; - * } - * - * .some-message.ng-enter {} - * .some-message.ng-enter.ng-enter-active {} - * - * .some-message.ng-leave {} - * .some-message.ng-leave.ng-leave-active {} - * ``` - * - * {@link ngAnimate Click here} to learn how to use JavaScript animations or to learn more about ngAnimate. - */ -angular.module('ngMessages', []) - - /** - * @ngdoc directive - * @module ngMessages - * @name ngMessages - * @restrict AE - * - * @description - * `ngMessages` is a directive that is designed to show and hide messages based on the state - * of a key/value object that it listens on. The directive itself complements error message - * reporting with the `ngModel` $error object (which stores a key/value state of validation errors). - * - * `ngMessages` manages the state of internal messages within its container element. The internal - * messages use the `ngMessage` directive and will be inserted/removed from the page depending - * on if they're present within the key/value object. By default, only one message will be displayed - * at a time and this depends on the prioritization of the messages within the template. (This can - * be changed by using the `ng-messages-multiple` or `multiple` attribute on the directive container.) - * - * A remote template can also be used to promote message reusability and messages can also be - * overridden. - * - * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`. - * - * @usage - * ```html - * - * - * ... - * ... - * ... - * - * - * - * - * ... - * ... - * ... - * - * ``` - * - * @param {string} ngMessages an angular expression evaluating to a key/value object - * (this is typically the $error object on an ngModel instance). - * @param {string=} ngMessagesMultiple|multiple when set, all messages will be displayed with true - * - * @example - * - * - *
        - * - *
        myForm.myName.$error = {{ myForm.myName.$error | json }}
        - * - *
        - *
        You did not enter a field
        - *
        Your field is too short
        - *
        Your field is too long
        - *
        - *
        - *
        - * - * angular.module('ngMessagesExample', ['ngMessages']); - * - *
        - */ - .directive('ngMessages', ['$animate', function($animate) { - var ACTIVE_CLASS = 'ng-active'; - var INACTIVE_CLASS = 'ng-inactive'; - - return { - require: 'ngMessages', - restrict: 'AE', - controller: ['$element', '$scope', '$attrs', function($element, $scope, $attrs) { - var ctrl = this; - var latestKey = 0; - var nextAttachId = 0; - - this.getAttachId = function getAttachId() { return nextAttachId++; }; - - var messages = this.messages = {}; - var renderLater, cachedCollection; - - this.render = function(collection) { - collection = collection || {}; - - renderLater = false; - cachedCollection = collection; - - // this is true if the attribute is empty or if the attribute value is truthy - var multiple = isAttrTruthy($scope, $attrs.ngMessagesMultiple) || - isAttrTruthy($scope, $attrs.multiple); - - var unmatchedMessages = []; - var matchedKeys = {}; - var messageItem = ctrl.head; - var messageFound = false; - var totalMessages = 0; - - // we use != instead of !== to allow for both undefined and null values - while (messageItem != null) { - totalMessages++; - var messageCtrl = messageItem.message; - - var messageUsed = false; - if (!messageFound) { - forEach(collection, function(value, key) { - if (!messageUsed && truthy(value) && messageCtrl.test(key)) { - // this is to prevent the same error name from showing up twice - if (matchedKeys[key]) return; - matchedKeys[key] = true; - - messageUsed = true; - messageCtrl.attach(); - } - }); - } - - if (messageUsed) { - // unless we want to display multiple messages then we should - // set a flag here to avoid displaying the next message in the list - messageFound = !multiple; - } else { - unmatchedMessages.push(messageCtrl); - } - - messageItem = messageItem.next; - } - - forEach(unmatchedMessages, function(messageCtrl) { - messageCtrl.detach(); - }); - - unmatchedMessages.length !== totalMessages - ? $animate.setClass($element, ACTIVE_CLASS, INACTIVE_CLASS) - : $animate.setClass($element, INACTIVE_CLASS, ACTIVE_CLASS); - }; - - $scope.$watchCollection($attrs.ngMessages || $attrs['for'], ctrl.render); - - this.reRender = function() { - if (!renderLater) { - renderLater = true; - $scope.$evalAsync(function() { - if (renderLater) { - cachedCollection && ctrl.render(cachedCollection); - } - }); - } - }; - - this.register = function(comment, messageCtrl) { - var nextKey = latestKey.toString(); - messages[nextKey] = { - message: messageCtrl - }; - insertMessageNode($element[0], comment, nextKey); - comment.$$ngMessageNode = nextKey; - latestKey++; - - ctrl.reRender(); - }; - - this.deregister = function(comment) { - var key = comment.$$ngMessageNode; - delete comment.$$ngMessageNode; - removeMessageNode($element[0], comment, key); - delete messages[key]; - ctrl.reRender(); - }; - - function findPreviousMessage(parent, comment) { - var prevNode = comment; - var parentLookup = []; - while (prevNode && prevNode !== parent) { - var prevKey = prevNode.$$ngMessageNode; - if (prevKey && prevKey.length) { - return messages[prevKey]; - } - - // dive deeper into the DOM and examine its children for any ngMessage - // comments that may be in an element that appears deeper in the list - if (prevNode.childNodes.length && parentLookup.indexOf(prevNode) == -1) { - parentLookup.push(prevNode); - prevNode = prevNode.childNodes[prevNode.childNodes.length - 1]; - } else { - prevNode = prevNode.previousSibling || prevNode.parentNode; - } - } - } - - function insertMessageNode(parent, comment, key) { - var messageNode = messages[key]; - if (!ctrl.head) { - ctrl.head = messageNode; - } else { - var match = findPreviousMessage(parent, comment); - if (match) { - messageNode.next = match.next; - match.next = messageNode; - } else { - messageNode.next = ctrl.head; - ctrl.head = messageNode; - } - } - } - - function removeMessageNode(parent, comment, key) { - var messageNode = messages[key]; - - var match = findPreviousMessage(parent, comment); - if (match) { - match.next = messageNode.next; - } else { - ctrl.head = messageNode.next; - } - } - }] - }; - - function isAttrTruthy(scope, attr) { - return (isString(attr) && attr.length === 0) || //empty attribute - truthy(scope.$eval(attr)); - } - - function truthy(val) { - return isString(val) ? val.length : !!val; - } - }]) - - /** - * @ngdoc directive - * @name ngMessagesInclude - * @restrict AE - * @scope - * - * @description - * `ngMessagesInclude` is a directive with the purpose to import existing ngMessage template - * code from a remote template and place the downloaded template code into the exact spot - * that the ngMessagesInclude directive is placed within the ngMessages container. This allows - * for a series of pre-defined messages to be reused and also allows for the developer to - * determine what messages are overridden due to the placement of the ngMessagesInclude directive. - * - * @usage - * ```html - * - * - * ... - * - * - * - * - * ... - * - * ``` - * - * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`. - * - * @param {string} ngMessagesInclude|src a string value corresponding to the remote template. - */ - .directive('ngMessagesInclude', - ['$templateRequest', '$document', '$compile', function($templateRequest, $document, $compile) { - - return { - restrict: 'AE', - require: '^^ngMessages', // we only require this for validation sake - link: function($scope, element, attrs) { - var src = attrs.ngMessagesInclude || attrs.src; - $templateRequest(src).then(function(html) { - $compile(html)($scope, function(contents) { - element.after(contents); - - // the anchor is placed for debugging purposes - var anchor = jqLite($document[0].createComment(' ngMessagesInclude: ' + src + ' ')); - element.after(anchor); - - // we don't want to pollute the DOM anymore by keeping an empty directive element - element.remove(); - }); - }); - } - }; - }]) - - /** - * @ngdoc directive - * @name ngMessage - * @restrict AE - * @scope - * - * @description - * `ngMessage` is a directive with the purpose to show and hide a particular message. - * For `ngMessage` to operate, a parent `ngMessages` directive on a parent DOM element - * must be situated since it determines which messages are visible based on the state - * of the provided key/value map that `ngMessages` listens on. - * - * More information about using `ngMessage` can be found in the - * {@link module:ngMessages `ngMessages` module documentation}. - * - * @usage - * ```html - * - * - * ... - * ... - * - * - * - * - * ... - * ... - * - * ``` - * - * @param {expression} ngMessage|when a string value corresponding to the message key. - */ - .directive('ngMessage', ngMessageDirectiveFactory()) - - - /** - * @ngdoc directive - * @name ngMessageExp - * @restrict AE - * @priority 1 - * @scope - * - * @description - * `ngMessageExp` is a directive with the purpose to show and hide a particular message. - * For `ngMessageExp` to operate, a parent `ngMessages` directive on a parent DOM element - * must be situated since it determines which messages are visible based on the state - * of the provided key/value map that `ngMessages` listens on. - * - * @usage - * ```html - * - * - * ... - * - * - * - * - * ... - * - * ``` - * - * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`. - * - * @param {expression} ngMessageExp|whenExp an expression value corresponding to the message key. - */ - .directive('ngMessageExp', ngMessageDirectiveFactory()); - -function ngMessageDirectiveFactory() { - return ['$animate', function($animate) { - return { - restrict: 'AE', - transclude: 'element', - priority: 1, // must run before ngBind, otherwise the text is set on the comment - terminal: true, - require: '^^ngMessages', - link: function(scope, element, attrs, ngMessagesCtrl, $transclude) { - var commentNode = element[0]; - - var records; - var staticExp = attrs.ngMessage || attrs.when; - var dynamicExp = attrs.ngMessageExp || attrs.whenExp; - var assignRecords = function(items) { - records = items - ? (isArray(items) - ? items - : items.split(/[\s,]+/)) - : null; - ngMessagesCtrl.reRender(); - }; - - if (dynamicExp) { - assignRecords(scope.$eval(dynamicExp)); - scope.$watchCollection(dynamicExp, assignRecords); - } else { - assignRecords(staticExp); - } - - var currentElement, messageCtrl; - ngMessagesCtrl.register(commentNode, messageCtrl = { - test: function(name) { - return contains(records, name); - }, - attach: function() { - if (!currentElement) { - $transclude(scope, function(elm) { - $animate.enter(elm, null, element); - currentElement = elm; - - // Each time we attach this node to a message we get a new id that we can match - // when we are destroying the node later. - var $$attachId = currentElement.$$attachId = ngMessagesCtrl.getAttachId(); - - // in the event that the parent element is destroyed - // by any other structural directive then it's time - // to deregister the message from the controller - currentElement.on('$destroy', function() { - if (currentElement && currentElement.$$attachId === $$attachId) { - ngMessagesCtrl.deregister(commentNode); - messageCtrl.detach(); - } - }); - }); - } - }, - detach: function() { - if (currentElement) { - var elm = currentElement; - currentElement = null; - $animate.leave(elm); - } - } - }); - } - }; - }]; - - function contains(collection, key) { - if (collection) { - return isArray(collection) - ? collection.indexOf(key) >= 0 - : collection.hasOwnProperty(key); - } - } -} - - -})(window, window.angular); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-messages.min.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-messages.min.js deleted file mode 100644 index 19f59cc8..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-messages.min.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - AngularJS v1.5.0 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(A,d,B){'use strict';function l(){return["$animate",function(v){return{restrict:"AE",transclude:"element",priority:1,terminal:!0,require:"^^ngMessages",link:function(n,r,a,b,m){var k=r[0],f,p=a.ngMessage||a.when;a=a.ngMessageExp||a.whenExp;var d=function(a){f=a?w(a)?a:a.split(/[\s,]+/):null;b.reRender()};a?(d(n.$eval(a)),n.$watchCollection(a,d)):d(p);var e,q;b.register(k,q={test:function(a){var g=f;a=g?w(g)?0<=g.indexOf(a):g.hasOwnProperty(a):void 0;return a},attach:function(){e||m(n,function(a){v.enter(a, -null,r);e=a;var g=e.$$attachId=b.getAttachId();e.on("$destroy",function(){e&&e.$$attachId===g&&(b.deregister(k),q.detach())})})},detach:function(){if(e){var a=e;e=null;v.leave(a)}}})}}}]}var w=d.isArray,x=d.forEach,y=d.isString,z=d.element;d.module("ngMessages",[]).directive("ngMessages",["$animate",function(d){function n(a,b){return y(b)&&0===b.length||r(a.$eval(b))}function r(a){return y(a)?a.length:!!a}return{require:"ngMessages",restrict:"AE",controller:["$element","$scope","$attrs",function(a, -b,m){function k(a,b){for(var c=b,f=[];c&&c!==a;){var h=c.$$ngMessageNode;if(h&&h.length)return e[h];c.childNodes.length&&-1==f.indexOf(c)?(f.push(c),c=c.childNodes[c.childNodes.length-1]):c=c.previousSibling||c.parentNode}}var f=this,p=0,l=0;this.getAttachId=function(){return l++};var e=this.messages={},q,s;this.render=function(g){g=g||{};q=!1;s=g;for(var e=n(b,m.ngMessagesMultiple)||n(b,m.multiple),c=[],k={},h=f.head,p=!1,l=0;null!=h;){l++;var t=h.message,u=!1;p||x(g,function(a,c){!u&&r(a)&&t.test(c)&& -!k[c]&&(u=k[c]=!0,t.attach())});u?p=!e:c.push(t);h=h.next}x(c,function(a){a.detach()});c.length!==l?d.setClass(a,"ng-active","ng-inactive"):d.setClass(a,"ng-inactive","ng-active")};b.$watchCollection(m.ngMessages||m["for"],f.render);this.reRender=function(){q||(q=!0,b.$evalAsync(function(){q&&s&&f.render(s)}))};this.register=function(g,b){var c=p.toString();e[c]={message:b};var d=a[0],h=e[c];f.head?(d=k(d,g))?(h.next=d.next,d.next=h):(h.next=f.head,f.head=h):f.head=h;g.$$ngMessageNode=c;p++;f.reRender()}; -this.deregister=function(b){var d=b.$$ngMessageNode;delete b.$$ngMessageNode;var c=e[d];(b=k(a[0],b))?b.next=c.next:f.head=c.next;delete e[d];f.reRender()}}]}}]).directive("ngMessagesInclude",["$templateRequest","$document","$compile",function(d,n,l){return{restrict:"AE",require:"^^ngMessages",link:function(a,b,m){var k=m.ngMessagesInclude||m.src;d(k).then(function(d){l(d)(a,function(a){b.after(a);a=z(n[0].createComment(" ngMessagesInclude: "+k+" "));b.after(a);b.remove()})})}}}]).directive("ngMessage", -l()).directive("ngMessageExp",l())})(window,window.angular); -//# sourceMappingURL=angular-messages.min.js.map diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-messages.min.js.map b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-messages.min.js.map deleted file mode 100644 index 0cb2a943..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-messages.min.js.map +++ /dev/null @@ -1,8 +0,0 @@ -{ -"version":3, -"file":"angular-messages.min.js", -"lineCount":11, -"mappings":"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", -"sources":["angular-messages.js"], -"names":["window","angular","undefined","ngMessageDirectiveFactory","$animate","restrict","transclude","priority","terminal","require","link","scope","element","attrs","ngMessagesCtrl","$transclude","commentNode","records","staticExp","ngMessage","when","dynamicExp","ngMessageExp","whenExp","assignRecords","items","isArray","split","reRender","$eval","$watchCollection","currentElement","messageCtrl","register","test","name","collection","indexOf","hasOwnProperty","attach","elm","enter","$$attachId","getAttachId","on","deregister","detach","leave","forEach","isString","jqLite","module","directive","isAttrTruthy","attr","length","truthy","val","controller","$element","$scope","$attrs","findPreviousMessage","parent","comment","prevNode","parentLookup","prevKey","$$ngMessageNode","messages","childNodes","push","previousSibling","parentNode","ctrl","latestKey","nextAttachId","this.getAttachId","renderLater","cachedCollection","render","this.render","multiple","ngMessagesMultiple","unmatchedMessages","matchedKeys","messageItem","head","messageFound","totalMessages","message","messageUsed","value","key","next","setClass","ACTIVE_CLASS","INACTIVE_CLASS","ngMessages","this.reRender","$evalAsync","this.register","nextKey","toString","messageNode","match","this.deregister","$templateRequest","$document","$compile","src","ngMessagesInclude","then","html","contents","after","anchor","createComment","remove"] -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-mocks.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-mocks.js deleted file mode 100644 index 34d36087..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-mocks.js +++ /dev/null @@ -1,2842 +0,0 @@ -/** - * @license AngularJS v1.5.0 - * (c) 2010-2016 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular, undefined) { - -'use strict'; - -/** - * @ngdoc object - * @name angular.mock - * @description - * - * Namespace from 'angular-mocks.js' which contains testing related code. - */ -angular.mock = {}; - -/** - * ! This is a private undocumented service ! - * - * @name $browser - * - * @description - * This service is a mock implementation of {@link ng.$browser}. It provides fake - * implementation for commonly used browser apis that are hard to test, e.g. setTimeout, xhr, - * cookies, etc... - * - * The api of this service is the same as that of the real {@link ng.$browser $browser}, except - * that there are several helper methods available which can be used in tests. - */ -angular.mock.$BrowserProvider = function() { - this.$get = function() { - return new angular.mock.$Browser(); - }; -}; - -angular.mock.$Browser = function() { - var self = this; - - this.isMock = true; - self.$$url = "http://server/"; - self.$$lastUrl = self.$$url; // used by url polling fn - self.pollFns = []; - - // TODO(vojta): remove this temporary api - self.$$completeOutstandingRequest = angular.noop; - self.$$incOutstandingRequestCount = angular.noop; - - - // register url polling fn - - self.onUrlChange = function(listener) { - self.pollFns.push( - function() { - if (self.$$lastUrl !== self.$$url || self.$$state !== self.$$lastState) { - self.$$lastUrl = self.$$url; - self.$$lastState = self.$$state; - listener(self.$$url, self.$$state); - } - } - ); - - return listener; - }; - - self.$$applicationDestroyed = angular.noop; - self.$$checkUrlChange = angular.noop; - - self.deferredFns = []; - self.deferredNextId = 0; - - self.defer = function(fn, delay) { - delay = delay || 0; - self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId}); - self.deferredFns.sort(function(a, b) { return a.time - b.time;}); - return self.deferredNextId++; - }; - - - /** - * @name $browser#defer.now - * - * @description - * Current milliseconds mock time. - */ - self.defer.now = 0; - - - self.defer.cancel = function(deferId) { - var fnIndex; - - angular.forEach(self.deferredFns, function(fn, index) { - if (fn.id === deferId) fnIndex = index; - }); - - if (angular.isDefined(fnIndex)) { - self.deferredFns.splice(fnIndex, 1); - return true; - } - - return false; - }; - - - /** - * @name $browser#defer.flush - * - * @description - * Flushes all pending requests and executes the defer callbacks. - * - * @param {number=} number of milliseconds to flush. See {@link #defer.now} - */ - self.defer.flush = function(delay) { - if (angular.isDefined(delay)) { - self.defer.now += delay; - } else { - if (self.deferredFns.length) { - self.defer.now = self.deferredFns[self.deferredFns.length - 1].time; - } else { - throw new Error('No deferred tasks to be flushed'); - } - } - - while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) { - self.deferredFns.shift().fn(); - } - }; - - self.$$baseHref = '/'; - self.baseHref = function() { - return this.$$baseHref; - }; -}; -angular.mock.$Browser.prototype = { - -/** - * @name $browser#poll - * - * @description - * run all fns in pollFns - */ - poll: function poll() { - angular.forEach(this.pollFns, function(pollFn) { - pollFn(); - }); - }, - - url: function(url, replace, state) { - if (angular.isUndefined(state)) { - state = null; - } - if (url) { - this.$$url = url; - // Native pushState serializes & copies the object; simulate it. - this.$$state = angular.copy(state); - return this; - } - - return this.$$url; - }, - - state: function() { - return this.$$state; - }, - - notifyWhenNoOutstandingRequests: function(fn) { - fn(); - } -}; - - -/** - * @ngdoc provider - * @name $exceptionHandlerProvider - * - * @description - * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors - * passed to the `$exceptionHandler`. - */ - -/** - * @ngdoc service - * @name $exceptionHandler - * - * @description - * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed - * to it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration - * information. - * - * - * ```js - * describe('$exceptionHandlerProvider', function() { - * - * it('should capture log messages and exceptions', function() { - * - * module(function($exceptionHandlerProvider) { - * $exceptionHandlerProvider.mode('log'); - * }); - * - * inject(function($log, $exceptionHandler, $timeout) { - * $timeout(function() { $log.log(1); }); - * $timeout(function() { $log.log(2); throw 'banana peel'; }); - * $timeout(function() { $log.log(3); }); - * expect($exceptionHandler.errors).toEqual([]); - * expect($log.assertEmpty()); - * $timeout.flush(); - * expect($exceptionHandler.errors).toEqual(['banana peel']); - * expect($log.log.logs).toEqual([[1], [2], [3]]); - * }); - * }); - * }); - * ``` - */ - -angular.mock.$ExceptionHandlerProvider = function() { - var handler; - - /** - * @ngdoc method - * @name $exceptionHandlerProvider#mode - * - * @description - * Sets the logging mode. - * - * @param {string} mode Mode of operation, defaults to `rethrow`. - * - * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log` - * mode stores an array of errors in `$exceptionHandler.errors`, to allow later - * assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and - * {@link ngMock.$log#reset reset()} - * - `rethrow`: If any errors are passed to the handler in tests, it typically means that there - * is a bug in the application or test, so this mock will make these tests fail. - * For any implementations that expect exceptions to be thrown, the `rethrow` mode - * will also maintain a log of thrown errors. - */ - this.mode = function(mode) { - - switch (mode) { - case 'log': - case 'rethrow': - var errors = []; - handler = function(e) { - if (arguments.length == 1) { - errors.push(e); - } else { - errors.push([].slice.call(arguments, 0)); - } - if (mode === "rethrow") { - throw e; - } - }; - handler.errors = errors; - break; - default: - throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!"); - } - }; - - this.$get = function() { - return handler; - }; - - this.mode('rethrow'); -}; - - -/** - * @ngdoc service - * @name $log - * - * @description - * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays - * (one array per logging level). These arrays are exposed as `logs` property of each of the - * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`. - * - */ -angular.mock.$LogProvider = function() { - var debug = true; - - function concat(array1, array2, index) { - return array1.concat(Array.prototype.slice.call(array2, index)); - } - - this.debugEnabled = function(flag) { - if (angular.isDefined(flag)) { - debug = flag; - return this; - } else { - return debug; - } - }; - - this.$get = function() { - var $log = { - log: function() { $log.log.logs.push(concat([], arguments, 0)); }, - warn: function() { $log.warn.logs.push(concat([], arguments, 0)); }, - info: function() { $log.info.logs.push(concat([], arguments, 0)); }, - error: function() { $log.error.logs.push(concat([], arguments, 0)); }, - debug: function() { - if (debug) { - $log.debug.logs.push(concat([], arguments, 0)); - } - } - }; - - /** - * @ngdoc method - * @name $log#reset - * - * @description - * Reset all of the logging arrays to empty. - */ - $log.reset = function() { - /** - * @ngdoc property - * @name $log#log.logs - * - * @description - * Array of messages logged using {@link ng.$log#log `log()`}. - * - * @example - * ```js - * $log.log('Some Log'); - * var first = $log.log.logs.unshift(); - * ``` - */ - $log.log.logs = []; - /** - * @ngdoc property - * @name $log#info.logs - * - * @description - * Array of messages logged using {@link ng.$log#info `info()`}. - * - * @example - * ```js - * $log.info('Some Info'); - * var first = $log.info.logs.unshift(); - * ``` - */ - $log.info.logs = []; - /** - * @ngdoc property - * @name $log#warn.logs - * - * @description - * Array of messages logged using {@link ng.$log#warn `warn()`}. - * - * @example - * ```js - * $log.warn('Some Warning'); - * var first = $log.warn.logs.unshift(); - * ``` - */ - $log.warn.logs = []; - /** - * @ngdoc property - * @name $log#error.logs - * - * @description - * Array of messages logged using {@link ng.$log#error `error()`}. - * - * @example - * ```js - * $log.error('Some Error'); - * var first = $log.error.logs.unshift(); - * ``` - */ - $log.error.logs = []; - /** - * @ngdoc property - * @name $log#debug.logs - * - * @description - * Array of messages logged using {@link ng.$log#debug `debug()`}. - * - * @example - * ```js - * $log.debug('Some Error'); - * var first = $log.debug.logs.unshift(); - * ``` - */ - $log.debug.logs = []; - }; - - /** - * @ngdoc method - * @name $log#assertEmpty - * - * @description - * Assert that all of the logging methods have no logged messages. If any messages are present, - * an exception is thrown. - */ - $log.assertEmpty = function() { - var errors = []; - angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) { - angular.forEach($log[logLevel].logs, function(log) { - angular.forEach(log, function(logItem) { - errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' + - (logItem.stack || '')); - }); - }); - }); - if (errors.length) { - errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or " + - "an expected log message was not checked and removed:"); - errors.push(''); - throw new Error(errors.join('\n---------\n')); - } - }; - - $log.reset(); - return $log; - }; -}; - - -/** - * @ngdoc service - * @name $interval - * - * @description - * Mock implementation of the $interval service. - * - * Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to - * move forward by `millis` milliseconds and trigger any functions scheduled to run in that - * time. - * - * @param {function()} fn A function that should be called repeatedly. - * @param {number} delay Number of milliseconds between each function call. - * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat - * indefinitely. - * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise - * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. - * @param {...*=} Pass additional parameters to the executed function. - * @returns {promise} A promise which will be notified on each iteration. - */ -angular.mock.$IntervalProvider = function() { - this.$get = ['$browser', '$rootScope', '$q', '$$q', - function($browser, $rootScope, $q, $$q) { - var repeatFns = [], - nextRepeatId = 0, - now = 0; - - var $interval = function(fn, delay, count, invokeApply) { - var hasParams = arguments.length > 4, - args = hasParams ? Array.prototype.slice.call(arguments, 4) : [], - iteration = 0, - skipApply = (angular.isDefined(invokeApply) && !invokeApply), - deferred = (skipApply ? $$q : $q).defer(), - promise = deferred.promise; - - count = (angular.isDefined(count)) ? count : 0; - promise.then(null, null, (!hasParams) ? fn : function() { - fn.apply(null, args); - }); - - promise.$$intervalId = nextRepeatId; - - function tick() { - deferred.notify(iteration++); - - if (count > 0 && iteration >= count) { - var fnIndex; - deferred.resolve(iteration); - - angular.forEach(repeatFns, function(fn, index) { - if (fn.id === promise.$$intervalId) fnIndex = index; - }); - - if (angular.isDefined(fnIndex)) { - repeatFns.splice(fnIndex, 1); - } - } - - if (skipApply) { - $browser.defer.flush(); - } else { - $rootScope.$apply(); - } - } - - repeatFns.push({ - nextTime:(now + delay), - delay: delay, - fn: tick, - id: nextRepeatId, - deferred: deferred - }); - repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;}); - - nextRepeatId++; - return promise; - }; - /** - * @ngdoc method - * @name $interval#cancel - * - * @description - * Cancels a task associated with the `promise`. - * - * @param {promise} promise A promise from calling the `$interval` function. - * @returns {boolean} Returns `true` if the task was successfully cancelled. - */ - $interval.cancel = function(promise) { - if (!promise) return false; - var fnIndex; - - angular.forEach(repeatFns, function(fn, index) { - if (fn.id === promise.$$intervalId) fnIndex = index; - }); - - if (angular.isDefined(fnIndex)) { - repeatFns[fnIndex].deferred.reject('canceled'); - repeatFns.splice(fnIndex, 1); - return true; - } - - return false; - }; - - /** - * @ngdoc method - * @name $interval#flush - * @description - * - * Runs interval tasks scheduled to be run in the next `millis` milliseconds. - * - * @param {number=} millis maximum timeout amount to flush up until. - * - * @return {number} The amount of time moved forward. - */ - $interval.flush = function(millis) { - now += millis; - while (repeatFns.length && repeatFns[0].nextTime <= now) { - var task = repeatFns[0]; - task.fn(); - task.nextTime += task.delay; - repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;}); - } - return millis; - }; - - return $interval; - }]; -}; - - -/* jshint -W101 */ -/* The R_ISO8061_STR regex is never going to fit into the 100 char limit! - * This directive should go inside the anonymous function but a bug in JSHint means that it would - * not be enacted early enough to prevent the warning. - */ -var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; - -function jsonStringToDate(string) { - var match; - if (match = string.match(R_ISO8061_STR)) { - var date = new Date(0), - tzHour = 0, - tzMin = 0; - if (match[9]) { - tzHour = toInt(match[9] + match[10]); - tzMin = toInt(match[9] + match[11]); - } - date.setUTCFullYear(toInt(match[1]), toInt(match[2]) - 1, toInt(match[3])); - date.setUTCHours(toInt(match[4] || 0) - tzHour, - toInt(match[5] || 0) - tzMin, - toInt(match[6] || 0), - toInt(match[7] || 0)); - return date; - } - return string; -} - -function toInt(str) { - return parseInt(str, 10); -} - -function padNumber(num, digits, trim) { - var neg = ''; - if (num < 0) { - neg = '-'; - num = -num; - } - num = '' + num; - while (num.length < digits) num = '0' + num; - if (trim) { - num = num.substr(num.length - digits); - } - return neg + num; -} - - -/** - * @ngdoc type - * @name angular.mock.TzDate - * @description - * - * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`. - * - * Mock of the Date type which has its timezone specified via constructor arg. - * - * The main purpose is to create Date-like instances with timezone fixed to the specified timezone - * offset, so that we can test code that depends on local timezone settings without dependency on - * the time zone settings of the machine where the code is running. - * - * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored) - * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC* - * - * @example - * !!!! WARNING !!!!! - * This is not a complete Date object so only methods that were implemented can be called safely. - * To make matters worse, TzDate instances inherit stuff from Date via a prototype. - * - * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is - * incomplete we might be missing some non-standard methods. This can result in errors like: - * "Date.prototype.foo called on incompatible Object". - * - * ```js - * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z'); - * newYearInBratislava.getTimezoneOffset() => -60; - * newYearInBratislava.getFullYear() => 2010; - * newYearInBratislava.getMonth() => 0; - * newYearInBratislava.getDate() => 1; - * newYearInBratislava.getHours() => 0; - * newYearInBratislava.getMinutes() => 0; - * newYearInBratislava.getSeconds() => 0; - * ``` - * - */ -angular.mock.TzDate = function(offset, timestamp) { - var self = new Date(0); - if (angular.isString(timestamp)) { - var tsStr = timestamp; - - self.origDate = jsonStringToDate(timestamp); - - timestamp = self.origDate.getTime(); - if (isNaN(timestamp)) { - throw { - name: "Illegal Argument", - message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string" - }; - } - } else { - self.origDate = new Date(timestamp); - } - - var localOffset = new Date(timestamp).getTimezoneOffset(); - self.offsetDiff = localOffset * 60 * 1000 - offset * 1000 * 60 * 60; - self.date = new Date(timestamp + self.offsetDiff); - - self.getTime = function() { - return self.date.getTime() - self.offsetDiff; - }; - - self.toLocaleDateString = function() { - return self.date.toLocaleDateString(); - }; - - self.getFullYear = function() { - return self.date.getFullYear(); - }; - - self.getMonth = function() { - return self.date.getMonth(); - }; - - self.getDate = function() { - return self.date.getDate(); - }; - - self.getHours = function() { - return self.date.getHours(); - }; - - self.getMinutes = function() { - return self.date.getMinutes(); - }; - - self.getSeconds = function() { - return self.date.getSeconds(); - }; - - self.getMilliseconds = function() { - return self.date.getMilliseconds(); - }; - - self.getTimezoneOffset = function() { - return offset * 60; - }; - - self.getUTCFullYear = function() { - return self.origDate.getUTCFullYear(); - }; - - self.getUTCMonth = function() { - return self.origDate.getUTCMonth(); - }; - - self.getUTCDate = function() { - return self.origDate.getUTCDate(); - }; - - self.getUTCHours = function() { - return self.origDate.getUTCHours(); - }; - - self.getUTCMinutes = function() { - return self.origDate.getUTCMinutes(); - }; - - self.getUTCSeconds = function() { - return self.origDate.getUTCSeconds(); - }; - - self.getUTCMilliseconds = function() { - return self.origDate.getUTCMilliseconds(); - }; - - self.getDay = function() { - return self.date.getDay(); - }; - - // provide this method only on browsers that already have it - if (self.toISOString) { - self.toISOString = function() { - return padNumber(self.origDate.getUTCFullYear(), 4) + '-' + - padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' + - padNumber(self.origDate.getUTCDate(), 2) + 'T' + - padNumber(self.origDate.getUTCHours(), 2) + ':' + - padNumber(self.origDate.getUTCMinutes(), 2) + ':' + - padNumber(self.origDate.getUTCSeconds(), 2) + '.' + - padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'; - }; - } - - //hide all methods not implemented in this mock that the Date prototype exposes - var unimplementedMethods = ['getUTCDay', - 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', - 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', - 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', - 'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString', - 'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf']; - - angular.forEach(unimplementedMethods, function(methodName) { - self[methodName] = function() { - throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock"); - }; - }); - - return self; -}; - -//make "tzDateInstance instanceof Date" return true -angular.mock.TzDate.prototype = Date.prototype; -/* jshint +W101 */ - - -/** - * @ngdoc service - * @name $animate - * - * @description - * Mock implementation of the {@link ng.$animate `$animate`} service. Exposes two additional methods - * for testing animations. - */ -angular.mock.animate = angular.module('ngAnimateMock', ['ng']) - - .config(['$provide', function($provide) { - - $provide.factory('$$forceReflow', function() { - function reflowFn() { - reflowFn.totalReflows++; - } - reflowFn.totalReflows = 0; - return reflowFn; - }); - - $provide.factory('$$animateAsyncRun', function() { - var queue = []; - var queueFn = function() { - return function(fn) { - queue.push(fn); - }; - }; - queueFn.flush = function() { - if (queue.length === 0) return false; - - for (var i = 0; i < queue.length; i++) { - queue[i](); - } - queue = []; - - return true; - }; - return queueFn; - }); - - $provide.decorator('$$animateJs', ['$delegate', function($delegate) { - var runners = []; - - var animateJsConstructor = function() { - var animator = $delegate.apply($delegate, arguments); - // If no javascript animation is found, animator is undefined - if (animator) { - runners.push(animator); - } - return animator; - }; - - animateJsConstructor.$closeAndFlush = function() { - runners.forEach(function(runner) { - runner.end(); - }); - runners = []; - }; - - return animateJsConstructor; - }]); - - $provide.decorator('$animateCss', ['$delegate', function($delegate) { - var runners = []; - - var animateCssConstructor = function(element, options) { - var animator = $delegate(element, options); - runners.push(animator); - return animator; - }; - - animateCssConstructor.$closeAndFlush = function() { - runners.forEach(function(runner) { - runner.end(); - }); - runners = []; - }; - - return animateCssConstructor; - }]); - - $provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF', '$animateCss', '$$animateJs', - '$$forceReflow', '$$animateAsyncRun', '$rootScope', - function($delegate, $timeout, $browser, $$rAF, $animateCss, $$animateJs, - $$forceReflow, $$animateAsyncRun, $rootScope) { - var animate = { - queue: [], - cancel: $delegate.cancel, - on: $delegate.on, - off: $delegate.off, - pin: $delegate.pin, - get reflows() { - return $$forceReflow.totalReflows; - }, - enabled: $delegate.enabled, - /** - * @ngdoc method - * @name $animate#closeAndFlush - * @description - * - * This method will close all pending animations (both {@link ngAnimate#javascript-based-animations Javascript} - * and {@link ngAnimate.$animateCss CSS}) and it will also flush any remaining animation frames and/or callbacks. - */ - closeAndFlush: function() { - // we allow the flush command to swallow the errors - // because depending on whether CSS or JS animations are - // used, there may not be a RAF flush. The primary flush - // at the end of this function must throw an exception - // because it will track if there were pending animations - this.flush(true); - $animateCss.$closeAndFlush(); - $$animateJs.$closeAndFlush(); - this.flush(); - }, - /** - * @ngdoc method - * @name $animate#flush - * @description - * - * This method is used to flush the pending callbacks and animation frames to either start - * an animation or conclude an animation. Note that this will not actually close an - * actively running animation (see {@link ngMock.$animate#closeAndFlush `closeAndFlush()`} for that). - */ - flush: function(hideErrors) { - $rootScope.$digest(); - - var doNextRun, somethingFlushed = false; - do { - doNextRun = false; - - if ($$rAF.queue.length) { - $$rAF.flush(); - doNextRun = somethingFlushed = true; - } - - if ($$animateAsyncRun.flush()) { - doNextRun = somethingFlushed = true; - } - } while (doNextRun); - - if (!somethingFlushed && !hideErrors) { - throw new Error('No pending animations ready to be closed or flushed'); - } - - $rootScope.$digest(); - } - }; - - angular.forEach( - ['animate','enter','leave','move','addClass','removeClass','setClass'], function(method) { - animate[method] = function() { - animate.queue.push({ - event: method, - element: arguments[0], - options: arguments[arguments.length - 1], - args: arguments - }); - return $delegate[method].apply($delegate, arguments); - }; - }); - - return animate; - }]); - - }]); - - -/** - * @ngdoc function - * @name angular.mock.dump - * @description - * - * *NOTE*: this is not an injectable instance, just a globally available function. - * - * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for - * debugging. - * - * This method is also available on window, where it can be used to display objects on debug - * console. - * - * @param {*} object - any object to turn into string. - * @return {string} a serialized string of the argument - */ -angular.mock.dump = function(object) { - return serialize(object); - - function serialize(object) { - var out; - - if (angular.isElement(object)) { - object = angular.element(object); - out = angular.element('
        '); - angular.forEach(object, function(element) { - out.append(angular.element(element).clone()); - }); - out = out.html(); - } else if (angular.isArray(object)) { - out = []; - angular.forEach(object, function(o) { - out.push(serialize(o)); - }); - out = '[ ' + out.join(', ') + ' ]'; - } else if (angular.isObject(object)) { - if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) { - out = serializeScope(object); - } else if (object instanceof Error) { - out = object.stack || ('' + object.name + ': ' + object.message); - } else { - // TODO(i): this prevents methods being logged, - // we should have a better way to serialize objects - out = angular.toJson(object, true); - } - } else { - out = String(object); - } - - return out; - } - - function serializeScope(scope, offset) { - offset = offset || ' '; - var log = [offset + 'Scope(' + scope.$id + '): {']; - for (var key in scope) { - if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) { - log.push(' ' + key + ': ' + angular.toJson(scope[key])); - } - } - var child = scope.$$childHead; - while (child) { - log.push(serializeScope(child, offset + ' ')); - child = child.$$nextSibling; - } - log.push('}'); - return log.join('\n' + offset); - } -}; - -/** - * @ngdoc service - * @name $httpBackend - * @description - * Fake HTTP backend implementation suitable for unit testing applications that use the - * {@link ng.$http $http service}. - * - * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less - * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}. - * - * During unit testing, we want our unit tests to run quickly and have no external dependencies so - * we don’t want to send [XHR](https://developer.mozilla.org/en/xmlhttprequest) or - * [JSONP](http://en.wikipedia.org/wiki/JSONP) requests to a real server. All we really need is - * to verify whether a certain request has been sent or not, or alternatively just let the - * application make requests, respond with pre-trained responses and assert that the end result is - * what we expect it to be. - * - * This mock implementation can be used to respond with static or dynamic responses via the - * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc). - * - * When an Angular application needs some data from a server, it calls the $http service, which - * sends the request to a real server using $httpBackend service. With dependency injection, it is - * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify - * the requests and respond with some testing data without sending a request to a real server. - * - * There are two ways to specify what test data should be returned as http responses by the mock - * backend when the code under test makes http requests: - * - * - `$httpBackend.expect` - specifies a request expectation - * - `$httpBackend.when` - specifies a backend definition - * - * - * ## Request Expectations vs Backend Definitions - * - * Request expectations provide a way to make assertions about requests made by the application and - * to define responses for those requests. The test will fail if the expected requests are not made - * or they are made in the wrong order. - * - * Backend definitions allow you to define a fake backend for your application which doesn't assert - * if a particular request was made or not, it just returns a trained response if a request is made. - * The test will pass whether or not the request gets made during testing. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
        Request expectationsBackend definitions
        Syntax.expect(...).respond(...).when(...).respond(...)
        Typical usagestrict unit testsloose (black-box) unit testing
        Fulfills multiple requestsNOYES
        Order of requests mattersYESNO
        Request requiredYESNO
        Response requiredoptional (see below)YES
        - * - * In cases where both backend definitions and request expectations are specified during unit - * testing, the request expectations are evaluated first. - * - * If a request expectation has no response specified, the algorithm will search your backend - * definitions for an appropriate response. - * - * If a request didn't match any expectation or if the expectation doesn't have the response - * defined, the backend definitions are evaluated in sequential order to see if any of them match - * the request. The response from the first matched definition is returned. - * - * - * ## Flushing HTTP requests - * - * The $httpBackend used in production always responds to requests asynchronously. If we preserved - * this behavior in unit testing, we'd have to create async unit tests, which are hard to write, - * to follow and to maintain. But neither can the testing mock respond synchronously; that would - * change the execution of the code under test. For this reason, the mock $httpBackend has a - * `flush()` method, which allows the test to explicitly flush pending requests. This preserves - * the async api of the backend, while allowing the test to execute synchronously. - * - * - * ## Unit testing with mock $httpBackend - * The following code shows how to setup and use the mock backend when unit testing a controller. - * First we create the controller under test: - * - ```js - // The module code - angular - .module('MyApp', []) - .controller('MyController', MyController); - - // The controller code - function MyController($scope, $http) { - var authToken; - - $http.get('/auth.py').then(function(response) { - authToken = response.headers('A-Token'); - $scope.user = response.data; - }); - - $scope.saveMessage = function(message) { - var headers = { 'Authorization': authToken }; - $scope.status = 'Saving...'; - - $http.post('/add-msg.py', message, { headers: headers } ).then(function(response) { - $scope.status = ''; - }).catch(function() { - $scope.status = 'Failed...'; - }); - }; - } - ``` - * - * Now we setup the mock backend and create the test specs: - * - ```js - // testing controller - describe('MyController', function() { - var $httpBackend, $rootScope, createController, authRequestHandler; - - // Set up the module - beforeEach(module('MyApp')); - - beforeEach(inject(function($injector) { - // Set up the mock http service responses - $httpBackend = $injector.get('$httpBackend'); - // backend definition common for all tests - authRequestHandler = $httpBackend.when('GET', '/auth.py') - .respond({userId: 'userX'}, {'A-Token': 'xxx'}); - - // Get hold of a scope (i.e. the root scope) - $rootScope = $injector.get('$rootScope'); - // The $controller service is used to create instances of controllers - var $controller = $injector.get('$controller'); - - createController = function() { - return $controller('MyController', {'$scope' : $rootScope }); - }; - })); - - - afterEach(function() { - $httpBackend.verifyNoOutstandingExpectation(); - $httpBackend.verifyNoOutstandingRequest(); - }); - - - it('should fetch authentication token', function() { - $httpBackend.expectGET('/auth.py'); - var controller = createController(); - $httpBackend.flush(); - }); - - - it('should fail authentication', function() { - - // Notice how you can change the response even after it was set - authRequestHandler.respond(401, ''); - - $httpBackend.expectGET('/auth.py'); - var controller = createController(); - $httpBackend.flush(); - expect($rootScope.status).toBe('Failed...'); - }); - - - it('should send msg to server', function() { - var controller = createController(); - $httpBackend.flush(); - - // now you don’t care about the authentication, but - // the controller will still send the request and - // $httpBackend will respond without you having to - // specify the expectation and response for this request - - $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, ''); - $rootScope.saveMessage('message content'); - expect($rootScope.status).toBe('Saving...'); - $httpBackend.flush(); - expect($rootScope.status).toBe(''); - }); - - - it('should send auth header', function() { - var controller = createController(); - $httpBackend.flush(); - - $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) { - // check if the header was sent, if it wasn't the expectation won't - // match the request and the test will fail - return headers['Authorization'] == 'xxx'; - }).respond(201, ''); - - $rootScope.saveMessage('whatever'); - $httpBackend.flush(); - }); - }); - ``` - * - * ## Dynamic responses - * - * You define a response to a request by chaining a call to `respond()` onto a definition or expectation. - * If you provide a **callback** as the first parameter to `respond(callback)` then you can dynamically generate - * a response based on the properties of the request. - * - * The `callback` function should be of the form `function(method, url, data, headers, params)`. - * - * ### Query parameters - * - * By default, query parameters on request URLs are parsed into the `params` object. So a request URL - * of `/list?q=searchstr&orderby=-name` would set `params` to be `{q: 'searchstr', orderby: '-name'}`. - * - * ### Regex parameter matching - * - * If an expectation or definition uses a **regex** to match the URL, you can provide an array of **keys** via a - * `params` argument. The index of each **key** in the array will match the index of a **group** in the - * **regex**. - * - * The `params` object in the **callback** will now have properties with these keys, which hold the value of the - * corresponding **group** in the **regex**. - * - * This also applies to the `when` and `expect` shortcut methods. - * - * - * ```js - * $httpBackend.expect('GET', /\/user\/(.+)/, undefined, undefined, ['id']) - * .respond(function(method, url, data, headers, params) { - * // for requested url of '/user/1234' params is {id: '1234'} - * }); - * - * $httpBackend.whenPATCH(/\/user\/(.+)\/article\/(.+)/, undefined, undefined, ['user', 'article']) - * .respond(function(method, url, data, headers, params) { - * // for url of '/user/1234/article/567' params is {user: '1234', article: '567'} - * }); - * ``` - * - * ## Matching route requests - * - * For extra convenience, `whenRoute` and `expectRoute` shortcuts are available. These methods offer colon - * delimited matching of the url path, ignoring the query string. This allows declarations - * similar to how application routes are configured with `$routeProvider`. Because these methods convert - * the definition url to regex, declaration order is important. Combined with query parameter parsing, - * the following is possible: - * - ```js - $httpBackend.whenRoute('GET', '/users/:id') - .respond(function(method, url, data, headers, params) { - return [200, MockUserList[Number(params.id)]]; - }); - - $httpBackend.whenRoute('GET', '/users') - .respond(function(method, url, data, headers, params) { - var userList = angular.copy(MockUserList), - defaultSort = 'lastName', - count, pages, isPrevious, isNext; - - // paged api response '/v1/users?page=2' - params.page = Number(params.page) || 1; - - // query for last names '/v1/users?q=Archer' - if (params.q) { - userList = $filter('filter')({lastName: params.q}); - } - - pages = Math.ceil(userList.length / pagingLength); - isPrevious = params.page > 1; - isNext = params.page < pages; - - return [200, { - count: userList.length, - previous: isPrevious, - next: isNext, - // sort field -> '/v1/users?sortBy=firstName' - results: $filter('orderBy')(userList, params.sortBy || defaultSort) - .splice((params.page - 1) * pagingLength, pagingLength) - }]; - }); - ``` - */ -angular.mock.$HttpBackendProvider = function() { - this.$get = ['$rootScope', '$timeout', createHttpBackendMock]; -}; - -/** - * General factory function for $httpBackend mock. - * Returns instance for unit testing (when no arguments specified): - * - passing through is disabled - * - auto flushing is disabled - * - * Returns instance for e2e testing (when `$delegate` and `$browser` specified): - * - passing through (delegating request to real backend) is enabled - * - auto flushing is enabled - * - * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified) - * @param {Object=} $browser Auto-flushing enabled if specified - * @return {Object} Instance of $httpBackend mock - */ -function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { - var definitions = [], - expectations = [], - responses = [], - responsesPush = angular.bind(responses, responses.push), - copy = angular.copy; - - function createResponse(status, data, headers, statusText) { - if (angular.isFunction(status)) return status; - - return function() { - return angular.isNumber(status) - ? [status, data, headers, statusText] - : [200, status, data, headers]; - }; - } - - // TODO(vojta): change params to: method, url, data, headers, callback - function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) { - var xhr = new MockXhr(), - expectation = expectations[0], - wasExpected = false; - - function prettyPrint(data) { - return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp) - ? data - : angular.toJson(data); - } - - function wrapResponse(wrapped) { - if (!$browser && timeout) { - timeout.then ? timeout.then(handleTimeout) : $timeout(handleTimeout, timeout); - } - - return handleResponse; - - function handleResponse() { - var response = wrapped.response(method, url, data, headers, wrapped.params(url)); - xhr.$$respHeaders = response[2]; - callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(), - copy(response[3] || '')); - } - - function handleTimeout() { - for (var i = 0, ii = responses.length; i < ii; i++) { - if (responses[i] === handleResponse) { - responses.splice(i, 1); - callback(-1, undefined, ''); - break; - } - } - } - } - - if (expectation && expectation.match(method, url)) { - if (!expectation.matchData(data)) { - throw new Error('Expected ' + expectation + ' with different data\n' + - 'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data); - } - - if (!expectation.matchHeaders(headers)) { - throw new Error('Expected ' + expectation + ' with different headers\n' + - 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' + - prettyPrint(headers)); - } - - expectations.shift(); - - if (expectation.response) { - responses.push(wrapResponse(expectation)); - return; - } - wasExpected = true; - } - - var i = -1, definition; - while ((definition = definitions[++i])) { - if (definition.match(method, url, data, headers || {})) { - if (definition.response) { - // if $browser specified, we do auto flush all requests - ($browser ? $browser.defer : responsesPush)(wrapResponse(definition)); - } else if (definition.passThrough) { - $delegate(method, url, data, callback, headers, timeout, withCredentials); - } else throw new Error('No response defined !'); - return; - } - } - throw wasExpected ? - new Error('No response defined !') : - new Error('Unexpected request: ' + method + ' ' + url + '\n' + - (expectation ? 'Expected ' + expectation : 'No more request expected')); - } - - /** - * @ngdoc method - * @name $httpBackend#when - * @description - * Creates a new backend definition. - * - * @param {string} method HTTP method. - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives - * data string and returns true if the data is as expected. - * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header - * object and returns true if the headers match the current definition. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - * - * - respond – - * `{function([status,] data[, headers, statusText]) - * | function(function(method, url, data, headers, params)}` - * – The respond method takes a set of static data to be returned or a function that can - * return an array containing response status (number), response data (string), response - * headers (Object), and the text for the status (string). The respond method returns the - * `requestHandler` object for possible overrides. - */ - $httpBackend.when = function(method, url, data, headers, keys) { - var definition = new MockHttpExpectation(method, url, data, headers, keys), - chain = { - respond: function(status, data, headers, statusText) { - definition.passThrough = undefined; - definition.response = createResponse(status, data, headers, statusText); - return chain; - } - }; - - if ($browser) { - chain.passThrough = function() { - definition.response = undefined; - definition.passThrough = true; - return chain; - }; - } - - definitions.push(definition); - return chain; - }; - - /** - * @ngdoc method - * @name $httpBackend#whenGET - * @description - * Creates a new backend definition for GET requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenHEAD - * @description - * Creates a new backend definition for HEAD requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenDELETE - * @description - * Creates a new backend definition for DELETE requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenPOST - * @description - * Creates a new backend definition for POST requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives - * data string and returns true if the data is as expected. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenPUT - * @description - * Creates a new backend definition for PUT requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives - * data string and returns true if the data is as expected. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenJSONP - * @description - * Creates a new backend definition for JSONP requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - createShortMethods('when'); - - /** - * @ngdoc method - * @name $httpBackend#whenRoute - * @description - * Creates a new backend definition that compares only with the requested route. - * - * @param {string} method HTTP method. - * @param {string} url HTTP url string that supports colon param matching. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. See #when for more info. - */ - $httpBackend.whenRoute = function(method, url) { - var pathObj = parseRoute(url); - return $httpBackend.when(method, pathObj.regexp, undefined, undefined, pathObj.keys); - }; - - function parseRoute(url) { - var ret = { - regexp: url - }, - keys = ret.keys = []; - - if (!url || !angular.isString(url)) return ret; - - url = url - .replace(/([().])/g, '\\$1') - .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) { - var optional = option === '?' ? option : null; - var star = option === '*' ? option : null; - keys.push({ name: key, optional: !!optional }); - slash = slash || ''; - return '' - + (optional ? '' : slash) - + '(?:' - + (optional ? slash : '') - + (star && '(.+?)' || '([^/]+)') - + (optional || '') - + ')' - + (optional || ''); - }) - .replace(/([\/$\*])/g, '\\$1'); - - ret.regexp = new RegExp('^' + url, 'i'); - return ret; - } - - /** - * @ngdoc method - * @name $httpBackend#expect - * @description - * Creates a new request expectation. - * - * @param {string} method HTTP method. - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header - * object and returns true if the headers match the current expectation. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - * - * - respond – - * `{function([status,] data[, headers, statusText]) - * | function(function(method, url, data, headers, params)}` - * – The respond method takes a set of static data to be returned or a function that can - * return an array containing response status (number), response data (string), response - * headers (Object), and the text for the status (string). The respond method returns the - * `requestHandler` object for possible overrides. - */ - $httpBackend.expect = function(method, url, data, headers, keys) { - var expectation = new MockHttpExpectation(method, url, data, headers, keys), - chain = { - respond: function(status, data, headers, statusText) { - expectation.response = createResponse(status, data, headers, statusText); - return chain; - } - }; - - expectations.push(expectation); - return chain; - }; - - /** - * @ngdoc method - * @name $httpBackend#expectGET - * @description - * Creates a new request expectation for GET requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {Object=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. See #expect for more info. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectHEAD - * @description - * Creates a new request expectation for HEAD requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {Object=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectDELETE - * @description - * Creates a new request expectation for DELETE requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {Object=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectPOST - * @description - * Creates a new request expectation for POST requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {Object=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectPUT - * @description - * Creates a new request expectation for PUT requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {Object=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectPATCH - * @description - * Creates a new request expectation for PATCH requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {Object=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectJSONP - * @description - * Creates a new request expectation for JSONP requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives an url - * and returns true if the url matches the current definition. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - createShortMethods('expect'); - - /** - * @ngdoc method - * @name $httpBackend#expectRoute - * @description - * Creates a new request expectation that compares only with the requested route. - * - * @param {string} method HTTP method. - * @param {string} url HTTP url string that supports colon param matching. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. See #expect for more info. - */ - $httpBackend.expectRoute = function(method, url) { - var pathObj = parseRoute(url); - return $httpBackend.expect(method, pathObj.regexp, undefined, undefined, pathObj.keys); - }; - - - /** - * @ngdoc method - * @name $httpBackend#flush - * @description - * Flushes all pending requests using the trained responses. - * - * @param {number=} count Number of responses to flush (in the order they arrived). If undefined, - * all pending requests will be flushed. If there are no pending requests when the flush method - * is called an exception is thrown (as this typically a sign of programming error). - */ - $httpBackend.flush = function(count, digest) { - if (digest !== false) $rootScope.$digest(); - if (!responses.length) throw new Error('No pending request to flush !'); - - if (angular.isDefined(count) && count !== null) { - while (count--) { - if (!responses.length) throw new Error('No more pending request to flush !'); - responses.shift()(); - } - } else { - while (responses.length) { - responses.shift()(); - } - } - $httpBackend.verifyNoOutstandingExpectation(digest); - }; - - - /** - * @ngdoc method - * @name $httpBackend#verifyNoOutstandingExpectation - * @description - * Verifies that all of the requests defined via the `expect` api were made. If any of the - * requests were not made, verifyNoOutstandingExpectation throws an exception. - * - * Typically, you would call this method following each test case that asserts requests using an - * "afterEach" clause. - * - * ```js - * afterEach($httpBackend.verifyNoOutstandingExpectation); - * ``` - */ - $httpBackend.verifyNoOutstandingExpectation = function(digest) { - if (digest !== false) $rootScope.$digest(); - if (expectations.length) { - throw new Error('Unsatisfied requests: ' + expectations.join(', ')); - } - }; - - - /** - * @ngdoc method - * @name $httpBackend#verifyNoOutstandingRequest - * @description - * Verifies that there are no outstanding requests that need to be flushed. - * - * Typically, you would call this method following each test case that asserts requests using an - * "afterEach" clause. - * - * ```js - * afterEach($httpBackend.verifyNoOutstandingRequest); - * ``` - */ - $httpBackend.verifyNoOutstandingRequest = function() { - if (responses.length) { - throw new Error('Unflushed requests: ' + responses.length); - } - }; - - - /** - * @ngdoc method - * @name $httpBackend#resetExpectations - * @description - * Resets all request expectations, but preserves all backend definitions. Typically, you would - * call resetExpectations during a multiple-phase test when you want to reuse the same instance of - * $httpBackend mock. - */ - $httpBackend.resetExpectations = function() { - expectations.length = 0; - responses.length = 0; - }; - - return $httpBackend; - - - function createShortMethods(prefix) { - angular.forEach(['GET', 'DELETE', 'JSONP', 'HEAD'], function(method) { - $httpBackend[prefix + method] = function(url, headers, keys) { - return $httpBackend[prefix](method, url, undefined, headers, keys); - }; - }); - - angular.forEach(['PUT', 'POST', 'PATCH'], function(method) { - $httpBackend[prefix + method] = function(url, data, headers, keys) { - return $httpBackend[prefix](method, url, data, headers, keys); - }; - }); - } -} - -function MockHttpExpectation(method, url, data, headers, keys) { - - this.data = data; - this.headers = headers; - - this.match = function(m, u, d, h) { - if (method != m) return false; - if (!this.matchUrl(u)) return false; - if (angular.isDefined(d) && !this.matchData(d)) return false; - if (angular.isDefined(h) && !this.matchHeaders(h)) return false; - return true; - }; - - this.matchUrl = function(u) { - if (!url) return true; - if (angular.isFunction(url.test)) return url.test(u); - if (angular.isFunction(url)) return url(u); - return url == u; - }; - - this.matchHeaders = function(h) { - if (angular.isUndefined(headers)) return true; - if (angular.isFunction(headers)) return headers(h); - return angular.equals(headers, h); - }; - - this.matchData = function(d) { - if (angular.isUndefined(data)) return true; - if (data && angular.isFunction(data.test)) return data.test(d); - if (data && angular.isFunction(data)) return data(d); - if (data && !angular.isString(data)) { - return angular.equals(angular.fromJson(angular.toJson(data)), angular.fromJson(d)); - } - return data == d; - }; - - this.toString = function() { - return method + ' ' + url; - }; - - this.params = function(u) { - return angular.extend(parseQuery(), pathParams()); - - function pathParams() { - var keyObj = {}; - if (!url || !angular.isFunction(url.test) || !keys || keys.length === 0) return keyObj; - - var m = url.exec(u); - if (!m) return keyObj; - for (var i = 1, len = m.length; i < len; ++i) { - var key = keys[i - 1]; - var val = m[i]; - if (key && val) { - keyObj[key.name || key] = val; - } - } - - return keyObj; - } - - function parseQuery() { - var obj = {}, key_value, key, - queryStr = u.indexOf('?') > -1 - ? u.substring(u.indexOf('?') + 1) - : ""; - - angular.forEach(queryStr.split('&'), function(keyValue) { - if (keyValue) { - key_value = keyValue.replace(/\+/g,'%20').split('='); - key = tryDecodeURIComponent(key_value[0]); - if (angular.isDefined(key)) { - var val = angular.isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true; - if (!hasOwnProperty.call(obj, key)) { - obj[key] = val; - } else if (angular.isArray(obj[key])) { - obj[key].push(val); - } else { - obj[key] = [obj[key],val]; - } - } - } - }); - return obj; - } - function tryDecodeURIComponent(value) { - try { - return decodeURIComponent(value); - } catch (e) { - // Ignore any invalid uri component - } - } - }; -} - -function createMockXhr() { - return new MockXhr(); -} - -function MockXhr() { - - // hack for testing $http, $httpBackend - MockXhr.$$lastInstance = this; - - this.open = function(method, url, async) { - this.$$method = method; - this.$$url = url; - this.$$async = async; - this.$$reqHeaders = {}; - this.$$respHeaders = {}; - }; - - this.send = function(data) { - this.$$data = data; - }; - - this.setRequestHeader = function(key, value) { - this.$$reqHeaders[key] = value; - }; - - this.getResponseHeader = function(name) { - // the lookup must be case insensitive, - // that's why we try two quick lookups first and full scan last - var header = this.$$respHeaders[name]; - if (header) return header; - - name = angular.lowercase(name); - header = this.$$respHeaders[name]; - if (header) return header; - - header = undefined; - angular.forEach(this.$$respHeaders, function(headerVal, headerName) { - if (!header && angular.lowercase(headerName) == name) header = headerVal; - }); - return header; - }; - - this.getAllResponseHeaders = function() { - var lines = []; - - angular.forEach(this.$$respHeaders, function(value, key) { - lines.push(key + ': ' + value); - }); - return lines.join('\n'); - }; - - this.abort = angular.noop; -} - - -/** - * @ngdoc service - * @name $timeout - * @description - * - * This service is just a simple decorator for {@link ng.$timeout $timeout} service - * that adds a "flush" and "verifyNoPendingTasks" methods. - */ - -angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $browser) { - - /** - * @ngdoc method - * @name $timeout#flush - * @description - * - * Flushes the queue of pending tasks. - * - * @param {number=} delay maximum timeout amount to flush up until - */ - $delegate.flush = function(delay) { - $browser.defer.flush(delay); - }; - - /** - * @ngdoc method - * @name $timeout#verifyNoPendingTasks - * @description - * - * Verifies that there are no pending tasks that need to be flushed. - */ - $delegate.verifyNoPendingTasks = function() { - if ($browser.deferredFns.length) { - throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' + - formatPendingTasksAsString($browser.deferredFns)); - } - }; - - function formatPendingTasksAsString(tasks) { - var result = []; - angular.forEach(tasks, function(task) { - result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}'); - }); - - return result.join(', '); - } - - return $delegate; -}]; - -angular.mock.$RAFDecorator = ['$delegate', function($delegate) { - var rafFn = function(fn) { - var index = rafFn.queue.length; - rafFn.queue.push(fn); - return function() { - rafFn.queue.splice(index, 1); - }; - }; - - rafFn.queue = []; - rafFn.supported = $delegate.supported; - - rafFn.flush = function() { - if (rafFn.queue.length === 0) { - throw new Error('No rAF callbacks present'); - } - - var length = rafFn.queue.length; - for (var i = 0; i < length; i++) { - rafFn.queue[i](); - } - - rafFn.queue = rafFn.queue.slice(i); - }; - - return rafFn; -}]; - -/** - * - */ -angular.mock.$RootElementProvider = function() { - this.$get = function() { - return angular.element('
        '); - }; -}; - -/** - * @ngdoc service - * @name $controller - * @description - * A decorator for {@link ng.$controller} with additional `bindings` parameter, useful when testing - * controllers of directives that use {@link $compile#-bindtocontroller- `bindToController`}. - * - * - * ## Example - * - * ```js - * - * // Directive definition ... - * - * myMod.directive('myDirective', { - * controller: 'MyDirectiveController', - * bindToController: { - * name: '@' - * } - * }); - * - * - * // Controller definition ... - * - * myMod.controller('MyDirectiveController', ['$log', function($log) { - * $log.info(this.name); - * })]; - * - * - * // In a test ... - * - * describe('myDirectiveController', function() { - * it('should write the bound name to the log', inject(function($controller, $log) { - * var ctrl = $controller('MyDirectiveController', { /* no locals */ }, { name: 'Clark Kent' }); - * expect(ctrl.name).toEqual('Clark Kent'); - * expect($log.info.logs).toEqual(['Clark Kent']); - * }); - * }); - * - * ``` - * - * @param {Function|string} constructor If called with a function then it's considered to be the - * controller constructor function. Otherwise it's considered to be a string which is used - * to retrieve the controller constructor using the following steps: - * - * * check if a controller with given name is registered via `$controllerProvider` - * * check if evaluating the string on the current scope returns a constructor - * * if $controllerProvider#allowGlobals, check `window[constructor]` on the global - * `window` object (not recommended) - * - * The string can use the `controller as property` syntax, where the controller instance is published - * as the specified property on the `scope`; the `scope` must be injected into `locals` param for this - * to work correctly. - * - * @param {Object} locals Injection locals for Controller. - * @param {Object=} bindings Properties to add to the controller before invoking the constructor. This is used - * to simulate the `bindToController` feature and simplify certain kinds of tests. - * @return {Object} Instance of given controller. - */ -angular.mock.$ControllerDecorator = ['$delegate', function($delegate) { - return function(expression, locals, later, ident) { - if (later && typeof later === 'object') { - var create = $delegate(expression, locals, true, ident); - angular.extend(create.instance, later); - return create(); - } - return $delegate(expression, locals, later, ident); - }; -}]; - -/** - * @ngdoc service - * @name $componentController - * @description - * A service that can be used to create instances of component controllers. - *
        - * Be aware that the controller will be instantiated and attached to the scope as specified in - * the component definition object. That means that you must always provide a `$scope` object - * in the `locals` param. - *
        - * @param {string} componentName the name of the component whose controller we want to instantiate - * @param {Object} locals Injection locals for Controller. - * @param {Object=} bindings Properties to add to the controller before invoking the constructor. This is used - * to simulate the `bindToController` feature and simplify certain kinds of tests. - * @param {string=} ident Override the property name to use when attaching the controller to the scope. - * @return {Object} Instance of requested controller. - */ -angular.mock.$ComponentControllerProvider = ['$compileProvider', function($compileProvider) { - return { - $get: ['$controller','$injector', function($controller,$injector) { - return function $componentController(componentName, locals, bindings, ident) { - // get all directives associated to the component name - var directives = $injector.get(componentName + 'Directive'); - // look for those directives that are components - var candidateDirectives = directives.filter(function(directiveInfo) { - // components have controller, controllerAs and restrict:'E' - return directiveInfo.controller && directiveInfo.controllerAs && directiveInfo.restrict === 'E'; - }); - // check if valid directives found - if (candidateDirectives.length === 0) { - throw new Error('No component found'); - } - if (candidateDirectives.length > 1) { - throw new Error('Too many components found'); - } - // get the info of the component - var directiveInfo = candidateDirectives[0]; - return $controller(directiveInfo.controller, locals, bindings, ident || directiveInfo.controllerAs); - }; - }] - }; -}]; - - -/** - * @ngdoc module - * @name ngMock - * @packageName angular-mocks - * @description - * - * # ngMock - * - * The `ngMock` module provides support to inject and mock Angular services into unit tests. - * In addition, ngMock also extends various core ng services such that they can be - * inspected and controlled in a synchronous manner within test code. - * - * - *
        - * - */ -angular.module('ngMock', ['ng']).provider({ - $browser: angular.mock.$BrowserProvider, - $exceptionHandler: angular.mock.$ExceptionHandlerProvider, - $log: angular.mock.$LogProvider, - $interval: angular.mock.$IntervalProvider, - $httpBackend: angular.mock.$HttpBackendProvider, - $rootElement: angular.mock.$RootElementProvider, - $componentController: angular.mock.$ComponentControllerProvider -}).config(['$provide', function($provide) { - $provide.decorator('$timeout', angular.mock.$TimeoutDecorator); - $provide.decorator('$$rAF', angular.mock.$RAFDecorator); - $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator); - $provide.decorator('$controller', angular.mock.$ControllerDecorator); -}]); - -/** - * @ngdoc module - * @name ngMockE2E - * @module ngMockE2E - * @packageName angular-mocks - * @description - * - * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing. - * Currently there is only one mock present in this module - - * the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock. - */ -angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { - $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator); -}]); - -/** - * @ngdoc service - * @name $httpBackend - * @module ngMockE2E - * @description - * Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of - * applications that use the {@link ng.$http $http service}. - * - * *Note*: For fake http backend implementation suitable for unit testing please see - * {@link ngMock.$httpBackend unit-testing $httpBackend mock}. - * - * This implementation can be used to respond with static or dynamic responses via the `when` api - * and its shortcuts (`whenGET`, `whenPOST`, etc) and optionally pass through requests to the - * real $httpBackend for specific requests (e.g. to interact with certain remote apis or to fetch - * templates from a webserver). - * - * As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application - * is being developed with the real backend api replaced with a mock, it is often desirable for - * certain category of requests to bypass the mock and issue a real http request (e.g. to fetch - * templates or static files from the webserver). To configure the backend with this behavior - * use the `passThrough` request handler of `when` instead of `respond`. - * - * Additionally, we don't want to manually have to flush mocked out requests like we do during unit - * testing. For this reason the e2e $httpBackend flushes mocked out requests - * automatically, closely simulating the behavior of the XMLHttpRequest object. - * - * To setup the application to run with this http backend, you have to create a module that depends - * on the `ngMockE2E` and your application modules and defines the fake backend: - * - * ```js - * myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']); - * myAppDev.run(function($httpBackend) { - * phones = [{name: 'phone1'}, {name: 'phone2'}]; - * - * // returns the current list of phones - * $httpBackend.whenGET('/phones').respond(phones); - * - * // adds a new phone to the phones array - * $httpBackend.whenPOST('/phones').respond(function(method, url, data) { - * var phone = angular.fromJson(data); - * phones.push(phone); - * return [200, phone, {}]; - * }); - * $httpBackend.whenGET(/^\/templates\//).passThrough(); - * //... - * }); - * ``` - * - * Afterwards, bootstrap your app with this new module. - */ - -/** - * @ngdoc method - * @name $httpBackend#when - * @module ngMockE2E - * @description - * Creates a new backend definition. - * - * @param {string} method HTTP method. - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header - * object and returns true if the headers match the current definition. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described on - * {@link ngMock.$httpBackend $httpBackend mock}. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - * - * - respond – - * `{function([status,] data[, headers, statusText]) - * | function(function(method, url, data, headers, params)}` - * – The respond method takes a set of static data to be returned or a function that can return - * an array containing response status (number), response data (string), response headers - * (Object), and the text for the status (string). - * - passThrough – `{function()}` – Any request matching a backend definition with - * `passThrough` handler will be passed through to the real backend (an XHR request will be made - * to the server.) - * - Both methods return the `requestHandler` object for possible overrides. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenGET - * @module ngMockE2E - * @description - * Creates a new backend definition for GET requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described on - * {@link ngMock.$httpBackend $httpBackend mock}. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenHEAD - * @module ngMockE2E - * @description - * Creates a new backend definition for HEAD requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described on - * {@link ngMock.$httpBackend $httpBackend mock}. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenDELETE - * @module ngMockE2E - * @description - * Creates a new backend definition for DELETE requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described on - * {@link ngMock.$httpBackend $httpBackend mock}. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenPOST - * @module ngMockE2E - * @description - * Creates a new backend definition for POST requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described on - * {@link ngMock.$httpBackend $httpBackend mock}. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenPUT - * @module ngMockE2E - * @description - * Creates a new backend definition for PUT requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described on - * {@link ngMock.$httpBackend $httpBackend mock}. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenPATCH - * @module ngMockE2E - * @description - * Creates a new backend definition for PATCH requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described on - * {@link ngMock.$httpBackend $httpBackend mock}. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenJSONP - * @module ngMockE2E - * @description - * Creates a new backend definition for JSONP requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives a url - * and returns true if the url matches the current definition. - * @param {(Array)=} keys Array of keys to assign to regex matches in request url described on - * {@link ngMock.$httpBackend $httpBackend mock}. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ -/** - * @ngdoc method - * @name $httpBackend#whenRoute - * @module ngMockE2E - * @description - * Creates a new backend definition that compares only with the requested route. - * - * @param {string} method HTTP method. - * @param {string} url HTTP url string that supports colon param matching. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ -angular.mock.e2e = {}; -angular.mock.e2e.$httpBackendDecorator = - ['$rootScope', '$timeout', '$delegate', '$browser', createHttpBackendMock]; - - -/** - * @ngdoc type - * @name $rootScope.Scope - * @module ngMock - * @description - * {@link ng.$rootScope.Scope Scope} type decorated with helper methods useful for testing. These - * methods are automatically available on any {@link ng.$rootScope.Scope Scope} instance when - * `ngMock` module is loaded. - * - * In addition to all the regular `Scope` methods, the following helper methods are available: - */ -angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) { - - var $rootScopePrototype = Object.getPrototypeOf($delegate); - - $rootScopePrototype.$countChildScopes = countChildScopes; - $rootScopePrototype.$countWatchers = countWatchers; - - return $delegate; - - // ------------------------------------------------------------------------------------------ // - - /** - * @ngdoc method - * @name $rootScope.Scope#$countChildScopes - * @module ngMock - * @description - * Counts all the direct and indirect child scopes of the current scope. - * - * The current scope is excluded from the count. The count includes all isolate child scopes. - * - * @returns {number} Total number of child scopes. - */ - function countChildScopes() { - // jshint validthis: true - var count = 0; // exclude the current scope - var pendingChildHeads = [this.$$childHead]; - var currentScope; - - while (pendingChildHeads.length) { - currentScope = pendingChildHeads.shift(); - - while (currentScope) { - count += 1; - pendingChildHeads.push(currentScope.$$childHead); - currentScope = currentScope.$$nextSibling; - } - } - - return count; - } - - - /** - * @ngdoc method - * @name $rootScope.Scope#$countWatchers - * @module ngMock - * @description - * Counts all the watchers of direct and indirect child scopes of the current scope. - * - * The watchers of the current scope are included in the count and so are all the watchers of - * isolate child scopes. - * - * @returns {number} Total number of watchers. - */ - function countWatchers() { - // jshint validthis: true - var count = this.$$watchers ? this.$$watchers.length : 0; // include the current scope - var pendingChildHeads = [this.$$childHead]; - var currentScope; - - while (pendingChildHeads.length) { - currentScope = pendingChildHeads.shift(); - - while (currentScope) { - count += currentScope.$$watchers ? currentScope.$$watchers.length : 0; - pendingChildHeads.push(currentScope.$$childHead); - currentScope = currentScope.$$nextSibling; - } - } - - return count; - } -}]; - - -if (window.jasmine || window.mocha) { - - var currentSpec = null, - annotatedFunctions = [], - isSpecRunning = function() { - return !!currentSpec; - }; - - angular.mock.$$annotate = angular.injector.$$annotate; - angular.injector.$$annotate = function(fn) { - if (typeof fn === 'function' && !fn.$inject) { - annotatedFunctions.push(fn); - } - return angular.mock.$$annotate.apply(this, arguments); - }; - - - (window.beforeEach || window.setup)(function() { - annotatedFunctions = []; - currentSpec = this; - }); - - (window.afterEach || window.teardown)(function() { - var injector = currentSpec.$injector; - - annotatedFunctions.forEach(function(fn) { - delete fn.$inject; - }); - - angular.forEach(currentSpec.$modules, function(module) { - if (module && module.$$hashKey) { - module.$$hashKey = undefined; - } - }); - - currentSpec.$injector = null; - currentSpec.$modules = null; - currentSpec.$providerInjector = null; - currentSpec = null; - - if (injector) { - injector.get('$rootElement').off(); - injector.get('$rootScope').$destroy(); - } - - // clean up jquery's fragment cache - angular.forEach(angular.element.fragments, function(val, key) { - delete angular.element.fragments[key]; - }); - - MockXhr.$$lastInstance = null; - - angular.forEach(angular.callbacks, function(val, key) { - delete angular.callbacks[key]; - }); - angular.callbacks.counter = 0; - }); - - /** - * @ngdoc function - * @name angular.mock.module - * @description - * - * *NOTE*: This function is also published on window for easy access.
        - * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha - * - * This function registers a module configuration code. It collects the configuration information - * which will be used when the injector is created by {@link angular.mock.inject inject}. - * - * See {@link angular.mock.inject inject} for usage example - * - * @param {...(string|Function|Object)} fns any number of modules which are represented as string - * aliases or as anonymous module initialization functions. The modules are used to - * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an - * object literal is passed each key-value pair will be registered on the module via - * {@link auto.$provide $provide}.value, the key being the string name (or token) to associate - * with the value on the injector. - */ - window.module = angular.mock.module = function() { - var moduleFns = Array.prototype.slice.call(arguments, 0); - return isSpecRunning() ? workFn() : workFn; - ///////////////////// - function workFn() { - if (currentSpec.$injector) { - throw new Error('Injector already created, can not register a module!'); - } else { - var fn, modules = currentSpec.$modules || (currentSpec.$modules = []); - angular.forEach(moduleFns, function(module) { - if (angular.isObject(module) && !angular.isArray(module)) { - fn = function($provide) { - angular.forEach(module, function(value, key) { - $provide.value(key, value); - }); - }; - } else { - fn = module; - } - if (currentSpec.$providerInjector) { - currentSpec.$providerInjector.invoke(fn); - } else { - modules.push(fn); - } - }); - } - } - }; - - /** - * @ngdoc function - * @name angular.mock.inject - * @description - * - * *NOTE*: This function is also published on window for easy access.
        - * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha - * - * The inject function wraps a function into an injectable function. The inject() creates new - * instance of {@link auto.$injector $injector} per test, which is then used for - * resolving references. - * - * - * ## Resolving References (Underscore Wrapping) - * Often, we would like to inject a reference once, in a `beforeEach()` block and reuse this - * in multiple `it()` clauses. To be able to do this we must assign the reference to a variable - * that is declared in the scope of the `describe()` block. Since we would, most likely, want - * the variable to have the same name of the reference we have a problem, since the parameter - * to the `inject()` function would hide the outer variable. - * - * To help with this, the injected parameters can, optionally, be enclosed with underscores. - * These are ignored by the injector when the reference name is resolved. - * - * For example, the parameter `_myService_` would be resolved as the reference `myService`. - * Since it is available in the function body as _myService_, we can then assign it to a variable - * defined in an outer scope. - * - * ``` - * // Defined out reference variable outside - * var myService; - * - * // Wrap the parameter in underscores - * beforeEach( inject( function(_myService_){ - * myService = _myService_; - * })); - * - * // Use myService in a series of tests. - * it('makes use of myService', function() { - * myService.doStuff(); - * }); - * - * ``` - * - * See also {@link angular.mock.module angular.mock.module} - * - * ## Example - * Example of what a typical jasmine tests looks like with the inject method. - * ```js - * - * angular.module('myApplicationModule', []) - * .value('mode', 'app') - * .value('version', 'v1.0.1'); - * - * - * describe('MyApp', function() { - * - * // You need to load modules that you want to test, - * // it loads only the "ng" module by default. - * beforeEach(module('myApplicationModule')); - * - * - * // inject() is used to inject arguments of all given functions - * it('should provide a version', inject(function(mode, version) { - * expect(version).toEqual('v1.0.1'); - * expect(mode).toEqual('app'); - * })); - * - * - * // The inject and module method can also be used inside of the it or beforeEach - * it('should override a version and test the new version is injected', function() { - * // module() takes functions or strings (module aliases) - * module(function($provide) { - * $provide.value('version', 'overridden'); // override version here - * }); - * - * inject(function(version) { - * expect(version).toEqual('overridden'); - * }); - * }); - * }); - * - * ``` - * - * @param {...Function} fns any number of functions which will be injected using the injector. - */ - - - - var ErrorAddingDeclarationLocationStack = function(e, errorForStack) { - this.message = e.message; - this.name = e.name; - if (e.line) this.line = e.line; - if (e.sourceId) this.sourceId = e.sourceId; - if (e.stack && errorForStack) - this.stack = e.stack + '\n' + errorForStack.stack; - if (e.stackArray) this.stackArray = e.stackArray; - }; - ErrorAddingDeclarationLocationStack.prototype.toString = Error.prototype.toString; - - window.inject = angular.mock.inject = function() { - var blockFns = Array.prototype.slice.call(arguments, 0); - var errorForStack = new Error('Declaration Location'); - return isSpecRunning() ? workFn.call(currentSpec) : workFn; - ///////////////////// - function workFn() { - var modules = currentSpec.$modules || []; - var strictDi = !!currentSpec.$injectorStrict; - modules.unshift(function($injector) { - currentSpec.$providerInjector = $injector; - }); - modules.unshift('ngMock'); - modules.unshift('ng'); - var injector = currentSpec.$injector; - if (!injector) { - if (strictDi) { - // If strictDi is enabled, annotate the providerInjector blocks - angular.forEach(modules, function(moduleFn) { - if (typeof moduleFn === "function") { - angular.injector.$$annotate(moduleFn); - } - }); - } - injector = currentSpec.$injector = angular.injector(modules, strictDi); - currentSpec.$injectorStrict = strictDi; - } - for (var i = 0, ii = blockFns.length; i < ii; i++) { - if (currentSpec.$injectorStrict) { - // If the injector is strict / strictDi, and the spec wants to inject using automatic - // annotation, then annotate the function here. - injector.annotate(blockFns[i]); - } - try { - /* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */ - injector.invoke(blockFns[i] || angular.noop, this); - /* jshint +W040 */ - } catch (e) { - if (e.stack && errorForStack) { - throw new ErrorAddingDeclarationLocationStack(e, errorForStack); - } - throw e; - } finally { - errorForStack = null; - } - } - } - }; - - - angular.mock.inject.strictDi = function(value) { - value = arguments.length ? !!value : true; - return isSpecRunning() ? workFn() : workFn; - - function workFn() { - if (value !== currentSpec.$injectorStrict) { - if (currentSpec.$injector) { - throw new Error('Injector already created, can not modify strict annotations'); - } else { - currentSpec.$injectorStrict = value; - } - } - } - }; -} - - -})(window, window.angular); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-resource.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-resource.js deleted file mode 100644 index 444be83c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-resource.js +++ /dev/null @@ -1,768 +0,0 @@ -/** - * @license AngularJS v1.5.0 - * (c) 2010-2016 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular, undefined) {'use strict'; - -var $resourceMinErr = angular.$$minErr('$resource'); - -// Helper functions and regex to lookup a dotted path on an object -// stopping at undefined/null. The path must be composed of ASCII -// identifiers (just like $parse) -var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/; - -function isValidDottedPath(path) { - return (path != null && path !== '' && path !== 'hasOwnProperty' && - MEMBER_NAME_REGEX.test('.' + path)); -} - -function lookupDottedPath(obj, path) { - if (!isValidDottedPath(path)) { - throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path); - } - var keys = path.split('.'); - for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) { - var key = keys[i]; - obj = (obj !== null) ? obj[key] : undefined; - } - return obj; -} - -/** - * Create a shallow copy of an object and clear other fields from the destination - */ -function shallowClearAndCopy(src, dst) { - dst = dst || {}; - - angular.forEach(dst, function(value, key) { - delete dst[key]; - }); - - for (var key in src) { - if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { - dst[key] = src[key]; - } - } - - return dst; -} - -/** - * @ngdoc module - * @name ngResource - * @description - * - * # ngResource - * - * The `ngResource` module provides interaction support with RESTful services - * via the $resource service. - * - * - *
        - * - * See {@link ngResource.$resource `$resource`} for usage. - */ - -/** - * @ngdoc service - * @name $resource - * @requires $http - * @requires ng.$log - * @requires $q - * @requires ng.$timeout - * - * @description - * A factory which creates a resource object that lets you interact with - * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources. - * - * The returned resource object has action methods which provide high-level behaviors without - * the need to interact with the low level {@link ng.$http $http} service. - * - * Requires the {@link ngResource `ngResource`} module to be installed. - * - * By default, trailing slashes will be stripped from the calculated URLs, - * which can pose problems with server backends that do not expect that - * behavior. This can be disabled by configuring the `$resourceProvider` like - * this: - * - * ```js - app.config(['$resourceProvider', function($resourceProvider) { - // Don't strip trailing slashes from calculated URLs - $resourceProvider.defaults.stripTrailingSlashes = false; - }]); - * ``` - * - * @param {string} url A parameterized URL template with parameters prefixed by `:` as in - * `/user/:username`. If you are using a URL with a port number (e.g. - * `http://example.com:8080/api`), it will be respected. - * - * If you are using a url with a suffix, just add the suffix, like this: - * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')` - * or even `$resource('http://example.com/resource/:resource_id.:format')` - * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be - * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you - * can escape it with `/\.`. - * - * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in - * `actions` methods. If a parameter value is a function, it will be executed every time - * when a param value needs to be obtained for a request (unless the param was overridden). - * - * Each key value in the parameter object is first bound to url template if present and then any - * excess keys are appended to the url search query after the `?`. - * - * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in - * URL `/path/greet?salutation=Hello`. - * - * If the parameter value is prefixed with `@` then the value for that parameter will be extracted - * from the corresponding property on the `data` object (provided when calling an action method). - * For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of - * `someParam` will be `data.someProp`. - * - * @param {Object.=} actions Hash with declaration of custom actions that should extend - * the default set of resource actions. The declaration should be created in the format of {@link - * ng.$http#usage $http.config}: - * - * {action1: {method:?, params:?, isArray:?, headers:?, ...}, - * action2: {method:?, params:?, isArray:?, headers:?, ...}, - * ...} - * - * Where: - * - * - **`action`** – {string} – The name of action. This name becomes the name of the method on - * your resource object. - * - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`, - * `DELETE`, `JSONP`, etc). - * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of - * the parameter value is a function, it will be executed every time when a param value needs to - * be obtained for a request (unless the param was overridden). - * - **`url`** – {string} – action specific `url` override. The url templating is supported just - * like for the resource-level urls. - * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, - * see `returns` section. - * - **`transformRequest`** – - * `{function(data, headersGetter)|Array.}` – - * transform function or an array of such functions. The transform function takes the http - * request body and headers and returns its transformed (typically serialized) version. - * By default, transformRequest will contain one function that checks if the request data is - * an object and serializes to using `angular.toJson`. To prevent this behavior, set - * `transformRequest` to an empty array: `transformRequest: []` - * - **`transformResponse`** – - * `{function(data, headersGetter)|Array.}` – - * transform function or an array of such functions. The transform function takes the http - * response body and headers and returns its transformed (typically deserialized) version. - * By default, transformResponse will contain one function that checks if the response looks - * like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior, - * set `transformResponse` to an empty array: `transformResponse: []` - * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the - * GET request, otherwise if a cache instance built with - * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for - * caching. - * - **`timeout`** – `{number}` – timeout in milliseconds.
        - * **Note:** In contrast to {@link ng.$http#usage $http.config}, {@link ng.$q promises} are - * **not** supported in $resource, because the same value would be used for multiple requests. - * If you are looking for a way to cancel requests, you should use the `cancellable` option. - * - **`cancellable`** – `{boolean}` – if set to true, the request made by a "non-instance" call - * will be cancelled (if not already completed) by calling `$cancelRequest()` on the call's - * return value. Calling `$cancelRequest()` for a non-cancellable or an already - * completed/cancelled request will have no effect.
        - * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the - * XHR object. See - * [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5) - * for more information. - * - **`responseType`** - `{string}` - see - * [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType). - * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods - - * `response` and `responseError`. Both `response` and `responseError` interceptors get called - * with `http response` object. See {@link ng.$http $http interceptors}. - * - * @param {Object} options Hash with custom settings that should extend the - * default `$resourceProvider` behavior. The supported options are: - * - * - **`stripTrailingSlashes`** – {boolean} – If true then the trailing - * slashes from any calculated URL will be stripped. (Defaults to true.) - * - **`cancellable`** – {boolean} – If true, the request made by a "non-instance" call will be - * cancelled (if not already completed) by calling `$cancelRequest()` on the call's return value. - * This can be overwritten per action. (Defaults to false.) - * - * @returns {Object} A resource "class" object with methods for the default set of resource actions - * optionally extended with custom `actions`. The default set contains these actions: - * ```js - * { 'get': {method:'GET'}, - * 'save': {method:'POST'}, - * 'query': {method:'GET', isArray:true}, - * 'remove': {method:'DELETE'}, - * 'delete': {method:'DELETE'} }; - * ``` - * - * Calling these methods invoke an {@link ng.$http} with the specified http method, - * destination and parameters. When the data is returned from the server then the object is an - * instance of the resource class. The actions `save`, `remove` and `delete` are available on it - * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create, - * read, update, delete) on server-side data like this: - * ```js - * var User = $resource('/user/:userId', {userId:'@id'}); - * var user = User.get({userId:123}, function() { - * user.abc = true; - * user.$save(); - * }); - * ``` - * - * It is important to realize that invoking a $resource object method immediately returns an - * empty reference (object or array depending on `isArray`). Once the data is returned from the - * server the existing reference is populated with the actual data. This is a useful trick since - * usually the resource is assigned to a model which is then rendered by the view. Having an empty - * object results in no rendering, once the data arrives from the server then the object is - * populated with the data and the view automatically re-renders itself showing the new data. This - * means that in most cases one never has to write a callback function for the action methods. - * - * The action methods on the class object or instance object can be invoked with the following - * parameters: - * - * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])` - * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])` - * - non-GET instance actions: `instance.$action([parameters], [success], [error])` - * - * - * Success callback is called with (value, responseHeaders) arguments, where the value is - * the populated resource instance or collection object. The error callback is called - * with (httpResponse) argument. - * - * Class actions return empty instance (with additional properties below). - * Instance actions return promise of the action. - * - * The Resource instances and collections have these additional properties: - * - * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this - * instance or collection. - * - * On success, the promise is resolved with the same resource instance or collection object, - * updated with data from server. This makes it easy to use in - * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view - * rendering until the resource(s) are loaded. - * - * On failure, the promise is rejected with the {@link ng.$http http response} object, without - * the `resource` property. - * - * If an interceptor object was provided, the promise will instead be resolved with the value - * returned by the interceptor. - * - * - `$resolved`: `true` after first server interaction is completed (either with success or - * rejection), `false` before that. Knowing if the Resource has been resolved is useful in - * data-binding. - * - * The Resource instances and collections have these additional methods: - * - * - `$cancelRequest`: If there is a cancellable, pending request related to the instance or - * collection, calling this method will abort the request. - * - * @example - * - * # Credit card resource - * - * ```js - // Define CreditCard class - var CreditCard = $resource('/user/:userId/card/:cardId', - {userId:123, cardId:'@id'}, { - charge: {method:'POST', params:{charge:true}} - }); - - // We can retrieve a collection from the server - var cards = CreditCard.query(function() { - // GET: /user/123/card - // server returns: [ {id:456, number:'1234', name:'Smith'} ]; - - var card = cards[0]; - // each item is an instance of CreditCard - expect(card instanceof CreditCard).toEqual(true); - card.name = "J. Smith"; - // non GET methods are mapped onto the instances - card.$save(); - // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'} - // server returns: {id:456, number:'1234', name: 'J. Smith'}; - - // our custom method is mapped as well. - card.$charge({amount:9.99}); - // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'} - }); - - // we can create an instance as well - var newCard = new CreditCard({number:'0123'}); - newCard.name = "Mike Smith"; - newCard.$save(); - // POST: /user/123/card {number:'0123', name:'Mike Smith'} - // server returns: {id:789, number:'0123', name: 'Mike Smith'}; - expect(newCard.id).toEqual(789); - * ``` - * - * The object returned from this function execution is a resource "class" which has "static" method - * for each action in the definition. - * - * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and - * `headers`. - * - * @example - * - * # User resource - * - * When the data is returned from the server then the object is an instance of the resource type and - * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD - * operations (create, read, update, delete) on server-side data. - - ```js - var User = $resource('/user/:userId', {userId:'@id'}); - User.get({userId:123}, function(user) { - user.abc = true; - user.$save(); - }); - ``` - * - * It's worth noting that the success callback for `get`, `query` and other methods gets passed - * in the response that came from the server as well as $http header getter function, so one - * could rewrite the above example and get access to http headers as: - * - ```js - var User = $resource('/user/:userId', {userId:'@id'}); - User.get({userId:123}, function(user, getResponseHeaders){ - user.abc = true; - user.$save(function(user, putResponseHeaders) { - //user => saved user object - //putResponseHeaders => $http header getter - }); - }); - ``` - * - * You can also access the raw `$http` promise via the `$promise` property on the object returned - * - ``` - var User = $resource('/user/:userId', {userId:'@id'}); - User.get({userId:123}) - .$promise.then(function(user) { - $scope.user = user; - }); - ``` - * - * @example - * - * # Creating a custom 'PUT' request - * - * In this example we create a custom method on our resource to make a PUT request - * ```js - * var app = angular.module('app', ['ngResource', 'ngRoute']); - * - * // Some APIs expect a PUT request in the format URL/object/ID - * // Here we are creating an 'update' method - * app.factory('Notes', ['$resource', function($resource) { - * return $resource('/notes/:id', null, - * { - * 'update': { method:'PUT' } - * }); - * }]); - * - * // In our controller we get the ID from the URL using ngRoute and $routeParams - * // We pass in $routeParams and our Notes factory along with $scope - * app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes', - function($scope, $routeParams, Notes) { - * // First get a note object from the factory - * var note = Notes.get({ id:$routeParams.id }); - * $id = note.id; - * - * // Now call update passing in the ID first then the object you are updating - * Notes.update({ id:$id }, note); - * - * // This will PUT /notes/ID with the note object in the request payload - * }]); - * ``` - * - * @example - * - * # Cancelling requests - * - * If an action's configuration specifies that it is cancellable, you can cancel the request related - * to an instance or collection (as long as it is a result of a "non-instance" call): - * - ```js - // ...defining the `Hotel` resource... - var Hotel = $resource('/api/hotel/:id', {id: '@id'}, { - // Let's make the `query()` method cancellable - query: {method: 'get', isArray: true, cancellable: true} - }); - - // ...somewhere in the PlanVacationController... - ... - this.onDestinationChanged = function onDestinationChanged(destination) { - // We don't care about any pending request for hotels - // in a different destination any more - this.availableHotels.$cancelRequest(); - - // Let's query for hotels in '' - // (calls: /api/hotel?location=) - this.availableHotels = Hotel.query({location: destination}); - }; - ``` - * - */ -angular.module('ngResource', ['ng']). - provider('$resource', function() { - var PROTOCOL_AND_DOMAIN_REGEX = /^https?:\/\/[^\/]*/; - var provider = this; - - this.defaults = { - // Strip slashes by default - stripTrailingSlashes: true, - - // Default actions configuration - actions: { - 'get': {method: 'GET'}, - 'save': {method: 'POST'}, - 'query': {method: 'GET', isArray: true}, - 'remove': {method: 'DELETE'}, - 'delete': {method: 'DELETE'} - } - }; - - this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) { - - var noop = angular.noop, - forEach = angular.forEach, - extend = angular.extend, - copy = angular.copy, - isFunction = angular.isFunction; - - /** - * We need our custom method because encodeURIComponent is too aggressive and doesn't follow - * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set - * (pchar) allowed in path segments: - * segment = *pchar - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * pct-encoded = "%" HEXDIG HEXDIG - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - * / "*" / "+" / "," / ";" / "=" - */ - function encodeUriSegment(val) { - return encodeUriQuery(val, true). - replace(/%26/gi, '&'). - replace(/%3D/gi, '='). - replace(/%2B/gi, '+'); - } - - - /** - * This method is intended for encoding *key* or *value* parts of query component. We need a - * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't - * have to be encoded per http://tools.ietf.org/html/rfc3986: - * query = *( pchar / "/" / "?" ) - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * pct-encoded = "%" HEXDIG HEXDIG - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - * / "*" / "+" / "," / ";" / "=" - */ - function encodeUriQuery(val, pctEncodeSpaces) { - return encodeURIComponent(val). - replace(/%40/gi, '@'). - replace(/%3A/gi, ':'). - replace(/%24/g, '$'). - replace(/%2C/gi, ','). - replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); - } - - function Route(template, defaults) { - this.template = template; - this.defaults = extend({}, provider.defaults, defaults); - this.urlParams = {}; - } - - Route.prototype = { - setUrlParams: function(config, params, actionUrl) { - var self = this, - url = actionUrl || self.template, - val, - encodedVal, - protocolAndDomain = ''; - - var urlParams = self.urlParams = {}; - forEach(url.split(/\W/), function(param) { - if (param === 'hasOwnProperty') { - throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name."); - } - if (!(new RegExp("^\\d+$").test(param)) && param && - (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) { - urlParams[param] = { - isQueryParamValue: (new RegExp("\\?.*=:" + param + "(?:\\W|$)")).test(url) - }; - } - }); - url = url.replace(/\\:/g, ':'); - url = url.replace(PROTOCOL_AND_DOMAIN_REGEX, function(match) { - protocolAndDomain = match; - return ''; - }); - - params = params || {}; - forEach(self.urlParams, function(paramInfo, urlParam) { - val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam]; - if (angular.isDefined(val) && val !== null) { - if (paramInfo.isQueryParamValue) { - encodedVal = encodeUriQuery(val, true); - } else { - encodedVal = encodeUriSegment(val); - } - url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) { - return encodedVal + p1; - }); - } else { - url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match, - leadingSlashes, tail) { - if (tail.charAt(0) == '/') { - return tail; - } else { - return leadingSlashes + tail; - } - }); - } - }); - - // strip trailing slashes and set the url (unless this behavior is specifically disabled) - if (self.defaults.stripTrailingSlashes) { - url = url.replace(/\/+$/, '') || '/'; - } - - // then replace collapse `/.` if found in the last URL path segment before the query - // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x` - url = url.replace(/\/\.(?=\w+($|\?))/, '.'); - // replace escaped `/\.` with `/.` - config.url = protocolAndDomain + url.replace(/\/\\\./, '/.'); - - - // set params - delegate param encoding to $http - forEach(params, function(value, key) { - if (!self.urlParams[key]) { - config.params = config.params || {}; - config.params[key] = value; - } - }); - } - }; - - - function resourceFactory(url, paramDefaults, actions, options) { - var route = new Route(url, options); - - actions = extend({}, provider.defaults.actions, actions); - - function extractParams(data, actionParams) { - var ids = {}; - actionParams = extend({}, paramDefaults, actionParams); - forEach(actionParams, function(value, key) { - if (isFunction(value)) { value = value(); } - ids[key] = value && value.charAt && value.charAt(0) == '@' ? - lookupDottedPath(data, value.substr(1)) : value; - }); - return ids; - } - - function defaultResponseInterceptor(response) { - return response.resource; - } - - function Resource(value) { - shallowClearAndCopy(value || {}, this); - } - - Resource.prototype.toJSON = function() { - var data = extend({}, this); - delete data.$promise; - delete data.$resolved; - return data; - }; - - forEach(actions, function(action, name) { - var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method); - var numericTimeout = action.timeout; - var cancellable = angular.isDefined(action.cancellable) ? action.cancellable : - (options && angular.isDefined(options.cancellable)) ? options.cancellable : - provider.defaults.cancellable; - - if (numericTimeout && !angular.isNumber(numericTimeout)) { - $log.debug('ngResource:\n' + - ' Only numeric values are allowed as `timeout`.\n' + - ' Promises are not supported in $resource, because the same value would ' + - 'be used for multiple requests. If you are looking for a way to cancel ' + - 'requests, you should use the `cancellable` option.'); - delete action.timeout; - numericTimeout = null; - } - - Resource[name] = function(a1, a2, a3, a4) { - var params = {}, data, success, error; - - /* jshint -W086 */ /* (purposefully fall through case statements) */ - switch (arguments.length) { - case 4: - error = a4; - success = a3; - //fallthrough - case 3: - case 2: - if (isFunction(a2)) { - if (isFunction(a1)) { - success = a1; - error = a2; - break; - } - - success = a2; - error = a3; - //fallthrough - } else { - params = a1; - data = a2; - success = a3; - break; - } - case 1: - if (isFunction(a1)) success = a1; - else if (hasBody) data = a1; - else params = a1; - break; - case 0: break; - default: - throw $resourceMinErr('badargs', - "Expected up to 4 arguments [params, data, success, error], got {0} arguments", - arguments.length); - } - /* jshint +W086 */ /* (purposefully fall through case statements) */ - - var isInstanceCall = this instanceof Resource; - var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data)); - var httpConfig = {}; - var responseInterceptor = action.interceptor && action.interceptor.response || - defaultResponseInterceptor; - var responseErrorInterceptor = action.interceptor && action.interceptor.responseError || - undefined; - var timeoutDeferred; - var numericTimeoutPromise; - - forEach(action, function(value, key) { - switch (key) { - default: - httpConfig[key] = copy(value); - break; - case 'params': - case 'isArray': - case 'interceptor': - case 'cancellable': - break; - } - }); - - if (!isInstanceCall && cancellable) { - timeoutDeferred = $q.defer(); - httpConfig.timeout = timeoutDeferred.promise; - - if (numericTimeout) { - numericTimeoutPromise = $timeout(timeoutDeferred.resolve, numericTimeout); - } - } - - if (hasBody) httpConfig.data = data; - route.setUrlParams(httpConfig, - extend({}, extractParams(data, action.params || {}), params), - action.url); - - var promise = $http(httpConfig).then(function(response) { - var data = response.data; - - if (data) { - // Need to convert action.isArray to boolean in case it is undefined - // jshint -W018 - if (angular.isArray(data) !== (!!action.isArray)) { - throw $resourceMinErr('badcfg', - 'Error in resource configuration for action `{0}`. Expected response to ' + - 'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object', - angular.isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url); - } - // jshint +W018 - if (action.isArray) { - value.length = 0; - forEach(data, function(item) { - if (typeof item === "object") { - value.push(new Resource(item)); - } else { - // Valid JSON values may be string literals, and these should not be converted - // into objects. These items will not have access to the Resource prototype - // methods, but unfortunately there - value.push(item); - } - }); - } else { - var promise = value.$promise; // Save the promise - shallowClearAndCopy(data, value); - value.$promise = promise; // Restore the promise - } - } - response.resource = value; - - return response; - }, function(response) { - (error || noop)(response); - return $q.reject(response); - }); - - promise.finally(function() { - value.$resolved = true; - if (!isInstanceCall && cancellable) { - value.$cancelRequest = angular.noop; - $timeout.cancel(numericTimeoutPromise); - timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null; - } - }); - - promise = promise.then( - function(response) { - var value = responseInterceptor(response); - (success || noop)(value, response.headers); - return value; - }, - responseErrorInterceptor); - - if (!isInstanceCall) { - // we are creating instance / collection - // - set the initial promise - // - return the instance / collection - value.$promise = promise; - value.$resolved = false; - if (cancellable) value.$cancelRequest = timeoutDeferred.resolve; - - return value; - } - - // instance call - return promise; - }; - - - Resource.prototype['$' + name] = function(params, success, error) { - if (isFunction(params)) { - error = success; success = params; params = {}; - } - var result = Resource[name].call(this, params, this, success, error); - return result.$promise || result; - }; - }); - - Resource.bind = function(additionalParamDefaults) { - return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions); - }; - - return Resource; - } - - return resourceFactory; - }]; - }); - - -})(window, window.angular); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-resource.min.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-resource.min.js deleted file mode 100644 index 306657dc..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-resource.min.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - AngularJS v1.5.0 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(Q,d,G){'use strict';function H(t,g){g=g||{};d.forEach(g,function(d,q){delete g[q]});for(var q in t)!t.hasOwnProperty(q)||"$"===q.charAt(0)&&"$"===q.charAt(1)||(g[q]=t[q]);return g}var z=d.$$minErr("$resource"),N=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;d.module("ngResource",["ng"]).provider("$resource",function(){var t=/^https?:\/\/[^\/]*/,g=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}}; -this.$get=["$http","$log","$q","$timeout",function(q,M,I,J){function A(d,h){return encodeURIComponent(d).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,h?"%20":"+")}function B(d,h){this.template=d;this.defaults=v({},g.defaults,h);this.urlParams={}}function K(e,h,n,k){function c(a,b){var c={};b=v({},h,b);u(b,function(b,h){x(b)&&(b=b());var f;if(b&&b.charAt&&"@"==b.charAt(0)){f=a;var l=b.substr(1);if(null==l||""===l||"hasOwnProperty"===l||!N.test("."+ -l))throw z("badmember",l);for(var l=l.split("."),m=0,k=l.length;m - */ - /* global -ngRouteModule */ -var ngRouteModule = angular.module('ngRoute', ['ng']). - provider('$route', $RouteProvider), - $routeMinErr = angular.$$minErr('ngRoute'); - -/** - * @ngdoc provider - * @name $routeProvider - * - * @description - * - * Used for configuring routes. - * - * ## Example - * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`. - * - * ## Dependencies - * Requires the {@link ngRoute `ngRoute`} module to be installed. - */ -function $RouteProvider() { - function inherit(parent, extra) { - return angular.extend(Object.create(parent), extra); - } - - var routes = {}; - - /** - * @ngdoc method - * @name $routeProvider#when - * - * @param {string} path Route path (matched against `$location.path`). If `$location.path` - * contains redundant trailing slash or is missing one, the route will still match and the - * `$location.path` will be updated to add or drop the trailing slash to exactly match the - * route definition. - * - * * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up - * to the next slash are matched and stored in `$routeParams` under the given `name` - * when the route matches. - * * `path` can contain named groups starting with a colon and ending with a star: - * e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name` - * when the route matches. - * * `path` can contain optional named groups with a question mark: e.g.`:name?`. - * - * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match - * `/color/brown/largecode/code/with/slashes/edit` and extract: - * - * * `color: brown` - * * `largecode: code/with/slashes`. - * - * - * @param {Object} route Mapping information to be assigned to `$route.current` on route - * match. - * - * Object properties: - * - * - `controller` – `{(string|function()=}` – Controller fn that should be associated with - * newly created scope or the name of a {@link angular.Module#controller registered - * controller} if passed as a string. - * - `controllerAs` – `{string=}` – An identifier name for a reference to the controller. - * If present, the controller will be published to scope under the `controllerAs` name. - * - `template` – `{string=|function()=}` – html template as a string or a function that - * returns an html template as a string which should be used by {@link - * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives. - * This property takes precedence over `templateUrl`. - * - * If `template` is a function, it will be called with the following parameters: - * - * - `{Array.}` - route parameters extracted from the current - * `$location.path()` by applying the current route - * - * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html - * template that should be used by {@link ngRoute.directive:ngView ngView}. - * - * If `templateUrl` is a function, it will be called with the following parameters: - * - * - `{Array.}` - route parameters extracted from the current - * `$location.path()` by applying the current route - * - * - `resolve` - `{Object.=}` - An optional map of dependencies which should - * be injected into the controller. If any of these dependencies are promises, the router - * will wait for them all to be resolved or one to be rejected before the controller is - * instantiated. - * If all the promises are resolved successfully, the values of the resolved promises are - * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is - * fired. If any of the promises are rejected the - * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. - * For easier access to the resolved dependencies from the template, the `resolve` map will - * be available on the scope of the route, under `$resolve` (by default) or a custom name - * specified by the `resolveAs` property (see below). This can be particularly useful, when - * working with {@link angular.Module#component components} as route templates.
        - *
        - * **Note:** If your scope already contains a property with this name, it will be hidden - * or overwritten. Make sure, you specify an appropriate name for this property, that - * does not collide with other properties on the scope. - *
        - * The map object is: - * - * - `key` – `{string}`: a name of a dependency to be injected into the controller. - * - `factory` - `{string|function}`: If `string` then it is an alias for a service. - * Otherwise if function, then it is {@link auto.$injector#invoke injected} - * and the return value is treated as the dependency. If the result is a promise, it is - * resolved before its value is injected into the controller. Be aware that - * `ngRoute.$routeParams` will still refer to the previous route within these resolve - * functions. Use `$route.current.params` to access the new route parameters, instead. - * - * - `resolveAs` - `{string=}` - The name under which the `resolve` map will be available on - * the scope of the route. If omitted, defaults to `$resolve`. - * - * - `redirectTo` – `{(string|function())=}` – value to update - * {@link ng.$location $location} path with and trigger route redirection. - * - * If `redirectTo` is a function, it will be called with the following parameters: - * - * - `{Object.}` - route parameters extracted from the current - * `$location.path()` by applying the current route templateUrl. - * - `{string}` - current `$location.path()` - * - `{Object}` - current `$location.search()` - * - * The custom `redirectTo` function is expected to return a string which will be used - * to update `$location.path()` and `$location.search()`. - * - * - `[reloadOnSearch=true]` - `{boolean=}` - reload route when only `$location.search()` - * or `$location.hash()` changes. - * - * If the option is set to `false` and url in the browser changes, then - * `$routeUpdate` event is broadcasted on the root scope. - * - * - `[caseInsensitiveMatch=false]` - `{boolean=}` - match routes without being case sensitive - * - * If the option is set to `true`, then the particular route can be matched without being - * case sensitive - * - * @returns {Object} self - * - * @description - * Adds a new route definition to the `$route` service. - */ - this.when = function(path, route) { - //copy original route object to preserve params inherited from proto chain - var routeCopy = angular.copy(route); - if (angular.isUndefined(routeCopy.reloadOnSearch)) { - routeCopy.reloadOnSearch = true; - } - if (angular.isUndefined(routeCopy.caseInsensitiveMatch)) { - routeCopy.caseInsensitiveMatch = this.caseInsensitiveMatch; - } - routes[path] = angular.extend( - routeCopy, - path && pathRegExp(path, routeCopy) - ); - - // create redirection for trailing slashes - if (path) { - var redirectPath = (path[path.length - 1] == '/') - ? path.substr(0, path.length - 1) - : path + '/'; - - routes[redirectPath] = angular.extend( - {redirectTo: path}, - pathRegExp(redirectPath, routeCopy) - ); - } - - return this; - }; - - /** - * @ngdoc property - * @name $routeProvider#caseInsensitiveMatch - * @description - * - * A boolean property indicating if routes defined - * using this provider should be matched using a case insensitive - * algorithm. Defaults to `false`. - */ - this.caseInsensitiveMatch = false; - - /** - * @param path {string} path - * @param opts {Object} options - * @return {?Object} - * - * @description - * Normalizes the given path, returning a regular expression - * and the original path. - * - * Inspired by pathRexp in visionmedia/express/lib/utils.js. - */ - function pathRegExp(path, opts) { - var insensitive = opts.caseInsensitiveMatch, - ret = { - originalPath: path, - regexp: path - }, - keys = ret.keys = []; - - path = path - .replace(/([().])/g, '\\$1') - .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) { - var optional = option === '?' ? option : null; - var star = option === '*' ? option : null; - keys.push({ name: key, optional: !!optional }); - slash = slash || ''; - return '' - + (optional ? '' : slash) - + '(?:' - + (optional ? slash : '') - + (star && '(.+?)' || '([^/]+)') - + (optional || '') - + ')' - + (optional || ''); - }) - .replace(/([\/$\*])/g, '\\$1'); - - ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : ''); - return ret; - } - - /** - * @ngdoc method - * @name $routeProvider#otherwise - * - * @description - * Sets route definition that will be used on route change when no other route definition - * is matched. - * - * @param {Object|string} params Mapping information to be assigned to `$route.current`. - * If called with a string, the value maps to `redirectTo`. - * @returns {Object} self - */ - this.otherwise = function(params) { - if (typeof params === 'string') { - params = {redirectTo: params}; - } - this.when(null, params); - return this; - }; - - - this.$get = ['$rootScope', - '$location', - '$routeParams', - '$q', - '$injector', - '$templateRequest', - '$sce', - function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) { - - /** - * @ngdoc service - * @name $route - * @requires $location - * @requires $routeParams - * - * @property {Object} current Reference to the current route definition. - * The route definition contains: - * - * - `controller`: The controller constructor as defined in the route definition. - * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for - * controller instantiation. The `locals` contain - * the resolved values of the `resolve` map. Additionally the `locals` also contain: - * - * - `$scope` - The current route scope. - * - `$template` - The current route template HTML. - * - * The `locals` will be assigned to the route scope's `$resolve` property. You can override - * the property name, using `resolveAs` in the route definition. See - * {@link ngRoute.$routeProvider $routeProvider} for more info. - * - * @property {Object} routes Object with all route configuration Objects as its properties. - * - * @description - * `$route` is used for deep-linking URLs to controllers and views (HTML partials). - * It watches `$location.url()` and tries to map the path to an existing route definition. - * - * Requires the {@link ngRoute `ngRoute`} module to be installed. - * - * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API. - * - * The `$route` service is typically used in conjunction with the - * {@link ngRoute.directive:ngView `ngView`} directive and the - * {@link ngRoute.$routeParams `$routeParams`} service. - * - * @example - * This example shows how changing the URL hash causes the `$route` to match a route against the - * URL, and the `ngView` pulls in the partial. - * - * - * - *
        - * Choose: - * Moby | - * Moby: Ch1 | - * Gatsby | - * Gatsby: Ch4 | - * Scarlet Letter
        - * - *
        - * - *
        - * - *
        $location.path() = {{$location.path()}}
        - *
        $route.current.templateUrl = {{$route.current.templateUrl}}
        - *
        $route.current.params = {{$route.current.params}}
        - *
        $route.current.scope.name = {{$route.current.scope.name}}
        - *
        $routeParams = {{$routeParams}}
        - *
        - *
        - * - * - * controller: {{name}}
        - * Book Id: {{params.bookId}}
        - *
        - * - * - * controller: {{name}}
        - * Book Id: {{params.bookId}}
        - * Chapter Id: {{params.chapterId}} - *
        - * - * - * angular.module('ngRouteExample', ['ngRoute']) - * - * .controller('MainController', function($scope, $route, $routeParams, $location) { - * $scope.$route = $route; - * $scope.$location = $location; - * $scope.$routeParams = $routeParams; - * }) - * - * .controller('BookController', function($scope, $routeParams) { - * $scope.name = "BookController"; - * $scope.params = $routeParams; - * }) - * - * .controller('ChapterController', function($scope, $routeParams) { - * $scope.name = "ChapterController"; - * $scope.params = $routeParams; - * }) - * - * .config(function($routeProvider, $locationProvider) { - * $routeProvider - * .when('/Book/:bookId', { - * templateUrl: 'book.html', - * controller: 'BookController', - * resolve: { - * // I will cause a 1 second delay - * delay: function($q, $timeout) { - * var delay = $q.defer(); - * $timeout(delay.resolve, 1000); - * return delay.promise; - * } - * } - * }) - * .when('/Book/:bookId/ch/:chapterId', { - * templateUrl: 'chapter.html', - * controller: 'ChapterController' - * }); - * - * // configure html5 to get links working on jsfiddle - * $locationProvider.html5Mode(true); - * }); - * - * - * - * - * it('should load and compile correct template', function() { - * element(by.linkText('Moby: Ch1')).click(); - * var content = element(by.css('[ng-view]')).getText(); - * expect(content).toMatch(/controller\: ChapterController/); - * expect(content).toMatch(/Book Id\: Moby/); - * expect(content).toMatch(/Chapter Id\: 1/); - * - * element(by.partialLinkText('Scarlet')).click(); - * - * content = element(by.css('[ng-view]')).getText(); - * expect(content).toMatch(/controller\: BookController/); - * expect(content).toMatch(/Book Id\: Scarlet/); - * }); - * - *
        - */ - - /** - * @ngdoc event - * @name $route#$routeChangeStart - * @eventType broadcast on root scope - * @description - * Broadcasted before a route change. At this point the route services starts - * resolving all of the dependencies needed for the route change to occur. - * Typically this involves fetching the view template as well as any dependencies - * defined in `resolve` route property. Once all of the dependencies are resolved - * `$routeChangeSuccess` is fired. - * - * The route change (and the `$location` change that triggered it) can be prevented - * by calling `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} - * for more details about event object. - * - * @param {Object} angularEvent Synthetic event object. - * @param {Route} next Future route information. - * @param {Route} current Current route information. - */ - - /** - * @ngdoc event - * @name $route#$routeChangeSuccess - * @eventType broadcast on root scope - * @description - * Broadcasted after a route change has happened successfully. - * The `resolve` dependencies are now available in the `current.locals` property. - * - * {@link ngRoute.directive:ngView ngView} listens for the directive - * to instantiate the controller and render the view. - * - * @param {Object} angularEvent Synthetic event object. - * @param {Route} current Current route information. - * @param {Route|Undefined} previous Previous route information, or undefined if current is - * first route entered. - */ - - /** - * @ngdoc event - * @name $route#$routeChangeError - * @eventType broadcast on root scope - * @description - * Broadcasted if any of the resolve promises are rejected. - * - * @param {Object} angularEvent Synthetic event object - * @param {Route} current Current route information. - * @param {Route} previous Previous route information. - * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise. - */ - - /** - * @ngdoc event - * @name $route#$routeUpdate - * @eventType broadcast on root scope - * @description - * The `reloadOnSearch` property has been set to false, and we are reusing the same - * instance of the Controller. - * - * @param {Object} angularEvent Synthetic event object - * @param {Route} current Current/previous route information. - */ - - var forceReload = false, - preparedRoute, - preparedRouteIsUpdateOnly, - $route = { - routes: routes, - - /** - * @ngdoc method - * @name $route#reload - * - * @description - * Causes `$route` service to reload the current route even if - * {@link ng.$location $location} hasn't changed. - * - * As a result of that, {@link ngRoute.directive:ngView ngView} - * creates new scope and reinstantiates the controller. - */ - reload: function() { - forceReload = true; - - var fakeLocationEvent = { - defaultPrevented: false, - preventDefault: function fakePreventDefault() { - this.defaultPrevented = true; - forceReload = false; - } - }; - - $rootScope.$evalAsync(function() { - prepareRoute(fakeLocationEvent); - if (!fakeLocationEvent.defaultPrevented) commitRoute(); - }); - }, - - /** - * @ngdoc method - * @name $route#updateParams - * - * @description - * Causes `$route` service to update the current URL, replacing - * current route parameters with those specified in `newParams`. - * Provided property names that match the route's path segment - * definitions will be interpolated into the location's path, while - * remaining properties will be treated as query params. - * - * @param {!Object} newParams mapping of URL parameter names to values - */ - updateParams: function(newParams) { - if (this.current && this.current.$$route) { - newParams = angular.extend({}, this.current.params, newParams); - $location.path(interpolate(this.current.$$route.originalPath, newParams)); - // interpolate modifies newParams, only query params are left - $location.search(newParams); - } else { - throw $routeMinErr('norout', 'Tried updating route when with no current route'); - } - } - }; - - $rootScope.$on('$locationChangeStart', prepareRoute); - $rootScope.$on('$locationChangeSuccess', commitRoute); - - return $route; - - ///////////////////////////////////////////////////// - - /** - * @param on {string} current url - * @param route {Object} route regexp to match the url against - * @return {?Object} - * - * @description - * Check if the route matches the current url. - * - * Inspired by match in - * visionmedia/express/lib/router/router.js. - */ - function switchRouteMatcher(on, route) { - var keys = route.keys, - params = {}; - - if (!route.regexp) return null; - - var m = route.regexp.exec(on); - if (!m) return null; - - for (var i = 1, len = m.length; i < len; ++i) { - var key = keys[i - 1]; - - var val = m[i]; - - if (key && val) { - params[key.name] = val; - } - } - return params; - } - - function prepareRoute($locationEvent) { - var lastRoute = $route.current; - - preparedRoute = parseRoute(); - preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route - && angular.equals(preparedRoute.pathParams, lastRoute.pathParams) - && !preparedRoute.reloadOnSearch && !forceReload; - - if (!preparedRouteIsUpdateOnly && (lastRoute || preparedRoute)) { - if ($rootScope.$broadcast('$routeChangeStart', preparedRoute, lastRoute).defaultPrevented) { - if ($locationEvent) { - $locationEvent.preventDefault(); - } - } - } - } - - function commitRoute() { - var lastRoute = $route.current; - var nextRoute = preparedRoute; - - if (preparedRouteIsUpdateOnly) { - lastRoute.params = nextRoute.params; - angular.copy(lastRoute.params, $routeParams); - $rootScope.$broadcast('$routeUpdate', lastRoute); - } else if (nextRoute || lastRoute) { - forceReload = false; - $route.current = nextRoute; - if (nextRoute) { - if (nextRoute.redirectTo) { - if (angular.isString(nextRoute.redirectTo)) { - $location.path(interpolate(nextRoute.redirectTo, nextRoute.params)).search(nextRoute.params) - .replace(); - } else { - $location.url(nextRoute.redirectTo(nextRoute.pathParams, $location.path(), $location.search())) - .replace(); - } - } - } - - $q.when(nextRoute). - then(function() { - if (nextRoute) { - var locals = angular.extend({}, nextRoute.resolve), - template, templateUrl; - - angular.forEach(locals, function(value, key) { - locals[key] = angular.isString(value) ? - $injector.get(value) : $injector.invoke(value, null, null, key); - }); - - if (angular.isDefined(template = nextRoute.template)) { - if (angular.isFunction(template)) { - template = template(nextRoute.params); - } - } else if (angular.isDefined(templateUrl = nextRoute.templateUrl)) { - if (angular.isFunction(templateUrl)) { - templateUrl = templateUrl(nextRoute.params); - } - if (angular.isDefined(templateUrl)) { - nextRoute.loadedTemplateUrl = $sce.valueOf(templateUrl); - template = $templateRequest(templateUrl); - } - } - if (angular.isDefined(template)) { - locals['$template'] = template; - } - return $q.all(locals); - } - }). - then(function(locals) { - // after route change - if (nextRoute == $route.current) { - if (nextRoute) { - nextRoute.locals = locals; - angular.copy(nextRoute.params, $routeParams); - } - $rootScope.$broadcast('$routeChangeSuccess', nextRoute, lastRoute); - } - }, function(error) { - if (nextRoute == $route.current) { - $rootScope.$broadcast('$routeChangeError', nextRoute, lastRoute, error); - } - }); - } - } - - - /** - * @returns {Object} the current active route, by matching it against the URL - */ - function parseRoute() { - // Match a route - var params, match; - angular.forEach(routes, function(route, path) { - if (!match && (params = switchRouteMatcher($location.path(), route))) { - match = inherit(route, { - params: angular.extend({}, $location.search(), params), - pathParams: params}); - match.$$route = route; - } - }); - // No route matched; fallback to "otherwise" route - return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}}); - } - - /** - * @returns {string} interpolation of the redirect path with the parameters - */ - function interpolate(string, params) { - var result = []; - angular.forEach((string || '').split(':'), function(segment, i) { - if (i === 0) { - result.push(segment); - } else { - var segmentMatch = segment.match(/(\w+)(?:[?*])?(.*)/); - var key = segmentMatch[1]; - result.push(params[key]); - result.push(segmentMatch[2] || ''); - delete params[key]; - } - }); - return result.join(''); - } - }]; -} - -ngRouteModule.provider('$routeParams', $RouteParamsProvider); - - -/** - * @ngdoc service - * @name $routeParams - * @requires $route - * - * @description - * The `$routeParams` service allows you to retrieve the current set of route parameters. - * - * Requires the {@link ngRoute `ngRoute`} module to be installed. - * - * The route parameters are a combination of {@link ng.$location `$location`}'s - * {@link ng.$location#search `search()`} and {@link ng.$location#path `path()`}. - * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched. - * - * In case of parameter name collision, `path` params take precedence over `search` params. - * - * The service guarantees that the identity of the `$routeParams` object will remain unchanged - * (but its properties will likely change) even when a route change occurs. - * - * Note that the `$routeParams` are only updated *after* a route change completes successfully. - * This means that you cannot rely on `$routeParams` being correct in route resolve functions. - * Instead you can use `$route.current.params` to access the new route's parameters. - * - * @example - * ```js - * // Given: - * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby - * // Route: /Chapter/:chapterId/Section/:sectionId - * // - * // Then - * $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'} - * ``` - */ -function $RouteParamsProvider() { - this.$get = function() { return {}; }; -} - -ngRouteModule.directive('ngView', ngViewFactory); -ngRouteModule.directive('ngView', ngViewFillContentFactory); - - -/** - * @ngdoc directive - * @name ngView - * @restrict ECA - * - * @description - * # Overview - * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by - * including the rendered template of the current route into the main layout (`index.html`) file. - * Every time the current route changes, the included view changes with it according to the - * configuration of the `$route` service. - * - * Requires the {@link ngRoute `ngRoute`} module to be installed. - * - * @animations - * enter - animation is used to bring new content into the browser. - * leave - animation is used to animate existing content away. - * - * The enter and leave animation occur concurrently. - * - * @scope - * @priority 400 - * @param {string=} onload Expression to evaluate whenever the view updates. - * - * @param {string=} autoscroll Whether `ngView` should call {@link ng.$anchorScroll - * $anchorScroll} to scroll the viewport after the view is updated. - * - * - If the attribute is not set, disable scrolling. - * - If the attribute is set without value, enable scrolling. - * - Otherwise enable scrolling only if the `autoscroll` attribute value evaluated - * as an expression yields a truthy value. - * @example - - -
        - Choose: - Moby | - Moby: Ch1 | - Gatsby | - Gatsby: Ch4 | - Scarlet Letter
        - -
        -
        -
        -
        - -
        $location.path() = {{main.$location.path()}}
        -
        $route.current.templateUrl = {{main.$route.current.templateUrl}}
        -
        $route.current.params = {{main.$route.current.params}}
        -
        $routeParams = {{main.$routeParams}}
        -
        -
        - - -
        - controller: {{book.name}}
        - Book Id: {{book.params.bookId}}
        -
        -
        - - -
        - controller: {{chapter.name}}
        - Book Id: {{chapter.params.bookId}}
        - Chapter Id: {{chapter.params.chapterId}} -
        -
        - - - .view-animate-container { - position:relative; - height:100px!important; - background:white; - border:1px solid black; - height:40px; - overflow:hidden; - } - - .view-animate { - padding:10px; - } - - .view-animate.ng-enter, .view-animate.ng-leave { - transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; - - display:block; - width:100%; - border-left:1px solid black; - - position:absolute; - top:0; - left:0; - right:0; - bottom:0; - padding:10px; - } - - .view-animate.ng-enter { - left:100%; - } - .view-animate.ng-enter.ng-enter-active { - left:0; - } - .view-animate.ng-leave.ng-leave-active { - left:-100%; - } - - - - angular.module('ngViewExample', ['ngRoute', 'ngAnimate']) - .config(['$routeProvider', '$locationProvider', - function($routeProvider, $locationProvider) { - $routeProvider - .when('/Book/:bookId', { - templateUrl: 'book.html', - controller: 'BookCtrl', - controllerAs: 'book' - }) - .when('/Book/:bookId/ch/:chapterId', { - templateUrl: 'chapter.html', - controller: 'ChapterCtrl', - controllerAs: 'chapter' - }); - - $locationProvider.html5Mode(true); - }]) - .controller('MainCtrl', ['$route', '$routeParams', '$location', - function($route, $routeParams, $location) { - this.$route = $route; - this.$location = $location; - this.$routeParams = $routeParams; - }]) - .controller('BookCtrl', ['$routeParams', function($routeParams) { - this.name = "BookCtrl"; - this.params = $routeParams; - }]) - .controller('ChapterCtrl', ['$routeParams', function($routeParams) { - this.name = "ChapterCtrl"; - this.params = $routeParams; - }]); - - - - - it('should load and compile correct template', function() { - element(by.linkText('Moby: Ch1')).click(); - var content = element(by.css('[ng-view]')).getText(); - expect(content).toMatch(/controller\: ChapterCtrl/); - expect(content).toMatch(/Book Id\: Moby/); - expect(content).toMatch(/Chapter Id\: 1/); - - element(by.partialLinkText('Scarlet')).click(); - - content = element(by.css('[ng-view]')).getText(); - expect(content).toMatch(/controller\: BookCtrl/); - expect(content).toMatch(/Book Id\: Scarlet/); - }); - -
        - */ - - -/** - * @ngdoc event - * @name ngView#$viewContentLoaded - * @eventType emit on the current ngView scope - * @description - * Emitted every time the ngView content is reloaded. - */ -ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate']; -function ngViewFactory($route, $anchorScroll, $animate) { - return { - restrict: 'ECA', - terminal: true, - priority: 400, - transclude: 'element', - link: function(scope, $element, attr, ctrl, $transclude) { - var currentScope, - currentElement, - previousLeaveAnimation, - autoScrollExp = attr.autoscroll, - onloadExp = attr.onload || ''; - - scope.$on('$routeChangeSuccess', update); - update(); - - function cleanupLastView() { - if (previousLeaveAnimation) { - $animate.cancel(previousLeaveAnimation); - previousLeaveAnimation = null; - } - - if (currentScope) { - currentScope.$destroy(); - currentScope = null; - } - if (currentElement) { - previousLeaveAnimation = $animate.leave(currentElement); - previousLeaveAnimation.then(function() { - previousLeaveAnimation = null; - }); - currentElement = null; - } - } - - function update() { - var locals = $route.current && $route.current.locals, - template = locals && locals.$template; - - if (angular.isDefined(template)) { - var newScope = scope.$new(); - var current = $route.current; - - // Note: This will also link all children of ng-view that were contained in the original - // html. If that content contains controllers, ... they could pollute/change the scope. - // However, using ng-view on an element with additional content does not make sense... - // Note: We can't remove them in the cloneAttchFn of $transclude as that - // function is called before linking the content, which would apply child - // directives to non existing elements. - var clone = $transclude(newScope, function(clone) { - $animate.enter(clone, null, currentElement || $element).then(function onNgViewEnter() { - if (angular.isDefined(autoScrollExp) - && (!autoScrollExp || scope.$eval(autoScrollExp))) { - $anchorScroll(); - } - }); - cleanupLastView(); - }); - - currentElement = clone; - currentScope = current.scope = newScope; - currentScope.$emit('$viewContentLoaded'); - currentScope.$eval(onloadExp); - } else { - cleanupLastView(); - } - } - } - }; -} - -// This directive is called during the $transclude call of the first `ngView` directive. -// It will replace and compile the content of the element with the loaded template. -// We need this directive so that the element content is already filled when -// the link function of another directive on the same element as ngView -// is called. -ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route']; -function ngViewFillContentFactory($compile, $controller, $route) { - return { - restrict: 'ECA', - priority: -400, - link: function(scope, $element) { - var current = $route.current, - locals = current.locals; - - $element.html(locals.$template); - - var link = $compile($element.contents()); - - if (current.controller) { - locals.$scope = scope; - var controller = $controller(current.controller, locals); - if (current.controllerAs) { - scope[current.controllerAs] = controller; - } - $element.data('$ngControllerController', controller); - $element.children().data('$ngControllerController', controller); - } - scope[current.resolveAs || '$resolve'] = locals; - - link(scope); - } - }; -} - - -})(window, window.angular); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-route.min.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-route.min.js deleted file mode 100644 index 4d0d0187..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-route.min.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - AngularJS v1.5.0 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(r,d,C){'use strict';function x(s,h,g){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,y){function k(){n&&(g.cancel(n),n=null);l&&(l.$destroy(),l=null);m&&(n=g.leave(m),n.then(function(){n=null}),m=null)}function z(){var b=s.current&&s.current.locals;if(d.isDefined(b&&b.$template)){var b=a.$new(),f=s.current;m=y(b,function(b){g.enter(b,null,m||c).then(function(){!d.isDefined(u)||u&&!a.$eval(u)||h()});k()});l=f.scope=b;l.$emit("$viewContentLoaded"); -l.$eval(v)}else k()}var l,m,n,u=b.autoscroll,v=b.onload||"";a.$on("$routeChangeSuccess",z);z()}}}function A(d,h,g){return{restrict:"ECA",priority:-400,link:function(a,c){var b=g.current,f=b.locals;c.html(f.$template);var y=d(c.contents());if(b.controller){f.$scope=a;var k=h(b.controller,f);b.controllerAs&&(a[b.controllerAs]=k);c.data("$ngControllerController",k);c.children().data("$ngControllerController",k)}a[b.resolveAs||"$resolve"]=f;y(a)}}}r=d.module("ngRoute",["ng"]).provider("$route",function(){function s(a, -c){return d.extend(Object.create(a),c)}function h(a,d){var b=d.caseInsensitiveMatch,f={originalPath:a,regexp:a},g=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,d,b,c){a="?"===c?c:null;c="*"===c?c:null;g.push({name:b,optional:!!a});d=d||"";return""+(a?"":d)+"(?:"+(a?d:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=new RegExp("^"+a+"$",b?"i":"");return f}var g={};this.when=function(a,c){var b=d.copy(c);d.isUndefined(b.reloadOnSearch)&& -(b.reloadOnSearch=!0);d.isUndefined(b.caseInsensitiveMatch)&&(b.caseInsensitiveMatch=this.caseInsensitiveMatch);g[a]=d.extend(b,a&&h(a,b));if(a){var f="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";g[f]=d.extend({redirectTo:a},h(f,b))}return this};this.caseInsensitiveMatch=!1;this.otherwise=function(a){"string"===typeof a&&(a={redirectTo:a});this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function(a,c,b,f,h,k,r){function l(b){var e= -t.current;(x=(p=n())&&e&&p.$$route===e.$$route&&d.equals(p.pathParams,e.pathParams)&&!p.reloadOnSearch&&!v)||!e&&!p||a.$broadcast("$routeChangeStart",p,e).defaultPrevented&&b&&b.preventDefault()}function m(){var w=t.current,e=p;if(x)w.params=e.params,d.copy(w.params,b),a.$broadcast("$routeUpdate",w);else if(e||w)v=!1,(t.current=e)&&e.redirectTo&&(d.isString(e.redirectTo)?c.path(u(e.redirectTo,e.params)).search(e.params).replace():c.url(e.redirectTo(e.pathParams,c.path(),c.search())).replace()),f.when(e).then(function(){if(e){var a= -d.extend({},e.resolve),b,c;d.forEach(a,function(b,e){a[e]=d.isString(b)?h.get(b):h.invoke(b,null,null,e)});d.isDefined(b=e.template)?d.isFunction(b)&&(b=b(e.params)):d.isDefined(c=e.templateUrl)&&(d.isFunction(c)&&(c=c(e.params)),d.isDefined(c)&&(e.loadedTemplateUrl=r.valueOf(c),b=k(c)));d.isDefined(b)&&(a.$template=b);return f.all(a)}}).then(function(c){e==t.current&&(e&&(e.locals=c,d.copy(e.params,b)),a.$broadcast("$routeChangeSuccess",e,w))},function(b){e==t.current&&a.$broadcast("$routeChangeError", -e,w,b)})}function n(){var a,b;d.forEach(g,function(f,g){var q;if(q=!b){var h=c.path();q=f.keys;var l={};if(f.regexp)if(h=f.regexp.exec(h)){for(var k=1,n=h.length;k - * - * See {@link ngSanitize.$sanitize `$sanitize`} for usage. - */ - -/** - * @ngdoc service - * @name $sanitize - * @kind function - * - * @description - * Sanitizes an html string by stripping all potentially dangerous tokens. - * - * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are - * then serialized back to properly escaped html string. This means that no unsafe input can make - * it into the returned string. - * - * The whitelist for URL sanitization of attribute values is configured using the functions - * `aHrefSanitizationWhitelist` and `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider - * `$compileProvider`}. - * - * The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}. - * - * @param {string} html HTML input. - * @returns {string} Sanitized HTML. - * - * @example - - - -
        - Snippet: - - - - - - - - - - - - - - - - - - - - - - - - - -
        DirectiveHowSourceRendered
        ng-bind-htmlAutomatically uses $sanitize
        <div ng-bind-html="snippet">
        </div>
        ng-bind-htmlBypass $sanitize by explicitly trusting the dangerous value -
        <div ng-bind-html="deliberatelyTrustDangerousSnippet()">
        -</div>
        -
        ng-bindAutomatically escapes
        <div ng-bind="snippet">
        </div>
        -
        -
        - - it('should sanitize the html snippet by default', function() { - expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). - toBe('

        an html\nclick here\nsnippet

        '); - }); - - it('should inline raw snippet if bound to a trusted value', function() { - expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()). - toBe("

        an html\n" + - "click here\n" + - "snippet

        "); - }); - - it('should escape snippet without any filter', function() { - expect(element(by.css('#bind-default div')).getInnerHtml()). - toBe("<p style=\"color:blue\">an html\n" + - "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + - "snippet</p>"); - }); - - it('should update', function() { - element(by.model('snippet')).clear(); - element(by.model('snippet')).sendKeys('new text'); - expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). - toBe('new text'); - expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe( - 'new text'); - expect(element(by.css('#bind-default div')).getInnerHtml()).toBe( - "new <b onclick=\"alert(1)\">text</b>"); - }); -
        -
        - */ - - -/** - * @ngdoc provider - * @name $sanitizeProvider - * - * @description - * Creates and configures {@link $sanitize} instance. - */ -function $SanitizeProvider() { - var svgEnabled = false; - - this.$get = ['$$sanitizeUri', function($$sanitizeUri) { - if (svgEnabled) { - angular.extend(validElements, svgElements); - } - return function(html) { - var buf = []; - htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) { - return !/^unsafe:/.test($$sanitizeUri(uri, isImage)); - })); - return buf.join(''); - }; - }]; - - - /** - * @ngdoc method - * @name $sanitizeProvider#enableSvg - * @kind function - * - * @description - * Enables a subset of svg to be supported by the sanitizer. - * - *
        - *

        By enabling this setting without taking other precautions, you might expose your - * application to click-hijacking attacks. In these attacks, sanitized svg elements could be positioned - * outside of the containing element and be rendered over other elements on the page (e.g. a login - * link). Such behavior can then result in phishing incidents.

        - * - *

        To protect against these, explicitly setup `overflow: hidden` css rule for all potential svg - * tags within the sanitized content:

        - * - *
        - * - *
        
        -   *   .rootOfTheIncludedContent svg {
        -   *     overflow: hidden !important;
        -   *   }
        -   *   
        - *
        - * - * @param {boolean=} regexp New regexp to whitelist urls with. - * @returns {boolean|ng.$sanitizeProvider} Returns the currently configured value if called - * without an argument or self for chaining otherwise. - */ - this.enableSvg = function(enableSvg) { - if (angular.isDefined(enableSvg)) { - svgEnabled = enableSvg; - return this; - } else { - return svgEnabled; - } - }; -} - -function sanitizeText(chars) { - var buf = []; - var writer = htmlSanitizeWriter(buf, angular.noop); - writer.chars(chars); - return buf.join(''); -} - - -// Regular Expressions for parsing tags and attributes -var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, - // Match everything outside of normal chars and " (quote character) - NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g; - - -// Good source of info about elements and attributes -// http://dev.w3.org/html5/spec/Overview.html#semantics -// http://simon.html5.org/html-elements - -// Safe Void Elements - HTML5 -// http://dev.w3.org/html5/spec/Overview.html#void-elements -var voidElements = toMap("area,br,col,hr,img,wbr"); - -// Elements that you can, intentionally, leave open (and which close themselves) -// http://dev.w3.org/html5/spec/Overview.html#optional-tags -var optionalEndTagBlockElements = toMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"), - optionalEndTagInlineElements = toMap("rp,rt"), - optionalEndTagElements = angular.extend({}, - optionalEndTagInlineElements, - optionalEndTagBlockElements); - -// Safe Block Elements - HTML5 -var blockElements = angular.extend({}, optionalEndTagBlockElements, toMap("address,article," + - "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," + - "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul")); - -// Inline Elements - HTML5 -var inlineElements = angular.extend({}, optionalEndTagInlineElements, toMap("a,abbr,acronym,b," + - "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," + - "samp,small,span,strike,strong,sub,sup,time,tt,u,var")); - -// SVG Elements -// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements -// Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted. -// They can potentially allow for arbitrary javascript to be executed. See #11290 -var svgElements = toMap("circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph," + - "hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline," + - "radialGradient,rect,stop,svg,switch,text,title,tspan"); - -// Blocked Elements (will be stripped) -var blockedElements = toMap("script,style"); - -var validElements = angular.extend({}, - voidElements, - blockElements, - inlineElements, - optionalEndTagElements); - -//Attributes that have href and hence need to be sanitized -var uriAttrs = toMap("background,cite,href,longdesc,src,xlink:href"); - -var htmlAttrs = toMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' + - 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' + - 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' + - 'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' + - 'valign,value,vspace,width'); - -// SVG attributes (without "id" and "name" attributes) -// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes -var svgAttrs = toMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' + - 'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' + - 'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' + - 'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' + - 'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' + - 'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' + - 'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' + - 'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' + - 'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' + - 'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' + - 'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' + - 'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' + - 'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' + - 'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' + - 'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true); - -var validAttrs = angular.extend({}, - uriAttrs, - svgAttrs, - htmlAttrs); - -function toMap(str, lowercaseKeys) { - var obj = {}, items = str.split(','), i; - for (i = 0; i < items.length; i++) { - obj[lowercaseKeys ? angular.lowercase(items[i]) : items[i]] = true; - } - return obj; -} - -var inertBodyElement; -(function(window) { - var doc; - if (window.document && window.document.implementation) { - doc = window.document.implementation.createHTMLDocument("inert"); - } else { - throw $sanitizeMinErr('noinert', "Can't create an inert html document"); - } - var docElement = doc.documentElement || doc.getDocumentElement(); - var bodyElements = docElement.getElementsByTagName('body'); - - // usually there should be only one body element in the document, but IE doesn't have any, so we need to create one - if (bodyElements.length === 1) { - inertBodyElement = bodyElements[0]; - } else { - var html = doc.createElement('html'); - inertBodyElement = doc.createElement('body'); - html.appendChild(inertBodyElement); - doc.appendChild(html); - } -})(window); - -/** - * @example - * htmlParser(htmlString, { - * start: function(tag, attrs) {}, - * end: function(tag) {}, - * chars: function(text) {}, - * comment: function(text) {} - * }); - * - * @param {string} html string - * @param {object} handler - */ -function htmlParser(html, handler) { - if (html === null || html === undefined) { - html = ''; - } else if (typeof html !== 'string') { - html = '' + html; - } - inertBodyElement.innerHTML = html; - - //mXSS protection - var mXSSAttempts = 5; - do { - if (mXSSAttempts === 0) { - throw $sanitizeMinErr('uinput', "Failed to sanitize html because the input is unstable"); - } - mXSSAttempts--; - - // strip custom-namespaced attributes on IE<=11 - if (document.documentMode <= 11) { - stripCustomNsAttrs(inertBodyElement); - } - html = inertBodyElement.innerHTML; //trigger mXSS - inertBodyElement.innerHTML = html; - } while (html !== inertBodyElement.innerHTML); - - var node = inertBodyElement.firstChild; - while (node) { - switch (node.nodeType) { - case 1: // ELEMENT_NODE - handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes)); - break; - case 3: // TEXT NODE - handler.chars(node.textContent); - break; - } - - var nextNode; - if (!(nextNode = node.firstChild)) { - if (node.nodeType == 1) { - handler.end(node.nodeName.toLowerCase()); - } - nextNode = node.nextSibling; - if (!nextNode) { - while (nextNode == null) { - node = node.parentNode; - if (node === inertBodyElement) break; - nextNode = node.nextSibling; - if (node.nodeType == 1) { - handler.end(node.nodeName.toLowerCase()); - } - } - } - } - node = nextNode; - } - - while (node = inertBodyElement.firstChild) { - inertBodyElement.removeChild(node); - } -} - -function attrToMap(attrs) { - var map = {}; - for (var i = 0, ii = attrs.length; i < ii; i++) { - var attr = attrs[i]; - map[attr.name] = attr.value; - } - return map; -} - - -/** - * Escapes all potentially dangerous characters, so that the - * resulting string can be safely inserted into attribute or - * element text. - * @param value - * @returns {string} escaped text - */ -function encodeEntities(value) { - return value. - replace(/&/g, '&'). - replace(SURROGATE_PAIR_REGEXP, function(value) { - var hi = value.charCodeAt(0); - var low = value.charCodeAt(1); - return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';'; - }). - replace(NON_ALPHANUMERIC_REGEXP, function(value) { - return '&#' + value.charCodeAt(0) + ';'; - }). - replace(//g, '>'); -} - -/** - * create an HTML/XML writer which writes to buffer - * @param {Array} buf use buf.join('') to get out sanitized html string - * @returns {object} in the form of { - * start: function(tag, attrs) {}, - * end: function(tag) {}, - * chars: function(text) {}, - * comment: function(text) {} - * } - */ -function htmlSanitizeWriter(buf, uriValidator) { - var ignoreCurrentElement = false; - var out = angular.bind(buf, buf.push); - return { - start: function(tag, attrs) { - tag = angular.lowercase(tag); - if (!ignoreCurrentElement && blockedElements[tag]) { - ignoreCurrentElement = tag; - } - if (!ignoreCurrentElement && validElements[tag] === true) { - out('<'); - out(tag); - angular.forEach(attrs, function(value, key) { - var lkey=angular.lowercase(key); - var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background'); - if (validAttrs[lkey] === true && - (uriAttrs[lkey] !== true || uriValidator(value, isImage))) { - out(' '); - out(key); - out('="'); - out(encodeEntities(value)); - out('"'); - } - }); - out('>'); - } - }, - end: function(tag) { - tag = angular.lowercase(tag); - if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) { - out(''); - } - if (tag == ignoreCurrentElement) { - ignoreCurrentElement = false; - } - }, - chars: function(chars) { - if (!ignoreCurrentElement) { - out(encodeEntities(chars)); - } - } - }; -} - - -/** - * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1' attribute to declare - * ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo'). This is undesirable since we don't want - * to allow any of these custom attributes. This method strips them all. - * - * @param node Root element to process - */ -function stripCustomNsAttrs(node) { - if (node.nodeType === Node.ELEMENT_NODE) { - var attrs = node.attributes; - for (var i = 0, l = attrs.length; i < l; i++) { - var attrNode = attrs[i]; - var attrName = attrNode.name.toLowerCase(); - if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) { - node.removeAttributeNode(attrNode); - i--; - l--; - } - } - } - - var nextNode = node.firstChild; - if (nextNode) { - stripCustomNsAttrs(nextNode); - } - - nextNode = node.nextSibling; - if (nextNode) { - stripCustomNsAttrs(nextNode); - } -} - - - -// define ngSanitize module and register $sanitize service -angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider); - -/* global sanitizeText: false */ - -/** - * @ngdoc filter - * @name linky - * @kind function - * - * @description - * Finds links in text input and turns them into html links. Supports `http/https/ftp/mailto` and - * plain email address links. - * - * Requires the {@link ngSanitize `ngSanitize`} module to be installed. - * - * @param {string} text Input text. - * @param {string} target Window (`_blank|_self|_parent|_top`) or named frame to open links in. - * @param {object|function(url)} [attributes] Add custom attributes to the link element. - * - * Can be one of: - * - * - `object`: A map of attributes - * - `function`: Takes the url as a parameter and returns a map of attributes - * - * If the map of attributes contains a value for `target`, it overrides the value of - * the target parameter. - * - * - * @returns {string} Html-linkified and {@link $sanitize sanitized} text. - * - * @usage - - * - * @example - - -
        - Snippet: - - - - - - - - - - - - - - - - - - - - - - - - - - -
        FilterSourceRendered
        linky filter -
        <div ng-bind-html="snippet | linky">
        </div>
        -
        -
        -
        linky target -
        <div ng-bind-html="snippetWithSingleURL | linky:'_blank'">
        </div>
        -
        -
        -
        linky custom attributes -
        <div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}">
        </div>
        -
        -
        -
        no filter
        <div ng-bind="snippet">
        </div>
        - - - angular.module('linkyExample', ['ngSanitize']) - .controller('ExampleController', ['$scope', function($scope) { - $scope.snippet = - 'Pretty text with some links:\n'+ - 'http://angularjs.org/,\n'+ - 'mailto:us@somewhere.org,\n'+ - 'another@somewhere.org,\n'+ - 'and one more: ftp://127.0.0.1/.'; - $scope.snippetWithSingleURL = 'http://angularjs.org/'; - }]); - - - it('should linkify the snippet with urls', function() { - expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). - toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' + - 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); - expect(element.all(by.css('#linky-filter a')).count()).toEqual(4); - }); - - it('should not linkify snippet without the linky filter', function() { - expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()). - toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' + - 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); - expect(element.all(by.css('#escaped-html a')).count()).toEqual(0); - }); - - it('should update', function() { - element(by.model('snippet')).clear(); - element(by.model('snippet')).sendKeys('new http://link.'); - expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). - toBe('new http://link.'); - expect(element.all(by.css('#linky-filter a')).count()).toEqual(1); - expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()) - .toBe('new http://link.'); - }); - - it('should work with the target property', function() { - expect(element(by.id('linky-target')). - element(by.binding("snippetWithSingleURL | linky:'_blank'")).getText()). - toBe('http://angularjs.org/'); - expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank'); - }); - - it('should optionally add custom attributes', function() { - expect(element(by.id('linky-custom-attributes')). - element(by.binding("snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}")).getText()). - toBe('http://angularjs.org/'); - expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow'); - }); - - - */ -angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { - var LINKY_URL_REGEXP = - /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i, - MAILTO_REGEXP = /^mailto:/i; - - var linkyMinErr = angular.$$minErr('linky'); - var isString = angular.isString; - - return function(text, target, attributes) { - if (text == null || text === '') return text; - if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text); - - var match; - var raw = text; - var html = []; - var url; - var i; - while ((match = raw.match(LINKY_URL_REGEXP))) { - // We can not end in these as they are sometimes found at the end of the sentence - url = match[0]; - // if we did not match ftp/http/www/mailto then assume mailto - if (!match[2] && !match[4]) { - url = (match[3] ? 'http://' : 'mailto:') + url; - } - i = match.index; - addText(raw.substr(0, i)); - addLink(url, match[0].replace(MAILTO_REGEXP, '')); - raw = raw.substring(i + match[0].length); - } - addText(raw); - return $sanitize(html.join('')); - - function addText(text) { - if (!text) { - return; - } - html.push(sanitizeText(text)); - } - - function addLink(url, text) { - var key; - html.push(''); - addText(text); - html.push(''); - } - }; -}]); - - -})(window, window.angular); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-sanitize.min.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-sanitize.min.js deleted file mode 100644 index 135d5a0e..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-sanitize.min.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - AngularJS v1.5.0 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(A,e,B){'use strict';function C(a){var c=[];v(c,e.noop).chars(a);return c.join("")}function h(a,c){var b={},d=a.split(","),l;for(l=0;l=document.documentMode&&n(g);a=g.innerHTML;g.innerHTML=a}while(a!==g.innerHTML);for(b=g.firstChild;b;){switch(b.nodeType){case 1:c.start(b.nodeName.toLowerCase(),E(b.attributes)); -break;case 3:c.chars(b.textContent)}var d;if(!(d=b.firstChild)&&(1==b.nodeType&&c.end(b.nodeName.toLowerCase()),d=b.nextSibling,!d))for(;null==d;){b=b.parentNode;if(b===g)break;d=b.nextSibling;1==b.nodeType&&c.end(b.nodeName.toLowerCase())}b=d}for(;b=g.firstChild;)g.removeChild(b)}function E(a){for(var c={},b=0,d=a.length;b/g,">")}function v(a,c){var b=!1,d=e.bind(a,a.push);return{start:function(a,f){a=e.lowercase(a);!b&&H[a]&&(b=a);b||!0!==t[a]||(d("<"),d(a),e.forEach(f,function(b,f){var g=e.lowercase(f),h="img"===a&&"src"===g||"background"===g;!0!==I[g]||!0===y[g]&&!c(b,h)||(d(" "),d(f),d('="'),d(x(b)),d('"'))}),d(">"))},end:function(a){a=e.lowercase(a);b||!0!==t[a]||!0===z[a]||(d(""));a== -b&&(b=!1)},chars:function(a){b||d(x(a))}}}function n(a){if(a.nodeType===Node.ELEMENT_NODE)for(var c=a.attributes,b=0,d=c.length;b"\u201d\u2019]/i,b=/^mailto:/i,d=e.$$minErr("linky"),g=e.isString;return function(f,h,m){function k(a){a&&p.push(C(a))}function q(a,b){var c;p.push("');k(b);p.push("")}if(null==f||""===f)return f;if(!g(f))throw d("notstring",f);for(var r=f,p=[],s,n;f=r.match(c);)s=f[0],f[2]||f[4]||(s=(f[3]?"http://":"mailto:")+s),n=f.index,k(r.substr(0,n)),q(s,f[0].replace(b,"")),r=r.substring(n+f[0].length);k(r);return a(p.join(""))}}])})(window,window.angular); -//# sourceMappingURL=angular-sanitize.min.js.map diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-sanitize.min.js.map b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-sanitize.min.js.map deleted file mode 100644 index 7276abd2..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-sanitize.min.js.map +++ /dev/null @@ -1,8 +0,0 @@ -{ -"version":3, -"file":"angular-sanitize.min.js", -"lineCount":14, -"mappings":"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", -"sources":["angular-sanitize.js"], -"names":["window","angular","undefined","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","toMap","str","lowercaseKeys","obj","items","split","i","length","lowercase","htmlParser","html","handler","inertBodyElement","innerHTML","mXSSAttempts","$sanitizeMinErr","document","documentMode","stripCustomNsAttrs","node","firstChild","nodeType","start","nodeName","toLowerCase","attrToMap","attributes","textContent","nextNode","end","nextSibling","parentNode","removeChild","attrs","map","ii","attr","name","value","encodeEntities","replace","SURROGATE_PAIR_REGEXP","hi","charCodeAt","low","NON_ALPHANUMERIC_REGEXP","uriValidator","ignoreCurrentElement","out","bind","push","tag","blockedElements","validElements","forEach","key","lkey","isImage","validAttrs","uriAttrs","voidElements","Node","ELEMENT_NODE","l","attrNode","attrName","indexOf","removeAttributeNode","$$minErr","optionalEndTagBlockElements","optionalEndTagInlineElements","optionalEndTagElements","extend","blockElements","inlineElements","svgElements","htmlAttrs","svgAttrs","implementation","doc","createHTMLDocument","bodyElements","getElementsByTagName","documentElement","getDocumentElement","createElement","appendChild","module","provider","$SanitizeProvider","svgEnabled","$get","$$sanitizeUri","uri","test","enableSvg","this.enableSvg","isDefined","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","linkyMinErr","isString","text","target","addText","addLink","url","isFunction","isObject","raw","match","index","substr","substring"] -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-scenario.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-scenario.js deleted file mode 100644 index 20af805f..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/external/angular-1.5/angular-scenario.js +++ /dev/null @@ -1,41849 +0,0 @@ -/*! - * jQuery JavaScript Library v2.1.1 - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-05-01T17:11Z - */ - -(function( global, factory ) {'use strict'; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - // For CommonJS and CommonJS-like environments where a proper window is present, - // execute the factory and get jQuery - // For environments that do not inherently posses a window with a document - // (such as Node.js), expose a jQuery-making factory as module.exports - // This accentuates the need for the creation of a real window - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Can't do this because several apps including ASP.NET trace -// the stack via arguments.caller.callee and Firefox dies if -// you try to trace through "use strict" call chains. (#13335) -// Support: Firefox 18+ -// - -var arr = []; - -var slice = arr.slice; - -var concat = arr.concat; - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var support = {}; - - - -var - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - - version = "2.1.1", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }, - - // Support: Android<4.1 - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([\da-z])/gi, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; - -jQuery.fn = jQuery.prototype = { - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // Start with an empty selector - selector: "", - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num != null ? - - // Return just the one element from the set - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : - - // Return all the elements in a clean array - slice.call( this ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray, - - isWindow: function( obj ) { - return obj != null && obj === obj.window; - }, - - isNumeric: function( obj ) { - // parseFloat NaNs numeric-cast false positives (null|true|false|"") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; - }, - - isPlainObject: function( obj ) { - // Not plain objects: - // - Any object or value whose internal [[Class]] property is not "[object Object]" - // - DOM nodes - // - window - if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.constructor && - !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { - return false; - } - - // If the function hasn't returned already, we're confident that - // |obj| is a plain object, created by {} or constructed with new Object - return true; - }, - - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - // Support: Android < 4.0, iOS < 6 (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call(obj) ] || "object" : - typeof obj; - }, - - // Evaluates a script in a global context - globalEval: function( code ) { - var script, - indirect = eval; - - code = jQuery.trim( code ); - - if ( code ) { - // If the code includes a valid, prologue position - // strict mode pragma, execute code by injecting a - // script tag into the document. - if ( code.indexOf("use strict") === 1 ) { - script = document.createElement("script"); - script.text = code; - document.head.appendChild( script ).parentNode.removeChild( script ); - } else { - // Otherwise, avoid the DOM node creation, insertion - // and removal by using an indirect global eval - indirect( code ); - } - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - // args is for internal usage only - each: function( obj, callback, args ) { - var value, - i = 0, - length = obj.length, - isArray = isArraylike( obj ); - - if ( args ) { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } - } - - return obj; - }, - - // Support: Android<4.1 - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArraylike( Object(arr) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, - i = 0, - length = elems.length, - isArray = isArraylike( elems ), - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var tmp, args, proxy; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: Date.now, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -function isArraylike( obj ) { - var length = obj.length, - type = jQuery.type( obj ); - - if ( type === "function" || jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.nodeType === 1 && length ) { - return true; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v1.10.19 - * http://sizzlejs.com/ - * - * Copyright 2013 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-04-18 - */ -(function( window ) { - -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + -(new Date()), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // General-purpose constants - strundefined = typeof undefined, - MAX_NEGATIVE = 1 << 31, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf if we can't use a native one - indexOf = arr.indexOf || function( elem ) { - var i = 0, - len = this.length; - for ( ; i < len; i++ ) { - if ( this[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/css3-syntax/#characters - characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - - // Loosely modeled on CSS identifier characters - // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors - // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = characterEncoding.replace( "w", "w#" ), - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + characterEncoding + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + characterEncoding + ")" ), - "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - rescape = /'|\\/g, - - // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }; - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var match, elem, m, nodeType, - // QSA vars - i, groups, old, nid, newContext, newSelector; - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - - context = context || document; - results = results || []; - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { - return []; - } - - if ( documentIsHTML && !seed ) { - - // Shortcuts - if ( (match = rquickExpr.exec( selector )) ) { - // Speed-up: Sizzle("#ID") - if ( (m = match[1]) ) { - if ( nodeType === 9 ) { - elem = context.getElementById( m ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document (jQuery #6963) - if ( elem && elem.parentNode ) { - // Handle the case where IE, Opera, and Webkit return items - // by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - } else { - // Context is not a document - if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && - contains( context, elem ) && elem.id === m ) { - results.push( elem ); - return results; - } - } - - // Speed-up: Sizzle("TAG") - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Speed-up: Sizzle(".CLASS") - } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // QSA path - if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - nid = old = expando; - newContext = context; - newSelector = nodeType === 9 && selector; - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - groups = tokenize( selector ); - - if ( (old = context.getAttribute("id")) ) { - nid = old.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", nid ); - } - nid = "[id='" + nid + "'] "; - - i = groups.length; - while ( i-- ) { - groups[i] = nid + toSelector( groups[i] ); - } - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; - newSelector = groups.join(","); - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch(qsaError) { - } finally { - if ( !old ) { - context.removeAttribute("id"); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {Function(string, Object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result - */ -function assert( fn ) { - var div = document.createElement("div"); - - try { - return !!fn( div ); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if ( div.parentNode ) { - div.parentNode.removeChild( div ); - } - // release memory in IE - div = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = attrs.length; - - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - ( ~b.sourceIndex || MAX_NEGATIVE ) - - ( ~a.sourceIndex || MAX_NEGATIVE ); - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { - argument = +argument; - return markFunction(function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== strundefined && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, - doc = node ? node.ownerDocument || node : preferredDoc, - parent = doc.defaultView; - - // If no document and documentElement is available, return - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Set our document - document = doc; - docElem = doc.documentElement; - - // Support tests - documentIsHTML = !isXML( doc ); - - // Support: IE>8 - // If iframe document is assigned to "document" variable and if iframe has been reloaded, - // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 - // IE6-8 do not support the defaultView property so parent will be undefined - if ( parent && parent !== parent.top ) { - // IE11 does not have attachEvent, so all must suffer - if ( parent.addEventListener ) { - parent.addEventListener( "unload", function() { - setDocument(); - }, false ); - } else if ( parent.attachEvent ) { - parent.attachEvent( "onunload", function() { - setDocument(); - }); - } - } - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) - support.attributes = assert(function( div ) { - div.className = "i"; - return !div.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( div ) { - div.appendChild( doc.createComment("") ); - return !div.getElementsByTagName("*").length; - }); - - // Check if getElementsByClassName can be trusted - support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { - div.innerHTML = "
        "; - - // Support: Safari<4 - // Catch class over-caching - div.firstChild.className = "i"; - // Support: Opera<10 - // Catch gEBCN failure to find non-leading classes - return div.getElementsByClassName("i").length === 2; - }); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function( div ) { - docElem.appendChild( div ).id = expando; - return !doc.getElementsByName || !doc.getElementsByName( expando ).length; - }); - - // ID find and filter - if ( support.getById ) { - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== strundefined && documentIsHTML ) { - var m = context.getElementById( id ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [ m ] : []; - } - }; - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute("id") === attrId; - }; - }; - } else { - // Support: IE6/7 - // getElementById is not reliable as a find shortcut - delete Expr.find["ID"]; - - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== strundefined ) { - return context.getElementsByTagName( tag ); - } - } : - function( tag, context ) { - var elem, - tmp = [], - i = 0, - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( (elem = results[i++]) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See http://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function( div ) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // http://bugs.jquery.com/ticket/12359 - div.innerHTML = ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( div.querySelectorAll("[msallowclip^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !div.querySelectorAll("[selected]").length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); - } - }); - - assert(function( div ) { - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = doc.createElement("input"); - input.setAttribute( "type", "hidden" ); - div.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( div.querySelectorAll("[name=d]").length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":enabled").length ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - div.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { - - assert(function( div ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( div, "div" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( div, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully does not implement inclusive descendent - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); - } : - function( a, b ) { - if ( b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - // Choose the first element that is related to our preferred document - if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { - return -1; - } - if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - return a === doc ? -1 : - b === doc ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( (cur = cur.parentNode) ) { - ap.unshift( cur ); - } - cur = b; - while ( (cur = cur.parentNode) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return doc; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace( rattributeQuotes, "='$1']" ); - - if ( support.matchesSelector && documentIsHTML && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch(e) {} - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - // If no nodeType, this is expected to be an array - while ( (node = elem[i++]) ) { - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); - - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if ( match[1].slice( 0, 3 ) === "nth" ) { - // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); - - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[6] && match[2]; - - if ( matchExpr["CHILD"].test( match[0] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[3] ) { - match[2] = match[4] || match[5] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { - - // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { return true; } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); - }); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - }; - }, - - "CHILD": function( type, what, argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, context, xml ) { - var cache, outerCache, node, diff, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( (node = node[ dir ]) ) { - if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - // Seek `elem` from a previously-cached index - outerCache = parent[ expando ] || (parent[ expando ] = {}); - cache = outerCache[ type ] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = cache[0] === dirruns && cache[2]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( (node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - outerCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - // Use previously-cached element index if available - } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { - diff = cache[1]; - - // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) - } else { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { - // Cache the index of each encountered element - if ( useCache ) { - (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf.call( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); - } - }) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function( selector ) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function( elem, context, xml ) { - input[0] = elem; - matcher( input, null, xml, results ); - return !results.pop(); - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - - "contains": markFunction(function( text ) { - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( (elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); - return false; - }; - }), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": function( elem ) { - return elem.disabled === false; - }, - - "disabled": function( elem ) { - return elem.disabled === true; - }, - - "checked": function( elem ) { - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo(function() { - return [ 0 ]; - }), - - "last": createPositionalPseudo(function( matchIndexes, length ) { - return [ length - 1 ]; - }), - - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - }), - - "even": createPositionalPseudo(function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }) - } -}; - -Expr.pseudos["nth"] = Expr.pseudos["eq"]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { - if ( match ) { - // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; - } - groups.push( (tokens = []) ); - } - - matched = false; - - // Combinators - if ( (match = rcombinators.exec( soFar )) ) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[i].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - checkNonElements = base && dir === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching - if ( xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); - if ( (oldCache = outerCache[ dir ]) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return (newCache[ 2 ] = oldCache[ 2 ]); - } else { - // Reuse newcache so results back-propagate to previous elements - outerCache[ dir ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { - return true; - } - } - } - } - } - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[0]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction(function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) ) { - // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); - } - } - postFinder( null, (matcherOut = []), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - }); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf.call( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - } ]; - - for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; - } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if ( outermost ) { - outermostContext = context !== document && context; - } - - // Add elements passing elementMatchers directly to results - // Keep `i` a string if there are no elements so `matchedCount` will be "00" below - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // Apply set filters to unmatched elements - matchedCount += i; - if ( bySet && i !== matchedCount ) { - j = 0; - while ( (matcher = setMatchers[j++]) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[i] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); - - results = results || []; - - // Try to minimize operations if there is no seed and only one group - if ( match.length === 1 ) { - - // Take a shortcut and set the context if the root selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - support.getById && context.nodeType === 9 && documentIsHTML && - Expr.relative[ tokens[1].type ] ) { - - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[i]; - - // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { - break; - } - if ( (find = Expr.find[ type ]) ) { - // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; - -// Support: Chrome<14 -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( div1 ) { - // Should return 1, but returns 4 (following) - return div1.compareDocumentPosition( document.createElement("div") ) & 1; -}); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( div ) { - div.innerHTML = ""; - return div.firstChild.getAttribute("href") === "#" ; -}) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - }); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( div ) { - div.innerHTML = ""; - div.firstChild.setAttribute( "value", "" ); - return div.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - }); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( div ) { - return div.getAttribute("disabled") == null; -}) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - null; - } - }); -} - -return Sizzle; - -})( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.pseudos; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - - -var rneedsContext = jQuery.expr.match.needsContext; - -var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); - - - -var risSimple = /^.[^:#\[\.,]*$/; - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - /* jshint -W018 */ - return !!qualifier.call( elem, i, elem ) !== not; - }); - - } - - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - }); - - } - - if ( typeof qualifier === "string" ) { - if ( risSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - qualifier = jQuery.filter( qualifier, elements ); - } - - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; - }); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 && elem.nodeType === 1 ? - jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : - jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - })); -}; - -jQuery.fn.extend({ - find: function( selector ) { - var i, - len = this.length, - ret = [], - self = this; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }) ); - } - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); - ret.selector = this.selector ? this.selector + " " + selector : selector; - return ret; - }, - filter: function( selector ) { - return this.pushStack( winnow(this, selector || [], false) ); - }, - not: function( selector ) { - return this.pushStack( winnow(this, selector || [], true) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -}); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - - init = jQuery.fn.init = function( selector, context ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - - // scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return typeof rootjQuery.ready !== "undefined" ? - rootjQuery.ready( selector ) : - // Execute immediately if ready is not present - selector( jQuery ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.extend({ - dir: function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; - }, - - sibling: function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; - } -}); - -jQuery.fn.extend({ - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; - - return this.filter(function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( ; i < l; i++ ) { - for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { - // Always skip document fragments - if ( cur.nodeType < 11 && (pos ? - pos.index(cur) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors)) ) { - - matched.push( cur ); - break; - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } - - // Locate the position of the desired element - return indexOf.call( this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.unique( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter(selector) - ); - } -}); - -function sibling( cur, dir ) { - while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} - return cur; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return elem.contentDocument || jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } - - if ( this.length > 1 ) { - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.unique( matched ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); - } - } - - return this.pushStack( matched ); - }; -}); -var rnotwhite = (/\S+/g); - - - -// String to Object options format cache -var optionsCache = {}; - -// Convert String-formatted options into Object-formatted ones and store in cache -function createOptions( options ) { - var object = optionsCache[ options ] = {}; - jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { - object[ flag ] = true; - }); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - ( optionsCache[ options ] || createOptions( options ) ) : - jQuery.extend( {}, options ); - - var // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list was already fired - fired, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = !options.once && [], - // Fire callbacks - fire = function( data ) { - memory = options.memory && data; - fired = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - firing = true; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { - memory = false; // To prevent further calls using add - break; - } - } - firing = false; - if ( list ) { - if ( stack ) { - if ( stack.length ) { - fire( stack.shift() ); - } - } else if ( memory ) { - list = []; - } else { - self.disable(); - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - // First, we save the current length - var start = list.length; - (function add( args ) { - jQuery.each( args, function( _, arg ) { - var type = jQuery.type( arg ); - if ( type === "function" ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && type !== "string" ) { - // Inspect recursively - add( arg ); - } - }); - })( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away - } else if ( memory ) { - firingStart = start; - fire( memory ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - // Handle firing indexes - if ( firing ) { - if ( index <= firingLength ) { - firingLength--; - } - if ( index <= firingIndex ) { - firingIndex--; - } - } - } - }); - } - return this; - }, - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); - }, - // Remove all callbacks from the list - empty: function() { - list = []; - firingLength = 0; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( list && ( !fired || stack ) ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - if ( firing ) { - stack.push( args ); - } else { - fire( args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -jQuery.extend({ - - Deferred: function( func ) { - var tuples = [ - // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], - [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], - [ "notify", "progress", jQuery.Callbacks("memory") ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - then: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - return jQuery.Deferred(function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; - // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ](function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); - } - }); - }); - fns = null; - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Keep pipe for back-compat - promise.pipe = promise.then; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 3 ]; - - // promise[ done | fail | progress ] = list.add - promise[ tuple[1] ] = list.add; - - // Handle state - if ( stateString ) { - list.add(function() { - // state = [ resolved | rejected ] - state = stateString; - - // [ reject_list | resolve_list ].disable; progress_list.lock - }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); - } - - // deferred[ resolve | reject | notify ] - deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); - return this; - }; - deferred[ tuple[0] + "With" ] = list.fireWith; - }); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( subordinate /* , ..., subordinateN */ ) { - var i = 0, - resolveValues = slice.call( arguments ), - length = resolveValues.length, - - // the count of uncompleted subordinates - remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - - // the master Deferred. If resolveValues consist of only a single Deferred, just use that. - deferred = remaining === 1 ? subordinate : jQuery.Deferred(), - - // Update function for both resolve and progress values - updateFunc = function( i, contexts, values ) { - return function( value ) { - contexts[ i ] = this; - values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( values === progressValues ) { - deferred.notifyWith( contexts, values ); - } else if ( !( --remaining ) ) { - deferred.resolveWith( contexts, values ); - } - }; - }, - - progressValues, progressContexts, resolveContexts; - - // add listeners to Deferred subordinates; treat others as resolved - if ( length > 1 ) { - progressValues = new Array( length ); - progressContexts = new Array( length ); - resolveContexts = new Array( length ); - for ( ; i < length; i++ ) { - if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { - resolveValues[ i ].promise() - .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ) - .progress( updateFunc( i, progressContexts, progressValues ) ); - } else { - --remaining; - } - } - } - - // if we're not waiting on anything, resolve the master - if ( !remaining ) { - deferred.resolveWith( resolveContexts, resolveValues ); - } - - return deferred.promise(); - } -}); - - -// The deferred used on DOM ready -var readyList; - -jQuery.fn.ready = function( fn ) { - // Add the callback - jQuery.ready.promise().done( fn ); - - return this; -}; - -jQuery.extend({ - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.triggerHandler ) { - jQuery( document ).triggerHandler( "ready" ); - jQuery( document ).off( "ready" ); - } - } -}); - -/** - * The ready event handler and self cleanup method - */ -function completed() { - document.removeEventListener( "DOMContentLoaded", completed, false ); - window.removeEventListener( "load", completed, false ); - jQuery.ready(); -} - -jQuery.ready.promise = function( obj ) { - if ( !readyList ) { - - readyList = jQuery.Deferred(); - - // Catch cases where $(document).ready() is called after the browser event has already occurred. - // we once tried to use readyState "interactive" here, but it caused issues like the one - // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - setTimeout( jQuery.ready ); - - } else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed, false ); - } - } - return readyList.promise( obj ); -}; - -// Kick off the DOM ready check even if the user does not -jQuery.ready.promise(); - - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); - } - } - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - len ? fn( elems[0], key ) : emptyGet; -}; - - -/** - * Determines whether an object can have data - */ -jQuery.acceptData = function( owner ) { - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - /* jshint -W018 */ - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; - - -function Data() { - // Support: Android < 4, - // Old WebKit does not have Object.preventExtensions/freeze method, - // return new empty object instead with no [[set]] accessor - Object.defineProperty( this.cache = {}, 0, { - get: function() { - return {}; - } - }); - - this.expando = jQuery.expando + Math.random(); -} - -Data.uid = 1; -Data.accepts = jQuery.acceptData; - -Data.prototype = { - key: function( owner ) { - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return the key for a frozen object. - if ( !Data.accepts( owner ) ) { - return 0; - } - - var descriptor = {}, - // Check if the owner object already has a cache key - unlock = owner[ this.expando ]; - - // If not, create one - if ( !unlock ) { - unlock = Data.uid++; - - // Secure it in a non-enumerable, non-writable property - try { - descriptor[ this.expando ] = { value: unlock }; - Object.defineProperties( owner, descriptor ); - - // Support: Android < 4 - // Fallback to a less secure definition - } catch ( e ) { - descriptor[ this.expando ] = unlock; - jQuery.extend( owner, descriptor ); - } - } - - // Ensure the cache object - if ( !this.cache[ unlock ] ) { - this.cache[ unlock ] = {}; - } - - return unlock; - }, - set: function( owner, data, value ) { - var prop, - // There may be an unlock assigned to this node, - // if there is no entry for this "owner", create one inline - // and set the unlock as though an owner entry had always existed - unlock = this.key( owner ), - cache = this.cache[ unlock ]; - - // Handle: [ owner, key, value ] args - if ( typeof data === "string" ) { - cache[ data ] = value; - - // Handle: [ owner, { properties } ] args - } else { - // Fresh assignments by object are shallow copied - if ( jQuery.isEmptyObject( cache ) ) { - jQuery.extend( this.cache[ unlock ], data ); - // Otherwise, copy the properties one-by-one to the cache object - } else { - for ( prop in data ) { - cache[ prop ] = data[ prop ]; - } - } - } - return cache; - }, - get: function( owner, key ) { - // Either a valid cache is found, or will be created. - // New caches will be created and the unlock returned, - // allowing direct access to the newly created - // empty data object. A valid owner object must be provided. - var cache = this.cache[ this.key( owner ) ]; - - return key === undefined ? - cache : cache[ key ]; - }, - access: function( owner, key, value ) { - var stored; - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ((key && typeof key === "string") && value === undefined) ) { - - stored = this.get( owner, key ); - - return stored !== undefined ? - stored : this.get( owner, jQuery.camelCase(key) ); - } - - // [*]When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, name, camel, - unlock = this.key( owner ), - cache = this.cache[ unlock ]; - - if ( key === undefined ) { - this.cache[ unlock ] = {}; - - } else { - // Support array or space separated string of keys - if ( jQuery.isArray( key ) ) { - // If "name" is an array of keys... - // When data is initially created, via ("key", "val") signature, - // keys will be converted to camelCase. - // Since there is no way to tell _how_ a key was added, remove - // both plain key and camelCase key. #12786 - // This will only penalize the array argument path. - name = key.concat( key.map( jQuery.camelCase ) ); - } else { - camel = jQuery.camelCase( key ); - // Try the string as a key before any manipulation - if ( key in cache ) { - name = [ key, camel ]; - } else { - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - name = camel; - name = name in cache ? - [ name ] : ( name.match( rnotwhite ) || [] ); - } - } - - i = name.length; - while ( i-- ) { - delete cache[ name[ i ] ]; - } - } - }, - hasData: function( owner ) { - return !jQuery.isEmptyObject( - this.cache[ owner[ this.expando ] ] || {} - ); - }, - discard: function( owner ) { - if ( owner[ this.expando ] ) { - delete this.cache[ owner[ this.expando ] ]; - } - } -}; -var data_priv = new Data(); - -var data_user = new Data(); - - - -/* - Implementation Summary - - 1. Enforce API surface and semantic compatibility with 1.9.x branch - 2. Improve the module's maintainability by reducing the storage - paths to a single mechanism. - 3. Use the same single mechanism to support "private" and "user" data. - 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) - 5. Avoid exposing implementation details on user objects (eg. expando properties) - 6. Provide a clear path for implementation upgrade to WeakMap in 2014 -*/ -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /([A-Z])/g; - -function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - // Only convert to a number if it doesn't change the string - +data + "" === data ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - data_user.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend({ - hasData: function( elem ) { - return data_user.hasData( elem ) || data_priv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return data_user.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - data_user.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to data_priv methods, these can be deprecated. - _data: function( elem, name, data ) { - return data_priv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - data_priv.remove( elem, name ); - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = data_user.get( elem ); - - if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE11+ - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice(5) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - data_priv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each(function() { - data_user.set( this, key ); - }); - } - - return access( this, function( value ) { - var data, - camelKey = jQuery.camelCase( key ); - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - // Attempt to get data from the cache - // with the key as-is - data = data_user.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to get data from the cache - // with the key camelized - data = data_user.get( elem, camelKey ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, camelKey, undefined ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each(function() { - // First, attempt to store a copy or reference of any - // data that might've been store with a camelCased key. - var data = data_user.get( this, camelKey ); - - // For HTML5 data-* attribute interop, we have to - // store property names with dashes in a camelCase form. - // This might not apply to all properties...* - data_user.set( this, camelKey, value ); - - // *... In the case of properties that might _actually_ - // have dashes, we need to also store a copy of that - // unchanged property. - if ( key.indexOf("-") !== -1 && data !== undefined ) { - data_user.set( this, key, value ); - } - }); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each(function() { - data_user.remove( this, key ); - }); - } -}); - - -jQuery.extend({ - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = data_priv.get( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || jQuery.isArray( data ) ) { - queue = data_priv.access( elem, type, jQuery.makeArray(data) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // not intended for public consumption - generates a queueHooks object, or returns the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return data_priv.get( elem, key ) || data_priv.access( elem, key, { - empty: jQuery.Callbacks("once memory").add(function() { - data_priv.remove( elem, [ type + "queue", key ] ); - }) - }); - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[0], type ); - } - - return data === undefined ? - this : - this.each(function() { - var queue = jQuery.queue( this, type, data ); - - // ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = data_priv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -}); -var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var isHidden = function( elem, el ) { - // isHidden might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); - }; - -var rcheckableType = (/^(?:checkbox|radio)$/i); - - - -(function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // #11217 - WebKit loses check when the name is after the checked attribute - // Support: Windows Web Apps (WWA) - // `name` and `type` need .setAttribute for WWA - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 - // old WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Make sure textarea (and checkbox) defaultValue is properly cloned - // Support: IE9-IE11+ - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -})(); -var strundefined = typeof undefined; - - - -support.focusinBubbles = "onfocusin" in window; - - -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = data_priv.get( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !(events = elemData.events) ) { - events = elemData.events = {}; - } - if ( !(eventHandle = elemData.handle) ) { - eventHandle = elemData.handle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !(handlers = events[ type ]) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = data_priv.hasData( elem ) && data_priv.get( elem ); - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; - data_priv.remove( elem, "events" ); - } - }, - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.namespace_re = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === (elem.ownerDocument || document) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && jQuery.acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && - jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event ); - - var i, j, ret, matched, handleObj, - handlerQueue = [], - args = slice.call( arguments ), - handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( (event.result = ret) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, matches, sel, handleObj, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - // Black-hole SVG instance trees (#13180) - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.disabled !== true || event.type !== "click" ) { - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matches[ sel ] === undefined ) { - matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matches[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, handlers: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( delegateCount < handlers.length ) { - handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); - } - - return handlerQueue; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var eventDoc, doc, body, - button = original.button; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, copy, - type = event.type, - originalEvent = event, - fixHook = this.fixHooks[ type ]; - - if ( !fixHook ) { - this.fixHooks[ type ] = fixHook = - rmouseEvent.test( type ) ? this.mouseHooks : - rkeyEvent.test( type ) ? this.keyHooks : - {}; - } - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = new jQuery.Event( originalEvent ); - - i = copy.length; - while ( i-- ) { - prop = copy[ i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Support: Cordova 2.5 (WebKit) (#13255) - // All events should have a target; Cordova deviceready doesn't - if ( !event.target ) { - event.target = document; - } - - // Support: Safari 6.0+, Chrome < 28 - // Target should not be a text node (#504, #13143) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; - }, - - special: { - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - this.focus(); - return false; - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return jQuery.nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -jQuery.removeEvent = function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } -}; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - // Support: Android < 4.0 - src.returnValue === false ? - returnTrue : - returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && e.preventDefault ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && e.stopPropagation ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && e.stopImmediatePropagation ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -// Support: Chrome 15+ -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// Create "bubbling" focus and blur events -// Support: Firefox, Chrome, Safari -if ( !support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - data_priv.remove( doc, fix ); - - } else { - data_priv.access( doc, fix, attaches ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - var elem = this[0]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -}); - - -var - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, - rtagName = /<([\w:]+)/, - rhtml = /<|&#?\w+;/, - rnoInnerhtml = /<(?:script|style|link)/i, - // checked="checked" or checked - rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, - rscriptType = /^$|\/(?:java|ecma)script/i, - rscriptTypeMasked = /^true\/(.*)/, - rcleanScript = /^\s*\s*$/g, - - // We have to close these tags to support XHTML (#13200) - wrapMap = { - - // Support: IE 9 - option: [ 1, "" ], - - thead: [ 1, "", "
        " ], - col: [ 2, "", "
        " ], - tr: [ 2, "", "
        " ], - td: [ 3, "", "
        " ], - - _default: [ 0, "", "" ] - }; - -// Support: IE 9 -wrapMap.optgroup = wrapMap.option; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: 1.x compatibility -// Manipulating tables requires a tbody -function manipulationTarget( elem, content ) { - return jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? - - elem.getElementsByTagName("tbody")[0] || - elem.appendChild( elem.ownerDocument.createElement("tbody") ) : - elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - - if ( match ) { - elem.type = match[ 1 ]; - } else { - elem.removeAttribute("type"); - } - - return elem; -} - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - data_priv.set( - elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) - ); - } -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( data_priv.hasData( src ) ) { - pdataOld = data_priv.access( src ); - pdataCur = data_priv.set( dest, pdataOld ); - events = pdataOld.events; - - if ( events ) { - delete pdataCur.handle; - pdataCur.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( data_user.hasData( src ) ) { - udataOld = data_user.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - data_user.set( dest, udataCur ); - } -} - -function getAll( context, tag ) { - var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : - context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : - []; - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], ret ) : - ret; -} - -// Support: IE >= 9 -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -jQuery.extend({ - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = jQuery.contains( elem.ownerDocument, elem ); - - // Support: IE >= 9 - // Fix Cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - buildFragment: function( elems, context, scripts, selection ) { - var elem, tmp, tag, wrap, contains, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - // Support: QtWebKit - // jQuery.merge because push.apply(_, arraylike) throws - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement("div") ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: QtWebKit - // jQuery.merge because push.apply(_, arraylike) throws - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Fixes #12346 - // Support: Webkit, IE - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( (elem = nodes[ i++ ]) ) { - - // #4087 - If origin and destination elements are the same, and this is - // that element, do not do anything - if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( (elem = tmp[ j++ ]) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; - }, - - cleanData: function( elems ) { - var data, elem, type, key, - special = jQuery.event.special, - i = 0; - - for ( ; (elem = elems[ i ]) !== undefined; i++ ) { - if ( jQuery.acceptData( elem ) ) { - key = elem[ data_priv.expando ]; - - if ( key && (data = data_priv.cache[ key ]) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - if ( data_priv.cache[ key ] ) { - // Discard any remaining `private` data - delete data_priv.cache[ key ]; - } - } - } - // Discard any remaining `user` data - delete data_user.cache[ elem[ data_user.expando ] ]; - } - } -}); - -jQuery.fn.extend({ - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each(function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - }); - }, null, value, arguments.length ); - }, - - append: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - }); - }, - - prepend: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - }); - }, - - before: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - }); - }, - - after: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - }); - }, - - remove: function( selector, keepData /* Internal Use Only */ ) { - var elem, - elems = selector ? jQuery.filter( selector, this ) : this, - i = 0; - - for ( ; (elem = elems[i]) != null; i++ ) { - if ( !keepData && elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem ) ); - } - - if ( elem.parentNode ) { - if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { - setGlobalEval( getAll( elem, "script" ) ); - } - elem.parentNode.removeChild( elem ); - } - } - - return this; - }, - - empty: function() { - var elem, - i = 0; - - for ( ; (elem = this[i]) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map(function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - }); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = value.replace( rxhtmlTag, "<$1>" ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var arg = arguments[ 0 ]; - - // Make the changes, replacing each context element with the new content - this.domManip( arguments, function( elem ) { - arg = this.parentNode; - - jQuery.cleanData( getAll( this ) ); - - if ( arg ) { - arg.replaceChild( elem, this ); - } - }); - - // Force removal if there was no new content (e.g., from empty arguments) - return arg && (arg.length || arg.nodeType) ? this : this.remove(); - }, - - detach: function( selector ) { - return this.remove( selector, true ); - }, - - domManip: function( args, callback ) { - - // Flatten any nested arrays - args = concat.apply( [], args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = this.length, - set = this, - iNoClone = l - 1, - value = args[ 0 ], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return this.each(function( index ) { - var self = set.eq( index ); - if ( isFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - self.domManip( args, callback ); - }); - } - - if ( l ) { - fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - if ( first ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - // Support: QtWebKit - // jQuery.merge because push.apply(_, arraylike) throws - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( this[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { - - if ( node.src ) { - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); - } - } - } - } - } - } - - return this; - } -}); - -jQuery.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: QtWebKit - // .get() because push.apply(_, arraylike) throws - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -}); - - -var iframe, - elemdisplay = {}; - -/** - * Retrieve the actual display of a element - * @param {String} name nodeName of the element - * @param {Object} doc Document object - */ -// Called only from within defaultDisplay -function actualDisplay( name, doc ) { - var style, - elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - - // getDefaultComputedStyle might be reliably used only on attached element - display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? - - // Use of this method is a temporary fix (more like optmization) until something better comes along, - // since it was removed from specification and supported only in FF - style.display : jQuery.css( elem[ 0 ], "display" ); - - // We don't have any data stored on the element, - // so use "detach" method as fast way to get rid of the element - elem.detach(); - - return display; -} - -/** - * Try to determine the default display value of an element - * @param {String} nodeName - */ -function defaultDisplay( nodeName ) { - var doc = document, - display = elemdisplay[ nodeName ]; - - if ( !display ) { - display = actualDisplay( nodeName, doc ); - - // If the simple way fails, read from inside an iframe - if ( display === "none" || !display ) { - - // Use the already-created iframe if possible - iframe = (iframe || jQuery( "
        - - - - - - --> - - - - - - - - - - - - - - - - - - - - - - -
        -
        -
        -
        -
        -
        -
        -
        -
        - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-viz.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-viz.html deleted file mode 100644 index 3c0afd29..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook-viz.html +++ /dev/null @@ -1,26 +0,0 @@ - -
        - - -
        - - -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook.htm b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook.htm deleted file mode 100644 index bfd74ad3..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebook.htm +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -
        -
        -
        -
        -
        -
        -
        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebookInputs.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebookInputs.html deleted file mode 100644 index 0a28b50e..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/notebook-integration/scripts/view-models/notebookInputs.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - -
        -
        -
        -
        - -
        -
        - - - - - - -
        -
        -
        - -
        - -
        - -
        - -
        -
        - -
        - -
        - - - Remove -
        -
        -
        -
        - - - - -
        - -
        - Submit -
        - - - -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/adminController.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/adminController.js deleted file mode 100644 index a99be9fe..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/adminController.js +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.config(function($routeProvider) { - $routeProvider - - - .when('/role_function_list', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/role_function_list.html', - controller: 'roleFunctionListController' - }) - - .when('/admin_menu_edit', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/admin_menu_edit.html', - controller: 'AdminMenuEditController' - }) - .when('/role/:roleId', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/role.html', - controller: 'roleController' - }) - .when('/jcs_admin', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/jcs_admin.html', - controller: 'cacheAdminController' - }) - .when('/broadcast_list', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/broadcast_list.html', - controller: 'broadcastListController' - }) - .when('/broadcast/:messageLocationId/:messageLocation/:messageId', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/broadcast.html', - controller: 'broadcastController' - }) - .when('/broadcast/:messageLocationId/:messageLocation', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/broadcast.html', - controller: 'broadcastController' - }) - .when('/collaborate_list', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/collaborate_list.html', - controller: 'collaborateListController' - }) - .when('/usage_list', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/usage_list.html', - controller: 'usageListController' - }) - .otherwise({ - templateUrl: 'app/fusion/scripts/view-models/profile-page/role_list.html', - controller : "roleListController" - }); -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/admin_menu_edit.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/admin_menu_edit.js deleted file mode 100644 index 54d58a45..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/admin_menu_edit.js +++ /dev/null @@ -1,230 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('AdminMenuEditController', function ($scope, AdminService, modalService, $modal, $route){ - $( "#dialog" ).hide(); - -/* AdminService.getRoleFunctionList().then(function(data){ - - var j = data; - $scope.data = JSON.parse(j.data); - $scope.availableRoleFunctions =JSON.parse($scope.data.availableRoleFunctions); - - //$scope.resetMenu(); - - },function(error){ - console.log("failed"); - reloadPageOnce(); - });*/ - $scope.init = function () { - $scope.numberOfRecordstoShow=20; - AdminService.getFnMenuItems().then(function(data){ - var j = data; - $scope.data =JSON.parse(j.data); - $scope.fnMenuItems =($scope.data.fnMenuItems); - - },function(error){ - console.log("failed"); - //reloadPageOnce(); - }); - } - $scope.init(); - $scope.mapActiveStatus = function(status){ - if(status) - status = "Y"; - else - status = "N"; - return status; - - }; - - - $scope.addNewFnMenuItemModalPopup = function(availableFnMenuItem) { - $scope.editFnMenuItem = null; - var modalInstance = $modal.open({ - templateUrl: 'fn_menu_add_popup.html', - controller: 'fn_menu_popupController', - resolve: { - message: function () { - var message = { - availableFnMenuItem: $scope.editFnMenuItem - }; - return message; - } - } - }); - modalInstance.result.then(function(response){ - console.log('response', response); - $scope.availableFnMenuItems=response.availableFnMenuItems; - $route.reload(); - }); - }; - - $scope.removeMenuItem = function(fnMenuItem) { - modalService.popupConfirmWin("Confirm","You are about to delete the menu item "+fnMenuItem.label+". Do you want to continue?", - function(){ - var uuu = "admin_fn_menu/removeMenuItem.htm"; - var postData={fnMenuItem: fnMenuItem}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.fnMenuItem=data.fnMenuItem;}); - $route.reload(); - }, - error : function(data){ - console.log(data); - modalService.showFailure("Fail","Error while deleting: "+ data.responseText); - } - }); - - }) - - }; - - $scope.editRoleFunction = null; - var dialog = null; - $scope.editRoleFunctionPopup = function(availableRoleFunction) { - $scope.editRoleFunction = availableRoleFunction; - $( "#dialog" ).dialog({ - modal: true - }); - }; - - $scope.editMenuItemModalPopup = function(availableFnMenuItem) { - $scope.editFnMenuItem = availableFnMenuItem; - var modalInstance = $modal.open({ - templateUrl: 'fn_menu_add_popup.html', - controller: 'fn_menu_popupController', - resolve: { - message: function () { - var message = { - availableFnMenuItem: $scope.editFnMenuItem - }; - return message; - } - } - }); - modalInstance.result.then(function(response){ - $scope.availableFnMenuItems=response.availableFnMenuItems; - $route.reload(); - }); - }; - - $scope.editRoleFunctionModalPopup = function(availableRoleFunction) { - $scope.editRoleFunction = availableRoleFunction; - var modalInstance = $modal.open({ - templateUrl: 'edit_role_function_popup.html', - controller: 'rolefunctionpopupController', - resolve: { - message: function () { - var message = { - availableRoleFunction: $scope.editRoleFunction - }; - return message; - } - } - }); - modalInstance.result.then(function(response){ - console.log('response', response); - $scope.availableRoleFunctions=response.availableRoleFunctions; - }); - }; - - $scope.addNewRoleFunctionModalPopup = function(availableRoleFunction) { - $scope.editRoleFunction = null; - var modalInstance = $modal.open({ - templateUrl: 'edit_role_function_popup.html', - controller: 'rolefunctionpopupController', - resolve: { - message: function () { - var message = { - availableRoleFunction: $scope.editRoleFunction - }; - return message; - } - } - }); - modalInstance.result.then(function(response){ - console.log('response', response); - $scope.availableRoleFunctions=response.availableRoleFunctions; - }); - }; - - $scope.addNewRoleFunctionPopup = function() { - $scope.editRoleFunction = null; - $( "#dialog" ).dialog({ - modal: true - }); - }; - - $scope.saveRoleFunction = function(availableRoleFunction) { - var uuu = "role_function_list/saveRoleFunction.htm"; - var postData={availableRoleFunction: availableRoleFunction}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){ - $scope.availableRoleFunctions=[];$scope.$apply(); - $scope.availableRoleFunctions=data.availableRoleFunctions;}); - //alert("Update Successful.") ; - console.log($scope.availableRoleFunctions); - - $scope.editRoleFunction = null; - $( "#dialog" ).dialog("close"); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - }; - - - $scope.removeRole = function(availableRoleFunction) { - modalService.popupConfirmWin("Confirm","You are about to delete the role function "+availableRoleFunction.name+". Do you want to continue?", - function(){ - var uuu = "role_function_list/removeRoleFunction.htm"; - var postData={availableRoleFunction: availableRoleFunction}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.availableRoleFunctions=data.availableRoleFunctions;}); - }, - error : function(data){ - console.log(data); - modalService.showFailure("Fail","Error while deleting: "+ data.responseText); - } - }); - - }) - - }; - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/ase-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/ase-controller.js deleted file mode 100644 index 45fc31ac..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/ase-controller.js +++ /dev/null @@ -1,22 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('aseCtrl', function ($scope){ -/* do nothing yet*/ -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/broadcast-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/broadcast-controller.js deleted file mode 100644 index 77ee22f5..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/broadcast-controller.js +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('broadcastController', function ($scope, modalService, $modal,AdminService,$routeParams){ - //$scope.broadcastMessage=${broadcastMessage}; - //$scope.broadcastSites=${broadcastSites}; - //console.log($scope.broadcastMessage); - $scope.broadcastMessage=[]; - $scope.broadcastSites=[]; - AdminService.getBroadcast($routeParams.messageLocationId, $routeParams.messageLocation, $routeParams.messageId).then(function(data){ - var j = data; - $scope.data = JSON.parse(j.data); - $scope.broadcastMessage=JSON.parse($scope.data.broadcastMessage); - $scope.broadcastSites=JSON.parse($scope.data.broadcastSites); - console.log($scope.broadcastMessage); - console.log($scope.broadcastMessage.id); - console.log($scope.broadcastSites); - //$scope.resetMenu(); - - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - $scope.save = function() { - var uuu = "broadcast/save"; - var postData={broadcastMessage: $scope.broadcastMessage}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - window.location.href = "admin#/broadcast_list"; - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - }; - - $scope.close = function() { - window.location.href = "admin#/broadcast_list"; -}; - -}); - -$(function() { - $( "#startDatepicker" ).datepicker(); - $( "#endDatepicker" ).datepicker(); - - $( "#startDatepicker" ).change(function() { - var tempStartDate = moment($( "#startDatepicker" ).val()).format('YYYY-MM-DD hh:mm:ss.S'); - $( "#startDateHidden" ).val(tempStartDate.toString()); - //alert( $( "#startDateHidden" ).val() ); - }); - $( "#endDatepicker" ).change(function() { - var tempEndDate = moment($( "#endDatepicker" ).val()).format('YYYY-MM-DD hh:mm:ss.S'); - $( "#endDateHidden" ).val(tempEndDate.toString()); - //alert( $( "#endDateHidden" ).val() ); - }); -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/broadcast-list-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/broadcast-list-controller.js deleted file mode 100644 index cb10a29b..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/broadcast-list-controller.js +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('broadcastListController', function ($scope, modalService, $modal,AdminService){ - //$scope.broadcastMessage=${broadcastMessage}; - //$scope.broadcastSites=${broadcastSites}; - //console.log($scope.broadcastMessage); - var messagesMap = {}; - AdminService.getBroadcastList().then(function(data){ - - var j = data; - $scope.data = JSON.parse(j.data); - $scope.messagesList=(($scope.data.messagesList===null) ? [""]:$scope.data.messagesList); - $scope.messageLocations=(($scope.data.messageLocations===null) ? [""]:$scope.data.messageLocations); - console.log("messages: "+$scope.messagesList); - console.log("location: "+$scope.messageLocations); - $.each($scope.messageLocations, function(i, a){ - //var result = []; - angular.forEach($scope.messagesList, function(value, key) { - if (key+'' === a.value+'') { - //var objsJSON = JSON.parse(value); - - $.each(value, function(i, a){ - var startDateLong = a.startDate; - var tempStartDate = new Date(startDateLong); - tempStartDate = moment(tempStartDate).format('DD MMM YYYY hh:mmA zz');//03 Jun 2013 04:15PM EDT - a.displayStartDate=tempStartDate.toString(); - - var endDateLong = a.endDate; - var tempEndDate = new Date(endDateLong); - tempEndDate = moment(tempEndDate).format('DD MMM YYYY hh:mmA zz');//03 Jun 2013 04:15PM EDT - a.displayEndDate=tempEndDate.toString(); - }); - a.messages = value; - } - }); - console.log(a.messages); - }); - - //$scope.resetMenu(); - - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - - $scope.editMessage = function(location) { - - editMessage(location.value, location.label); - }; - - $scope.toggleActive = function(broadcastMessage) { - - //alert('deleted'+role.name); - var uuu = "broadcast_list/toggleActive"; - var postData={broadcastMessage:broadcastMessage}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - //window.location.reload(); - }, - error : function(data){ - console.log(data); - modalService.showFailure("Fail","Error while toggling: "+ data.responseText); - - } - }); - - - }; - - $scope.remove = function(broadcastMessage) { - - //alert('deleted'+role.name); - var uuu = "broadcast_list/remove"; - var postData={broadcastMessage:broadcastMessage}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - window.location.reload(); - }, - error : function(data){ - console.log(data); - modalService.showFailure("Fail","Error while deleting: "+ data.responseText); - } - }); - - - }; - -}); - -function editMessage(messageLocationId, messageLocation, messageId) { - window.location='admin#/broadcast/'+messageLocationId + '/' + messageLocation + ((messageId != null) ? '/' + messageId : ''); -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/collaborate-list-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/collaborate-list-controller.js deleted file mode 100644 index 5b0b9342..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/collaborate-list-controller.js +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller("collaborateListController", function ($scope,$http,modalService, $modal,AdminService) { - // Table Data - AdminService.getCollaborateList().then(function(data){ - - var j = data; - $scope.tableData = JSON.parse(j.data); - //$scope.resetMenu(); - - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - $scope.viewPerPage = 20; - $scope.scrollViewsPerPage = 2; - $scope.currentPage = 1; - $scope.totalPage; - $scope.searchCategory = ""; - $scope.searchString = ""; - /* modalService.showSuccess('','Modal Sample') ; */ - for(x in $scope.tableData){ - if($scope.tableData[x].active_yn=='Y') - $scope.tableData[x].active_yn=true; - else - $scope.tableData[x].active_yn=false; - } - $scope.openCollaboration = function(chatId){ - openInNewTab('collaboration?chat_id=' + chatId); - } - - $scope.toggleProfileActive = function(profileId) { - modalService.popupConfirmWin("Confirm","You are about to change user's active status. Do you want to continue?", - function(){ - $http.get("profile/toggleProfileActive?profile_id="+profileId).success(function(){}); - - }) - }; - -}); - -function openInNewTab(url) { - var win = window.open(url, '_blank'); - win.focus(); -}; diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/fn_menu_add_popup_controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/fn_menu_add_popup_controller.js deleted file mode 100644 index e0179946..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/fn_menu_add_popup_controller.js +++ /dev/null @@ -1,281 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -var fn_menu_popupController = function ($scope, $modalInstance, message, $http){ /// examine the LeftMenuService - if(message.availableFnMenuItem==null) - $scope.label='Add New Menu Item' - - else{ - $scope.label='Edit Menu Item' - //$scope.disableParentId=true; - } - - $scope.getParentData = function(){ - var uuu = "admin_fn_menu/get_parent_list" - $.ajax({ - type : 'GET', - url : uuu, - dataType: 'json', // data type expected from server - contentType: 'application/json', - //data: JSON.stringify(postData), // data type sent to server - success : function(data){ - $scope.$apply(function(){ - //$scope.availableRoleFunctions=[];$scope.$apply(); - $scope.parentListSelectData=data; // data from server - menuItems = $scope.parentListSelectData; - var heirarchicalMenuItems = []; - var children = []; - for ( var i=0; i b[prop]) { - return 1; - } else if (a[prop] < b[prop]) { - return -1; - } - return 0; - } - - }; - - $scope.getParentLabel = function(parentId, parentListSelectData){ - var element; - element = parentListSelectData[0]; - for (var i=0; i=0) - $scope.importProfileList.splice(index, 1); - } - }; - - $scope.prepareProfileSelection = function() { - if($scope.importProfileList) - $.each($scope.importProfileList, function(i, profile){ - $scope.preparePostSearchBean(profile); - }); - ; - } - - $scope.preparePostSearchBean = function(profile) { - //console.log('Importing: '+profile.orgUserId); - //console.log('ngexistinguser:'+$scope.ngexistingUsers[profile.orgUserId]) - if($scope.postSearchBean.selected==null){ - $scope.postSearchBean.selected=[]; - $scope.postSearchBean.postOrgUserId=[]; - $scope.postSearchBean.postHrid=[]; - $scope.postSearchBean.postFirstName=[]; - $scope.postSearchBean.postLastName=[]; - $scope.postSearchBean.postOrgCode=[]; - $scope.postSearchBean.postPhone=[]; - $scope.postSearchBean.postEmail=[]; - $scope.postSearchBean.postAddress1=[]; - $scope.postSearchBean.postAddress2=[]; - $scope.postSearchBean.postCity=[]; - $scope.postSearchBean.postState=[]; - $scope.postSearchBean.postZipCode=[]; - $scope.postSearchBean.postLocationClli=[]; - $scope.postSearchBean.postBusinessCountryCode=[]; - $scope.postSearchBean.postBusinessCountryName=[]; - $scope.postSearchBean.postDepartment=[]; - $scope.postSearchBean.postDepartmentName=[]; - $scope.postSearchBean.postBusinessUnit=[]; - $scope.postSearchBean.postBusinessUnitName=[]; - $scope.postSearchBean.postJobTitle=[]; - $scope.postSearchBean.postOrgManagerUserId=[]; - $scope.postSearchBean.postCommandChain=[]; - $scope.postSearchBean.postCompanyCode=[]; - $scope.postSearchBean.postCompany=[]; - $scope.postSearchBean.postCostCenter=[]; - $scope.postSearchBean.postSiloStatus=[]; - $scope.postSearchBean.postFinancialLocCode=[]; - } - - $scope.postSearchBean.selected.push(profile.orgUserId); - $scope.postSearchBean.postOrgUserId.push(profile.orgUserId); - $scope.postSearchBean.postHrid.push(profile.hrid); - $scope.postSearchBean.postFirstName.push(profile.firstName); - $scope.postSearchBean.postLastName.push(profile.lastName); - $scope.postSearchBean.postOrgCode.push(profile.orgCode); - $scope.postSearchBean.postPhone.push(profile.phone); - $scope.postSearchBean.postEmail.push(profile.email); - $scope.postSearchBean.postAddress1.push(profile.address1); - $scope.postSearchBean.postAddress2.push(profile.address2); - $scope.postSearchBean.postCity.push(profile.city); - $scope.postSearchBean.postState.push(profile.state); - if(profile.zipCodeSuffix==null) - $scope.postSearchBean.postZipCode.push(profile.zipCode); - else - $scope.postSearchBean.postZipCode.push(profile.zipCode+'-'+profile.zipCodeSuffix); - $scope.postSearchBean.postLocationClli.push(profile.locationClli); - $scope.postSearchBean.postBusinessCountryCode.push(profile.businessCountryCode); - $scope.postSearchBean.postBusinessCountryName.push(profile.businessCountryName); - $scope.postSearchBean.postDepartment.push(profile.department); - $scope.postSearchBean.postDepartmentName.push(profile.departmentName); - $scope.postSearchBean.postBusinessUnit.push(profile.businessUnit); - $scope.postSearchBean.postBusinessUnitName.push(profile.businessUnitName); - $scope.postSearchBean.postJobTitle.push(profile.jobTitle); - $scope.postSearchBean.postOrgManagerUserId.push(profile.orgManagerUserId); - $scope.postSearchBean.postCommandChain.push(profile.commandChain); - $scope.postSearchBean.postCompanyCode.push(profile.companyCode); - $scope.postSearchBean.postCompany.push(profile.company); - $scope.postSearchBean.postCostCenter.push(profile.costCenter); - $scope.postSearchBean.postSiloStatus.push(profile.siloStatus); - $scope.postSearchBean.postFinancialLocCode.push(profile.financialLocCode); - }; - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profile-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profile-controller.js deleted file mode 100644 index aa0066b0..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profile-controller.js +++ /dev/null @@ -1,286 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('profileController', function ($scope,$http,ProfileService,$routeParams,modalService){ - $scope.tableData=[]; - $scope.profile=[]; - $scope.ociavailableRoles=[]; - $scope.ociTimeZones; - $scope.ociCountries; - var stateList=[]; - $scope.availableRoles = []; - $scope.timeZones = []; - $scope.selectedTimeZone = null; - $scope.countries = []; - $scope.selectedCountry = null; - - ProfileService.getProfileDetail($routeParams.profileId).then(function(data){ - var j = data; - $scope.data = JSON.parse(j.data); - $scope.profile =JSON.parse($scope.data.profile); - $scope.ociavailableRoles =JSON.parse($scope.data.availableRoles); - $scope.ociTimeZones=JSON.parse($scope.data.timeZones); - $scope.ociCountries=JSON.parse($scope.data.countries); - stateList=JSON.parse($scope.data.stateList); - $scope.orgUserId=$scope.profile.orgUserId; - $scope.orgManagerUserId=$scope.profile.orgManagerUserId; - - - if($scope.ociavailableRoles) - $.each($scope.ociavailableRoles, function(i, a){ - var availableRole = a; - availableRole.selected = false; - $.each($scope.profile.roles, function(j, b){ - if(a.id === b.id) { - availableRole.selected = true; - } - }); - $scope.availableRoles.push(availableRole); - }); - ; - - /*$scope.ociTimeZones = ${model.timeZones};*/ - - if($scope.ociTimeZones){ - $.each($scope.ociTimeZones, function(i, a){ - var timeZone = {"index":i, "value":a.value, "title":a.label}; - $scope.timeZones.push(timeZone); - if($scope.profile.timeZoneId !== null && a.value === $scope.profile.timeZoneId.toString()){ - $scope.selectedTimeZone = timeZone; - } - }); - }; - - /*$scope.ociCountries = ${model.countries};*/ - - //alert($scope.ociCountries[0].label); - if($scope.ociCountries) - $.each($scope.ociCountries, function(i, a){ - var country = {"index":i, "value":a.value, "title":a.label}; - $scope.countries.push(country); - if(a.value === $scope.profile.country){ - $scope.selectedCountry = country; - } - }); - ; - - /*var stateList=${model.stateList};*/ - //alert(stateList[0].label); - stateList = stateList== null? []: stateList; - var selectedState= $scope.profile.state ? $scope.profile.state:""; - $scope.stateList = initDropdownWithLookUp(stateList,selectedState ); - - //$scope.resetMenu(); - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - /*$scope.profile=${model.profile};*/ - $scope.orgUserId=$scope.profile.orgUserId; - $scope.orgManagerUserId=$scope.profile.orgManagerUserId; - - $scope.viewPerPage = 2; - $scope.currentPage = 1; - $scope.totalPage; - $scope.searchCategory = ""; - $scope.searchString = ""; - - $( "#dialog" ).hide(); - - /*$scope.ociavailableRoles=${model.availableRoles};*/ - //modalService.showFailure('Error','') ; - - - $scope.saveProfile = function() { - var uuu = "profile/saveProfile?profile_id=" + $routeParams.profileId; - var postData={profile: $scope.profile, - selectedCountry:$scope.selectedCountry!=null?$scope.selectedCountry.value:"", - selectedState:$scope.stateList.selected!=null?$scope.stateList.selected.value:"", - selectedTimeZone:$scope.selectedTimeZone!=null?$scope.selectedTimeZone.value:"" - }; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - modalService.showSuccess("Success","Update Successful."); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - }; - - $scope.addNewRolePopup = function(role) { - $( "#dialog" ).dialog({ - modal: true, - width: 500, - height:600 - }); - $(".ui-dialog").css("z-index",2001); - $(".ui-dialog-titlebar").hide(); - }; - - $scope.toggleRole = function(selected,availableRole) { - $scope.profileTemp=$scope.profile; - $scope.profile={}; - //alert('toggleRole: '+selected); - if(!selected) { - //remove role - var uuu = "profile/removeRole?profile_id=" + $routeParams.profileId; - modalService.popupConfirmWinWithCancel("Confirm","You are about to remove the role "+availableRole.name+" from the profile for "+$scope.profile.firstName+" "+$scope.profile.lastName+". Do you want to continue?", - function(){ - var postData={role:availableRole}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.profile=data;}); - }, - error : function(data){ - $scope.$apply(function(){$scope.profile=$scope.profileTemp;}); - modalService.showFailure("Fail","Error while saving."); - } - }); - }, - function(){ - availableRole.selected=!availableRole.selected; - }); - - - } else { - //add role - var uuu = "profile/addNewRole?profile_id=" + $routeParams.profileId; - modalService.popupConfirmWinWithCancel("Confirm","You are about to add the role "+availableRole.name+" from the profile for "+$scope.profile.firstName+" "+$scope.profile.lastName+". Do you want to continue?", - function(){ - var postData={role:availableRole}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.profile=data;}); - }, - error : function(data){ - $scope.$apply(function(){$scope.profile=$scope.profileTemp;}); - modalService.showFailure("Fail","Error while saving."); - } - }); - - },function(){ - availableRole.selected=!availableRole.selected; - }) - - } - - - }; - - $scope.removeRole = function(role) { - - - modalService.popupConfirmWin("Confirm","You are about to remove the role "+role.name+" from the profile for "+$scope.profile.firstName+" "+$scope.profile.lastName+". Do you want to continue?", - function(){ - $scope.profileTemp=$scope.profile; - $scope.profile={}; - var uuu = "profile/removeRole?profile_id=" + $routeParams.profileId; - var postData={role:role}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){ - $scope.profile=data; - $.each($scope.availableRoles, function(k, c){ - if(c.id === role.id) { - c.selected = false; - } - }); - }); - - }, - error : function(data){ - $scope.$apply(function(){$scope.profile=$scope.profileTemp;}); - modalService.showFailure("Fail","Error while saving."); - } - }); - - }) - - - }; - - function initDropdownWithLookUp(arr,selectedValue){ - var dropdownArray=[]; - var selected = null; - if(arr){ - for(var i = 0,l = arr.length; i < l; i++) { - var option = { - "index" : i , - "value" : arr[i].value, - "title" : arr[i].label - }; - dropdownArray.push(option); - if(arr[i].value === selectedValue){ - selected = option; - } - } - } - var dropDown={}; - dropDown.options = dropdownArray; - dropDown.selected = selected; - return dropDown; - }; - - $scope.doRolePopup = function() { - var modalInstance = $modal.open({ - templateUrl: 'roles_popup.html', - controller: 'rolepopupController', - resolve: { - message: function () { - var message ={ - availableRoles: $scope.availableRoles - }; - return message; - } - } - }); - modalInstance.result.then(function (opts) { - if(opts!=null){ - $scope.profile=opts.profile; - } - }); - } - - $scope.close = function(){ - $('#dialog').dialog('close'); - } - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profile-search-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profile-search-controller.js deleted file mode 100644 index 6da82dcc..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profile-search-controller.js +++ /dev/null @@ -1,80 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('profileSearchCtrl', function($scope, $http,ProfileService,modalService){ - - $scope.showInput = true; - $scope.totalPages1 = 5; - $scope.viewPerPage1 = 8; - $scope.currentPage1 = 1; - - $scope.$watch('viewPerPage1', function(val) { - ProfileService.getProfilePagination($scope.currentPage1, val).then(function(data){ - var j = data; - $scope.data = JSON.parse(j.data); - $scope.tableData =JSON.parse($scope.data.profileList); - $scope.totalPages1 =JSON.parse($scope.data.totalPage); - for(x in $scope.tableData){ - if($scope.tableData[x].active_yn=='Y') - $scope.tableData[x].active_yn=true; - else - $scope.tableData[x].active_yn=false; - } - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - }); - - $scope.customHandler = function(num) { - $scope.currentPage1 = num; - ProfileService.getProfilePagination($scope.currentPage1,$scope.viewPerPage1).then(function(data){ - var j = data; - $scope.data = JSON.parse(j.data); - $scope.tableData =JSON.parse($scope.data.profileList); - $scope.totalPages1 =JSON.parse($scope.data.totalPage); - for(x in $scope.tableData){ - if($scope.tableData[x].active_yn=='Y') - $scope.tableData[x].active_yn=true; - else - $scope.tableData[x].active_yn=false; - } - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - }; - - $scope.editRow = function(profileId){ - window.location = 'userProfile#/profile/' + profileId; - }; - - $scope.toggleProfileActive = function(rowData) { - modalService.popupConfirmWinWithCancel("Confirm","You are about to change user's active status. Do you want to continue?", - function(){ - $http.get("profile/toggleProfileActive?profile_id="+rowData.id).success(function(){}); - }, - function(){ - rowData.active=!rowData.active; - }) - }; - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profileController.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profileController.js deleted file mode 100644 index 4b30e40e..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/profileController.js +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.config(function($routeProvider) { - $routeProvider - .when('/profile/:profileId', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/profile_detail.html', - controller: 'profileController' - }) - .when('/post_search', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/post_search.html', - controller: 'postSearchCtrl' - }) - .when('/self_profile', { - templateUrl: 'app/fusion/scripts/view-models/profile-page/self_profile.html', - controller: 'selfProfileController' - }) - .otherwise({ - templateUrl: 'app/fusion/scripts/view-models/profile-page/profile_search.html', - controller : "profileSearchCtrl" - }); -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-controller.js deleted file mode 100644 index 50913af8..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-controller.js +++ /dev/null @@ -1,226 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('roleController', function ($scope, modalService, $modal, AdminService,$routeParams){ - //$scope.role=${role}; - //console.log($scope.role.roleFunctions); - - $( "#dialogRoleFunction" ).hide(); - $( "#dialogChildRole" ).hide(); - - //$scope.ociavailableRoleFunctions=${availableRoleFunctions}; - - AdminService.getRole($routeParams.roleId).then(function(data){ - - var j = data; - $scope.data = JSON.parse(j.data); - - $scope.role =JSON.parse($scope.data.role); - console.log($scope.role); - - $scope.ociavailableRoleFunctions =JSON.parse($scope.data.availableRoleFunctions); - console.log($scope.ociavailableRoleFunctions); - $scope.availableRoleFunctions=[]; - - if($scope.ociavailableRoleFunctions) - $.each($scope.ociavailableRoleFunctions, function(i, a){ - var availableRoleFunction = a; - availableRoleFunction.selected = false; - $.each($scope.role.roleFunctions, function(j, b){ - if(a.code === b.code) { - availableRoleFunction.selected = true; - } - }); - $scope.availableRoleFunctions.push(availableRoleFunction); - }); - - - $scope.ociavailableRoles=JSON.parse($scope.data.availableRoles); - console.log($scope.ociavailableRoles); - console.log("testing roles if exist"); - $scope.availableRoles=[]; - - if($scope.ociavailableRoles) - $.each($scope.ociavailableRoles, function(i, a){ - var availableRole = a; - availableRole.selected = false; - if($scope.role.childRoles){ - $.each($scope.role.childRoles, function(j, b){ - if(a.id === b.id) { - availableRole.selected = true; - } - }); - }; - $scope.availableRoles.push(availableRole); - }); - - - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - $scope.saveRole = function() { - var exists = false; - for(x in $scope.availableRoles){ - console.log($scope.availableRoles[x].name); - if($scope.availableRoles[x].name==$scope.role.name){ - modalService.showFailure("Warning", "Role already exists."); - exists = true; - //$modalInstance.close({availableRoleFunctions:message.availableRoleFunctions}); - } - } - if(!exists){ - var uuu = "role/saveRole.htm?role_id="+$routeParams.roleId; - var postData={role: $scope.role, childRoles: $scope.role.childRoles, roleFunctions : $scope.role.roleFunctions}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - modalService.showSuccess("Success","Update Successful."); - }, - error : function(data){ - console.log(data); - modalService.showFailure("Fail","Error while saving."); - } - }); - } - - }; - - $scope.addNewRoleFunctionModalPopup = function() { - var modalInstance = $modal.open({ - templateUrl: 'role_functions_popup.html', - controller: 'rolepopupController', - backdrop: 'static', - resolve: { - roleId: function () { - return $routeParams.roleId; - }, - role: function () { - return $scope.role; - }, - availableRoles: function () { - return $scope.ociavailableRoles; - }, - availableRoleFunctions: function () { - return $scope.ociavailableRoleFunctions; - } - } - }); - modalInstance.result.then(function(response){ - console.log('response', response); - $scope.role=response.role; - }); - }; - - $scope.addNewChildRoleModalPopup = function() { - var modalInstance = $modal.open({ - templateUrl: 'child_roles_popup.html', - controller: 'rolepopupController', - backdrop: 'static', - resolve: { - roleId: function () { - return $routeParams.roleId; - }, - role: function () { - return $scope.role; - }, - availableRoles: function () { - return $scope.ociavailableRoles; - }, - availableRoleFunctions: function () { - return $scope.ociavailableRoleFunctions; - } - } - }); - modalInstance.result.then(function(response){ - console.log('response', response); - $scope.role=response.role; - }); - }; - - - - $scope.removeRoleFunction = function(roleFunction) { - modalService.popupConfirmWin("Confirm","You are about to remove the role function "+roleFunction.name+" from the role for "+$scope.role.name+". Do you want to continue?", - function(){ - var uuu = "role/removeRoleFunction.htm?role_id=" + $routeParams.roleId; - var postData={roleFunction:roleFunction}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){ - $scope.role=data.role; - $.each($scope.availableRoleFunctions, function(k, c){ - if(c.code === roleFunction.code) { - c.selected = false; - } - }); - }); - - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - - }) - - }; - - $scope.removeChildRole = function(childRole) { - modalService.popupConfirmWin("Confirm","You are about to remove the child role "+childRole.name+" from the role for "+$scope.role.name+". Do you want to continue?", - function(){ - var uuu = "role/removeChildRole.htm?role_id=" + $routeParams.roleId; - var postData={childRole:childRole}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){ - $scope.role=data.role; - $.each($scope.availableRoles, function(k, c){ - if(c.id === childRole.id) { - c.selected = false; - } - }); - }); - - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - - }) - - }; - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-function-list-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-function-list-controller.js deleted file mode 100644 index eedac3e0..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-function-list-controller.js +++ /dev/null @@ -1,157 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('roleFunctionListController', function ($scope, AdminService, modalService, $modal){ - $( "#dialog" ).hide(); - - AdminService.getRoleFunctionList().then(function(data){ - - var j = data; - $scope.data = JSON.parse(j.data); - $scope.availableRoleFunctions =JSON.parse($scope.data.availableRoleFunctions); - - //$scope.resetMenu(); - - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - $scope.editRoleFunction = null; - var dialog = null; - $scope.editRoleFunctionPopup = function(availableRoleFunction) { - $scope.editRoleFunction = availableRoleFunction; - $( "#dialog" ).dialog({ - modal: true - }); - }; - - $scope.editRoleFunctionModalPopup = function(availableRoleFunction) { - $scope.editRoleFunction = availableRoleFunction; - $scope.availableRoleFunctionsTemp=$scope.availableRoleFunctions; - $scope.availableRoleFunctions={}; - var modalInstance = $modal.open({ - templateUrl: 'edit_role_function_popup.html', - controller: 'rolefunctionpopupController', - resolve: { - message: function () { - var message = { - availableRoleFunction: $scope.editRoleFunction, - availableRoleFunctions: $scope.availableRoleFunctionsTemp - }; - return message; - } - } - }); - modalInstance.result.then(function(response){ - console.log('response', response); - if(response!=null) - $scope.availableRoleFunctions=response.availableRoleFunctions; - else - $scope.availableRoleFunctions=$scope.availableRoleFunctionsTemp; - }); - }; - - $scope.addNewRoleFunctionModalPopup = function(availableRoleFunction) { - $scope.editRoleFunction = null; - $scope.availableRoleFunctionsTemp=$scope.availableRoleFunctions; - $scope.availableRoleFunctions={}; - var modalInstance = $modal.open({ - templateUrl: 'edit_role_function_popup.html', - controller: 'rolefunctionpopupController', - resolve: { - message: function () { - var message = { - availableRoleFunction: $scope.editRoleFunction, - availableRoleFunctions: $scope.availableRoleFunctionsTemp - }; - return message; - } - } - }); - modalInstance.result.then(function(response){ - console.log('response', response); - if(response!=null) - $scope.availableRoleFunctions=response.availableRoleFunctions; - else - $scope.availableRoleFunctions=$scope.availableRoleFunctionsTemp; - }); - }; - - $scope.addNewRoleFunctionPopup = function() { - $scope.editRoleFunction = null; - $( "#dialog" ).dialog({ - modal: true - }); - }; - - $scope.saveRoleFunction = function(availableRoleFunction) { - var uuu = "role_function_list/saveRoleFunction.htm"; - var postData={availableRoleFunction: availableRoleFunction}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){ - $scope.availableRoleFunctions=[];$scope.$apply(); - $scope.availableRoleFunctions=data.availableRoleFunctions;}); - //alert("Update Successful.") ; - console.log($scope.availableRoleFunctions); - - $scope.editRoleFunction = null; - $( "#dialog" ).dialog("close"); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - }; - - - $scope.removeRole = function(availableRoleFunction) { - modalService.popupConfirmWin("Confirm","You are about to delete the role function "+availableRoleFunction.name+". Do you want to continue?", - function(){ - $scope.availableRoleFunctionsTemp=$scope.availableRoleFunctions; - $scope.availableRoleFunctions={}; - var uuu = "role_function_list/removeRoleFunction.htm"; - var postData={availableRoleFunction: availableRoleFunction}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.availableRoleFunctions=data.availableRoleFunctions;}); - }, - error : function(data){ - console.log(data); - $scope.$apply(function(){$scope.availableRoleFunctions=$scope.availableRoleFunctionsTemp;}); - modalService.showFailure("Fail","Error while deleting: "+ data.responseText); - } - }); - - }) - - }; - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-list-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-list-controller.js deleted file mode 100644 index a16d61ef..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/role-list-controller.js +++ /dev/null @@ -1,102 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('roleListController', function ($scope,AdminService,modalService){ - - AdminService.getRoles().then(function(data){ - - var j = data; - $scope.data = JSON.parse(j.data); - $scope.availableRoles =JSON.parse($scope.data.availableRoles); - - //$scope.resetMenu(); - - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - //console.log($scope.availableRoles); - $scope.toggleRole = function(selected,availableRole) { - //alert('toggleRole: '+selected); - var toggleType = null; - if(selected) { - toggleType = "activate"; - } else { - toggleType = "inactivate"; - } - - modalService.popupConfirmWinWithCancel("Confirm","You are about to "+toggleType+" the test role "+availableRole.name+". Do you want to continue?", - function(){ - var uuu = "role_list/toggleRole"; - - var postData={role:availableRole}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - console.log(data); - $scope.$apply(function(){$scope.availableRoles=data.availableRoles;}); - console.log($scope.availableRoles); - }, - error : function(data){ - console.log(data); - modalService.showFailure("Fail","Error while saving."); - } - }); - - }, - function(){ - availableRole.active=!availableRole.active; - }) - - - }; - - $scope.removeRole = function(role) { - - modalService.popupConfirmWin("Confirm","You are about to delete the role "+role.name+". Do you want to continue?", - function(){ - var uuu = "role_list/removeRole"; - var postData={role:role}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.availableRoles=data.availableRoles;}); - }, - error : function(data){ - console.log(data); - modalService.showFailure("Fail","Error while deleting: "+ data.responseText); - } - }); - - }) - - - }; - - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/rolefunctionpopupController.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/rolefunctionpopupController.js deleted file mode 100644 index 14aea22c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/rolefunctionpopupController.js +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -var rolefunctionpopupController = function ($scope, modalService, $modalInstance, message, $http,AdminService){ - if(message.availableRoleFunction==null) { - $scope.label='Add Role Function'; - var tempText = ""; - } - else{ - $scope.label='Edit Role Function' - $scope.disableCd=true; - var tempText = new String(message.availableRoleFunction.name); - $scope.editRoleFunction = message.availableRoleFunction; - } - - $scope.tempText = tempText; - - $scope.saveRoleFunction = function(availableRoleFunction) { - var uuu = "role_function_list/saveRoleFunction.htm"; - var postData={availableRoleFunction: availableRoleFunction}; - - if(availableRoleFunction==null){ - modalService.showFailure("Warning", "Please enter valid role function details."); - } - var exists = false; - for(x in message.availableRoleFunctions){ - console.log(message.availableRoleFunctions[x].name); - if(message.availableRoleFunctions[x].name==availableRoleFunction.name){ - modalService.showFailure("Warning", "Role Function already exists."); - exists = true; - availableRoleFunction.name = $scope.tempText; - } - } - - if(!exists && availableRoleFunction.name.trim() != '' && availableRoleFunction.code.trim() != ''){ - $http.post(uuu, JSON.stringify(postData)).then(function(res){ - console.log("data"); -// console.log(res.data); -// $scope.availableRoleFunctionsTemp = res.data.availableRoleFunctions; - AdminService.getRoleFunctionList().then(function(data){ - - var j = data; - $scope.data = JSON.parse(j.data); - $scope.availableRoleFunctions =JSON.parse($scope.data.availableRoleFunctions); - - //$scope.resetMenu(); - $modalInstance.close(); - },function(error){ - console.log("failed"); - reloadPageOnce(); - $modalInstance.close(); - }); - - - }); - - - - - } - }; - - - - $scope.close = function() { - $modalInstance.close(); - }; -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/rolepopupmodelController.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/rolepopupmodelController.js deleted file mode 100644 index f8ecfadd..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/rolepopupmodelController.js +++ /dev/null @@ -1,205 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -var rolepopupController = function ($scope, $modalInstance, role, roleId, availableRoles, availableRoleFunctions,AdminService,modalService){ - - $scope.role = role; - console.log($scope.role); - if($scope.role.childRoles==null){ - $scope.role.childRoles=[]; - } - - $scope.ociavailableRoles=availableRoles; - console.log($scope.ociavailableRoles); - - $scope.availableRoles=[]; - if($scope.ociavailableRoles) - $.each($scope.ociavailableRoles, function(i, a){ - var availableRole = a; - availableRole.selected = false; - if($scope.role.childRoles){ - $.each($scope.role.childRoles, function(j, b){ - if(a.id === b.id) { - availableRole.selected = true; - } - }); - }; - $scope.availableRoles.push(availableRole); - }); - - $scope.ociavailableRoleFunctions = availableRoleFunctions; - console.log($scope.ociavailableRoleFunctions); - $scope.availableRoleFunctions = []; - if($scope.ociavailableRoleFunctions) - $.each($scope.ociavailableRoleFunctions, function(i, a){ - var availableRoleFunction = a; - availableRoleFunction.selected = false; - $.each($scope.role.roleFunctions, function(j, b){ - if(a.code === b.code) { - availableRoleFunction.selected = true; - } - }); - $scope.availableRoleFunctions.push(availableRoleFunction); - }); - //$scope.resetMenu(); - - $scope.toggleRoleFunction = function(selected,availableRoleFunction) { - //alert('toggleRole: '+selected); - - if(!selected) { - //remove role function - if(role.id==null){ - var index = $scope.role.roleFunctions.indexOf(availableRoleFunction); - if(index>=0) - $scope.role.roleFunctions.splice(index, 1); - return; - } - var uuu = "role/removeRoleFunction.htm?role_id=" + roleId; - modalService.popupConfirmWinWithCancel("Confirm","You are about to remove the role function "+availableRoleFunction.name+" from the role for "+$scope.role.name+". Do you want to continue?", - function(){ - var postData={roleFunction:availableRoleFunction}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.role=data.role;}); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - - }, - function(){ - availableRoleFunction.selected=!availableRoleFunction.selected; - }) - - } else { - //add role function - if(role.id==null){ - $scope.role.roleFunctions.push(availableRoleFunction); - return; - } - var uuu = "role/addRoleFunction.htm?role_id=" + roleId; - - modalService.popupConfirmWinWithCancel("Confirm","You are about to add the role function "+availableRoleFunction.name+" to the role for "+$scope.role.name+". Do you want to continue?", - function(){ - var postData={roleFunction:availableRoleFunction}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.role=data.role;}); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - - }, - function(){ - availableRoleFunction.selected=!availableRoleFunction.selected; - }) - } - - - }; - - $scope.toggleChildRole = function(selected,availableRole) { - //alert('toggleRole: '+selected); - - if(!selected) { - //remove role - if(role.id==null){ - var index = $scope.role.childRoles.indexOf(availableRole); - if(index>=0) - $scope.role.childRoles.splice(index, 1); - return; - } - var uuu = "role/removeChildRole.htm?role_id=" + roleId; - - modalService.popupConfirmWinWithCancel("Confirm","You are about to remove the child role "+availableRole.name+" from the role for "+$scope.role.name+". Do you want to continue?", - function(){ - var postData={childRole:availableRole}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - console.log('role',data.role); - $scope.$apply(function(){$scope.role=data.role;}); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - - }, - function(){ - availableRole.selected=true; - }) - - } else { - //add role - if(role.id==null){ - $scope.role.childRoles.push(availableRole); - return; - } - var uuu = "role/addChildRole.htm?role_id=" + roleId; - - modalService.popupConfirmWinWithCancel("Confirm","You are about to add the child role "+availableRole.name+" to the role for "+$scope.role.name+". Do you want to continue?", - function(){ - var postData={childRole:availableRole}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.role=data.role;}); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - - }, - function(){ - availableRole.selected=false; - }) - } - - - }; - - $scope.close = function() { - console.log('role', $scope.role); - $modalInstance.close({role:$scope.role}); - }; - -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/self-profile-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/self-profile-controller.js deleted file mode 100644 index b82dae30..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/self-profile-controller.js +++ /dev/null @@ -1,284 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('selfProfileController', function ($scope,$http,ProfileService,$routeParams,modalService){ - $scope.tableData=[]; - $scope.profile=[]; - $scope.ociavailableRoles=[]; - $scope.ociTimeZones; - $scope.ociCountries; - var stateList=[]; - $scope.availableRoles = []; - $scope.timeZones = []; - $scope.selectedTimeZone = null; - $scope.countries = []; - $scope.selectedCountry = null; - $scope.isUserSystemAdmin = false; - - ProfileService.getSelfProfileDetail().then(function(data){ - var j = data; - $scope.data = JSON.parse(j.data); - $scope.profile =JSON.parse($scope.data.profile); - $scope.profileId = $scope.profile.id; - $scope.ociavailableRoles =JSON.parse($scope.data.availableRoles); - $scope.ociTimeZones=JSON.parse($scope.data.timeZones); - $scope.ociCountries=JSON.parse($scope.data.countries); - stateList=JSON.parse($scope.data.stateList); - $scope.orgUserId=$scope.profile.orgUserId; - $scope.orgManagerUserId=$scope.profile.orgManagerUserId; - - if($scope.ociavailableRoles) - $.each($scope.ociavailableRoles, function(i, a){ - var availableRole = a; - availableRole.selected = false; - $.each($scope.profile.roles, function(j, b){ - if(a.id === b.id) { - availableRole.selected = true; - if(a.id === 1){ - $scope.isUserSystemAdmin = true; - } - } - }); - $scope.availableRoles.push(availableRole); - }); - ; - - /*$scope.ociTimeZones = ${model.timeZones};*/ - - if($scope.ociTimeZones){ - $.each($scope.ociTimeZones, function(i, a){ - var timeZone = {"index":i, "value":a.value, "title":a.label}; - $scope.timeZones.push(timeZone); - if($scope.profile.timeZoneId !== null && a.value === $scope.profile.timeZoneId.toString()){ - $scope.selectedTimeZone = timeZone; - } - }); - }; - - /*$scope.ociCountries = ${model.countries};*/ - - //alert($scope.ociCountries[0].label); - if($scope.ociCountries) - $.each($scope.ociCountries, function(i, a){ - var country = {"index":i, "value":a.value, "title":a.label}; - $scope.countries.push(country); - if(a.value === $scope.profile.country){ - $scope.selectedCountry = country; - } - }); - ; - - /*var stateList=${model.stateList};*/ - //alert(stateList[0].label); - stateList = stateList== null? []: stateList; - var selectedState= $scope.profile.state ? $scope.profile.state:""; - $scope.stateList = initDropdownWithLookUp(stateList,selectedState ); - - //$scope.resetMenu(); - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - /*$scope.profile=${model.profile};*/ - $scope.orgUserId=$scope.profile.orgUserId; - $scope.orgManagerUserId=$scope.profile.orgManagerUserId; - - $scope.viewPerPage = 2; - $scope.currentPage = 1; - $scope.totalPage; - $scope.searchCategory = ""; - $scope.searchString = ""; - - $( "#dialog" ).hide(); - - /*$scope.ociavailableRoles=${model.availableRoles};*/ - //modalService.showFailure('Error','') ; - - - $scope.saveProfile = function() { - var uuu = "profile/saveProfile?profile_id=" + $scope.profileId;; - var postData={profile: $scope.profile, - selectedCountry:$scope.selectedCountry!=null?$scope.selectedCountry.value:"", - selectedState:$scope.stateList.selected!=null?$scope.stateList.selected.value:"", - selectedTimeZone:$scope.selectedTimeZone!=null?$scope.selectedTimeZone.value:"" - }; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - modalService.showSuccess("Success","Update Successful."); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - }; - - $scope.addNewRolePopup = function(role) { - $( "#dialog" ).dialog({ - modal: true, - width: 500, - height:600 - }); - - $(".ui-dialog").css("z-index",10002); - $(".ui-dialog-titlebar").hide(); - }; - - $scope.toggleRole = function(selected,availableRole) { - //alert('toggleRole: '+selected); - if(!selected) { - //remove role - var uuu = "profile/removeRole?profile_id=" + $scope.profileId;; - modalService.popupConfirmWinWithCancel("Confirm","You are about to remove the role "+availableRole.name+" from the profile for "+$scope.profile.firstName+" "+$scope.profile.lastName+". Do you want to continue?", - function(){ - var postData={role:availableRole}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.profile=data;}); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - }, - function(){ - availableRole.selected=!availableRole.selected; - }); - - - } else { - //add role - var uuu = "profile/addNewRole?profile_id=" + $scope.profileId;; - modalService.popupConfirmWinWithCancel("Confirm","You are about to add the role "+availableRole.name+" from the profile for "+$scope.profile.firstName+" "+$scope.profile.lastName+". Do you want to continue?", - function(){ - var postData={role:availableRole}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){$scope.profile=data;}); - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - - },function(){ - availableRole.selected=!availableRole.selected; - }) - - } - - - }; - - $scope.removeRole = function(role) { - - - modalService.popupConfirmWin("Confirm","You are about to remove the role "+role.name+" from the profile for "+$scope.profile.firstName+" "+$scope.profile.lastName+". Do you want to continue?", - function(){ - var uuu = "profile/removeRole?profile_id=" + $scope.profileId;; - var postData={role:role}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){ - $scope.profile=data; - $.each($scope.availableRoles, function(k, c){ - if(c.id === role.id) { - c.selected = false; - } - }); - }); - - }, - error : function(data){ - modalService.showFailure("Fail","Error while saving."); - } - }); - - }) - - - }; - - function initDropdownWithLookUp(arr,selectedValue){ - var dropdownArray=[]; - var selected = null; - if(arr){ - for(var i = 0,l = arr.length; i < l; i++) { - var option = { - "index" : i , - "value" : arr[i].value, - "title" : arr[i].label - }; - dropdownArray.push(option); - if(arr[i].value === selectedValue){ - selected = option; - } - } - } - var dropDown={}; - dropDown.options = dropdownArray; - dropDown.selected = selected; - return dropDown; - }; - - $scope.doRolePopup = function() { - var modalInstance = $modal.open({ - templateUrl: 'roles_popup.html', - controller: 'rolepopupController', - resolve: { - message: function () { - var message ={ - availableRoles: $scope.availableRoles - }; - return message; - } - } - }); - modalInstance.result.then(function (opts) { - if(opts!=null){ - $scope.profile=opts.profile; - } - }); - } - - $scope.close = function(){ - $('#dialog').dialog('close'); - } - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/usage-list-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/usage-list-controller.js deleted file mode 100644 index b495b934..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/usage-list-controller.js +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('usageListController', function ($scope,$interval,$http,$modal,modalService,AdminService){ - - AdminService.getUsageList().then(function(data){ - - var j = data; - $scope.data = JSON.parse(j.data); - $scope.users =$scope.data; - //$scope.resetMenu(); - - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - $scope.removeSession = function(sessionId) { - modalService.popupConfirmWin("Confirm","You are about to expel this user from the application. All of their unsaved data will be lost. Do you want to continue?", - function(){ - $http.get("usage_list/removeSession?deleteSessionId="+sessionId).success(function(response){$scope.users=response;}); - }) - - } -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowApp.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowApp.js deleted file mode 100644 index 0a5c8019..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowApp.js +++ /dev/null @@ -1,24 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -angular.module('att.abs.helper', []); -angular.module('quantum', []); - -var app=angular.module("workflowApp", ["att.abs", "att.abs.helper","modalServices", - "att.gridster","checklist-model","ngRoute", "ui.bootstrap"]); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowController.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowController.js deleted file mode 100644 index 169a8868..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowController.js +++ /dev/null @@ -1,509 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('workflowsController', function($scope, $http, $uibModal, $log, modalService, $modal) { - - $scope.viewPerPage = 5; - $scope.scrollViewsPerPage = 20; - $scope.currentPage = 2; - $scope.totalPage; - $scope.searchCategory = ""; - $scope.searchString = ""; - $scope.radio = { - value: "" - }; - - - $scope.showModal = false; - $scope.toggleModal = function(){ - $scope.showModal = !$scope.showModal; - }; - - $scope.workflow = {}; - $scope.workflow.active = "true"; - - $scope.updateAllWorkflowStatus = function() { - angular.forEach($scope.workflows,function(value){ - $scope.checkWorkflowStatus(value); - }) - } - - $scope.fetchWorkflowsList = function() { - $http.get('workflows/list').then(function(workflowList){ - console.log('Got new list from server = ' + workflowList.data); - $scope.workflows = workflowList.data; - $scope.updateAllWorkflowStatus(); - }); - }; - - $scope.addNewWorkflow = function(newWorkflow) { - $http.post('workflows/addWorkflow/', JSON.stringify(newWorkflow)).success(function() { - $scope.fetchWorkflowsList(); - }); - - $scope.workflow.name = ''; - - }; - - $scope.updateWorkflow = function (workflowToEdit) { - //workflowToEdit.active='true'; - var modalInstance = $uibModal.open({ - animation: $scope.animationsEnabled, - templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-new.html', - //size : modalSize, - controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { - $scope.workflow = workflowToEdit; - $scope.ok = function() { - console.log('Updating existing workflow ... ' + JSON.stringify($scope.workflow)); - $http.post('workflows/editWorkflow/', JSON.stringify($scope.workflow)).then(function(returnedWorkflow){ - console.log('Returned Workflow = ' + JSON.stringify(returnedWorkflow)); - $uibModalInstance.close($scope.workflow); - }); - }; - - $scope.cancel = function() { - $uibModalInstance.dismiss(); - }; - }], - //End of inner controller - resolve: { - workflow: function() { - console.log('Passing ' + JSON.stringify($scope.workflow)); - return $scope.workflow; - } - } - }); - - modalInstance.result.then(function (editedWorkFlow) { - //Need to convert to proper date - later - delete editedWorkFlow.created; - delete editedWorkFlow.updated; - - delete editedWorkFlow.createdBy; - delete editedWorkFlow.modifiedBy; - - console.log('selected Item ' + JSON.stringify(editedWorkFlow)); - $scope.$emit('workflowAdded', editedWorkFlow); - - }, function () { - $log.info('Modal dismissed at: ' + new Date()); - }); - }; - - $scope.reset = function(){ - console.log("Resetting ...."); - }; - - $scope.update = function(){ - console.log("updating ...."); - }; - - $scope.createWorkflow = function (modalSize) { - - var modalInstance = $uibModal.open({ - animation: $scope.animationsEnabled, - templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-new.html', - size : modalSize, - controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { - $scope.workflow = {}; - $scope.workflow.active = 'true'; - $scope.ok = function() { - console.log('Saving new workflow ... ' + JSON.stringify($scope.workflow)); - $http.post('workflows/addWorkflow/', JSON.stringify($scope.workflow)).then(function(returnedWorkflow){ - console.log('Returned Workflow = ' + JSON.stringify(returnedWorkflow)); - $uibModalInstance.close($scope.workflow); - }); - }; -/* console.log(size);*/ - $scope.cancel = function() { - $uibModalInstance.dismiss(); - }; - }], - //End of inner controller - resolve: { - workflow: function() { - console.log('Passing ' + JSON.stringify($scope.workflow)); - return $scope.workflow; - } - } - }); - - modalInstance.result.then(function (newWorkflow) { - console.log('selected Item ' + JSON.stringify(newWorkflow)); - $scope.$emit('workflowAdded', newWorkflow); - - }, function () { - $log.info('Modal dismissed at: ' + new Date()); - }); - };//End of createWorkflow function - - - $scope.removeWorkflow = function(workflowToRemove){ - var modalInstance = $uibModal.open({ - animation: $scope.animationsEnabled, - templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-remove.html', - controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { - $scope.workflowToRemove = workflowToRemove; - $scope.ok = function() { - console.log('Removing workflow ... ' + JSON.stringify($scope.workflowToRemove) + ' on client request.'); - $http.post('workflows/removeWorkflow/', JSON.stringify($scope.workflowToRemove.id)).then(function(){ - console.log('Workflow successfully removed !!!'); - $uibModalInstance.close(); - }); - }; - - $scope.cancel = function() { - $uibModalInstance.dismiss(); - }; - }] - }); - - modalInstance.result.then(function () { - $scope.$emit('workflowRemoved'); - }, function () { - $log.info('Modal dismissed at: ' + new Date()); - }); - - }; - - - - $scope.scheduleWorkflow = function(workflowToSchedule){ - var modalInstance = $uibModal.open({ - animation: $scope.animationsEnabled, - templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-schedule.html', - size:'lg', - - controller: ['$scope', '$uibModalInstance', '$http','dateFilter', function ($scope, $uibModalInstance, $http,dateFilter) { - - $scope.workflowToSchedule = workflowToSchedule; - $scope.dt = new Date(); - $scope.dt2 = new Date(); - $scope.dateformat = 'MM/dd/yyyy', - $scope.datetimeformat = "hh:mm a"; - - $scope.recurrenceOptions =[{ - index:0, value:'One-Time', title:'One-Time' - },{ - index:1, value: 'Hourly',title:'Hourly' - },{ - index:2, value: 'Daily',title:'Daily' - },{ - index:3, value: 'Weekly',title:'Weekly' - }] - $scope.selectRecurrenceOpt = $scope.recurrenceOptions[0]; - - $scope.hours = []; - for (var i=0; i<24; i++){ - var newObj={} - newObj.index = i; - newObj.value = ""+i; - newObj.title = ""+i; - $scope.hours.push(newObj); - } - - $scope.minutes = []; - for (var i=0; i<60; i++){ - var newObj={} - newObj.index = i; - newObj.value = ""+i; - newObj.title = ""+i; - $scope.minutes.push(newObj); - } - - $scope.AMPMOptions =[ - { - index:0, value:'AM', title:'AM' - },{ - index:1, value: 'PM',title:'PM' - }] - - $scope.selectFirstHour =$scope.hours[0]; - $scope.selectFirstMinute =$scope.minutes[0]; - - $scope.selectLastHour =$scope.hours[0]; - $scope.selectLastMinute =$scope.minutes[0]; - - $scope.selectStartAMPMOption=$scope.AMPMOptions[0]; - $scope.selectLastAMPMOption=$scope.AMPMOptions[0]; - - var GenerateCronExpression = function(trigger_dt, RecurrenceOpt) { - var CRON_sec = trigger_dt.getSeconds(); - var CRON_min = trigger_dt.getMinutes(); - var CRON_hr = trigger_dt.getHours(); - var CRON_date= trigger_dt.getDate(); - var CRON_month = trigger_dt.toLocaleString('en-US', {month: 'short'}).toUpperCase(); - var CRON_day = trigger_dt.toLocaleString('en-US', {weekday: 'short'}).toUpperCase(); - var CRON_year = trigger_dt.getFullYear(); - if (RecurrenceOpt ==="One-Time") { - CRON_day = '?' - } else { - if (RecurrenceOpt ==="Hourly") { - CRON_hr = '*'; - CRON_date = '*' - CRON_month = '*' - CRON_day = '?' - CRON_year = '*' - } else if (RecurrenceOpt ==="Daily") { - CRON_date = '*' - CRON_month = '*' - CRON_day = '?' - CRON_year = '*' - } else if (RecurrenceOpt ==="Weekly") { - CRON_date = '*' - CRON_month = '*' - CRON_year = '*' - } - } - - var CRON_Expression = [CRON_sec, CRON_min, CRON_hr, CRON_date, CRON_month, CRON_day, CRON_year]; - return CRON_Expression.join(" "); - } - - $scope.ok = function() { - - // DateTime for the start time: it should be noted that the start time - // for a CRON job should be prior to the trigger time. - $scope.trigger_dt = new Date( $scope.dt.getFullYear() + - "-" + ("0"+($scope.dt.getMonth()+1)).slice(-2) + - "-" +("0"+ $scope.dt.getDate()).slice(-2) + - " " + ("0" + $scope.selectFirstHour.value).slice(-2) + - ":" +("0" + $scope.selectFirstMinute.value).slice(-2) + - ":00.0"); - - $scope.startDateTime_CRON = GenerateCronExpression($scope.trigger_dt, $scope.selectRecurrenceOpt.value) - - //roll back the the start date time by 30 seconds (start time should be 30 seconds prior to trigger time) - dt_st = new Date($scope.trigger_dt - 30*1000) - - startDateTime = dt_st.getFullYear() + - "-" + ("0"+(dt_st.getMonth()+1)).slice(-2) + - "-" +("0"+ dt_st.getDate()).slice(-2) + - " " + ("0" + dt_st.getHours()).slice(-2) + - ":" +("0" + dt_st.getMinutes()).slice(-2) + - ":" + ("0" + dt_st.getSeconds()).slice(-2) +".0"; - $scope.startDateTime = startDateTime; - - $scope.endDateTime = $scope.dt2.getFullYear() + - "-" + ("0"+($scope.dt2.getMonth()+1)).slice(-2) + - "-" +("0"+ $scope.dt2.getDate()).slice(-2) + - " " + ("0"+ $scope.selectLastHour.value).slice(-2) + - ":" +("0" + $scope.selectLastMinute.value).slice(-2) + - ":00.0" - - $scope.WorkflowScheduleObject = {}; - $scope.WorkflowScheduleObject['startDateTime_CRON'] = $scope.startDateTime_CRON; - $scope.WorkflowScheduleObject['startDateTime'] = $scope.startDateTime; - $scope.WorkflowScheduleObject['endDateTime'] = $scope.endDateTime; - $scope.WorkflowScheduleObject['workflowKey'] = $scope.workflowToSchedule.workflowKey; - $scope.WorkflowScheduleObject['recurrence'] = $scope.selectRecurrenceOpt.value; - $scope.WorkflowScheduleObject['workflow_arguments'] = "test"; - $scope.WorkflowScheduleObject['workflow_server_url'] = $scope.workflowToSchedule.runLink; - - - TimeFromNowToStart = new Date($scope.startDateTime)-new Date() - TimeStartToEnd = new Date($scope.endDateTime)-new Date($scope.startDateTime) - - if (TimeFromNowToStart<=0) { - console.log("invalid start time input") - alert("Please ensure the scheduled start date time is later than current time.") - return; - } - if (TimeStartToEnd<=0) { - console.log("invalid end time input") - alert("Please ensure the schduled end date time is later than the start time.") - return; - } - // if successful then save and close - $scope.saveCronJob($scope.WorkflowScheduleObject); - $uibModalInstance.close(); - - }; - - $scope.saveCronJob = function(cronJobData){ - - console.log('saving cron job data: ' + cronJobData); - var uuu = "workflows/saveCronJob.htm"; - var postData={cronJobDataObj: cronJobData}; - $.ajax({ - type : 'POST', - url : uuu, - //dataType: 'json', // data type expected from server - contentType: 'application/json', - data: JSON.stringify(postData), // data type sent to server - success : function(data){ - $scope.$apply(function(){ - //$scope.availableRoleFunctions=[];$scope.$apply(); - // new // $scope.availableFnMenuItems=data.availableFnMenuItems; - } - ); - //alert("Update Successful.") ; - //$scope.editRoleFunction = null; - // new /// $modalInstance.close({availableFnMenuItems:$scope.availableRoleFunctions}); - }, - error : function(data){ - alert("Error while saving."); - } - }); - - }; - - $scope.cancel = function() { - console.log("cancel triggered") - $uibModalInstance.dismiss(); - }; - }] - }); - - modalInstance.result.then(function () { - $scope.$emit('workflowRemoved'); - }, function () { - $log.info('Modal dismissed at: ' + new Date()); - }); - - }; - - - - - - - - - $scope.previewWorkflow = function(workflowToPreview,modalSize){ - var modalInstance = $uibModal.open({ - animation: $scope.animationsEnabled, - templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-preview.html', - size:modalSize, - controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) { - $scope.workflowToPreview = workflowToPreview; - console.log('previewWorkFlow invoked'); - console.log($scope.workflowToPreview); - - $scope.cancel = function() { - $uibModalInstance.dismiss(); - }; - }] - }); - - modalInstance.result.then(function () { - $scope.$emit('workflowRemoved'); - }, function () { - $log.info('Modal dismissed at: ' + new Date()); - }); - - }; - - - /* change work flow status based on the boolean variable "suspendBool" which corresponds whether - * we would like to suspend or activate a workflow specified by key. */ - $scope.changeWorkflowStatus = function(workflowToChangeStatus,suspendBool){ - if (workflowToChangeStatus!==null) { - var statusUrl= workflowToChangeStatus.runLink+"/engine-rest/process-definition/key/"+workflowToChangeStatus.workflowKey - var suspendedUrl= statusUrl+"/suspended" - var xmlHttp = new XMLHttpRequest(); - xmlHttp.open('PUT', suspendedUrl, false); - xmlHttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); - xmlHttp.onload = function() { - if (suspendBool) { - console.log("process definition is now suspended"); - workflowToChangeStatus.active="false" - } else { - console.log("process definition is now activated"); - workflowToChangeStatus.active="true" - } - }; - xmlHttp.send(JSON.stringify({ - "suspended" : suspendBool, - "includeProcessInstances" : true, - "executionDate" : "2013-11-21T10:49:45" - })); - } - - }; - - $scope.activateWorkflow = function(workflowToActivate){ - $scope.changeWorkflowStatus(workflowToActivate,false) - - }; - - $scope.suspendWorkflow = function(workflowToActivate){ - $scope.changeWorkflowStatus(workflowToActivate,true) - }; - - $scope.checkWorkflowStatus = function(workflow) { - if (workflow!==null) { - var statusUrl= workflow.runLink+"/engine-rest/process-definition/key/"+workflow.workflowKey - var xmlHttp3 = new XMLHttpRequest(); - xmlHttp3.open('GET', statusUrl, true); - xmlHttp3.withCredentials = true; - xmlHttp3.send(); - xmlHttp3.onreadystatechange = function() { - if (xmlHttp3.readyState == 4 && xmlHttp3.status == 200) { - // do something with the response in the variable data - var temp = JSON.parse(xmlHttp3.responseText) - if (temp.suspended == false){ - console.log("Activated") - workflow.active="true" - } else { - console.log("Suspended") - workflow.active="false" - } - } - } - } - }; - - $scope.StartWorkflowInstance = function(workflowToStart){ - if (workflowToStart!==null) { - var statusUrl= workflowToStart.runLink+"/engine-rest/process-definition/key/"+workflowToStart.workflowKey - var suspendedUrl= statusUrl+"/submit-form" - var xmlHttp = new XMLHttpRequest(); - xmlHttp.open('POST', suspendedUrl, false); - xmlHttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); - xmlHttp.onload = function() { - }; - xmlHttp.send(JSON.stringify({ - "variables": { - "customerId": {"value":"asdasda","type":"String"}, - "amount":{"value":"100","type":"String"} - } - })); - } - - }; - - - $scope.$on('workflowAdded', function(event, newWorkflow) { - console.log("New Workflow to be added in list scope " + JSON.stringify(newWorkflow)); - //$scope.workflows.push(newWorkflow); - $scope.fetchWorkflowsList(); - console.log('newly added workflow = ' + JSON.stringify(newWorkflow)); - }); - - $scope.$on('workflowRemoved', function(event) { - $scope.fetchWorkflowsList(); - }); - - $scope.fetchWorkflowsList(); - - - -}); - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowRouting.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowRouting.js deleted file mode 100644 index 81fe4e28..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/controllers/workflows/workflowRouting.js +++ /dev/null @@ -1,26 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.config(function($routeProvider) { - $routeProvider - .when('/all', { - templateUrl: 'app/fusion/scripts/view-models/workflows/workflow-listing.html', - controller: 'workflowsController' - }) -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/footer.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/footer.js deleted file mode 100644 index a2dab75c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/footer.js +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.directive('qFooter', function () { - return { - restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements - replace: false, - templateUrl: "app/fusion/scripts/view-models/footer.html", - controller: ['$scope', '$filter', function ($scope, $filter) { - // Your behaviour goes here :) - }] - } -}); - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/header.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/header.js deleted file mode 100644 index bc90d200..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/header.js +++ /dev/null @@ -1,504 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.directive('qHeader', function () { - return { - restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements - replace: false, - templateUrl: "app/fusion/scripts/view-models/header.html", - controller: ['$scope', '$filter','$http','$timeout', '$log','UserInfoService', '$window', '$cookies', function ($scope, $filter, $http, $timeout, $log,UserInfoService, $window, $cookies) { - - /*Define fields*/ - $scope.userName; - $scope.userFirstName; - $scope.redirectUrl; - $scope.contactUsUrl; - $scope.getAccessUrl; - $scope.childData=[]; - $scope.parentData=[]; - $scope.menuItems = []; - $scope.loadMenufail=false; - $scope.megaMenuDataObject=[]; - $scope.activeClickSubMenu = { - x: '' - }; - $scope.activeClickMenu = { - x: '' - }; - $scope.favoritesMenuItems = []; - $scope.favoriteItemsCount = 0; - $scope.showFavorites = false; - $scope.emptyFavorites = false; - $scope.favoritesWindow = false; - - /*Menu Structure*/ - var menuStructureConvert = function(menuItems) { - console.log(menuItems); - $scope.megaMenuDataObjectTemp = - [ - { - text: "ECOMP", - children: menuItems - }, - { - text: "Help", - children: [ - { - text:"Contact Us", - url:$scope.contactUsUrl - }, - { - text:"Get Access", - url:$scope.getAccessUrl - }] - } - ]; - return $scope.megaMenuDataObjectTemp; - }; - - /***************functions**************/ - /*Put user info into fields*/ - $scope.inputUserInfo = function(userInfo){ - if (typeof(userInfo) != "undefined" && userInfo!=null && userInfo!=''){ - if(typeof(userInfo.USER_FIRST_NAME) != "undefined" && userInfo.USER_FIRST_NAME!=null){ - $scope.userFirstName = userInfo.USER_FIRST_NAME; - } - } - } - /*getting user info from session*/ - $scope.getUserNameFromSession = function(){ - UserInfoService.getFunctionalMenuStaticDetailSession() - .then(function (res) { - $scope.contactUsUrl=res.contactUsLink; - $scope.userName = res.userName; - $scope.userFirstName = res.firstName; - $scope.redirectUrl = res.portalUrl; - $scope.getAccessUrl = res.getAccessUrl; - }); - } - $scope.getTopMenuStaticInfo=function() { - var promise = UserInfoService.getFunctionalMenuStaticDetailShareContext(); - promise.then( - function(res) { - if(res==null || res==''){ - $log.info('failed getting static User information'); - $scope.getUserNameFromSession(); - }else{ - $log.info('Received static User information'); - - var resData = res; - console.log(resData); - $scope.inputUserInfo(resData); - $scope.userName = $scope.firstName+ ' '+ $scope.lastName; - } - }, - function(err) { - $log.info('failed getting static User information'); - } - ); - } - - $scope.returnToPortal=function(){ - window.location.href = $scope.redirectUrl; - } - - var unflatten = function( array, parent, tree ){ - tree = typeof tree !== 'undefined' ? tree : []; - parent = typeof parent !== 'undefined' ? parent : { menuId: null }; - var children = _.filter( array, function(child){ return child.parentMenuId == parent.menuId; }); - if( !_.isEmpty( children ) ){ - if( parent.menuId === null ){ - tree = children; - }else{ - parent['children'] = children - } - _.each( children, function( child ){ unflatten( array, child ) } ); - } - return tree; - } - - $scope.getMenu=function() { - $scope.getTopMenuStaticInfo(); - $http({ - method: "GET", - url: 'get_functional_menu', -// TIMEOUT USED FOR LOCAL TESTING ONLY -// timeout: 100 - }).success(function (response) { - - if (response == '101: Timeout') { - $log.debug('Timeout attempting to get_functional_menu'); - $scope.megaMenuDataObject = menuStructureConvert(""); -// $scope.createErrorMenu(); - //$scope.loadMenufail=true; - } else { - if(typeof response != 'undefined' && response.length!=0 && typeof response[0] != 'undefined' && typeof response[0].error!="undefined"){ - $log.debug('Timeout attempting to get_functional_menu'); - $scope.menuItems = unflatten( response); - $scope.megaMenuDataObject = menuStructureConvert($scope.menuItems); -// $scope.createErrorMenu(); - //$scope.loadMenufail=true; - }else{ - $scope.loadMenufail=false; - $scope.contactUsURL = response.contactUsLink; - $log.debug('functional_menu',response); - $scope.megaMenuDataObject = menuStructureConvert(""); - } - } - }).error(function (response){ - $scope.megaMenuDataObject = menuStructureConvert(""); -// $scope.createErrorMenu(); - //$scope.loadMenufail=true; - $log.debug('REST API failed get_functional_menu...'); - }); - - } - - $scope.adjustHeader=function() { - $scope.showHeader = ($cookies.show_app_header == undefined ? true : $cookies.show_app_header); - - if($scope.showHeader == true) { - $scope.drawer_margin_top = 70; - $scope.drawer_custom_top = 54; - $scope.toggle_drawer_top = 55; - } - else { - - $scope.drawer_margin_top = 60; - $scope.drawer_custom_top = 0; - $scope.toggle_drawer_top = 10; - } - - } - - $scope.getMenu(); - $scope.adjustHeader(); - -/* **************************************************************************/ -/* Logic for the favorite menus is here */ - - $scope.loadFavorites = function () { - $log.debug('loadFavorites has happened.'); - if ($scope.favoritesMenuItems == '') { - $scope.generateFavoriteItems(); - $log.debug('loadFavorites is calling generateFavoriteItems()'); - } else { - $log.debug('loadFavorites is NOT calling generateFavoriteItems()'); - } - } - - $scope.goToUrl = function (item) { - $log.info("goToUrl called") - $log.info(item); - - var url = item.url; - var restrictedApp = item.restrictedApp; - $log.debug('Restricted app status is: ' + restrictedApp); - if (!url) { - $log.info('No url found for this application, doing nothing..'); - return; - } - if (restrictedApp) { - $window.open(url, '_blank'); - } else { - $window.open(url, '_self'); - } - - } - - $scope.submenuLevelAction = function(index, column) { - if ($scope.favoritesMenuItems == '') { - $scope.generateFavoriteItems(); - $log.debug('submenuLevelAction is calling generateFavoriteItems()'); - } - $log.debug('item hovered/clicked: ' + index + '; column = ' + column); - if (column == 2) { // 2 is Design - $scope.favoritesWindow = false; - $scope.showFavorites = false; - $scope.emptyFavorites = false; - } - if (index=='Favorites' && $scope.favoriteItemsCount != 0) { - $log.debug('Showing Favorites window'); - $scope.favoritesWindow = true; - $scope.showFavorites = true; - $scope.emptyFavorites = false; - } - if (index=='Favorites' && $scope.favoriteItemsCount == 0) { - $log.debug('Hiding Favorites window in favor of No Favorites Window'); - $scope.favoritesWindow = true; - $scope.showFavorites = false; - $scope.emptyFavorites = true; - } - if (column > 2) { - $scope.favoritesWindow = false; - $scope.showFavorites = false; - $scope.emptyFavorites = false; - } - }; - - $scope.hideFavoritesWindow = function() { - $log.debug('$scope.hideFavoritesWindow has been called'); - $scope.showFavorites = false; - $scope.emptyFavorites = false; - } - - $scope.isUrlFavorite = function (menuId) { -// $log.debug('array objects in menu favorites = ' + $scope.favoriteItemsCount + '; menuId=' + menuId); - var jsonMenu = JSON.stringify($scope.favoritesMenuItems); - var isMenuFavorite = jsonMenu.indexOf('menuId\":' + menuId); - if (isMenuFavorite==-1) { - return false; - } else { - return true; - } - - } - - $scope.generateFavoriteItems = function() { - $http({ - method: "GET", - url: 'get_favorites', -// TIMEOUT USED FOR LOCAL TESTING ONLY -// timeout: 100 - }).success(function (response) { - if (response == '101: Timeout') { - $log.error('Timeout attempting to get_favorites_menu'); - } else { - if(typeof response != 'undefined' && response.length!=0 && typeof response[0] != 'undefined' && typeof response[0].error!="undefined"){ - $log.error('REST API failed get_favorites' + response); - }else{ - $log.debug('get_favorites = ' + JSON.stringify(response)); - $scope.favoritesMenuItems = response; - $scope.favoriteItemsCount = Object.keys($scope.favoritesMenuItems).length; - $log.info('number of favorite menus: ' + $scope.favoriteItemsCount); - } - } - }).error(function (response){ - $log.error('REST API failed get_favorites' + response); -//createFavoriteErrorMenu() USED FOR LOCAL TESTING ONLY -// $scope.createFavoriteErrorMenu(); - }); - } - - $scope.createFavoriteErrorMenu=function() { - $scope.favoritesMenuItems = []; - $scope.favoriteItemsCount = Object.keys($scope.favoritesMenuItems).length; - $log.info('number of favorite menus: ' + $scope.favoriteItemsCount); - } - - /* end of Favorite Menu code */ - /* **************************************************************************/ - - - /* **************************************************************************/ - // THIS IS USED FOR LOCAL TESTING ONLY - /* **************************************************************************/ - $scope.createErrorMenu=function() { - $log.debug('Creating fake menu now...'); -// $scope.loadMenufail=true; - $scope.menuItems = [ - { - "menuId": 1, - "column": 2, - "text": "Design", - "parentMenuId": null, - "url": "" - }, - { - "menuId": 2, - "column": 3, - "text": "Infrastructure Ordering", - "parentMenuId": null, - "url": "" - }, - { - "menuId": 3, - "column": 4, - "text": "Service Creation", - "parentMenuId": null, - "url": "" - }, - { - "menuId": 4, - "column": 5, - "text": "Service Mgmt", - "parentMenuId": null, - "url": "" - }, - { - "menuId": 90, - "column": 1, - "text": "Google", - "parentMenuId": 1, - "url": "" - }, - { - "menuId": 91, - "column": 1, - "text": "Mike Little's Coffee Cup", - "parentMenuId": 2, - "url": "" - }, - { - "menuId": 92, - "column": 2, - "text": "Andy and his Astrophotgraphy", - "parentMenuId": 3, - "url": "" - }, - { - "menuId": 93, - "column": 1, - "text": "JSONLint", - "parentMenuId": 4, - "url": "" - }, - { - "menuId": 94, - "column": 2, - "text": "HROneStop", - "parentMenuId": 4, - "url": "" - }, - { - "menuId": 95, - "column": 2, - "text": "4th Level App4a R16", - "parentMenuId": 4, - "url": "" - }, - { - "menuId": 96, - "column": 3, - "text": "3rd Level App1c R200", - "parentMenuId": 4, - "url": "" - }, - { - "menuId": 97, - "column": 1, - "text": "3rd Level App4b R16", - "parentMenuId": 5, - "url": "" - }, - { - "menuId": 98, - "column": 2, - "text": "3rd Level App2b R16", - "parentMenuId": 5, - "url": "" - }, - { - "menuId": 99, - "column": 1, - "text": "Favorites", - "parentMenuId": null, - "url": "" - } - ]; - $scope.menuItems = unflatten( $scope.menuItems ); - //remove this - $scope.megaMenuDataObject = menuStructureConvert($scope.menuItems); - } - }] - } -}); - -app.filter("ellipsis", function(){ - return function(text, length){ - if (text) { - var ellipsis = text.length > length ? "..." : ""; - return text.slice(0, length) + ellipsis; - }; - return text; - } -}); - -function reloadPageOnce() { - if( window.localStorage ) - { - if( !localStorage.getItem('firstLoad') ) - { - localStorage['firstLoad'] = true; - window.location.reload(); - } - else - localStorage.removeItem('firstLoad'); - } -} -app.controller('loginSnippetCtrl', function ($scope,$http, $log,UserInfoService){ - /*Define fields*/ - $scope.userProfile={ - firstName:'', - lastName:'', - fullName:'', - email:'', - userid:'' - } - /*Put user info into fields*/ - $scope.inputUserInfo = function(userInfo){ - if (typeof(userInfo) != "undefined" && userInfo!=null && userInfo!=''){ - if (typeof(userInfo.USER_FIRST_NAME) != "undefined" && userInfo.USER_FIRST_NAME!=null && userInfo.USER_FIRST_NAME!='') - $scope.userProfile.firstName = userInfo.USER_FIRST_NAME; - if (typeof(userInfo.USER_LAST_NAME) != "undefined" && userInfo.USER_LAST_NAME!=null && userInfo.USER_LAST_NAME!='') - $scope.userProfile.lastName = userInfo.USER_LAST_NAME; - if (typeof(userInfo.USER_EMAIL) != "undefined" && userInfo.USER_EMAIL!=null && userInfo.USER_EMAIL!='') - $scope.userProfile.email = userInfo.USER_EMAIL; - if (typeof(userInfo.USER_ORGUSERID) != "undefined" && userInfo.USER_ORGUSERID!=null && userInfo.USER_ORGUSERID!='') - $scope.userProfile.userid = userInfo.USER_ORGUSERID; - } - } - /*getting user info from session*/ - $scope.getUserNameFromSession = function(){ - UserInfoService.getFunctionalMenuStaticDetailSession() - .then(function (response) { - $scope.userProfile.fullName = response.userName; - $scope.userProfile.userid = response.userid; - $scope.userProfile.email = response.email; - }); - } - /*getting user info from shared context*/ - $scope.getUserName=function() { - var promise = UserInfoService.getFunctionalMenuStaticDetailShareContext(); - promise.then( - function(res) { - if(res==null || res==''){ - $log.info('Getting User information from session'); - $scope.getUserNameFromSession(); - - }else{ - $log.info('Received User information from shared context',res); - var resData = res; - console.log(resData); - $scope.inputUserInfo(resData); - $scope.userProfile.fullName = $scope.userProfile.firstName+ ' '+ $scope.userProfile.lastName; - } - }, - function(err) { - console.log('error'); - } - ); - }; - /*call the get user info function*/ - try{ - $scope.getUserName(); - }catch(err){ - $log.info('Error while getting User information',err); - } -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/leftMenu.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/leftMenu.js deleted file mode 100644 index 737cb801..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/directives/leftMenu.js +++ /dev/null @@ -1,203 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ - -app.directive('qMenu', function () { - return { - restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements - replace: false, - templateUrl: "app/fusion/scripts/view-models/left_menu.html", - controller: ['$scope', '$filter','$http','$timeout','$cookies','LeftMenuService', function ($scope, $filter, $http,$timeout,$cookies,LeftMenuService) { - - $scope.leftChildData=[]; - $scope.leftParentData=[]; - $scope.leftMenuItems = []; - $scope.app_name = ""; - $scope.app_name_full; - LeftMenuService.getLeftMenu().then(function(response){ - var j = response; - try{ - if(j && j !== "null" && j!== "undefined"){ - $scope.leftParentData = JSON.parse(j.data); - $scope.leftChildData = JSON.parse(j.data2); - }else{ - throw "Get Left Menu respsone is not an object/is empty"; - } - try{ - var leftChildItemList = $scope.leftChildData; - var pageUrl = window.location.href.split('/')[window.location.href.split('/').length-1]; - var leftParentList =$scope.leftParentData; - for (var i = 0; i < leftParentList.length; i++) { - $scope.item = { - parentLabel : leftParentList[i].label, - parentAction : leftParentList[i].action, - parentImageSrc : leftParentList[i].imageSrc, - open:pageUrl==leftParentList[i].action?true:false, - childItemList : leftChildItemList[i] - } - $scope.leftMenuItems.push($scope.item); - }; - }catch(err){ - console.log("error happened while trying to set left menu structure"+err); - } - }catch (e) { - console.log("error happened while trying to get left menu items"+e); - reloadPageOnce(); - return; - } - },function(error){ - console.log("error happened while calling getLeftMenu"+error); - }); - - LeftMenuService.getAppName().then(function(response){ - var j = response; - try{ - if(j && j !== "null" && j!== "undefined"){ - console.log("app name is " + $scope.app_name); - $scope.app_name_full = j.data; - var processed_app_name = j.data; - var n = processed_app_name.length; - if (n > 15) { - n = 15; - } - $scope.app_name = processed_app_name.substr(0, n); - }else{ - throw "Get app_name respsone is not an object/is empty"; - } - }catch (e) { - console.log("error happened while trying to get app name "+e); - return; - } - },function(error){ - console.log("error happened while calling getAppName "+error); - }); - - $scope.adjustHeader=function() { - $scope.showHeader = ($cookies.show_app_header == undefined ? true : $cookies.show_app_header); - - if($scope.showHeader == true) { - $scope.drawer_margin_top = 50; - $scope.drawer_custom_top = 20; - $scope.toggle_drawer_top = 55; - } - else { - - $scope.drawer_margin_top = 0; - $scope.drawer_custom_top = 0; - $scope.toggle_drawer_top = 0; - } - - - }; - - $scope.adjustHLeftMenu = function (type){ - $scope.showHeader = ($cookies.show_app_header == undefined ? true : $cookies.show_app_header); - - if($scope.showHeader == true) { - $scope.drawer_margin_top = 60; - $scope.drawer_custom_top = 54; - $scope.toggle_drawer_top = 55; - } - else { - - $scope.drawer_margin_top = 50; - $scope.drawer_custom_top = 0; - $scope.toggle_drawer_top = 10; - } - if(type=='burgerIcon'){ - return { "top": $scope.toggle_drawer_top+"px"}; - }else if(type=='leftMenu'){ - return { "margin-top": $scope.drawer_margin_top+"px"}; - }else - return; - } - $scope.adjustHeader(); - $scope.drawerOpen = true; - - $scope.toggleDrawer = function() { - $scope.drawerOpen = !($scope.drawerOpen); - if ($scope.drawerOpen) { - // setCookie('drawerOpen','open',30); - $scope.arrowShow = true; - - - if (document.getElementById('fnMenueContent')!=null) - document.getElementById('fnMenueContent').style.marginLeft = "0px"; - - if (document.getElementById('rightContentAdmin')!=null) - document.getElementById('rightContentAdmin').style.marginLeft = "210px"; - - else if (document.getElementById('rightContentProfile')!=null) - document.getElementById('rightContentProfile').style.marginLeft = "210px"; - - - - } else { - - $scope.arrowShow = false; - - if (document.getElementById('fnMenueContent')!=null) - document.getElementById('fnMenueContent').style.marginLeft = "-150px"; - - if (document.getElementById('rightContentAdmin')!=null) { - document.getElementById('rightContentAdmin').style.marginLeft = "50px"; - - } - - else if (document.getElementById('rightContentProfile')!=null) - document.getElementById('rightContentProfile').style.marginLeft = "50px"; - - - - - } - }; - - $timeout(function() { - detectScrollEvent(); - }, 800); - }] - } - -}); -$(window).scroll(function() { - if ($('.att-drawer').is(':visible')) { - detectScrollEvent(); - } - -}); - -function detectScrollEvent() { - try{ - var footerOff = $('#footerContainer').offset().top; - var headOff = $('#headerContainer').offset().top; - var winHeight = $(window).height(); - if ((footerOff - headOff) <= winHeight) { - $('.att-drawer').css({ - "height" : footerOff - headOff - 55 - }); - } else { - $('.att-drawer').css({ - "height" : "94vh" - }); - } - }catch(err){ - console.log(err) - } -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/adminService.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/adminService.js deleted file mode 100644 index 85a4d1bd..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/adminService.js +++ /dev/null @@ -1,160 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.factory('AdminService', function ($http, $q) { - return { - getRoles: function() { - return $http.get('get_roles') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getRoleFunctionList: function() { - return $http.get('get_role_functions') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getFnMenuItems: function(){ - - return $http.get('admin_fn_menu') - .then(function(response) { - if (typeof response.data === 'object') { - - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getCacheRegions: function() { - return $http.get('get_regions') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getUsageList: function() { - return $http.get('get_usage_list') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getBroadcastList: function() { - return $http.get('get_broadcast_list') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getBroadcast: function(messageLocationId, messageLocation, messageId) { - return $http.get('get_broadcast?message_location_id='+messageLocationId + '&message_location=' + messageLocation + ((messageId != null) ? '&message_id=' + messageId : '')) - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getCollaborateList: function() { - return $http.get('get_collaborate_list') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getRole: function(roleId) { - - return $http.get('get_role?role_id=' + roleId) - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - } - }; -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/headerService.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/headerService.js deleted file mode 100644 index 4b4a2ec4..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/headerService.js +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -var menuStructureConvert = function(menuItems) { - var megaMenuDataObjectTemp = [ - { - text: "ECOMP", - children:menuItems - }, - { - text: "Help", - children: [{ - text:"Contact Us", - url:"javascript:angular.element('[ng-controller=headerController]').scope().redirectLink('contact');" - }, - { - text:"Get Access", - url:"javascript:angular.element('[ng-controller=headerController]').scope().redirectLink('access');" - }] - } - ]; - return megaMenuDataObjectTemp; -}; -var unflatten = function( array, parent, tree ){ - tree = typeof tree !== 'undefined' ? tree : []; - parent = typeof parent !== 'undefined' ? parent : { menuId: null }; - var children = _.filter( array, function(child){ return child.parentMenuId == parent.menuId; }); - - if( !_.isEmpty( children ) ){ - if( parent.menuId === null ){ - tree = children; - }else{ - parent['children'] = children - } - _.each( children, function( child ){ unflatten( array, child ) } ); - } - - return tree; - } -app.service('HeaderService', function ($http,$log, $q,UserInfoService) { - return{ - - getUserNameFromSession : function(){ - UserInfoService.getFunctionalMenuStaticDetailSession() - .then(function (res) { - $scope.userName = res.userName; - $scope.redirectUrl = res.portalUrl; - }); - }, - getTopMenuStaticInfo:function() { - var promise = UserInfoService.getFunctionalMenuStaticDetailShareContext(); - promise.then( - function(res) { - if(res==null || res==''){ - $log.info('failed getting static User information'); - this.getUserNameFromSession(); - }else{ - $log.info('Received static User information'); - var resData = res; - $scope.inputUserInfo(resData); - $scope.userProfile.fullName = $scope.userProfile.firstName+ ' '+ $scope.userProfile.lastName; - return $scope.userProfile; - } - }, - function(err) { - $log.info('failed getting static User information'); - } - ); - } - } - } -); - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/leftMenuService.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/leftMenuService.js deleted file mode 100644 index 17e53c7d..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/leftMenuService.js +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -function isRealValue(obj){ - return obj && obj !== "null" && obj!== "undefined"; -} -app.factory('LeftMenuService', function ($http,$log, $q) { - return { - getLeftMenu: function() { - return $http.get('get_menu') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - getAppName: function() { - return $http.get('get_app_name') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - } - - }; -}); - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/profileService.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/profileService.js deleted file mode 100644 index 7c73bed9..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/profileService.js +++ /dev/null @@ -1,98 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ - -app.factory('ProfileService', function ($http, $q) { - return { - getProfile: function() { - return $http.get('get_user') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getProfilePagination: function(pageNum,viewPerPage) { - return $http.get('get_user_pagination?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage) - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getPostProfile: function() { - return $http.get('post_search_sample') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getProfileDetail: function(profileId) { - return $http.get('get_profile?profile_id='+profileId) - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getSelfProfileDetail: function() { - return $http.get('get_self_profile') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - } - }; -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/userInfoService.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/userInfoService.js deleted file mode 100644 index 9c0d3c02..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/services/userInfoService.js +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.factory('UserInfoService', function ($http, $q,$log) { - return { - getFunctionalMenuStaticDetailShareContext: function(contextId,key) { - var deferred = $q.defer(); - $http({ - method: "GET", - url: "get_userinfo", - }).success( function(res) { - if(res==null || res=='') - $log.info('Not be able to get User Info via shared context'); - deferred.resolve(res); - }).error( function(status) { - deferred.reject(status); - }); - return deferred.promise; - }, - getFunctionalMenuStaticDetailSession: function() { - var deferred = $q.defer(); - $http({ - method: "GET", - url: "get_topMenuInfo", - }).success(function(res) { - if(res==null || res=='') - $log.info('Not be able to get User Info via shared context'); - deferred.resolve(res); - }).error( function(status) { - deferred.reject(status); - }); - return deferred.promise; - } - }; -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/socket/peerBroadcast.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/socket/peerBroadcast.js deleted file mode 100644 index 46fa5c92..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/socket/peerBroadcast.js +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ - -var output = $('#peerBroadcastSection'); -var websocket = ''; -var currentUser = ''; -var remoteUser = ''; -var f = ''; -var popupService; - -function setPopupService(_popupService) { - popupService = _popupService; -} - -function socketSetup(initialPageVisit,_currentUser, _remoteUser, _f) { - - - - if( true) { - - var href = window.location.href; - var hostPatt = new RegExp(window.location.host +"/[^/]*"); - var res = hostPatt.exec(href); - var protocol = window.location.protocol.replace("http","ws"); - - var signalingServerPath = protocol + "//" + res + "/contact"; - var wsUri = signalingServerPath; - console.log("Connecting to " + wsUri); - websocket = new WebSocket(wsUri); - //localStorage.notifySocket = JSON.stringify(websocket); - //window.top.notifySocket = websocket; - - currentUser = _currentUser; - remoteUser = _remoteUser; - f = socketSend; - - - } - - //var websocket = JSON.parse(localStorage.notifySocket || "{}") ; - if( websocket != null) { - websocket.onopen = function(evt) { onOpen(evt); }; - websocket.onmessage = function(evt) { onMessage(evt); }; - websocket.onerror = function(evt) { onError(evt); }; - - } - - //if(f != undefined) - // f(); - - //window.top.notifySocket.send(""); -} - - -function socketSend(currentUser, remoteUser) { - - - - websocket.send(JSON.stringify({ - from: currentUser, - to: remoteUser - })); - - //window.top.notifySocket.send(""); -} - - - - -function onOpen(evt) { - console.log("onOpen"); - //writeToScreen("CONNECTED"); - - if(f != undefined) - f(currentUser, remoteUser); - -} - -function onMessage(evt) { - if (typeof evt.data == "string") { - writeToScreen("RECEIVED (text): " + evt.data); - - if(popupService != undefined) { - popupService.showMessage("Call Request","You are being contacted by " + JSON.parse(evt.data).from + ". Please click on the online icon and then click view"); - - } - //if (confirm("You are being contacted by " + JSON.parse(evt.data).from )) { - - //} - - } else { - writeToScreen("RECEIVED (binary): " + evt.data); - } -} - -function onError(evt) { - writeToScreen('ERROR: ' + evt.data); -} - -function writeToScreen(message) { - var pre = document.createElement("p"); - pre.style.wordWrap = "break-word"; - pre.innerHTML = message; - output.append(pre); -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/utils/page-resource.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/utils/page-resource.js deleted file mode 100644 index 8449ecfc..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/utils/page-resource.js +++ /dev/null @@ -1,95 +0,0 @@ -function loadjscssfile(filename, filetype){ - if (filetype=="js"){ //if filename is a external JavaScript file - var done = false; - var script = document.createElement('script'); - script.src = filename; - script.async = false; - document.head.appendChild(script); - }else if (filetype=="css"){ //if filename is an external CSS file - var fileref=document.createElement("link") - fileref.setAttribute("rel", "stylesheet") - fileref.setAttribute("type", "text/css") - fileref.setAttribute("async", false) - fileref.setAttribute("href", filename) - document.head.appendChild(fileref); - } -} - -function loadResource(){ - //css - loadjscssfile("app/fusion/external/ebz/fn-ebz.css", "css"); - loadjscssfile("app/fusion/external/ebz/sandbox/styles/demo.css", "css"); - loadjscssfile("app/fusion/external/ebz/sandbox/styles/base.css", "css"); - loadjscssfile("app/fusion/external/ebz/sandbox/styles/btn.css", "css"); - loadjscssfile("app/fusion/external/ebz/sandbox/styles/dtpk.css", "css"); - loadjscssfile("app/fusion/external/ebz/sandbox/styles/frms.css", "css"); - loadjscssfile("app/fusion/external/ebz/sandbox/styles/sldr.css", "css"); - loadjscssfile("app/fusion/external/ebz/sandbox/styles/style.css", "css"); - loadjscssfile("app/fusion/external/ebz/sandbox/styles/tbs.css", "css"); - loadjscssfile("app/fusion/external/ebz/ebz_header/portal_ebz_header.css", "css"); - loadjscssfile("static/fusion/css/jquery-ui.css", "css"); - - - loadjscssfile("app/fusion/external/ebz/ebz_header/header.css", "css"); - loadjscssfile("app/fusion/external/ebz/ebz_header/footer.css", "css"); - // Basic AngularJS --> - loadjscssfile("app/fusion/external/ebz/angular_js/angular.js", "js"); - loadjscssfile("app/fusion/external/ebz/angular_js/angular-sanitize.js", "js"); - loadjscssfile("app/fusion/external/ebz/angular_js/angular-route.min.js", "js"); - loadjscssfile("app/fusion/external/ebz/angular_js/angular-cookies.js", "js"); - loadjscssfile("app/fusion/external/ebz/angular_js/gestures.js", "js"); - loadjscssfile("app/fusion/external/ebz/angular_js/app.js", "js"); - - loadjscssfile("app/fusion/external/ebz/sandbox/att-abs-tpls.js", "js"); - - // jQuery --> - loadjscssfile("static/js/jquery-1.10.2.js", "js"); - loadjscssfile("static/js/jquery.mask.min.js", "js"); - loadjscssfile("static/js/jquery-ui.js", "js"); - - // AngularJS Gridster --> - loadjscssfile("static/fusion/js/att_angular_gridster/ui-gridster-tpls.js", "js"); - loadjscssfile("static/fusion/js/att_angular_gridster/angular-gridster.js", "js"); - - // AngularJS Config --> - loadjscssfile("app/fusion/external/ebz/angular_js/checklist-model.js", "js"); - - // Utility --> - loadjscssfile("app/fusion/scripts/modalService.js", "js"); - loadjscssfile("app/fusion/external/angular-ui/ui-bootstrap-tpls-1.1.2.min.js", "js"); - - // Controller js --> - loadjscssfile("app/fusion/scripts/controllers/profile-search-controller.js", "js"); - loadjscssfile("app/fusion/scripts/controllers/profile-controller.js", "js"); - loadjscssfile("app/fusion/scripts/controllers/post-search-controller.js", "js"); - loadjscssfile("app/fusion/scripts/controllers/self-profile-controller.js", "js"); - loadjscssfile("app/fusion/scripts/controllers/rolefunctionpopupController.js", "js"); - loadjscssfile("app/fusion/scripts/controllers/modelpopupController.js", "js"); - - // Header and Footer --> - loadjscssfile("app/fusion/scripts/directives/footer.js", "js"); - loadjscssfile("app/fusion/external/ebz/js/footer.js", "js"); - loadjscssfile("app/fusion/scripts/directives/header.js", "js"); - loadjscssfile("app/fusion/scripts/directives/leftMenu.js", "js"); - - // Services --> - loadjscssfile("app/fusion/scripts/services/profileService.js", "js"); - loadjscssfile("app/fusion/scripts/services/userInfoService.js", "js"); - loadjscssfile("app/fusion/scripts/services/leftMenuService.js", "js"); - loadjscssfile("app/fusion/scripts/controllers/profileController.js", "js"); -} - -window.onload = loadResource(); -window.onload = function(){ - var appLoadingInterval = setInterval(function(){ loadApp() }, 500); - var count=0; - function loadApp(){ - count++ - if(typeof angular !== 'undefined') { - angular.bootstrap(document, ['abs']); - clearInterval(appLoadingInterval); - }else if(count>10){ - clearInterval(appLoadingInterval); - } - } -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/admin-page/admin.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/admin-page/admin.html deleted file mode 100644 index f83888d9..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/admin-page/admin.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        -
        -
        -
        -
        -
        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/admin-page/profile.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/admin-page/profile.html deleted file mode 100644 index 56c06ebc..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/admin-page/profile.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -
        -
        -
        -
        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/footer.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/footer.html deleted file mode 100644 index 56148731..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/footer.html +++ /dev/null @@ -1,42 +0,0 @@ - - -
        - -
        -
        - -
        - -
        -
        -
        - - -
        -
        - -
        -
        -
        -
        -
        -
        - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/header.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/header.html deleted file mode 100644 index adb5be35..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/header.html +++ /dev/null @@ -1,186 +0,0 @@ - -
        -
        -
        -
        -
        - - -
        -
        -
        -
        -
      • -
        - ECOMP Portal -
      • -
        -
        - - -
        - - -
        - -
        -
        -
        -
      • - Unable to load menus -
      • -
        -
      • -
        - - -
        -
      • -
      •  
      • -
        - -
        - -
        -
        -
        -
        -
        -
        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/left_menu.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/left_menu.html deleted file mode 100644 index 84ee6ead..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/left_menu.html +++ /dev/null @@ -1,41 +0,0 @@ - -
        - - - -     {{app_name}} - -
        -
        -
        -
        - - - - - -
        -
        -
        -
        -
        \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/admin_menu_edit.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/admin_menu_edit.html deleted file mode 100644 index ee23635f..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/admin_menu_edit.html +++ /dev/null @@ -1,175 +0,0 @@ - - -
        -
        -
        -

        Admin Menu Items

        -
        -
        - Add menu item here: -
        -
        - -
        -
        -
        - Existing menu items: -
        -
        - - - -
        - - -
        -
        - - - -
        Number of records to show: -
        - -
        -
        - -
        - - - - - -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast.html deleted file mode 100644 index a14da056..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast.html +++ /dev/null @@ -1,61 +0,0 @@ - -
        -
        -

        Broadcast Message Edit

        -
        - -
        - Please edit the broadcast message details below: 

        -
        -
        - -
        -
        -
        -
        - - -
        - -
        -
        - - -
        - -
        -
        - -
        - -
        -
        -
        -
        - -
        -
        - - -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast_list.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast_list.html deleted file mode 100644 index e9c4c291..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/broadcast_list.html +++ /dev/null @@ -1,71 +0,0 @@ - -
        - -
        - -

        Broadcast Messages

        -
        -
        - {{location.label}} Messages -
        - - - - - - - - - - - - - - - - - {{message.id}} - - - - - - - - - - - -
        No.Message TextStart DateEnd DateSort OrderServerActive?Delete?
        {{$index+1}}{{message.messageText}} - {{message.displayStartDate}} - {{message.displayEndDate}}{{message.sortOrder}}{{message.siteCd}} -
        - -
        -
        -
        -
        -
        - -


        -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/collaborate_list.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/collaborate_list.html deleted file mode 100644 index 5f07a47b..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/collaborate_list.html +++ /dev/null @@ -1,57 +0,0 @@ - -
        -
        -

        User List

        -
        - - - - - - - - - - - - - - - - - - - - - - -
        User IDLast NameFirst NameEmailUser IDOnline/Offline
        {{rowData.id}}{{rowData.lastName}}{{rowData.firstName}}{{rowData.email}}{{rowData.orgUserId}} - Offline - Online -
        -
        -
        - - - - Add the Chrome Extension for DescktopCapture and refresh page -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/jcs_admin.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/jcs_admin.html deleted file mode 100644 index 7da45780..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/jcs_admin.html +++ /dev/null @@ -1,87 +0,0 @@ - -
        - -

        Cache Regions

        -
        -
        - These are the regions which are currently defined in the cache. 'Items' and 'Bytes' refer to the elements currently in memory (not spooled). - You can clear all items for a region by clicking on the Clear icon next to the desired region below. You can also clear all regions - which empties the entire cache. -
        - -
        -
        -
        Cache Name
        -
        # of Items
        -
        Bytes
        -
        Status
        -
        Memory Hits
        -
        Aux Hits
        -
        Not Found Misses
        -
        Expired Misses
        -
        Clear?
        -
        Items
        -
        -
        -
        - -
        {{region.size}}
        -
        {{region.byteCount}}
        -
        {{region.status}}
        -
        {{region.hitCountRam}}
        -
        {{region.hitCountAux}}
        -
        {{region.missCountNotFound}}
        -
        {{region.missCountExpired}}
        -
        -
        -
        -
        - - -
        -
        -
        - -
        Key
        -
        Eternal?
        -
        Created
        -
        Max Life
        -
        Expires
        -
        Clear?
        -
        -
        -
        - - -
        {{item.eternal}}
        -
        {{item.createTime}}
        -
        {{item.maxLifeSeconds}}
        -
        {{item.expiresInSeconds}}
        -
        -
        -
        -
        -
        -
        -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal.html deleted file mode 100644 index 3cde902c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal.html +++ /dev/null @@ -1,282 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_add.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_add.html deleted file mode 100644 index 760f10b5..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_add.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_edit.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_edit.html deleted file mode 100644 index 4c23ba6f..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_fn_menu_edit.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_role.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_role.html deleted file mode 100644 index 4663bd46..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_role.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_rolefunction.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_rolefunction.html deleted file mode 100644 index b9e8ef0e..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/popup_modal_rolefunction.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/post_search.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/post_search.html deleted file mode 100644 index 2c4846dd..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/post_search.html +++ /dev/null @@ -1,139 +0,0 @@ - -
        -

        User Search

        -
        - Please enter search criteria below:
        - -
        - Last Name:
        - -
        - -
        - First Name:
        - -
        - -
        - User ID:
        - -
        - -
        - Manager User ID:
        - -
        -
        -
        - Organization:
        - -
        - -
        - Email:
        - -
        -
        -
        - - - -
        -
        - - {{noResultsString}} - -
        - - - - - - - - - - - - - - - - - - - - - - - - - -
        NoNameOrgUserIdOrganizationPhoneEmailImport?
        - {{$index + 1}} - -
        - {{profile.lastName}}, {{profile.firstName}} -
        - - -
        - {{profile.orgUserId}} - - {{profile.orgCode}} - - {{profile.phone}} - - {{profile.email}} - -
        -
        - -
        -
        -
        - Exists -
        -
        -
        - Rows Per Page: - -
        -
        - Current Page: - -
        -
        - Total Page(s): - -
        - -
        - -
        - -
        - -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/profile_detail.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/profile_detail.html deleted file mode 100644 index c5ef97a7..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/profile_detail.html +++ /dev/null @@ -1,188 +0,0 @@ - -
        -
        -

        Profile Edit

        -
        - Please edit the profile details below: 

        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        -   -
        -
        - -
        -
        -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        -
        -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        -
        -
        -
        - -
        - -
        -
        -
        -
        - -
        -
        - -
        - -
        -
        -
        -
        -
        -
        -
        -
        -
        - -
        - -
        - -
        -
        - - - -
        - - - - - - - - - - - - - - - - -
        NameRemove?
        {{ role.name }} - -
        - - - - - - -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/profile_search.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/profile_search.html deleted file mode 100644 index 9f49a80f..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/profile_search.html +++ /dev/null @@ -1,72 +0,0 @@ - -
        - -

        Profile Search

        - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        User IDLast NameFirst NameEmailUser IDManager User IDEditActive?
        -
        - -
        -
        - -
        - Records Per Page: - -
        - - - - -
        - -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role.html deleted file mode 100644 index c312f5b7..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role.html +++ /dev/null @@ -1,118 +0,0 @@ - -
        -
        - -
        -

        Role Edit

        -
        -
        - Please edit the role details below: 
        - -
        -
        - -
        - -
        -
        - -
        - -
        - -
        - -
        -
        - - -
        - - - - - - - - - - - - - - -
        NameRemove?
        {{ roleFunction.name }} -
        -
        - Manage Role Functions

        - -
        - - -
        - - - - - - - - - - - - - - -
        NameRemove?
        {{ role.name }} -
        -
        - -
        - - - - - - - - - - - - - - -
        Role
        -
        - -
        -
        {{ availableRole.name }}
        -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role_function_list.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role_function_list.html deleted file mode 100644 index b0851036..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role_function_list.html +++ /dev/null @@ -1,88 +0,0 @@ - -
        -
        - -

        Role Functions

        -
        - -
        - -
        -

        - -
        - -
        -
        - Click on the edit icon to update a role function, the plus icon to add additional role functions, or the delete icon to remove them. -
        -
        -
        - - - - - - - - - - - - - - - - - -
        NameCodeEdit?Delete?
        - -
        -
        - -
        -
        -
        - - -
        - -
        -
        - -
        -
        -
        -
        - -
        -
        - - -
        - -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role_list.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role_list.html deleted file mode 100644 index 1100cbb0..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/role_list.html +++ /dev/null @@ -1,61 +0,0 @@ - -
        - -

        Roles

        -
        -
        -Click on a Role to view its details. - -
        -
        - - - - - - - - - - - - - - - - - - -
        NamePriorityActive?Delete?
        {{ availableRole.name }}{{ availableRole.priority }} -
        - -
        -
        -
        -
        -
        - -
        - -
        - -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/self_profile.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/self_profile.html deleted file mode 100644 index bc8ddd2f..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/self_profile.html +++ /dev/null @@ -1,183 +0,0 @@ - - - -

        Self Profile

        -
        - Please edit the profile details below: 

        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        -
        -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        -
        -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        - -
        -
        - -
        -
        -
        -
        - -
        - -
        -
        -
        -
        - -
        -
        - -
        - -
        -
        -
        -
        -
        -
        -
        -
        -
        - -
        - -
        - -
        -
        - - - -
        - - - - - - - - - - - - - - - - -
        NameRemove?
        {{ role.name }} - -
        - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/usage_list.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/usage_list.html deleted file mode 100644 index 27ae72b5..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/profile-page/usage_list.html +++ /dev/null @@ -1,64 +0,0 @@ - -
        -
        -

        Users

        -
        - -
        - The following shows all users currently logged into the application. Click the icon to expel a user from the application. -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        Current User Sessions
        User IdUser NameEmailLast Access Time (minutes)Time Remaining (minutes)Expire User Session?
        {{user.id}}{{user.lastName}}{{user.email}}{{user.lastAccess}}{{user.remaining}}
        Current Session
        - -
        -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-landing.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-landing.html deleted file mode 100644 index 2b5e3b60..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-landing.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        -
        -
        -
        -
        -
        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-listing.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-listing.html deleted file mode 100644 index ceb88677..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-listing.html +++ /dev/null @@ -1,85 +0,0 @@ - -
        -
        -
        -
        -

        -

        -
        -
        -
        -
        - -
        -
        -
        -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        IdNameKeyDescriptionWorkflow Server URLViewActiveCreated Created ByActionScheduleEditDelete?
        {{workflow.id}}{{workflow.name}}{{workflow.workflowKey}}{{workflow.description}}{{workflow.runLink}}
        {{workflow.active}}{{workflow.created}}{{workflow.createdBy}}
        -
        - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-new.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-new.html deleted file mode 100644 index 4622b928..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-new.html +++ /dev/null @@ -1,108 +0,0 @@ - -
        - -
        -
        - -
        - - -
        - - -
        - Workflow Name is required !!! -
        - -
        -
        - - -
        - -
        - - -
        - Workflow Key is required !!! -
        - -
        -
        - - -
        - - -
        - -
        -
        - -
        - -
        - -
        - -
        - Run Link is required !!! - Not valid url! -
        - -
        - - - -
        - -
        - - - Active - Inactive - - -
        -
        - - -
        -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-preview.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-preview.html deleted file mode 100644 index 80fece4e..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-preview.html +++ /dev/null @@ -1,36 +0,0 @@ - -
        - -
        -
        - -
        - -
        - -
        -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-remove.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-remove.html deleted file mode 100644 index e21efad8..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-remove.html +++ /dev/null @@ -1,38 +0,0 @@ - -
        - -
        -
        - -
        - -
        - - -
        -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-schedule.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-schedule.html deleted file mode 100644 index aebc04fb..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/view-models/workflows/workflow-schedule.html +++ /dev/null @@ -1,116 +0,0 @@ - -
        - - -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - : - - - - - - - -
        - - -
        -
        -
        - - -Pick a date: - -Hour: - -Minute: -
        -
        - -
        -
        - - - -
        -
        -
        -
        -
        - -
        -
        - - -
        -
        -
        -
        - - - -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/webrtc/RTCMultiConnection.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/webrtc/RTCMultiConnection.js deleted file mode 100644 index 449e8d59..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/scripts/webrtc/RTCMultiConnection.js +++ /dev/null @@ -1,6788 +0,0 @@ -// Last time updated at Monday, December 21st, 2015, 5:25:26 PM - -// Quick-Demo for newbies: http://jsfiddle.net/c46de0L8/ -// Another simple demo: http://jsfiddle.net/zar6fg60/ - -// Latest file can be found here: https://cdn.webrtc-experiment.com/RTCMultiConnection.js - -// Muaz Khan - www.MuazKhan.com -// MIT License - www.WebRTC-Experiment.com/licence -// Documentation - www.RTCMultiConnection.org/docs -// FAQ - www.RTCMultiConnection.org/FAQ -// Changes log - www.RTCMultiConnection.org/changes-log/ -// Demos - www.WebRTC-Experiment.com/RTCMultiConnection - -// _________________________ -// RTCMultiConnection-v2.2.2 - -(function() { - - // RMC == RTCMultiConnection - // usually page-URL is used as channel-id - // you can always override it! - // www.RTCMultiConnection.org/docs/channel-id/ - window.RMCDefaultChannel = location.href.replace(/\/|:|#|\?|\$|\^|%|\.|`|~|!|\+|@|\[|\||]|\|*. /g, '').split('\n').join('').split('\r').join(''); - - // www.RTCMultiConnection.org/docs/constructor/ - window.RTCMultiConnection = function(channel) { - // an instance of constructor - var connection = this; - - // a reference to RTCMultiSession - var rtcMultiSession; - - // setting default channel or channel passed through constructor - connection.channel = channel || RMCDefaultChannel; - - // to allow single user to join multiple rooms; - // you can change this property at runtime! - connection.isAcceptNewSession = true; - - // www.RTCMultiConnection.org/docs/open/ - connection.open = function(args) { - connection.isAcceptNewSession = false; - - // www.RTCMultiConnection.org/docs/session-initiator/ - // you can always use this property to determine room owner! - connection.isInitiator = true; - - var dontTransmit = false; - - // a channel can contain multiple rooms i.e. sessions - if (args) { - if (isString(args)) { - connection.sessionid = args; - } else { - if (!isNull(args.transmitRoomOnce)) { - connection.transmitRoomOnce = args.transmitRoomOnce; - } - - if (!isNull(args.dontTransmit)) { - dontTransmit = args.dontTransmit; - } - - if (!isNull(args.sessionid)) { - connection.sessionid = args.sessionid; - } - } - } - - // if firebase && if session initiator - if (connection.socket && connection.socket.remove) { - connection.socket.remove(); - } - - if (!connection.sessionid) connection.sessionid = connection.channel; - connection.sessionDescription = { - sessionid: connection.sessionid, - userid: connection.userid, - session: connection.session, - extra: connection.extra - }; - - if (!connection.sessionDescriptions[connection.sessionDescription.sessionid]) { - connection.numberOfSessions++; - connection.sessionDescriptions[connection.sessionDescription.sessionid] = connection.sessionDescription; - } - - // connect with signaling channel - initRTCMultiSession(function() { - // "captureUserMediaOnDemand" is disabled by default. - // invoke "getUserMedia" only when first participant found. - rtcMultiSession.captureUserMediaOnDemand = args ? !!args.captureUserMediaOnDemand : false; - - if (args && args.onMediaCaptured) { - connection.onMediaCaptured = args.onMediaCaptured; - } - - // for session-initiator, user-media is captured as soon as "open" is invoked. - if (!rtcMultiSession.captureUserMediaOnDemand) captureUserMedia(function() { - rtcMultiSession.initSession({ - sessionDescription: connection.sessionDescription, - dontTransmit: dontTransmit - }); - - invokeMediaCaptured(connection); - }); - - if (rtcMultiSession.captureUserMediaOnDemand) { - rtcMultiSession.initSession({ - sessionDescription: connection.sessionDescription, - dontTransmit: dontTransmit - }); - } - }); - return connection.sessionDescription; - }; - - // www.RTCMultiConnection.org/docs/connect/ - connection.connect = function(sessionid) { - // a channel can contain multiple rooms i.e. sessions - if (sessionid) { - connection.sessionid = sessionid; - } - - // connect with signaling channel - initRTCMultiSession(function() { - log('Signaling channel is ready.'); - }); - - return this; - }; - - // www.RTCMultiConnection.org/docs/join/ - connection.join = joinSession; - - // www.RTCMultiConnection.org/docs/send/ - connection.send = function(data, _channel) { - if (connection.numberOfConnectedUsers <= 0) { - // no connections - setTimeout(function() { - // try again - connection.send(data, _channel); - }, 1000); - return; - } - - // send file/data or /text - if (!data) - throw 'No file, data or text message to share.'; - - // connection.send([file1, file2, file3]) - // you can share multiple files, strings or data objects using "send" method! - if (data instanceof Array && !isNull(data[0].size) && !isNull(data[0].type)) { - // this mechanism can cause failure for subsequent packets/data - // on Firefox especially; and on chrome as well! - // todo: need to use setTimeout instead. - for (var i = 0; i < data.length; i++) { - data[i].size && data[i].type && connection.send(data[i], _channel); - } - return; - } - - // File or Blob object MUST have "type" and "size" properties - if (!isNull(data.size) && !isNull(data.type)) { - if (!connection.enableFileSharing) { - throw '"enableFileSharing" boolean MUST be "true" to support file sharing.'; - } - - if (!rtcMultiSession.fileBufferReader) { - initFileBufferReader(connection, function(fbr) { - rtcMultiSession.fileBufferReader = fbr; - connection.send(data, _channel); - }); - return; - } - - var extra = merge({ - userid: connection.userid - }, data.extra || connection.extra); - - rtcMultiSession.fileBufferReader.readAsArrayBuffer(data, function(uuid) { - rtcMultiSession.fileBufferReader.getNextChunk(uuid, function(nextChunk, isLastChunk, extra) { - if (_channel) _channel.send(nextChunk); - else rtcMultiSession.send(nextChunk); - }); - }, extra); - } else { - // to allow longest string messages - // and largest data objects - // or anything of any size! - // to send multiple data objects concurrently! - - TextSender.send({ - text: data, - channel: rtcMultiSession, - _channel: _channel, - connection: connection - }); - } - }; - - function initRTCMultiSession(onSignalingReady) { - if (screenFrame) { - loadScreenFrame(); - } - - // RTCMultiSession is the backbone object; - // this object MUST be initialized once! - if (rtcMultiSession) return onSignalingReady(); - - // your everything is passed over RTCMultiSession constructor! - rtcMultiSession = new RTCMultiSession(connection, onSignalingReady); - } - - connection.disconnect = function() { - if (rtcMultiSession) rtcMultiSession.disconnect(); - rtcMultiSession = null; - }; - - function joinSession(session, joinAs) { - if (isString(session)) { - connection.skipOnNewSession = true; - } - - if (!rtcMultiSession) { - log('Signaling channel is not ready. Connecting...'); - // connect with signaling channel - initRTCMultiSession(function() { - log('Signaling channel is connected. Joining the session again...'); - setTimeout(function() { - joinSession(session, joinAs); - }, 1000); - }); - return; - } - - // connection.join('sessionid'); - if (isString(session)) { - if (connection.sessionDescriptions[session]) { - session = connection.sessionDescriptions[session]; - } else - return setTimeout(function() { - log('Session-Descriptions not found. Rechecking..'); - joinSession(session, joinAs); - }, 1000); - } - - // connection.join('sessionid', { audio: true }); - if (joinAs) { - return captureUserMedia(function() { - session.oneway = true; - joinSession(session); - }, joinAs); - } - - if (!session || !session.userid || !session.sessionid) { - error('missing arguments', arguments); - - var error = 'Invalid data passed over "connection.join" method.'; - connection.onstatechange({ - userid: 'browser', - extra: {}, - name: 'Unexpected data detected.', - reason: error - }); - - throw error; - } - - if (!connection.dontOverrideSession) { - connection.session = session.session; - } - - var extra = connection.extra || session.extra || {}; - - // todo: need to verify that if-block statement works as expected. - // expectations: if it is oneway streaming; or if it is data-only connection - // then, it shouldn't capture user-media on participant's side. - if (session.oneway || isData(session)) { - rtcMultiSession.joinSession(session, extra); - } else { - captureUserMedia(function() { - rtcMultiSession.joinSession(session, extra); - }); - } - } - - var isFirstSession = true; - - // www.RTCMultiConnection.org/docs/captureUserMedia/ - - function captureUserMedia(callback, _session, dontCheckChromExtension) { - // capture user's media resources - var session = _session || connection.session; - - if (isEmpty(session)) { - if (callback) callback(); - return; - } - - // you can force to skip media capturing! - if (connection.dontCaptureUserMedia) { - return callback(); - } - - // if it is data-only connection - // if it is one-way connection and current user is participant - if (isData(session) || (!connection.isInitiator && session.oneway)) { - // www.RTCMultiConnection.org/docs/attachStreams/ - connection.attachStreams = []; - return callback(); - } - - var constraints = { - audio: !!session.audio ? { - mandatory: {}, - optional: [{ - chromeRenderToAssociatedSink: true - }] - } : false, - video: !!session.video - }; - - // if custom audio device is selected - if (connection._mediaSources.audio) { - constraints.audio.optional.push({ - sourceId: connection._mediaSources.audio - }); - } - - // if custom video device is selected - if (connection._mediaSources.video) { - constraints.video = { - optional: [{ - sourceId: connection._mediaSources.video - }] - }; - } - - // for connection.session = {}; - if (!session.screen && !constraints.audio && !constraints.video) { - return callback(); - } - - var screen_constraints = { - audio: false, - video: { - mandatory: { - chromeMediaSource: DetectRTC.screen.chromeMediaSource, - maxWidth: screen.width > 1920 ? screen.width : 1920, - maxHeight: screen.height > 1080 ? screen.height : 1080 - }, - optional: [] - } - }; - - if (isFirefox && session.screen) { - if (location.protocol !== 'https:') { - return error(SCREEN_COMMON_FAILURE); - } - warn(Firefox_Screen_Capturing_Warning); - - screen_constraints.video = merge(screen_constraints.video.mandatory, { - mozMediaSource: 'window', // mozMediaSource is redundant here - mediaSource: 'window' // 'screen' || 'window' - }); - - // Firefox is supporting audio+screen from single getUserMedia request - // audio+video+screen will become audio+screen for Firefox - // because Firefox isn't supporting multi-streams feature version < 38 - // version >38 supports multi-stream sharing. - // we can use: firefoxVersion < 38 - // however capturing audio and screen using single getUserMedia is a better option - if (constraints.audio /* && !session.video */ ) { - screen_constraints.audio = true; - constraints = {}; - } - - delete screen_constraints.video.chromeMediaSource; - } - - // if screen is prompted - if (session.screen) { - if (isChrome && DetectRTC.screen.extensionid != ReservedExtensionID) { - useCustomChromeExtensionForScreenCapturing = true; - } - - if (isChrome && !useCustomChromeExtensionForScreenCapturing && !dontCheckChromExtension && !DetectRTC.screen.sourceId) { - listenEventHandler('message', onIFrameCallback); - - function onIFrameCallback(event) { - if (event.data && event.data.chromeMediaSourceId) { - // this event listener is no more needed - window.removeEventListener('message', onIFrameCallback); - - var sourceId = event.data.chromeMediaSourceId; - - DetectRTC.screen.sourceId = sourceId; - DetectRTC.screen.chromeMediaSource = 'desktop'; - - if (sourceId == 'PermissionDeniedError') { - var mediaStreamError = { - message: location.protocol == 'https:' ? 'User denied to share content of his screen.' : SCREEN_COMMON_FAILURE, - name: 'PermissionDeniedError', - constraintName: screen_constraints, - session: session - }; - currentUserMediaRequest.mutex = false; - DetectRTC.screen.sourceId = null; - return connection.onMediaError(mediaStreamError); - } - - captureUserMedia(callback, _session); - } - - if (event.data && event.data.chromeExtensionStatus) { - warn('Screen capturing extension status is:', event.data.chromeExtensionStatus); - DetectRTC.screen.chromeMediaSource = 'screen'; - captureUserMedia(callback, _session, true); - } - } - - if (!screenFrame) { - loadScreenFrame(); - } - - screenFrame.postMessage(); - return; - } - - // check if screen capturing extension is installed. - if (isChrome && useCustomChromeExtensionForScreenCapturing && !dontCheckChromExtension && DetectRTC.screen.chromeMediaSource == 'screen' && DetectRTC.screen.extensionid) { - if (DetectRTC.screen.extensionid == ReservedExtensionID && document.domain.indexOf('webrtc-experiment.com') == -1) { - return captureUserMedia(callback, _session, true); - } - - log('checking if chrome extension is installed.'); - DetectRTC.screen.getChromeExtensionStatus(function(status) { - if (status == 'installed-enabled') { - DetectRTC.screen.chromeMediaSource = 'desktop'; - } - - captureUserMedia(callback, _session, true); - log('chrome extension is installed?', DetectRTC.screen.chromeMediaSource == 'desktop'); - }); - return; - } - - if (isChrome && useCustomChromeExtensionForScreenCapturing && DetectRTC.screen.chromeMediaSource == 'desktop' && !DetectRTC.screen.sourceId) { - DetectRTC.screen.getSourceId(function(sourceId) { - if (sourceId == 'PermissionDeniedError') { - var mediaStreamError = { - message: 'User denied to share content of his screen.', - name: 'PermissionDeniedError', - constraintName: screen_constraints, - session: session - }; - currentUserMediaRequest.mutex = false; - DetectRTC.screen.chromeMediaSource = 'desktop'; - return connection.onMediaError(mediaStreamError); - } - - if (sourceId == 'No-Response') { - error('Chrome extension seems not available. Make sure that manifest.json#L16 has valid content-script matches pointing to your URL.'); - DetectRTC.screen.chromeMediaSource = 'screen'; - return captureUserMedia(callback, _session, true); - } - - captureUserMedia(callback, _session, true); - }); - return; - } - - if (isChrome && DetectRTC.screen.chromeMediaSource == 'desktop') { - screen_constraints.video.mandatory.chromeMediaSourceId = DetectRTC.screen.sourceId; - } - - var _isFirstSession = isFirstSession; - - _captureUserMedia(screen_constraints, constraints.audio || constraints.video ? function() { - - if (_isFirstSession) isFirstSession = true; - - _captureUserMedia(constraints, callback); - } : callback); - } else _captureUserMedia(constraints, callback, session.audio && !session.video); - - function _captureUserMedia(forcedConstraints, forcedCallback, isRemoveVideoTracks, dontPreventSSLAutoAllowed) { - connection.onstatechange({ - userid: 'browser', - extra: {}, - name: 'fetching-usermedia', - reason: 'About to capture user-media with constraints: ' + toStr(forcedConstraints) - }); - - - if (connection.preventSSLAutoAllowed && !dontPreventSSLAutoAllowed && isChrome) { - // if navigator.customGetUserMediaBar.js is missing - if (!navigator.customGetUserMediaBar) { - loadScript(connection.resources.customGetUserMediaBar, function() { - _captureUserMedia(forcedConstraints, forcedCallback, isRemoveVideoTracks, dontPreventSSLAutoAllowed); - }); - return; - } - - navigator.customGetUserMediaBar(forcedConstraints, function() { - _captureUserMedia(forcedConstraints, forcedCallback, isRemoveVideoTracks, true); - }, function() { - connection.onMediaError({ - name: 'PermissionDeniedError', - message: 'User denied permission.', - constraintName: forcedConstraints, - session: session - }); - }); - return; - } - - var mediaConfig = { - onsuccess: function(stream, returnBack, idInstance, streamid) { - onStreamSuccessCallback(stream, returnBack, idInstance, streamid, forcedConstraints, forcedCallback, isRemoveVideoTracks, screen_constraints, constraints, session); - }, - onerror: function(e, constraintUsed) { - // http://goo.gl/hrwF1a - if (isFirefox) { - if (e == 'PERMISSION_DENIED') { - e = { - message: '', - name: 'PermissionDeniedError', - constraintName: constraintUsed, - session: session - }; - } - } - - if (isFirefox && constraintUsed.video && constraintUsed.video.mozMediaSource) { - mediaStreamError = { - message: Firefox_Screen_Capturing_Warning, - name: e.name || 'PermissionDeniedError', - constraintName: constraintUsed, - session: session - }; - - connection.onMediaError(mediaStreamError); - return; - } - - if (isString(e)) { - return connection.onMediaError({ - message: 'Unknown Error', - name: e, - constraintName: constraintUsed, - session: session - }); - } - - // it seems that chrome 35+ throws "DevicesNotFoundError" exception - // when any of the requested media is either denied or absent - if (e.name && (e.name == 'PermissionDeniedError' || e.name == 'DevicesNotFoundError')) { - var mediaStreamError = 'Either: '; - mediaStreamError += '\n Media resolutions are not permitted.'; - mediaStreamError += '\n Another application is using same media device.'; - mediaStreamError += '\n Media device is not attached or drivers not installed.'; - mediaStreamError += '\n You denied access once and it is still denied.'; - - if (e.message && e.message.length) { - mediaStreamError += '\n ' + e.message; - } - - mediaStreamError = { - message: mediaStreamError, - name: e.name, - constraintName: constraintUsed, - session: session - }; - - connection.onMediaError(mediaStreamError); - - if (isChrome && (session.audio || session.video)) { - // todo: this snippet fails if user has two or more - // microphone/webcam attached. - DetectRTC.load(function() { - // it is possible to check presence of the microphone before using it! - if (session.audio && !DetectRTC.hasMicrophone) { - warn('It seems that you have no microphone attached to your device/system.'); - session.audio = session.audio = false; - - if (!session.video) { - alert('It seems that you are capturing microphone and there is no device available or access is denied. Reloading...'); - location.reload(); - } - } - - // it is possible to check presence of the webcam before using it! - if (session.video && !DetectRTC.hasWebcam) { - warn('It seems that you have no webcam attached to your device/system.'); - session.video = session.video = false; - - if (!session.audio) { - alert('It seems that you are capturing webcam and there is no device available or access is denied. Reloading...'); - location.reload(); - } - } - - if (!DetectRTC.hasMicrophone && !DetectRTC.hasWebcam) { - alert('It seems that either both microphone/webcam are not available or access is denied. Reloading...'); - location.reload(); - } else if (!connection.getUserMediaPromptedOnce) { - // make maximum two tries! - connection.getUserMediaPromptedOnce = true; - captureUserMedia(callback, session); - } - }); - } - } - - if (e.name && e.name == 'ConstraintNotSatisfiedError') { - var mediaStreamError = 'Either: '; - mediaStreamError += '\n You are prompting unknown media resolutions.'; - mediaStreamError += '\n You are using invalid media constraints.'; - - if (e.message && e.message.length) { - mediaStreamError += '\n ' + e.message; - } - - mediaStreamError = { - message: mediaStreamError, - name: e.name, - constraintName: constraintUsed, - session: session - }; - - connection.onMediaError(mediaStreamError); - } - - if (session.screen) { - if (isFirefox) { - error(Firefox_Screen_Capturing_Warning); - } else if (location.protocol !== 'https:') { - if (!isNodeWebkit && (location.protocol == 'file:' || location.protocol == 'http:')) { - error('You cannot use HTTP or file protocol for screen capturing. You must either use HTTPs or chrome extension page or Node-Webkit page.'); - } - } else { - error('Unable to detect actual issue. Maybe "deprecated" screen capturing flag was not set using command line or maybe you clicked "No" button or maybe chrome extension returned invalid "sourceId". Please install chrome-extension: http://bit.ly/webrtc-screen-extension'); - } - } - - currentUserMediaRequest.mutex = false; - - // to make sure same stream can be captured again! - var idInstance = JSON.stringify(constraintUsed); - if (currentUserMediaRequest.streams[idInstance]) { - delete currentUserMediaRequest.streams[idInstance]; - } - }, - mediaConstraints: connection.mediaConstraints || {} - }; - - mediaConfig.constraints = forcedConstraints || constraints; - mediaConfig.connection = connection; - getUserMedia(mediaConfig); - } - } - - function onStreamSuccessCallback(stream, returnBack, idInstance, streamid, forcedConstraints, forcedCallback, isRemoveVideoTracks, screen_constraints, constraints, session) { - if (!streamid) streamid = getRandomString(); - - connection.onstatechange({ - userid: 'browser', - extra: {}, - name: 'usermedia-fetched', - reason: 'Captured user media using constraints: ' + toStr(forcedConstraints) - }); - - if (isRemoveVideoTracks) { - stream = convertToAudioStream(stream); - } - - connection.localStreamids.push(streamid); - stream.onended = function() { - if (streamedObject.mediaElement && !streamedObject.mediaElement.parentNode && document.getElementById(stream.streamid)) { - streamedObject.mediaElement = document.getElementById(stream.streamid); - } - - // when a stream is stopped; it must be removed from "attachStreams" array - connection.attachStreams.forEach(function(_stream, index) { - if (_stream == stream) { - delete connection.attachStreams[index]; - connection.attachStreams = swap(connection.attachStreams); - } - }); - - onStreamEndedHandler(streamedObject, connection); - - if (connection.streams[streamid]) { - connection.removeStream(streamid); - } - - // if user clicks "stop" button to close screen sharing - var _stream = connection.streams[streamid]; - if (_stream && _stream.sockets.length) { - _stream.sockets.forEach(function(socket) { - socket.send({ - streamid: _stream.streamid, - stopped: true - }); - }); - } - - currentUserMediaRequest.mutex = false; - // to make sure same stream can be captured again! - if (currentUserMediaRequest.streams[idInstance]) { - delete currentUserMediaRequest.streams[idInstance]; - } - - // to allow re-capturing of the screen - DetectRTC.screen.sourceId = null; - }; - - if (!isIE) { - stream.streamid = streamid; - stream.isScreen = forcedConstraints == screen_constraints; - stream.isVideo = forcedConstraints == constraints && !!constraints.video; - stream.isAudio = forcedConstraints == constraints && !!constraints.audio && !constraints.video; - - // if muted stream is negotiated - stream.preMuted = { - audio: stream.getAudioTracks().length && !stream.getAudioTracks()[0].enabled, - video: stream.getVideoTracks().length && !stream.getVideoTracks()[0].enabled - }; - } - - var mediaElement = createMediaElement(stream, session); - mediaElement.muted = true; - - var streamedObject = { - stream: stream, - streamid: streamid, - mediaElement: mediaElement, - blobURL: mediaElement.mozSrcObject ? URL.createObjectURL(stream) : mediaElement.src, - type: 'local', - userid: connection.userid, - extra: connection.extra, - session: session, - isVideo: !!stream.isVideo, - isAudio: !!stream.isAudio, - isScreen: !!stream.isScreen, - isInitiator: !!connection.isInitiator, - rtcMultiConnection: connection - }; - - if (isFirstSession) { - connection.attachStreams.push(stream); - } - isFirstSession = false; - - connection.streams[streamid] = connection._getStream(streamedObject); - - if (!returnBack) { - connection.onstream(streamedObject); - } - - if (connection.setDefaultEventsForMediaElement) { - connection.setDefaultEventsForMediaElement(mediaElement, streamid); - } - - if (forcedCallback) forcedCallback(stream, streamedObject); - - if (connection.onspeaking) { - initHark({ - stream: stream, - streamedObject: streamedObject, - connection: connection - }); - } - } - - // www.RTCMultiConnection.org/docs/captureUserMedia/ - connection.captureUserMedia = captureUserMedia; - - // www.RTCMultiConnection.org/docs/leave/ - connection.leave = function(userid) { - if (!rtcMultiSession) return; - - isFirstSession = true; - - if (userid) { - connection.eject(userid); - return; - } - - rtcMultiSession.leave(); - }; - - // www.RTCMultiConnection.org/docs/eject/ - connection.eject = function(userid) { - if (!connection.isInitiator) throw 'Only session-initiator can eject a user.'; - if (!connection.peers[userid]) throw 'You ejected invalid user.'; - connection.peers[userid].sendCustomMessage({ - ejected: true - }); - }; - - // www.RTCMultiConnection.org/docs/close/ - connection.close = function() { - // close entire session - connection.autoCloseEntireSession = true; - connection.leave(); - }; - - // www.RTCMultiConnection.org/docs/renegotiate/ - connection.renegotiate = function(stream, session) { - if (connection.numberOfConnectedUsers <= 0) { - // no connections - setTimeout(function() { - // try again - connection.renegotiate(stream, session); - }, 1000); - return; - } - - rtcMultiSession.addStream({ - renegotiate: session || merge({ - oneway: true - }, connection.session), - stream: stream - }); - }; - - connection.attachExternalStream = function(stream, isScreen) { - var constraints = {}; - if (stream.getAudioTracks && stream.getAudioTracks().length) { - constraints.audio = true; - } - if (stream.getVideoTracks && stream.getVideoTracks().length) { - constraints.video = true; - } - - var screen_constraints = { - video: { - chromeMediaSource: 'fake' - } - }; - var forcedConstraints = isScreen ? screen_constraints : constraints; - onStreamSuccessCallback(stream, false, '', null, forcedConstraints, false, false, screen_constraints, constraints, constraints); - }; - - // www.RTCMultiConnection.org/docs/addStream/ - connection.addStream = function(session, socket) { - // www.RTCMultiConnection.org/docs/renegotiation/ - - if (connection.numberOfConnectedUsers <= 0) { - // no connections - setTimeout(function() { - // try again - connection.addStream(session, socket); - }, 1000); - return; - } - - // renegotiate new media stream - if (session) { - var isOneWayStreamFromParticipant; - if (!connection.isInitiator && session.oneway) { - session.oneway = false; - isOneWayStreamFromParticipant = true; - } - - captureUserMedia(function(stream) { - if (isOneWayStreamFromParticipant) { - session.oneway = true; - } - addStream(stream); - }, session); - } else addStream(); - - function addStream(stream) { - rtcMultiSession.addStream({ - stream: stream, - renegotiate: session || connection.session, - socket: socket - }); - } - }; - - // www.RTCMultiConnection.org/docs/removeStream/ - connection.removeStream = function(streamid, dontRenegotiate) { - if (connection.numberOfConnectedUsers <= 0) { - // no connections - setTimeout(function() { - // try again - connection.removeStream(streamid, dontRenegotiate); - }, 1000); - return; - } - - if (!streamid) streamid = 'all'; - if (!isString(streamid) || streamid.search(/all|audio|video|screen/gi) != -1) { - function _detachStream(_stream, config) { - if (config.local && _stream.type != 'local') return; - if (config.remote && _stream.type != 'remote') return; - - // connection.removeStream({screen:true}); - if (config.screen && !!_stream.isScreen) { - connection.detachStreams.push(_stream.streamid); - } - - // connection.removeStream({audio:true}); - if (config.audio && !!_stream.isAudio) { - connection.detachStreams.push(_stream.streamid); - } - - // connection.removeStream({video:true}); - if (config.video && !!_stream.isVideo) { - connection.detachStreams.push(_stream.streamid); - } - - // connection.removeStream({}); - if (!config.audio && !config.video && !config.screen) { - connection.detachStreams.push(_stream.streamid); - } - - if (connection.detachStreams.indexOf(_stream.streamid) != -1) { - log('removing stream', _stream.streamid); - onStreamEndedHandler(_stream, connection); - - if (config.stop) { - connection.stopMediaStream(_stream.stream); - } - } - } - - for (var stream in connection.streams) { - if (connection._skip.indexOf(stream) == -1) { - _stream = connection.streams[stream]; - - if (streamid == 'all') _detachStream(_stream, { - audio: true, - video: true, - screen: true - }); - - else if (isString(streamid)) { - // connection.removeStream('screen'); - var config = {}; - config[streamid] = true; - _detachStream(_stream, config); - } else _detachStream(_stream, streamid); - } - } - - if (!dontRenegotiate && connection.detachStreams.length) { - connection.renegotiate(); - } - - return; - } - - var stream = connection.streams[streamid]; - - // detach pre-attached streams - if (!stream) return warn('No such stream exists. Stream-id:', streamid); - - // www.RTCMultiConnection.org/docs/detachStreams/ - connection.detachStreams.push(stream.streamid); - - log('removing stream', stream.streamid); - onStreamEndedHandler(stream, connection); - - // todo: how to allow "stop" function? - // connection.stopMediaStream(stream.stream) - - if (!dontRenegotiate) { - connection.renegotiate(); - } - }; - - connection.switchStream = function(session) { - if (connection.numberOfConnectedUsers <= 0) { - // no connections - setTimeout(function() { - // try again - connection.switchStream(session); - }, 1000); - return; - } - - connection.removeStream('all', true); - connection.addStream(session); - }; - - // www.RTCMultiConnection.org/docs/sendCustomMessage/ - connection.sendCustomMessage = function(message) { - if (!rtcMultiSession || !rtcMultiSession.defaultSocket) { - return setTimeout(function() { - connection.sendCustomMessage(message); - }, 1000); - } - - rtcMultiSession.defaultSocket.send({ - customMessage: true, - message: message - }); - }; - - // set RTCMultiConnection defaults on constructor invocation - setDefaults(connection); - }; - - function RTCMultiSession(connection, callbackForSignalingReady) { - var socketObjects = {}; - var sockets = []; - var rtcMultiSession = this; - var participants = {}; - - if (!rtcMultiSession.fileBufferReader && connection.session.data && connection.enableFileSharing) { - initFileBufferReader(connection, function(fbr) { - rtcMultiSession.fileBufferReader = fbr; - }); - } - - var textReceiver = new TextReceiver(connection); - - function onDataChannelMessage(e) { - if (e.data.checkingPresence && connection.channels[e.userid]) { - connection.channels[e.userid].send({ - presenceDetected: true - }); - return; - } - - if (e.data.presenceDetected && connection.peers[e.userid]) { - connection.peers[e.userid].connected = true; - return; - } - - if (e.data.type === 'text') { - textReceiver.receive(e.data, e.userid, e.extra); - } else { - if (connection.autoTranslateText) { - e.original = e.data; - connection.Translator.TranslateText(e.data, function(translatedText) { - e.data = translatedText; - connection.onmessage(e); - }); - } else connection.onmessage(e); - } - } - - function onNewSession(session) { - if (connection.skipOnNewSession) return; - - if (!session.session) session.session = {}; - if (!session.extra) session.extra = {}; - - // todo: make sure this works as expected. - // i.e. "onNewSession" should be fired only for - // sessionid that is passed over "connect" method. - if (connection.sessionid && session.sessionid != connection.sessionid) return; - - if (connection.onNewSession) { - session.join = function(forceSession) { - if (!forceSession) return connection.join(session); - - for (var f in forceSession) { - session.session[f] = forceSession[f]; - } - - // keeping previous state - var isDontCaptureUserMedia = connection.dontCaptureUserMedia; - - connection.dontCaptureUserMedia = false; - connection.captureUserMedia(function() { - connection.dontCaptureUserMedia = true; - connection.join(session); - - // returning back previous state - connection.dontCaptureUserMedia = isDontCaptureUserMedia; - }, forceSession); - }; - if (!session.extra) session.extra = {}; - - return connection.onNewSession(session); - } - - connection.join(session); - } - - function updateSocketForLocalStreams(socket) { - for (var i = 0; i < connection.localStreamids.length; i++) { - var streamid = connection.localStreamids[i]; - if (connection.streams[streamid]) { - // using "sockets" array to keep references of all sockets using - // this media stream; so we can fire "onStreamEndedHandler" among all users. - connection.streams[streamid].sockets.push(socket); - } - } - } - - function newPrivateSocket(_config) { - var socketConfig = { - channel: _config.channel, - onmessage: socketResponse, - onopen: function(_socket) { - if (_socket) socket = _socket; - - if (isofferer && !peer) { - peerConfig.session = connection.session; - if (!peer) peer = new PeerConnection(); - peer.create('offer', peerConfig); - } - - _config.socketIndex = socket.index = sockets.length; - socketObjects[socketConfig.channel] = socket; - sockets[_config.socketIndex] = socket; - - updateSocketForLocalStreams(socket); - - if (!socket.__push) { - socket.__push = socket.send; - socket.send = function(message) { - message.userid = message.userid || connection.userid; - message.extra = message.extra || connection.extra || {}; - - socket.__push(message); - }; - } - } - }; - - socketConfig.callback = function(_socket) { - socket = _socket; - socketConfig.onopen(); - }; - - var socket = connection.openSignalingChannel(socketConfig); - if (socket) socketConfig.onopen(socket); - - var isofferer = _config.isofferer, - peer; - - var peerConfig = { - onopen: onChannelOpened, - onicecandidate: function(candidate) { - if (!connection.candidates) throw 'ICE candidates are mandatory.'; - if (!connection.iceProtocols) throw 'At least one must be true; UDP or TCP.'; - - var iceCandidates = connection.candidates; - - var stun = iceCandidates.stun; - var turn = iceCandidates.turn; - - if (!isNull(iceCandidates.reflexive)) stun = iceCandidates.reflexive; - if (!isNull(iceCandidates.relay)) turn = iceCandidates.relay; - - if (!iceCandidates.host && !!candidate.candidate.match(/a=candidate.*typ host/g)) return; - if (!turn && !!candidate.candidate.match(/a=candidate.*typ relay/g)) return; - if (!stun && !!candidate.candidate.match(/a=candidate.*typ srflx/g)) return; - - var protocol = connection.iceProtocols; - - if (!protocol.udp && !!candidate.candidate.match(/a=candidate.* udp/g)) return; - if (!protocol.tcp && !!candidate.candidate.match(/a=candidate.* tcp/g)) return; - - if (!window.selfNPObject) window.selfNPObject = candidate; - - socket && socket.send({ - candidate: JSON.stringify({ - candidate: candidate.candidate, - sdpMid: candidate.sdpMid, - sdpMLineIndex: candidate.sdpMLineIndex - }) - }); - }, - onmessage: function(data) { - if (!data) return; - - var abToStr = ab2str(data); - if (abToStr.indexOf('"userid":') != -1) { - abToStr = JSON.parse(abToStr); - onDataChannelMessage(abToStr); - } else if (data instanceof ArrayBuffer || data instanceof DataView) { - if (!connection.enableFileSharing) { - throw 'It seems that receiving data is either "Blob" or "File" but file sharing is disabled.'; - } - - if (!rtcMultiSession.fileBufferReader) { - var that = this; - initFileBufferReader(connection, function(fbr) { - rtcMultiSession.fileBufferReader = fbr; - that.onmessage(data); - }); - return; - } - - var fileBufferReader = rtcMultiSession.fileBufferReader; - - fileBufferReader.convertToObject(data, function(chunk) { - if (chunk.maxChunks || chunk.readyForNextChunk) { - // if target peer requested next chunk - if (chunk.readyForNextChunk) { - fileBufferReader.getNextChunk(chunk.uuid, function(nextChunk, isLastChunk, extra) { - rtcMultiSession.send(nextChunk); - }); - return; - } - - // if chunk is received - fileBufferReader.addChunk(chunk, function(promptNextChunk) { - // request next chunk - rtcMultiSession.send(promptNextChunk); - }); - return; - } - - connection.onmessage({ - data: chunk, - userid: _config.userid, - extra: _config.extra - }); - }); - return; - } - }, - onaddstream: function(stream, session) { - session = session || _config.renegotiate || connection.session; - - // if it is data-only connection; then return. - if (isData(session)) return; - - if (session.screen && (session.audio || session.video)) { - if (!_config.gotAudioOrVideo) { - // audio/video are fired earlier than screen - _config.gotAudioOrVideo = true; - session.screen = false; - } else { - // screen stream is always fired later - session.audio = false; - session.video = false; - } - } - - var preMuted = {}; - - if (_config.streaminfo) { - var streaminfo = _config.streaminfo.split('----'); - var strInfo = JSON.parse(streaminfo[streaminfo.length - 1]); - - if (!isIE) { - stream.streamid = strInfo.streamid; - stream.isScreen = !!strInfo.isScreen; - stream.isVideo = !!strInfo.isVideo; - stream.isAudio = !!strInfo.isAudio; - preMuted = strInfo.preMuted; - } - - streaminfo.pop(); - _config.streaminfo = streaminfo.join('----'); - } - - var mediaElement = createMediaElement(stream, merge({ - remote: true - }, session)); - - if (connection.setDefaultEventsForMediaElement) { - connection.setDefaultEventsForMediaElement(mediaElement, stream.streamid); - } - - if (!isPluginRTC && !stream.getVideoTracks().length) { - function eventListener() { - setTimeout(function() { - mediaElement.muted = false; - afterRemoteStreamStartedFlowing({ - mediaElement: mediaElement, - session: session, - stream: stream, - preMuted: preMuted - }); - }, 3000); - - mediaElement.removeEventListener('play', eventListener); - } - return mediaElement.addEventListener('play', eventListener, false); - } - - waitUntilRemoteStreamStartsFlowing({ - mediaElement: mediaElement, - session: session, - stream: stream, - preMuted: preMuted - }); - }, - - onremovestream: function(stream) { - if (stream && stream.streamid) { - stream = connection.streams[stream.streamid]; - if (stream) { - log('on:stream:ended via on:remove:stream', stream); - onStreamEndedHandler(stream, connection); - } - } else log('on:remove:stream', stream); - }, - - onclose: function(e) { - e.extra = _config.extra; - e.userid = _config.userid; - connection.onclose(e); - - // suggested in #71 by "efaj" - if (connection.channels[e.userid]) { - delete connection.channels[e.userid]; - } - }, - onerror: function(e) { - e.extra = _config.extra; - e.userid = _config.userid; - connection.onerror(e); - }, - - oniceconnectionstatechange: function(event) { - log('oniceconnectionstatechange', toStr(event)); - - if (peer.connection && peer.connection.iceConnectionState == 'connected' && peer.connection.iceGatheringState == 'complete' && peer.connection.signalingState == 'stable' && connection.numberOfConnectedUsers == 1) { - connection.onconnected({ - userid: _config.userid, - extra: _config.extra, - peer: connection.peers[_config.userid], - targetuser: _config.userinfo - }); - } - - if (!connection.isInitiator && peer.connection && peer.connection.iceConnectionState == 'connected' && peer.connection.iceGatheringState == 'complete' && peer.connection.signalingState == 'stable' && connection.numberOfConnectedUsers == 1) { - connection.onstatechange({ - userid: _config.userid, - extra: _config.extra, - name: 'connected-with-initiator', - reason: 'ICE connection state seems connected; gathering state is completed; and signaling state is stable.' - }); - } - - if (connection.peers[_config.userid] && connection.peers[_config.userid].oniceconnectionstatechange) { - connection.peers[_config.userid].oniceconnectionstatechange(event); - } - - // if ICE connectivity check is failed; renegotiate or redial - if (connection.peers[_config.userid] && connection.peers[_config.userid].peer.connection.iceConnectionState == 'failed') { - connection.onfailed({ - userid: _config.userid, - extra: _config.extra, - peer: connection.peers[_config.userid], - targetuser: _config.userinfo - }); - } - - if (connection.peers[_config.userid] && connection.peers[_config.userid].peer.connection.iceConnectionState == 'disconnected') { - !peer.connection.renegotiate && connection.ondisconnected({ - userid: _config.userid, - extra: _config.extra, - peer: connection.peers[_config.userid], - targetuser: _config.userinfo - }); - peer.connection.renegotiate = false; - } - - if (!connection.autoReDialOnFailure) return; - - if (connection.peers[_config.userid]) { - if (connection.peers[_config.userid].peer.connection.iceConnectionState != 'disconnected') { - _config.redialing = false; - } - - if (connection.peers[_config.userid].peer.connection.iceConnectionState == 'disconnected' && !_config.redialing) { - _config.redialing = true; - warn('Peer connection is closed.', toStr(connection.peers[_config.userid].peer.connection), 'ReDialing..'); - connection.peers[_config.userid].socket.send({ - redial: true - }); - - // to make sure all old "remote" streams are also removed! - connection.streams.remove({ - remote: true, - userid: _config.userid - }); - } - } - }, - - onsignalingstatechange: function(event) { - log('onsignalingstatechange', toStr(event)); - }, - - attachStreams: connection.dontAttachStream ? [] : connection.attachStreams, - iceServers: connection.iceServers, - rtcConfiguration: connection.rtcConfiguration, - bandwidth: connection.bandwidth, - sdpConstraints: connection.sdpConstraints, - optionalArgument: connection.optionalArgument, - disableDtlsSrtp: connection.disableDtlsSrtp, - dataChannelDict: connection.dataChannelDict, - preferSCTP: connection.preferSCTP, - - onSessionDescription: function(sessionDescription, streaminfo) { - sendsdp({ - sdp: sessionDescription, - socket: socket, - streaminfo: streaminfo - }); - }, - trickleIce: connection.trickleIce, - processSdp: connection.processSdp, - sendStreamId: function(stream) { - socket && socket.send({ - streamid: stream.streamid, - isScreen: !!stream.isScreen, - isAudio: !!stream.isAudio, - isVideo: !!stream.isVideo - }); - }, - rtcMultiConnection: connection - }; - - function waitUntilRemoteStreamStartsFlowing(args) { - // chrome for android may have some features missing - if (isMobileDevice || isPluginRTC || (isNull(connection.waitUntilRemoteStreamStartsFlowing) || !connection.waitUntilRemoteStreamStartsFlowing)) { - return afterRemoteStreamStartedFlowing(args); - } - - if (!args.numberOfTimes) args.numberOfTimes = 0; - args.numberOfTimes++; - - if (!(args.mediaElement.readyState <= HTMLMediaElement.HAVE_CURRENT_DATA || args.mediaElement.paused || args.mediaElement.currentTime <= 0)) { - return afterRemoteStreamStartedFlowing(args); - } - - if (args.numberOfTimes >= 60) { // wait 60 seconds while video is delivered! - return socket.send({ - failedToReceiveRemoteVideo: true, - streamid: args.stream.streamid - }); - } - - setTimeout(function() { - log('Waiting for incoming remote stream to be started flowing: ' + args.numberOfTimes + ' seconds.'); - waitUntilRemoteStreamStartsFlowing(args); - }, 900); - } - - function initFakeChannel() { - if (!connection.fakeDataChannels || connection.channels[_config.userid]) return; - - // for non-data connections; allow fake data sender! - if (!connection.session.data) { - var fakeChannel = { - send: function(data) { - socket.send({ - fakeData: data - }); - }, - readyState: 'open' - }; - // connection.channels['user-id'].send(data); - connection.channels[_config.userid] = { - channel: fakeChannel, - send: function(data) { - this.channel.send(data); - } - }; - peerConfig.onopen(fakeChannel); - } - } - - function afterRemoteStreamStartedFlowing(args) { - var mediaElement = args.mediaElement; - var session = args.session; - var stream = args.stream; - - stream.onended = function() { - if (streamedObject.mediaElement && !streamedObject.mediaElement.parentNode && document.getElementById(stream.streamid)) { - streamedObject.mediaElement = document.getElementById(stream.streamid); - } - - onStreamEndedHandler(streamedObject, connection); - }; - - var streamedObject = { - mediaElement: mediaElement, - - stream: stream, - streamid: stream.streamid, - session: session || connection.session, - - blobURL: isPluginRTC ? '' : mediaElement.mozSrcObject ? URL.createObjectURL(stream) : mediaElement.src, - type: 'remote', - - extra: _config.extra, - userid: _config.userid, - - isVideo: isPluginRTC ? !!session.video : !!stream.isVideo, - isAudio: isPluginRTC ? !!session.audio && !session.video : !!stream.isAudio, - isScreen: !!stream.isScreen, - isInitiator: !!_config.isInitiator, - - rtcMultiConnection: connection, - socket: socket - }; - - // connection.streams['stream-id'].mute({audio:true}) - connection.streams[stream.streamid] = connection._getStream(streamedObject); - connection.onstream(streamedObject); - - if (!isEmpty(args.preMuted) && (args.preMuted.audio || args.preMuted.video)) { - var fakeObject = merge({}, streamedObject); - fakeObject.session = merge(fakeObject.session, args.preMuted); - - fakeObject.isAudio = !!fakeObject.session.audio && !fakeObject.session.video; - fakeObject.isVideo = !!fakeObject.session.video; - fakeObject.isScreen = false; - - connection.onmute(fakeObject); - } - - log('on:add:stream', streamedObject); - - onSessionOpened(); - - if (connection.onspeaking) { - initHark({ - stream: stream, - streamedObject: streamedObject, - connection: connection - }); - } - } - - function onChannelOpened(channel) { - _config.channel = channel; - - // connection.channels['user-id'].send(data); - connection.channels[_config.userid] = { - channel: _config.channel, - send: function(data) { - connection.send(data, this.channel); - } - }; - - connection.onopen({ - extra: _config.extra, - userid: _config.userid, - channel: channel - }); - - // fetch files from file-queue - for (var q in connection.fileQueue) { - connection.send(connection.fileQueue[q], channel); - } - - if (isData(connection.session)) onSessionOpened(); - - if (connection.partOfScreen && connection.partOfScreen.sharing) { - connection.peers[_config.userid].sharePartOfScreen(connection.partOfScreen); - } - } - - function updateSocket() { - // todo: need to check following {if-block} MUST not affect "redial" process - if (socket.userid == _config.userid) - return; - - socket.userid = _config.userid; - sockets[_config.socketIndex] = socket; - - connection.numberOfConnectedUsers++; - // connection.peers['user-id'].addStream({audio:true}) - connection.peers[_config.userid] = { - socket: socket, - peer: peer, - userid: _config.userid, - extra: _config.extra, - userinfo: _config.userinfo, - addStream: function(session00) { - // connection.peers['user-id'].addStream({audio: true, video: true); - - connection.addStream(session00, this.socket); - }, - removeStream: function(streamid) { - if (!connection.streams[streamid]) - return warn('No such stream exists. Stream-id:', streamid); - - this.peer.connection.removeStream(connection.streams[streamid].stream); - this.renegotiate(); - }, - renegotiate: function(stream, session) { - // connection.peers['user-id'].renegotiate(); - - connection.renegotiate(stream, session); - }, - changeBandwidth: function(bandwidth) { - // connection.peers['user-id'].changeBandwidth(); - - if (!bandwidth) throw 'You MUST pass bandwidth object.'; - if (isString(bandwidth)) throw 'Pass object for bandwidth instead of string; e.g. {audio:10, video:20}'; - - // set bandwidth for self - this.peer.bandwidth = bandwidth; - - // ask remote user to synchronize bandwidth - this.socket.send({ - changeBandwidth: true, - bandwidth: bandwidth - }); - }, - sendCustomMessage: function(message) { - // connection.peers['user-id'].sendCustomMessage(); - - this.socket.send({ - customMessage: true, - message: message - }); - }, - onCustomMessage: function(message) { - log('Received "private" message from', this.userid, - isString(message) ? message : toStr(message)); - }, - drop: function(dontSendMessage) { - // connection.peers['user-id'].drop(); - - for (var stream in connection.streams) { - if (connection._skip.indexOf(stream) == -1) { - stream = connection.streams[stream]; - - if (stream.userid == connection.userid && stream.type == 'local') { - this.peer.connection.removeStream(stream.stream); - onStreamEndedHandler(stream, connection); - } - - if (stream.type == 'remote' && stream.userid == this.userid) { - onStreamEndedHandler(stream, connection); - } - } - } - - !dontSendMessage && this.socket.send({ - drop: true - }); - }, - hold: function(holdMLine) { - // connection.peers['user-id'].hold(); - - if (peer.prevCreateType == 'answer') { - this.socket.send({ - unhold: true, - holdMLine: holdMLine || 'both', - takeAction: true - }); - return; - } - - this.socket.send({ - hold: true, - holdMLine: holdMLine || 'both' - }); - - this.peer.hold = true; - this.fireHoldUnHoldEvents({ - kind: holdMLine, - isHold: true, - userid: connection.userid, - remoteUser: this.userid - }); - }, - unhold: function(holdMLine) { - // connection.peers['user-id'].unhold(); - - if (peer.prevCreateType == 'answer') { - this.socket.send({ - unhold: true, - holdMLine: holdMLine || 'both', - takeAction: true - }); - return; - } - - this.socket.send({ - unhold: true, - holdMLine: holdMLine || 'both' - }); - - this.peer.hold = false; - this.fireHoldUnHoldEvents({ - kind: holdMLine, - isHold: false, - userid: connection.userid, - remoteUser: this.userid - }); - }, - fireHoldUnHoldEvents: function(e) { - // this method is for inner usages only! - - var isHold = e.isHold; - var kind = e.kind; - var userid = e.remoteUser || e.userid; - - // hold means inactive a specific media line! - // a media line can contain multiple synced sources (ssrc) - // i.e. a media line can reference multiple tracks! - // that's why hold will affect all relevant tracks in a specific media line! - for (var stream in connection.streams) { - if (connection._skip.indexOf(stream) == -1) { - stream = connection.streams[stream]; - - if (stream.userid == userid) { - // www.RTCMultiConnection.org/docs/onhold/ - if (isHold) - connection.onhold(merge({ - kind: kind - }, stream)); - - // www.RTCMultiConnection.org/docs/onunhold/ - if (!isHold) - connection.onunhold(merge({ - kind: kind - }, stream)); - } - } - } - }, - redial: function() { - // connection.peers['user-id'].redial(); - - // 1st of all; remove all relevant remote media streams - for (var stream in connection.streams) { - if (connection._skip.indexOf(stream) == -1) { - stream = connection.streams[stream]; - - if (stream.userid == this.userid && stream.type == 'remote') { - onStreamEndedHandler(stream, connection); - } - } - } - - log('ReDialing...'); - - socket.send({ - recreatePeer: true - }); - - peer = new PeerConnection(); - peer.create('offer', peerConfig); - }, - sharePartOfScreen: function(args) { - // www.RTCMultiConnection.org/docs/onpartofscreen/ - var that = this; - var lastScreenshot = ''; - - function partOfScreenCapturer() { - // if stopped - if (that.stopPartOfScreenSharing) { - that.stopPartOfScreenSharing = false; - - if (connection.onpartofscreenstopped) { - connection.onpartofscreenstopped(); - } - return; - } - - // if paused - if (that.pausePartOfScreenSharing) { - if (connection.onpartofscreenpaused) { - connection.onpartofscreenpaused(); - } - - return setTimeout(partOfScreenCapturer, args.interval || 200); - } - - capturePartOfScreen({ - element: args.element, - connection: connection, - callback: function(screenshot) { - if (!connection.channels[that.userid]) { - throw 'No such data channel exists.'; - } - - // don't share repeated content - if (screenshot != lastScreenshot) { - lastScreenshot = screenshot; - connection.channels[that.userid].send({ - screenshot: screenshot, - isPartOfScreen: true - }); - } - - // "once" can be used to share single screenshot - !args.once && setTimeout(partOfScreenCapturer, args.interval || 200); - } - }); - } - - partOfScreenCapturer(); - }, - getConnectionStats: function(callback, interval) { - if (!callback) throw 'callback is mandatory.'; - - if (!window.getConnectionStats) { - loadScript(connection.resources.getConnectionStats, invoker); - } else invoker(); - - function invoker() { - RTCPeerConnection.prototype.getConnectionStats = window.getConnectionStats; - peer.connection && peer.connection.getConnectionStats(callback, interval); - } - }, - takeSnapshot: function(callback) { - takeSnapshot({ - userid: this.userid, - connection: connection, - callback: callback - }); - } - }; - } - - function onSessionOpened() { - // original conferencing infrastructure! - if (connection.isInitiator && getLength(participants) && getLength(participants) <= connection.maxParticipantsAllowed) { - if (!connection.session.oneway && !connection.session.broadcast) { - defaultSocket.send({ - sessionid: connection.sessionid, - newParticipant: _config.userid || socket.channel, - userData: { - userid: _config.userid || socket.channel, - extra: _config.extra - } - }); - } - } - - // 1st: renegotiation is supported only on chrome - // 2nd: must not renegotiate same media multiple times - // 3rd: todo: make sure that target-user has no such "renegotiated" media. - if (_config.userinfo.browser == 'chrome' && !_config.renegotiatedOnce) { - // this code snippet is added to make sure that "previously-renegotiated" streams are also - // renegotiated to this new user - for (var rSession in connection.renegotiatedSessions) { - _config.renegotiatedOnce = true; - - if (connection.renegotiatedSessions[rSession] && connection.renegotiatedSessions[rSession].stream) { - connection.peers[_config.userid].renegotiate(connection.renegotiatedSessions[rSession].stream, connection.renegotiatedSessions[rSession].session); - } - } - } - } - - function socketResponse(response) { - if (isRMSDeleted) return; - - if (response.userid == connection.userid) - return; - - if (response.sdp) { - _config.userid = response.userid; - _config.extra = response.extra || {}; - _config.renegotiate = response.renegotiate; - _config.streaminfo = response.streaminfo; - _config.isInitiator = response.isInitiator; - _config.userinfo = response.userinfo; - - var sdp = JSON.parse(response.sdp); - - if (sdp.type == 'offer') { - // to synchronize SCTP or RTP - peerConfig.preferSCTP = !!response.preferSCTP; - connection.fakeDataChannels = !!response.fakeDataChannels; - } - - // initializing fake channel - initFakeChannel(); - - sdpInvoker(sdp, response.labels); - } - - if (response.candidate) { - peer && peer.addIceCandidate(JSON.parse(response.candidate)); - } - - if (response.streamid) { - if (!rtcMultiSession.streamids) { - rtcMultiSession.streamids = {}; - } - if (!rtcMultiSession.streamids[response.streamid]) { - rtcMultiSession.streamids[response.streamid] = response.streamid; - connection.onstreamid(response); - } - } - - if (response.mute || response.unmute) { - if (response.promptMuteUnmute) { - if (!connection.privileges.canMuteRemoteStream) { - connection.onstatechange({ - userid: response.userid, - extra: response.extra, - name: 'mute-request-denied', - reason: response.userid + ' tried to mute your stream; however "privileges.canMuteRemoteStream" is "false".' - }); - return; - } - - if (connection.streams[response.streamid]) { - if (response.mute && !connection.streams[response.streamid].muted) { - connection.streams[response.streamid].mute(response.session); - } - if (response.unmute && connection.streams[response.streamid].muted) { - connection.streams[response.streamid].unmute(response.session); - } - } - } else { - var streamObject = {}; - if (connection.streams[response.streamid]) { - streamObject = connection.streams[response.streamid]; - } - - var session = response.session; - var fakeObject = merge({}, streamObject); - fakeObject.session = session; - - fakeObject.isAudio = !!fakeObject.session.audio && !fakeObject.session.video; - fakeObject.isVideo = !!fakeObject.session.video; - fakeObject.isScreen = !!fakeObject.session.screen; - - if (response.mute) connection.onmute(fakeObject || response); - if (response.unmute) connection.onunmute(fakeObject || response); - } - } - - if (response.isVolumeChanged) { - log('Volume of stream: ' + response.streamid + ' has changed to: ' + response.volume); - if (connection.streams[response.streamid]) { - var mediaElement = connection.streams[response.streamid].mediaElement; - if (mediaElement) mediaElement.volume = response.volume; - } - } - - // to stop local stream - if (response.stopped) { - if (connection.streams[response.streamid]) { - onStreamEndedHandler(connection.streams[response.streamid], connection); - } - } - - // to stop remote stream - if (response.promptStreamStop /* && !connection.isInitiator */ ) { - if (!connection.privileges.canStopRemoteStream) { - connection.onstatechange({ - userid: response.userid, - extra: response.extra, - name: 'stop-request-denied', - reason: response.userid + ' tried to stop your stream; however "privileges.canStopRemoteStream" is "false".' - }); - return; - } - warn('Remote stream has been manually stopped!'); - if (connection.streams[response.streamid]) { - connection.streams[response.streamid].stop(); - } - } - - if (response.left) { - // firefox is unable to stop remote streams - // firefox doesn't auto stop streams when peer.close() is called. - if (isFirefox) { - var userLeft = response.userid; - for (var stream in connection.streams) { - stream = connection.streams[stream]; - if (stream.userid == userLeft) { - connection.stopMediaStream(stream); - onStreamEndedHandler(stream, connection); - } - } - } - - if (peer && peer.connection) { - // todo: verify if-block's 2nd condition - if (peer.connection.signalingState != 'closed' && peer.connection.iceConnectionState.search(/disconnected|failed/gi) == -1) { - peer.connection.close(); - } - peer.connection = null; - } - - if (participants[response.userid]) delete participants[response.userid]; - - if (response.closeEntireSession) { - connection.onSessionClosed(response); - connection.leave(); - return; - } - - connection.remove(response.userid); - - onLeaveHandler({ - userid: response.userid, - extra: response.extra || {}, - entireSessionClosed: !!response.closeEntireSession - }, connection); - } - - // keeping session active even if initiator leaves - if (response.playRoleOfBroadcaster) { - if (response.extra) { - // clone extra-data from initial moderator - connection.extra = merge(connection.extra, response.extra); - } - if (response.participants) { - participants = response.participants; - - // make sure that if 2nd initiator leaves; control is shifted to 3rd person. - if (participants[connection.userid]) { - delete participants[connection.userid]; - } - - if (sockets[0] && sockets[0].userid == response.userid) { - delete sockets[0]; - sockets = swap(sockets); - } - - if (socketObjects[response.userid]) { - delete socketObjects[response.userid]; - } - } - - setTimeout(connection.playRoleOfInitiator, 2000); - } - - if (response.changeBandwidth) { - if (!connection.peers[response.userid]) throw 'No such peer exists.'; - - // synchronize bandwidth - connection.peers[response.userid].peer.bandwidth = response.bandwidth; - - // renegotiate to apply bandwidth - connection.peers[response.userid].renegotiate(); - } - - if (response.customMessage) { - if (!connection.peers[response.userid]) throw 'No such peer exists.'; - if (response.message.ejected) { - if (connection.sessionDescriptions[connection.sessionid].userid != response.userid) { - throw 'only initiator can eject a user.'; - } - // initiator ejected this user - connection.leave(); - - connection.onSessionClosed({ - userid: response.userid, - extra: response.extra || _config.extra, - isEjected: true - }); - } else connection.peers[response.userid].onCustomMessage(response.message); - } - - if (response.drop) { - if (!connection.peers[response.userid]) throw 'No such peer exists.'; - connection.peers[response.userid].drop(true); - connection.peers[response.userid].renegotiate(); - - connection.ondrop(response.userid); - } - - if (response.hold || response.unhold) { - if (!connection.peers[response.userid]) throw 'No such peer exists.'; - - if (response.takeAction) { - connection.peers[response.userid][!!response.hold ? 'hold' : 'unhold'](response.holdMLine); - return; - } - - connection.peers[response.userid].peer.hold = !!response.hold; - connection.peers[response.userid].peer.holdMLine = response.holdMLine; - - socket.send({ - isRenegotiate: true - }); - - connection.peers[response.userid].fireHoldUnHoldEvents({ - kind: response.holdMLine, - isHold: !!response.hold, - userid: response.userid - }); - } - - if (response.isRenegotiate) { - connection.peers[response.userid].renegotiate(null, connection.peers[response.userid].peer.session); - } - - // fake data channels! - if (response.fakeData) { - peerConfig.onmessage(response.fakeData); - } - - // sometimes we don't need to renegotiate e.g. when peers are disconnected - // or if it is firefox - if (response.recreatePeer) { - peer = new PeerConnection(); - } - - // remote video failed either out of ICE gathering process or ICE connectivity check-up - // or IceAgent was unable to locate valid candidates/ports. - if (response.failedToReceiveRemoteVideo) { - log('Remote peer hasn\'t received stream: ' + response.streamid + '. Renegotiating...'); - if (connection.peers[response.userid]) { - connection.peers[response.userid].renegotiate(); - } - } - - if (response.redial) { - if (connection.peers[response.userid]) { - if (connection.peers[response.userid].peer.connection.iceConnectionState != 'disconnected') { - _config.redialing = false; - } - - if (connection.peers[response.userid].peer.connection.iceConnectionState == 'disconnected' && !_config.redialing) { - _config.redialing = true; - - warn('Peer connection is closed.', toStr(connection.peers[response.userid].peer.connection), 'ReDialing..'); - connection.peers[response.userid].redial(); - } - } - } - } - - connection.playRoleOfInitiator = function() { - connection.dontCaptureUserMedia = true; - connection.open(); - sockets = swap(sockets); - connection.dontCaptureUserMedia = false; - }; - - connection.askToShareParticipants = function() { - defaultSocket && defaultSocket.send({ - askToShareParticipants: true - }); - }; - - connection.shareParticipants = function(args) { - var message = { - joinUsers: participants, - userid: connection.userid, - extra: connection.extra - }; - - if (args) { - if (args.dontShareWith) message.dontShareWith = args.dontShareWith; - if (args.shareWith) message.shareWith = args.shareWith; - } - - defaultSocket.send(message); - }; - - function sdpInvoker(sdp, labels) { - if (sdp.type == 'answer') { - peer.setRemoteDescription(sdp); - updateSocket(); - return; - } - if (!_config.renegotiate && sdp.type == 'offer') { - peerConfig.offerDescription = sdp; - - peerConfig.session = connection.session; - if (!peer) peer = new PeerConnection(); - peer.create('answer', peerConfig); - - updateSocket(); - return; - } - - var session = _config.renegotiate; - // detach streams - detachMediaStream(labels, peer.connection); - - if (session.oneway || isData(session)) { - createAnswer(); - delete _config.renegotiate; - } else { - if (_config.capturing) - return; - - _config.capturing = true; - - connection.captureUserMedia(function(stream) { - _config.capturing = false; - - peer.addStream(stream); - - connection.renegotiatedSessions[JSON.stringify(_config.renegotiate)] = { - session: _config.renegotiate, - stream: stream - }; - - delete _config.renegotiate; - - createAnswer(); - }, _config.renegotiate); - } - - function createAnswer() { - peer.recreateAnswer(sdp, session, function(_sdp, streaminfo) { - sendsdp({ - sdp: _sdp, - socket: socket, - streaminfo: streaminfo - }); - connection.detachStreams = []; - }); - } - } - } - - function detachMediaStream(labels, peer) { - if (!labels) return; - for (var i = 0; i < labels.length; i++) { - var label = labels[i]; - if (connection.streams[label]) { - peer.removeStream(connection.streams[label].stream); - } - } - } - - function sendsdp(e) { - e.socket.send({ - sdp: JSON.stringify({ - sdp: e.sdp.sdp, - type: e.sdp.type - }), - renegotiate: !!e.renegotiate ? e.renegotiate : false, - streaminfo: e.streaminfo || '', - labels: e.labels || [], - preferSCTP: !!connection.preferSCTP, - fakeDataChannels: !!connection.fakeDataChannels, - isInitiator: !!connection.isInitiator, - userinfo: { - browser: isFirefox ? 'firefox' : 'chrome' - } - }); - } - - // sharing new user with existing participants - - function onNewParticipant(response) { - var channel = response.newParticipant; - - if (!channel || !!participants[channel] || channel == connection.userid) - return; - - var new_channel = connection.token(); - newPrivateSocket({ - channel: new_channel, - extra: response.userData ? response.userData.extra : response.extra, - userid: response.userData ? response.userData.userid : response.userid - }); - - defaultSocket.send({ - participant: true, - targetUser: channel, - channel: new_channel - }); - } - - // if a user leaves - - function clearSession() { - connection.numberOfConnectedUsers--; - - var alertMessage = { - left: true, - extra: connection.extra || {}, - userid: connection.userid, - sessionid: connection.sessionid - }; - - if (connection.isInitiator) { - // if initiator wants to close entire session - if (connection.autoCloseEntireSession) { - alertMessage.closeEntireSession = true; - } else if (sockets[0]) { - // shift initiation control to another user - sockets[0].send({ - playRoleOfBroadcaster: true, - userid: connection.userid, - extra: connection.extra, - participants: participants - }); - } - } - - sockets.forEach(function(socket, i) { - socket.send(alertMessage); - - if (socketObjects[socket.channel]) { - delete socketObjects[socket.channel]; - } - - delete sockets[i]; - }); - - sockets = swap(sockets); - - connection.refresh(); - - webAudioMediaStreamSources.forEach(function(mediaStreamSource) { - // if source is connected; then chrome will crash on unload. - mediaStreamSource.disconnect(); - }); - - webAudioMediaStreamSources = []; - } - - // www.RTCMultiConnection.org/docs/remove/ - connection.remove = function(userid) { - if (rtcMultiSession.requestsFrom && rtcMultiSession.requestsFrom[userid]) delete rtcMultiSession.requestsFrom[userid]; - - if (connection.peers[userid]) { - if (connection.peers[userid].peer && connection.peers[userid].peer.connection) { - if (connection.peers[userid].peer.connection.signalingState != 'closed') { - connection.peers[userid].peer.connection.close(); - } - connection.peers[userid].peer.connection = null; - } - delete connection.peers[userid]; - } - if (participants[userid]) { - delete participants[userid]; - } - - for (var stream in connection.streams) { - stream = connection.streams[stream]; - if (stream.userid == userid) { - onStreamEndedHandler(stream, connection); - delete connection.streams[stream]; - } - } - - if (socketObjects[userid]) { - delete socketObjects[userid]; - } - }; - - // www.RTCMultiConnection.org/docs/refresh/ - connection.refresh = function() { - // if firebase; remove data from firebase servers - if (connection.isInitiator && !!connection.socket && !!connection.socket.remove) { - connection.socket.remove(); - } - - participants = {}; - - // to stop/remove self streams - for (var i = 0; i < connection.attachStreams.length; i++) { - connection.stopMediaStream(connection.attachStreams[i]); - } - - // to allow capturing of identical streams - currentUserMediaRequest = { - streams: [], - mutex: false, - queueRequests: [] - }; - - rtcMultiSession.isOwnerLeaving = true; - - connection.isInitiator = false; - connection.isAcceptNewSession = true; - connection.attachMediaStreams = []; - connection.sessionDescription = null; - connection.sessionDescriptions = {}; - connection.localStreamids = []; - connection.preRecordedMedias = {}; - connection.snapshots = {}; - - connection.numberOfConnectedUsers = 0; - connection.numberOfSessions = 0; - - connection.attachStreams = []; - connection.detachStreams = []; - connection.fileQueue = {}; - connection.channels = {}; - connection.renegotiatedSessions = {}; - - for (var peer in connection.peers) { - if (peer != connection.userid) { - delete connection.peers[peer]; - } - } - - // to make sure remote streams are also removed! - for (var stream in connection.streams) { - if (connection._skip.indexOf(stream) == -1) { - onStreamEndedHandler(connection.streams[stream], connection); - delete connection.streams[stream]; - } - } - - socketObjects = {}; - sockets = []; - participants = {}; - }; - - // www.RTCMultiConnection.org/docs/reject/ - connection.reject = function(userid) { - if (!isString(userid)) userid = userid.userid; - defaultSocket.send({ - rejectedRequestOf: userid - }); - - // remove relevant data to allow him join again - connection.remove(userid); - }; - - rtcMultiSession.leaveHandler = function(e) { - if (!connection.leaveOnPageUnload) return; - - if (isNull(e.keyCode)) { - return clearSession(); - } - - if (e.keyCode == 116) { - clearSession(); - } - }; - - listenEventHandler('beforeunload', rtcMultiSession.leaveHandler); - listenEventHandler('keyup', rtcMultiSession.leaveHandler); - - rtcMultiSession.onLineOffLineHandler = function() { - if (!navigator.onLine) { - rtcMultiSession.isOffLine = true; - } else if (rtcMultiSession.isOffLine) { - rtcMultiSession.isOffLine = !navigator.onLine; - - // defaultSocket = getDefaultSocketRef(); - - // pending tasks should be resumed? - // sockets should be reconnected? - // peers should be re-established? - } - }; - - listenEventHandler('load', rtcMultiSession.onLineOffLineHandler); - listenEventHandler('online', rtcMultiSession.onLineOffLineHandler); - listenEventHandler('offline', rtcMultiSession.onLineOffLineHandler); - - function onSignalingReady() { - if (rtcMultiSession.signalingReady) return; - rtcMultiSession.signalingReady = true; - - setTimeout(callbackForSignalingReady, 1000); - - if (!connection.isInitiator) { - // as soon as signaling gateway is connected; - // user should check existing rooms! - defaultSocket && defaultSocket.send({ - searchingForRooms: true - }); - } - } - - function joinParticipants(joinUsers) { - for (var user in joinUsers) { - if (!participants[joinUsers[user]]) { - onNewParticipant({ - sessionid: connection.sessionid, - newParticipant: joinUsers[user], - userid: connection.userid, - extra: connection.extra - }); - } - } - } - - function getDefaultSocketRef() { - return connection.openSignalingChannel({ - onmessage: function(response) { - // RMS == RTCMultiSession - if (isRMSDeleted) return; - - // if message is sent by same user - if (response.userid == connection.userid) return; - - if (response.sessionid && response.userid) { - if (!connection.sessionDescriptions[response.sessionid]) { - connection.numberOfSessions++; - connection.sessionDescriptions[response.sessionid] = response; - - // fire "onNewSession" only if: - // 1) "isAcceptNewSession" boolean is true - // 2) "sessionDescriptions" object isn't having same session i.e. to prevent duplicate invocations - if (connection.isAcceptNewSession) { - - if (!connection.dontOverrideSession) { - connection.session = response.session; - } - - onNewSession(response); - } - } - } - - if (response.newParticipant && !connection.isAcceptNewSession && rtcMultiSession.broadcasterid === response.userid) { - if (response.newParticipant != connection.userid) { - onNewParticipant(response); - } - } - - if (getLength(participants) < connection.maxParticipantsAllowed && response.targetUser == connection.userid && response.participant) { - if (connection.peers[response.userid] && !connection.peers[response.userid].peer) { - delete participants[response.userid]; - delete connection.peers[response.userid]; - connection.isAcceptNewSession = true; - return acceptRequest(response); - } - - if (!participants[response.userid]) { - acceptRequest(response); - } - } - - if (response.acceptedRequestOf == connection.userid) { - connection.onstatechange({ - userid: response.userid, - extra: response.extra, - name: 'request-accepted', - reason: response.userid + ' accepted your participation request.' - }); - } - - if (response.rejectedRequestOf == connection.userid) { - connection.onstatechange({ - userid: response.userid, - extra: response.extra, - name: 'request-rejected', - reason: response.userid + ' rejected your participation request.' - }); - } - - if (response.customMessage) { - if (response.message.drop) { - connection.ondrop(response.userid); - - connection.attachStreams = []; - // "drop" should detach all local streams - for (var stream in connection.streams) { - if (connection._skip.indexOf(stream) == -1) { - stream = connection.streams[stream]; - if (stream.type == 'local') { - connection.detachStreams.push(stream.streamid); - onStreamEndedHandler(stream, connection); - } else onStreamEndedHandler(stream, connection); - } - } - - if (response.message.renegotiate) { - // renegotiate; so "peer.removeStream" happens. - connection.renegotiate(); - } - } else if (connection.onCustomMessage) { - connection.onCustomMessage(response.message); - } - } - - if (connection.isInitiator && response.searchingForRooms) { - defaultSocket && defaultSocket.send({ - sessionDescription: connection.sessionDescription, - responseFor: response.userid - }); - } - - if (response.sessionDescription && response.responseFor == connection.userid) { - var sessionDescription = response.sessionDescription; - if (!connection.sessionDescriptions[sessionDescription.sessionid]) { - connection.numberOfSessions++; - connection.sessionDescriptions[sessionDescription.sessionid] = sessionDescription; - } - } - - if (connection.isInitiator && response.askToShareParticipants && defaultSocket) { - connection.shareParticipants({ - shareWith: response.userid - }); - } - - // participants are shared with single user - if (response.shareWith == connection.userid && response.dontShareWith != connection.userid && response.joinUsers) { - joinParticipants(response.joinUsers); - } - - // participants are shared with all users - if (!response.shareWith && response.joinUsers) { - if (response.dontShareWith) { - if (connection.userid != response.dontShareWith) { - joinParticipants(response.joinUsers); - } - } else joinParticipants(response.joinUsers); - } - - if (response.messageFor == connection.userid && response.presenceState) { - if (response.presenceState == 'checking') { - defaultSocket.send({ - messageFor: response.userid, - presenceState: 'available', - _config: response._config - }); - log('participant asked for availability'); - } - - if (response.presenceState == 'available') { - rtcMultiSession.presenceState = 'available'; - - connection.onstatechange({ - userid: 'browser', - extra: {}, - name: 'room-available', - reason: 'Initiator is available and room is active.' - }); - - joinSession(response._config); - } - } - - if (response.donotJoin && response.messageFor == connection.userid) { - log(response.userid, 'is not joining your room.'); - } - - // if initiator disconnects sockets, participants should also disconnect - if (response.isDisconnectSockets) { - log('Disconnecting your sockets because initiator also disconnected his sockets.'); - connection.disconnect(); - } - }, - callback: function(socket) { - socket && this.onopen(socket); - }, - onopen: function(socket) { - if (socket) defaultSocket = socket; - if (onSignalingReady) onSignalingReady(); - - rtcMultiSession.defaultSocket = defaultSocket; - - if (!defaultSocket.__push) { - defaultSocket.__push = defaultSocket.send; - defaultSocket.send = function(message) { - message.userid = message.userid || connection.userid; - message.extra = message.extra || connection.extra || {}; - - defaultSocket.__push(message); - }; - } - } - }); - } - - // default-socket is a common socket shared among all users in a specific channel; - // to share participation requests; room descriptions; and other stuff. - var defaultSocket = getDefaultSocketRef(); - - rtcMultiSession.defaultSocket = defaultSocket; - - if (defaultSocket && onSignalingReady) setTimeout(onSignalingReady, 2000); - - if (connection.session.screen) { - loadScreenFrame(); - } - // CUSTOM CODE // - - /* Commenting this - connection.getExternalIceServers && loadIceFrame(function(iceServers) - { - connection.iceServers = connection.iceServers.concat(iceServers); - }); - */ - - // CUSTOM CODE // - - if (connection.log == false) connection.skipLogs(); - if (connection.onlog) { - log = warn = error = function() { - var log = {}; - var index = 0; - Array.prototype.slice.call(arguments).forEach(function(argument) { - log[index++] = toStr(argument); - }); - toStr = function(str) { - return str; - }; - connection.onlog(log); - }; - } - - function setDirections() { - var userMaxParticipantsAllowed = 0; - - // if user has set a custom max participant setting, remember it - if (connection.maxParticipantsAllowed != 256) { - userMaxParticipantsAllowed = connection.maxParticipantsAllowed; - } - - if (connection.direction == 'one-way') connection.session.oneway = true; - if (connection.direction == 'one-to-one') connection.maxParticipantsAllowed = 1; - if (connection.direction == 'one-to-many') connection.session.broadcast = true; - if (connection.direction == 'many-to-many') { - if (!connection.maxParticipantsAllowed || connection.maxParticipantsAllowed == 1) { - connection.maxParticipantsAllowed = 256; - } - } - - // if user has set a custom max participant setting, set it back - if (userMaxParticipantsAllowed && connection.maxParticipantsAllowed != 1) { - connection.maxParticipantsAllowed = userMaxParticipantsAllowed; - } - } - - // open new session - this.initSession = function(args) { - rtcMultiSession.isOwnerLeaving = false; - - setDirections(); - participants = {}; - - rtcMultiSession.isOwnerLeaving = false; - - if (!isNull(args.transmitRoomOnce)) { - connection.transmitRoomOnce = args.transmitRoomOnce; - } - - function transmit() { - if (defaultSocket && getLength(participants) < connection.maxParticipantsAllowed && !rtcMultiSession.isOwnerLeaving) { - defaultSocket.send(connection.sessionDescription); - } - - if (!connection.transmitRoomOnce && !rtcMultiSession.isOwnerLeaving) - setTimeout(transmit, connection.interval || 3000); - } - - // todo: test and fix next line. - if (!args.dontTransmit /* || connection.transmitRoomOnce */ ) transmit(); - }; - - function joinSession(_config, skipOnStateChange) { - if (rtcMultiSession.donotJoin && rtcMultiSession.donotJoin == _config.sessionid) { - return; - } - - // dontOverrideSession allows you force RTCMultiConnection - // to not override default session for participants; - // by default, session is always overridden and set to the session coming from initiator! - if (!connection.dontOverrideSession) { - connection.session = _config.session || {}; - } - - // make sure that inappropriate users shouldn't receive onNewSession event - rtcMultiSession.broadcasterid = _config.userid; - - if (_config.sessionid) { - // used later to prevent external rooms messages to be used by this user! - connection.sessionid = _config.sessionid; - } - - connection.isAcceptNewSession = false; - - var channel = getRandomString(); - newPrivateSocket({ - channel: channel, - extra: _config.extra || {}, - userid: _config.userid - }); - - var offers = {}; - if (connection.attachStreams.length) { - var stream = connection.attachStreams[connection.attachStreams.length - 1]; - if (!!stream.getAudioTracks && stream.getAudioTracks().length) { - offers.audio = true; - } - if (stream.getVideoTracks().length) { - offers.video = true; - } - } - - if (!isEmpty(offers)) { - log(toStr(offers)); - } else log('Seems data-only connection.'); - - connection.onstatechange({ - userid: _config.userid, - extra: {}, - name: 'connecting-with-initiator', - reason: 'Checking presence of the initiator; and the room.' - }); - - defaultSocket.send({ - participant: true, - channel: channel, - targetUser: _config.userid, - session: connection.session, - offers: { - audio: !!offers.audio, - video: !!offers.video - } - }); - - connection.skipOnNewSession = false; - invokeMediaCaptured(connection); - } - - // join existing session - this.joinSession = function(_config) { - if (!defaultSocket) - return setTimeout(function() { - warn('Default-Socket is not yet initialized.'); - rtcMultiSession.joinSession(_config); - }, 1000); - - _config = _config || {}; - participants = {}; - - rtcMultiSession.presenceState = 'checking'; - - connection.onstatechange({ - userid: _config.userid, - extra: _config.extra || {}, - name: 'detecting-room-presence', - reason: 'Checking presence of the room.' - }); - - function contactInitiator() { - defaultSocket.send({ - messageFor: _config.userid, - presenceState: rtcMultiSession.presenceState, - _config: { - userid: _config.userid, - extra: _config.extra || {}, - sessionid: _config.sessionid, - session: _config.session || false - } - }); - } - contactInitiator(); - - function checker() { - if (rtcMultiSession.presenceState == 'checking') { - warn('Unable to reach initiator. Trying again...'); - contactInitiator(); - setTimeout(function() { - if (rtcMultiSession.presenceState == 'checking') { - connection.onstatechange({ - userid: _config.userid, - extra: _config.extra || {}, - name: 'room-not-available', - reason: 'Initiator seems absent. Waiting for someone to open the room.' - }); - - connection.isAcceptNewSession = true; - setTimeout(checker, 2000); - } - }, 2000); - } - } - - setTimeout(checker, 3000); - }; - - connection.donotJoin = function(sessionid) { - rtcMultiSession.donotJoin = sessionid; - - var session = connection.sessionDescriptions[sessionid]; - if (!session) return; - - defaultSocket.send({ - donotJoin: true, - messageFor: session.userid, - sessionid: sessionid - }); - - participants = {}; - connection.isAcceptNewSession = true; - connection.sessionid = null; - }; - - // send file/data or text message - this.send = function(message, _channel) { - if (!(message instanceof ArrayBuffer || message instanceof DataView)) { - message = str2ab({ - extra: connection.extra, - userid: connection.userid, - data: message - }); - } - - if (_channel) { - if (_channel.readyState == 'open') { - _channel.send(message); - } - return; - } - - for (var dataChannel in connection.channels) { - var channel = connection.channels[dataChannel].channel; - if (channel.readyState == 'open') { - channel.send(message); - } - } - }; - - // leave session - this.leave = function() { - clearSession(); - }; - - // renegotiate new stream - this.addStream = function(e) { - var session = e.renegotiate; - - if (!connection.renegotiatedSessions[JSON.stringify(e.renegotiate)]) { - connection.renegotiatedSessions[JSON.stringify(e.renegotiate)] = { - session: e.renegotiate, - stream: e.stream - }; - } - - if (e.socket) { - if (e.socket.userid != connection.userid) { - addStream(connection.peers[e.socket.userid]); - } - } else { - for (var peer in connection.peers) { - if (peer != connection.userid) { - addStream(connection.peers[peer]); - } - } - } - - function addStream(_peer) { - var socket = _peer.socket; - - if (!socket) { - warn(_peer, 'doesn\'t has socket.'); - return; - } - - updateSocketForLocalStreams(socket); - - if (!_peer || !_peer.peer) { - throw 'No peer to renegotiate.'; - } - - var peer = _peer.peer; - - if (e.stream) { - if (!peer.attachStreams) { - peer.attachStreams = []; - } - - peer.attachStreams.push(e.stream); - } - - // detaching old streams - detachMediaStream(connection.detachStreams, peer.connection); - - if (e.stream && (session.audio || session.video || session.screen)) { - peer.addStream(e.stream); - } - - peer.recreateOffer(session, function(sdp, streaminfo) { - sendsdp({ - sdp: sdp, - socket: socket, - renegotiate: session, - labels: connection.detachStreams, - streaminfo: streaminfo - }); - connection.detachStreams = []; - }); - } - }; - - // www.RTCMultiConnection.org/docs/request/ - connection.request = function(userid, extra) { - connection.captureUserMedia(function() { - // open private socket that will be used to receive offer-sdp - newPrivateSocket({ - channel: connection.userid, - extra: extra || {}, - userid: userid - }); - - // ask other user to create offer-sdp - defaultSocket.send({ - participant: true, - targetUser: userid - }); - }); - }; - - function acceptRequest(response) { - if (!rtcMultiSession.requestsFrom) rtcMultiSession.requestsFrom = {}; - if (rtcMultiSession.requestsFrom[response.userid]) return; - - var obj = { - userid: response.userid, - extra: response.extra, - channel: response.channel || response.userid, - session: response.session || connection.session - }; - - // check how participant is willing to join - if (response.offers) { - if (response.offers.audio && response.offers.video) { - log('target user has both audio/video streams.'); - } else if (response.offers.audio && !response.offers.video) { - log('target user has only audio stream.'); - } else if (!response.offers.audio && response.offers.video) { - log('target user has only video stream.'); - } else { - log('target user has no stream; it seems one-way streaming or data-only connection.'); - } - - var mandatory = connection.sdpConstraints.mandatory; - if (isNull(mandatory.OfferToReceiveAudio)) { - connection.sdpConstraints.mandatory.OfferToReceiveAudio = !!response.offers.audio; - } - if (isNull(mandatory.OfferToReceiveVideo)) { - connection.sdpConstraints.mandatory.OfferToReceiveVideo = !!response.offers.video; - } - - log('target user\'s SDP has?', toStr(connection.sdpConstraints.mandatory)); - } - - rtcMultiSession.requestsFrom[response.userid] = obj; - - // www.RTCMultiConnection.org/docs/onRequest/ - if (connection.onRequest && connection.isInitiator) { - connection.onRequest(obj); - } else _accept(obj); - } - - function _accept(e) { - if (rtcMultiSession.captureUserMediaOnDemand) { - rtcMultiSession.captureUserMediaOnDemand = false; - connection.captureUserMedia(function() { - _accept(e); - - invokeMediaCaptured(connection); - }); - return; - } - - log('accepting request from', e.userid); - participants[e.userid] = e.userid; - newPrivateSocket({ - isofferer: true, - userid: e.userid, - channel: e.channel, - extra: e.extra || {}, - session: e.session || connection.session - }); - } - - // www.RTCMultiConnection.org/docs/accept/ - connection.accept = function(e) { - // for backward compatibility - if (arguments.length > 1 && isString(arguments[0])) { - e = {}; - if (arguments[0]) e.userid = arguments[0]; - if (arguments[1]) e.extra = arguments[1]; - if (arguments[2]) e.channel = arguments[2]; - } - - connection.captureUserMedia(function() { - _accept(e); - }); - }; - - var isRMSDeleted = false; - this.disconnect = function() { - this.isOwnerLeaving = true; - - if (!connection.keepStreamsOpened) { - for (var streamid in connection.localStreams) { - connection.localStreams[streamid].stop(); - } - connection.localStreams = {}; - - currentUserMediaRequest = { - streams: [], - mutex: false, - queueRequests: [] - }; - } - - if (connection.isInitiator) { - defaultSocket.send({ - isDisconnectSockets: true - }); - } - - connection.refresh(); - - rtcMultiSession.defaultSocket = defaultSocket = null; - isRMSDeleted = true; - - connection.ondisconnected({ - userid: connection.userid, - extra: connection.extra, - peer: connection.peers[connection.userid], - isSocketsDisconnected: true - }); - - // if there is any peer still opened; close it. - connection.close(); - - window.removeEventListener('beforeunload', rtcMultiSession.leaveHandler); - window.removeEventListener('keyup', rtcMultiSession.leaveHandler); - - // it will not work, though :) - delete this; - - log('Disconnected your sockets, peers, streams and everything except RTCMultiConnection object.'); - }; - } - - var webAudioMediaStreamSources = []; - - function convertToAudioStream(mediaStream) { - if (!mediaStream) throw 'MediaStream is mandatory.'; - - if (mediaStream.getVideoTracks && !mediaStream.getVideoTracks().length) { - return mediaStream; - } - - var context = new AudioContext(); - var mediaStreamSource = context.createMediaStreamSource(mediaStream); - - var destination = context.createMediaStreamDestination(); - mediaStreamSource.connect(destination); - - webAudioMediaStreamSources.push(mediaStreamSource); - - return destination.stream; - } - - var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; - var isFirefox = typeof window.InstallTrigger !== 'undefined'; - var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; - var isChrome = !!window.chrome && !isOpera; - var isIE = !!document.documentMode; - - var isPluginRTC = isSafari || isIE; - - var isMobileDevice = !!navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i); - - // detect node-webkit - var isNodeWebkit = !!(window.process && (typeof window.process == 'object') && window.process.versions && window.process.versions['node-webkit']); - - window.MediaStream = window.MediaStream || window.webkitMediaStream; - window.AudioContext = window.AudioContext || window.webkitAudioContext; - - function getRandomString() { - // suggested by @rvulpescu from #154 - if (window.crypto && crypto.getRandomValues && navigator.userAgent.indexOf('Safari') == -1) { - var a = window.crypto.getRandomValues(new Uint32Array(3)), - token = ''; - for (var i = 0, l = a.length; i < l; i++) { - token += a[i].toString(36); - } - return token; - } else { - return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, ''); - } - } - - var chromeVersion = 50; - var matchArray = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); - if (isChrome && matchArray && matchArray[2]) { - chromeVersion = parseInt(matchArray[2], 10); - } - - var firefoxVersion = 50; - matchArray = navigator.userAgent.match(/Firefox\/(.*)/); - if (isFirefox && matchArray && matchArray[1]) { - firefoxVersion = parseInt(matchArray[1], 10); - } - - function isData(session) { - return !session.audio && !session.video && !session.screen && session.data; - } - - function isNull(obj) { - return typeof obj == 'undefined'; - } - - function isString(obj) { - return typeof obj == 'string'; - } - - function isEmpty(session) { - var length = 0; - for (var s in session) { - length++; - } - return length == 0; - } - - // this method converts array-buffer into string - function ab2str(buf) { - var result = ''; - try { - result = String.fromCharCode.apply(null, new Uint16Array(buf)); - } catch (e) {} - return result; - } - - // this method converts string into array-buffer - function str2ab(str) { - if (!isString(str)) str = JSON.stringify(str); - - var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char - var bufView = new Uint16Array(buf); - for (var i = 0, strLen = str.length; i < strLen; i++) { - bufView[i] = str.charCodeAt(i); - } - return buf; - } - - function swap(arr) { - var swapped = [], - length = arr.length; - for (var i = 0; i < length; i++) - if (arr[i] && arr[i] !== true) - swapped.push(arr[i]); - return swapped; - } - - function forEach(obj, callback) { - for (var item in obj) { - callback(obj[item], item); - } - } - - var console = window.console || { - log: function() {}, - error: function() {}, - warn: function() {} - }; - - function log() { - console.log(arguments); - } - - function error() { - console.error(arguments); - } - - function warn() { - console.warn(arguments); - } - - if (isChrome || isFirefox || isSafari) { - var log = console.log.bind(console); - var error = console.error.bind(console); - var warn = console.warn.bind(console); - } - - function toStr(obj) { - return JSON.stringify(obj, function(key, value) { - if (value && value.sdp) { - log(value.sdp.type, '\t', value.sdp.sdp); - return ''; - } else return value; - }, '\t'); - } - - function getLength(obj) { - var length = 0; - for (var o in obj) - if (o) length++; - return length; - } - - // Get HTMLAudioElement/HTMLVideoElement accordingly - - function createMediaElement(stream, session) { - var mediaElement = document.createElement(stream.isAudio ? 'audio' : 'video'); - mediaElement.id = stream.streamid; - - if (isPluginRTC) { - var body = (document.body || document.documentElement); - body.insertBefore(mediaElement, body.firstChild); - - setTimeout(function() { - Plugin.attachMediaStream(mediaElement, stream) - }, 1000); - - return Plugin.attachMediaStream(mediaElement, stream); - } - - // "mozSrcObject" is always preferred over "src"!! - mediaElement[isFirefox ? 'mozSrcObject' : 'src'] = isFirefox ? stream : (window.URL || window.webkitURL).createObjectURL(stream); - - mediaElement.controls = true; - mediaElement.autoplay = !!session.remote; - mediaElement.muted = session.remote ? false : true; - - // http://goo.gl/WZ5nFl - // Firefox don't yet support onended for any stream (remote/local) - isFirefox && mediaElement.addEventListener('ended', function() { - stream.onended(); - }, false); - - mediaElement.play(); - - return mediaElement; - } - - var onStreamEndedHandlerFiredFor = {}; - - function onStreamEndedHandler(streamedObject, connection) { - if (streamedObject.mediaElement && !streamedObject.mediaElement.parentNode) return; - - if (onStreamEndedHandlerFiredFor[streamedObject.streamid]) return; - onStreamEndedHandlerFiredFor[streamedObject.streamid] = streamedObject; - connection.onstreamended(streamedObject); - } - - var onLeaveHandlerFiredFor = {}; - - function onLeaveHandler(event, connection) { - if (onLeaveHandlerFiredFor[event.userid]) return; - onLeaveHandlerFiredFor[event.userid] = event; - connection.onleave(event); - } - - function takeSnapshot(args) { - var userid = args.userid; - var connection = args.connection; - - function _takeSnapshot(video) { - var canvas = document.createElement('canvas'); - canvas.width = video.videoWidth || video.clientWidth; - canvas.height = video.videoHeight || video.clientHeight; - - var context = canvas.getContext('2d'); - context.drawImage(video, 0, 0, canvas.width, canvas.height); - - connection.snapshots[userid] = canvas.toDataURL('image/png'); - args.callback && args.callback(connection.snapshots[userid]); - } - - if (args.mediaElement) return _takeSnapshot(args.mediaElement); - - for (var stream in connection.streams) { - stream = connection.streams[stream]; - if (stream.userid == userid && stream.stream && stream.stream.getVideoTracks && stream.stream.getVideoTracks().length) { - _takeSnapshot(stream.mediaElement); - continue; - } - } - } - - function invokeMediaCaptured(connection) { - // to let user know that media resource has been captured - // now, he can share "sessionDescription" using sockets - if (connection.onMediaCaptured) { - connection.onMediaCaptured(); - delete connection.onMediaCaptured; - } - } - - function merge(mergein, mergeto) { - if (!mergein) mergein = {}; - if (!mergeto) return mergein; - - for (var item in mergeto) { - mergein[item] = mergeto[item]; - } - return mergein; - } - - function loadScript(src, onload) { - var script = document.createElement('script'); - script.src = src; - script.onload = function() { - log('loaded resource:', src); - if (onload) onload(); - }; - document.documentElement.appendChild(script); - } - - function capturePartOfScreen(args) { - var connection = args.connection; - var element = args.element; - - if (!window.html2canvas) { - return loadScript(connection.resources.html2canvas, function() { - capturePartOfScreen(args); - }); - } - - if (isString(element)) { - element = document.querySelector(element); - if (!element) element = document.getElementById(element); - } - if (!element) throw 'HTML DOM Element is not accessible!'; - - // todo: store DOM element somewhere to minimize DOM querying issues - - // html2canvas.js is used to take screenshots - html2canvas(element, { - onrendered: function(canvas) { - args.callback(canvas.toDataURL()); - } - }); - } - - function initFileBufferReader(connection, callback) { - if (!window.FileBufferReader) { - loadScript(connection.resources.FileBufferReader, function() { - initFileBufferReader(connection, callback); - }); - return; - } - - function _private(chunk) { - chunk.userid = chunk.extra.userid; - return chunk; - } - - var fileBufferReader = new FileBufferReader(); - fileBufferReader.onProgress = function(chunk) { - connection.onFileProgress(_private(chunk), chunk.uuid); - }; - - fileBufferReader.onBegin = function(file) { - connection.onFileStart(_private(file)); - }; - - fileBufferReader.onEnd = function(file) { - connection.onFileEnd(_private(file)); - }; - - callback(fileBufferReader); - } - - var screenFrame, loadedScreenFrame; - - function loadScreenFrame(skip) { - if (DetectRTC.screen.extensionid != ReservedExtensionID) { - return; - } - - if (loadedScreenFrame) return; - if (!skip) return loadScreenFrame(true); - - loadedScreenFrame = true; - - var iframe = document.createElement('iframe'); - iframe.onload = function() { - iframe.isLoaded = true; - log('Screen Capturing frame is loaded.'); - }; - //iframe.src = 'https://www.webrtc-experiment.com/getSourceId/'; - // CUSTOM CODE // - iframe.src = 'app/fusion/scripts/webrtc/getSourceId.html'; - // CUSTOM CODE // - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); - - screenFrame = { - postMessage: function() { - if (!iframe.isLoaded) { - setTimeout(screenFrame.postMessage, 100); - return; - } - iframe.contentWindow.postMessage({ - captureSourceId: true - }, '*'); - } - }; - } - - var iceFrame, loadedIceFrame; - - function loadIceFrame(callback, skip) { - if (loadedIceFrame) return; - if (!skip) return loadIceFrame(callback, true); - - loadedIceFrame = true; - - var iframe = document.createElement('iframe'); - iframe.onload = function() { - iframe.isLoaded = true; - - listenEventHandler('message', iFrameLoaderCallback); - - function iFrameLoaderCallback(event) { - if (!event.data || !event.data.iceServers) return; - callback(event.data.iceServers); - - // this event listener is no more needed - window.removeEventListener('message', iFrameLoaderCallback); - } - - iframe.contentWindow.postMessage('get-ice-servers', '*'); - }; - iframe.src = 'https://cdn.webrtc-experiment.com/getIceServers/'; - iframe.style.display = 'none'; - (document.body || document.documentElement).appendChild(iframe); - } - - function muteOrUnmute(e) { - var stream = e.stream, - root = e.root, - session = e.session || {}, - enabled = e.enabled; - - if (!session.audio && !session.video) { - if (!isString(session)) { - session = merge(session, { - audio: true, - video: true - }); - } else { - session = { - audio: true, - video: true - }; - } - } - - // implementation from #68 - if (session.type) { - if (session.type == 'remote' && root.type != 'remote') return; - if (session.type == 'local' && root.type != 'local') return; - } - - log(enabled ? 'Muting' : 'UnMuting', 'session', toStr(session)); - - // enable/disable audio/video tracks - - if (root.type == 'local' && session.audio && !!stream.getAudioTracks) { - var audioTracks = stream.getAudioTracks()[0]; - if (audioTracks) - audioTracks.enabled = !enabled; - } - - if (root.type == 'local' && (session.video || session.screen) && !!stream.getVideoTracks) { - var videoTracks = stream.getVideoTracks()[0]; - if (videoTracks) - videoTracks.enabled = !enabled; - } - - root.sockets.forEach(function(socket) { - if (root.type == 'local') { - socket.send({ - streamid: root.streamid, - mute: !!enabled, - unmute: !enabled, - session: session - }); - } - - if (root.type == 'remote') { - socket.send({ - promptMuteUnmute: true, - streamid: root.streamid, - mute: !!enabled, - unmute: !enabled, - session: session - }); - } - }); - - if (root.type == 'remote') return; - - // According to issue #135, onmute/onumute must be fired for self - // "fakeObject" is used because we need to keep session for renegotiated streams; - // and MUST pass exact session over onStreamEndedHandler/onmute/onhold/etc. events. - var fakeObject = merge({}, root); - fakeObject.session = session; - - fakeObject.isAudio = !!fakeObject.session.audio && !fakeObject.session.video; - fakeObject.isVideo = !!fakeObject.session.video; - fakeObject.isScreen = !!fakeObject.session.screen; - - if (!!enabled) { - // if muted stream is negotiated - stream.preMuted = { - audio: stream.getAudioTracks().length && !stream.getAudioTracks()[0].enabled, - video: stream.getVideoTracks().length && !stream.getVideoTracks()[0].enabled - }; - root.rtcMultiConnection.onmute(fakeObject); - } - - if (!enabled) { - stream.preMuted = {}; - root.rtcMultiConnection.onunmute(fakeObject); - } - } - - var Firefox_Screen_Capturing_Warning = 'Make sure that you are using Firefox Nightly and you enabled: media.getusermedia.screensharing.enabled flag from about:config page. You also need to add your domain in "media.getusermedia.screensharing.allowed_domains" flag. If you are using WinXP then also enable "media.getusermedia.screensharing.allow_on_old_platforms" flag. NEVER forget to use "only" HTTPs for screen capturing!'; - var SCREEN_COMMON_FAILURE = 'HTTPs i.e. SSL-based URI is mandatory to use screen capturing.'; - // CUSTOM CODE // - var ReservedExtensionID = 'icgmlogfeajbfdffajhoebcfbibfhaen'; - //var ReservedExtensionID = 'ajhifddimkapgcifgcodmmfdlknahffk'; - - // if application-developer deployed his own extension on Google App Store - var useCustomChromeExtensionForScreenCapturing = document.domain.indexOf('webrtc-experiment.com') != -1; - - function initHark(args) { - if (!window.hark) { - loadScript(args.connection.resources.hark, function() { - initHark(args); - }); - return; - } - - var connection = args.connection; - var streamedObject = args.streamedObject; - var stream = args.stream; - - var options = {}; - var speechEvents = hark(stream, options); - - speechEvents.on('speaking', function() { - if (connection.onspeaking) { - connection.onspeaking(streamedObject); - } - }); - - speechEvents.on('stopped_speaking', function() { - if (connection.onsilence) { - connection.onsilence(streamedObject); - } - }); - - speechEvents.on('volume_change', function(volume, threshold) { - if (connection.onvolumechange) { - connection.onvolumechange(merge({ - volume: volume, - threshold: threshold - }, streamedObject)); - } - }); - } - - attachEventListener = function(video, type, listener, useCapture) { - video.addEventListener(type, listener, useCapture); - }; - - var Plugin = window.PluginRTC || {}; - window.onPluginRTCInitialized = function(pluginRTCObject) { - Plugin = pluginRTCObject; - MediaStreamTrack = Plugin.MediaStreamTrack; - RTCPeerConnection = Plugin.RTCPeerConnection; - RTCIceCandidate = Plugin.RTCIceCandidate; - RTCSessionDescription = Plugin.RTCSessionDescription; - - log(isPluginRTC ? 'Java-Applet' : 'ActiveX', 'plugin has been loaded.'); - }; - if (!isEmpty(Plugin)) window.onPluginRTCInitialized(Plugin); - - // if IE or Safari - if (isPluginRTC) { - loadScript('https://cdn.webrtc-experiment.com/Plugin.EveryWhere.js'); - // loadScript('https://cdn.webrtc-experiment.com/Plugin.Temasys.js'); - } - - var MediaStream = window.MediaStream; - - if (typeof MediaStream === 'undefined' && typeof webkitMediaStream !== 'undefined') { - MediaStream = webkitMediaStream; - } - - /*global MediaStream:true */ - if (typeof MediaStream !== 'undefined' && !('stop' in MediaStream.prototype)) { - MediaStream.prototype.stop = function() { - this.getAudioTracks().forEach(function(track) { - track.stop(); - }); - - this.getVideoTracks().forEach(function(track) { - track.stop(); - }); - }; - } - - var defaultConstraints = { - mandatory: {}, - optional: [] - }; - - /* by @FreCap pull request #41 */ - var currentUserMediaRequest = { - streams: [], - mutex: false, - queueRequests: [] - }; - - function getUserMedia(options) { - if (isPluginRTC) { - if (!Plugin.getUserMedia) { - setTimeout(function() { - getUserMedia(options); - }, 1000); - return; - } - - return Plugin.getUserMedia(options.constraints || { - audio: true, - video: true - }, options.onsuccess, options.onerror); - } - - if (currentUserMediaRequest.mutex === true) { - currentUserMediaRequest.queueRequests.push(options); - return; - } - currentUserMediaRequest.mutex = true; - - var connection = options.connection; - - // tools.ietf.org/html/draft-alvestrand-constraints-resolution-00 - var mediaConstraints = options.mediaConstraints || {}; - var videoConstraints = typeof mediaConstraints.video == 'boolean' ? mediaConstraints.video : mediaConstraints.video || mediaConstraints; - var audioConstraints = typeof mediaConstraints.audio == 'boolean' ? mediaConstraints.audio : mediaConstraints.audio || defaultConstraints; - - var n = navigator; - var hints = options.constraints || { - audio: defaultConstraints, - video: defaultConstraints - }; - - if (hints.video && hints.video.mozMediaSource) { - // "mozMediaSource" is redundant - // need to check "mediaSource" instead. - videoConstraints = {}; - } - - if (hints.video == true) hints.video = defaultConstraints; - if (hints.audio == true) hints.audio = defaultConstraints; - - // connection.mediaConstraints.audio = false; - if (typeof audioConstraints == 'boolean' && hints.audio) { - hints.audio = audioConstraints; - } - - // connection.mediaConstraints.video = false; - if (typeof videoConstraints == 'boolean' && hints.video) { - hints.video = videoConstraints; - } - - // connection.mediaConstraints.audio.mandatory = {prop:true}; - var audioMandatoryConstraints = audioConstraints.mandatory; - if (!isEmpty(audioMandatoryConstraints)) { - hints.audio.mandatory = merge(hints.audio.mandatory, audioMandatoryConstraints); - } - - // connection.media.min(320,180); - // connection.media.max(1920,1080); - var videoMandatoryConstraints = videoConstraints.mandatory; - if (videoMandatoryConstraints) { - var mandatory = {}; - - if (videoMandatoryConstraints.minWidth) { - mandatory.minWidth = videoMandatoryConstraints.minWidth; - } - - if (videoMandatoryConstraints.minHeight) { - mandatory.minHeight = videoMandatoryConstraints.minHeight; - } - - if (videoMandatoryConstraints.maxWidth) { - mandatory.maxWidth = videoMandatoryConstraints.maxWidth; - } - - if (videoMandatoryConstraints.maxHeight) { - mandatory.maxHeight = videoMandatoryConstraints.maxHeight; - } - - if (videoMandatoryConstraints.minAspectRatio) { - mandatory.minAspectRatio = videoMandatoryConstraints.minAspectRatio; - } - - if (videoMandatoryConstraints.maxFrameRate) { - mandatory.maxFrameRate = videoMandatoryConstraints.maxFrameRate; - } - - if (videoMandatoryConstraints.minFrameRate) { - mandatory.minFrameRate = videoMandatoryConstraints.minFrameRate; - } - - if (mandatory.minWidth && mandatory.minHeight) { - // http://goo.gl/IZVYsj - var allowed = ['1920:1080', '1280:720', '960:720', '640:360', '640:480', '320:240', '320:180']; - - if (allowed.indexOf(mandatory.minWidth + ':' + mandatory.minHeight) == -1 || - allowed.indexOf(mandatory.maxWidth + ':' + mandatory.maxHeight) == -1) { - error('The min/max width/height constraints you passed "seems" NOT supported.', toStr(mandatory)); - } - - if (mandatory.minWidth > mandatory.maxWidth || mandatory.minHeight > mandatory.maxHeight) { - error('Minimum value must not exceed maximum value.', toStr(mandatory)); - } - - if (mandatory.minWidth >= 1280 && mandatory.minHeight >= 720) { - warn('Enjoy HD video! min/' + mandatory.minWidth + ':' + mandatory.minHeight + ', max/' + mandatory.maxWidth + ':' + mandatory.maxHeight); - } - } - - hints.video.mandatory = merge(hints.video.mandatory, mandatory); - } - - if (videoMandatoryConstraints) { - hints.video.mandatory = merge(hints.video.mandatory, videoMandatoryConstraints); - } - - // videoConstraints.optional = [{prop:true}]; - if (videoConstraints.optional && videoConstraints.optional instanceof Array && videoConstraints.optional.length) { - hints.video.optional = hints.video.optional ? hints.video.optional.concat(videoConstraints.optional) : videoConstraints.optional; - } - - // audioConstraints.optional = [{prop:true}]; - if (audioConstraints.optional && audioConstraints.optional instanceof Array && audioConstraints.optional.length) { - hints.audio.optional = hints.audio.optional ? hints.audio.optional.concat(audioConstraints.optional) : audioConstraints.optional; - } - - if (hints.video.mandatory && !isEmpty(hints.video.mandatory) && connection._mediaSources.video) { - hints.video.optional.forEach(function(video, index) { - if (video.sourceId == connection._mediaSources.video) { - delete hints.video.optional[index]; - } - }); - - hints.video.optional = swap(hints.video.optional); - - hints.video.optional.push({ - sourceId: connection._mediaSources.video - }); - } - - if (hints.audio.mandatory && !isEmpty(hints.audio.mandatory) && connection._mediaSources.audio) { - hints.audio.optional.forEach(function(audio, index) { - if (audio.sourceId == connection._mediaSources.audio) { - delete hints.audio.optional[index]; - } - }); - - hints.audio.optional = swap(hints.audio.optional); - - hints.audio.optional.push({ - sourceId: connection._mediaSources.audio - }); - } - - if (hints.video && !hints.video.mozMediaSource && hints.video.optional && hints.video.mandatory) { - if (!hints.video.optional.length && isEmpty(hints.video.mandatory)) { - hints.video = true; - } - } - - if (isMobileDevice) { - // Android fails for some constraints - // so need to force {audio:true,video:true} - hints = { - audio: !!hints.audio, - video: !!hints.video - }; - } - - // connection.mediaConstraints always overrides constraints - // passed from "captureUserMedia" function. - // todo: need to verify all possible situations - log('invoked getUserMedia with constraints:', toStr(hints)); - - // easy way to match - var idInstance = JSON.stringify(hints); - - function streaming(stream, returnBack, streamid) { - if (!streamid) streamid = getRandomString(); - - // localStreams object will store stream - // until it is removed using native-stop method. - connection.localStreams[streamid] = stream; - - var video = options.video; - if (video) { - video[isFirefox ? 'mozSrcObject' : 'src'] = isFirefox ? stream : (window.URL || window.webkitURL).createObjectURL(stream); - video.play(); - } - - options.onsuccess(stream, returnBack, idInstance, streamid); - currentUserMediaRequest.streams[idInstance] = { - stream: stream, - streamid: streamid - }; - currentUserMediaRequest.mutex = false; - if (currentUserMediaRequest.queueRequests.length) - getUserMedia(currentUserMediaRequest.queueRequests.shift()); - } - - if (currentUserMediaRequest.streams[idInstance]) { - streaming(currentUserMediaRequest.streams[idInstance].stream, true, currentUserMediaRequest.streams[idInstance].streamid); - } else { - n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia; - - // http://goo.gl/eETIK4 - n.getMedia(hints, streaming, function(error) { - options.onerror(error, hints); - }); - } - } - - var RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription; - var RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate; - - var RTCPeerConnection; - if (typeof mozRTCPeerConnection !== 'undefined') { - RTCPeerConnection = mozRTCPeerConnection; - } else if (typeof webkitRTCPeerConnection !== 'undefined') { - RTCPeerConnection = webkitRTCPeerConnection; - } else if (typeof window.RTCPeerConnection !== 'undefined') { - RTCPeerConnection = window.RTCPeerConnection; - } else { - console.error('WebRTC 1.0 (RTCPeerConnection) API seems NOT available in this browser.'); - } - - function setSdpConstraints(config) { - var sdpConstraints; - - var sdpConstraints_mandatory = { - OfferToReceiveAudio: !!config.OfferToReceiveAudio, - OfferToReceiveVideo: !!config.OfferToReceiveVideo - }; - - sdpConstraints = { - mandatory: sdpConstraints_mandatory, - optional: [{ - VoiceActivityDetection: false - }] - }; - - if (!!navigator.mozGetUserMedia && firefoxVersion > 34) { - sdpConstraints = { - OfferToReceiveAudio: !!config.OfferToReceiveAudio, - OfferToReceiveVideo: !!config.OfferToReceiveVideo - }; - } - - return sdpConstraints; - } - - function PeerConnection() { - return { - create: function(type, options) { - merge(this, options); - - var self = this; - - this.type = type; - this.init(); - this.attachMediaStreams(); - - if (isFirefox && this.session.data) { - if (this.session.data && type == 'offer') { - this.createDataChannel(); - } - - this.getLocalDescription(type); - - if (this.session.data && type == 'answer') { - this.createDataChannel(); - } - } else self.getLocalDescription(type); - - return this; - }, - getLocalDescription: function(createType) { - log('(getLocalDescription) peer createType is', createType); - - if (this.session.inactive && isNull(this.rtcMultiConnection.waitUntilRemoteStreamStartsFlowing)) { - // inactive session returns blank-stream - this.rtcMultiConnection.waitUntilRemoteStreamStartsFlowing = false; - } - - var self = this; - - if (createType == 'answer') { - this.setRemoteDescription(this.offerDescription, createDescription); - } else createDescription(); - - function createDescription() { - self.connection[createType == 'offer' ? 'createOffer' : 'createAnswer'](function(sessionDescription) { - sessionDescription.sdp = self.serializeSdp(sessionDescription.sdp, createType); - self.connection.setLocalDescription(sessionDescription); - - if (self.trickleIce) { - self.onSessionDescription(sessionDescription, self.streaminfo); - } - - if (sessionDescription.type == 'offer') { - log('offer sdp', sessionDescription.sdp); - } - - self.prevCreateType = createType; - }, self.onSdpError, self.constraints); - } - }, - serializeSdp: function(sdp, createType) { - // it is "connection.processSdp=function(sdp){return sdp;}" - sdp = this.processSdp(sdp); - - if (isFirefox) return sdp; - - if (this.session.inactive && !this.holdMLine) { - this.hold = true; - if ((this.session.screen || this.session.video) && this.session.audio) { - this.holdMLine = 'both'; - } else if (this.session.screen || this.session.video) { - this.holdMLine = 'video'; - } else if (this.session.audio) { - this.holdMLine = 'audio'; - } - } - - sdp = this.setBandwidth(sdp); - if (this.holdMLine == 'both') { - if (this.hold) { - this.prevSDP = sdp; - sdp = sdp.replace(/a=sendonly|a=recvonly|a=sendrecv/g, 'a=inactive'); - } else if (this.prevSDP) { - if (!this.session.inactive) { - // it means that DTSL key exchange already happened for single or multiple media lines. - // this block checks, key-exchange must be happened for all media lines. - sdp = this.prevSDP; - - // todo: test it: makes sense? - if (chromeVersion <= 35) { - return sdp; - } - } - } - } else if (this.holdMLine == 'audio' || this.holdMLine == 'video') { - sdp = sdp.split('m='); - - var audio = ''; - var video = ''; - - if (sdp[1] && sdp[1].indexOf('audio') == 0) { - audio = 'm=' + sdp[1]; - } - if (sdp[2] && sdp[2].indexOf('audio') == 0) { - audio = 'm=' + sdp[2]; - } - - if (sdp[1] && sdp[1].indexOf('video') == 0) { - video = 'm=' + sdp[1]; - } - if (sdp[2] && sdp[2].indexOf('video') == 0) { - video = 'm=' + sdp[2]; - } - - if (this.holdMLine == 'audio') { - if (this.hold) { - this.prevSDP = sdp[0] + audio + video; - sdp = sdp[0] + audio.replace(/a=sendonly|a=recvonly|a=sendrecv/g, 'a=inactive') + video; - } else if (this.prevSDP) { - sdp = this.prevSDP; - } - } - - if (this.holdMLine == 'video') { - if (this.hold) { - this.prevSDP = sdp[0] + audio + video; - sdp = sdp[0] + audio + video.replace(/a=sendonly|a=recvonly|a=sendrecv/g, 'a=inactive'); - } else if (this.prevSDP) { - sdp = this.prevSDP; - } - } - } - - if (!this.hold && this.session.inactive) { - // transport.cc&l=852 - http://goo.gl/0FxxqG - // dtlstransport.h&l=234 - http://goo.gl/7E4sYF - // http://tools.ietf.org/html/rfc4340 - - // From RFC 4145, SDP setup attribute values. - // http://goo.gl/xETJEp && http://goo.gl/3Wgcau - if (createType == 'offer') { - sdp = sdp.replace(/a=setup:passive|a=setup:active|a=setup:holdconn/g, 'a=setup:actpass'); - } else { - sdp = sdp.replace(/a=setup:actpass|a=setup:passive|a=setup:holdconn/g, 'a=setup:active'); - } - - // whilst doing handshake, either media lines were "inactive" - // or no media lines were present - sdp = sdp.replace(/a=inactive/g, 'a=sendrecv'); - } - // this.session.inactive = false; - return sdp; - }, - init: function() { - this.setConstraints(); - this.connection = new RTCPeerConnection(this.iceServers, this.optionalArgument); - - if (this.session.data) { - log('invoked: createDataChannel'); - this.createDataChannel(); - } - - this.connection.onicecandidate = function(event) { - if (!event.candidate) { - if (!self.trickleIce) { - returnSDP(); - } - - return; - } - - if (!self.trickleIce) return; - - self.onicecandidate(event.candidate); - }; - - function returnSDP() { - if (self.returnedSDP) { - self.returnedSDP = false; - return; - }; - self.returnedSDP = true; - - self.onSessionDescription(self.connection.localDescription, self.streaminfo); - } - - this.connection.onaddstream = function(e) { - log('onaddstream', isPluginRTC ? e.stream : toStr(e.stream)); - - self.onaddstream(e.stream, self.session); - }; - - this.connection.onremovestream = function(e) { - self.onremovestream(e.stream); - }; - - this.connection.onsignalingstatechange = function() { - self.connection && self.oniceconnectionstatechange({ - iceConnectionState: self.connection.iceConnectionState, - iceGatheringState: self.connection.iceGatheringState, - signalingState: self.connection.signalingState - }); - }; - - this.connection.oniceconnectionstatechange = function() { - if (!self.connection) return; - - self.oniceconnectionstatechange({ - iceConnectionState: self.connection.iceConnectionState, - iceGatheringState: self.connection.iceGatheringState, - signalingState: self.connection.signalingState - }); - - if (self.trickleIce) return; - - if (self.connection.iceGatheringState == 'complete') { - log('iceGatheringState', self.connection.iceGatheringState); - returnSDP(); - } - }; - - var self = this; - }, - setBandwidth: function(sdp) { - if (isMobileDevice || isFirefox || !this.bandwidth) return sdp; - - var bandwidth = this.bandwidth; - - if (this.session.screen) { - if (!bandwidth.screen) { - warn('It seems that you are not using bandwidth for screen. Screen sharing is expected to fail.'); - } else if (bandwidth.screen < 300) { - warn('It seems that you are using wrong bandwidth value for screen. Screen sharing is expected to fail.'); - } - } - - // if screen; must use at least 300kbs - if (bandwidth.screen && this.session.screen) { - sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, ''); - sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + bandwidth.screen + '\r\n'); - } - - // remove existing bandwidth lines - if (bandwidth.audio || bandwidth.video || bandwidth.data) { - sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, ''); - } - - if (bandwidth.audio) { - sdp = sdp.replace(/a=mid:audio\r\n/g, 'a=mid:audio\r\nb=AS:' + bandwidth.audio + '\r\n'); - } - - if (bandwidth.video) { - sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + (this.session.screen ? bandwidth.screen : bandwidth.video) + '\r\n'); - } - - if (bandwidth.data && !this.preferSCTP) { - sdp = sdp.replace(/a=mid:data\r\n/g, 'a=mid:data\r\nb=AS:' + bandwidth.data + '\r\n'); - } - - return sdp; - }, - setConstraints: function() { - var sdpConstraints = setSdpConstraints({ - OfferToReceiveAudio: !!this.session.audio, - OfferToReceiveVideo: !!this.session.video || !!this.session.screen - }); - - if (this.sdpConstraints.mandatory) { - sdpConstraints = setSdpConstraints(this.sdpConstraints.mandatory); - } - - this.constraints = sdpConstraints; - - if (this.constraints) { - log('sdp-constraints', toStr(this.constraints)); - } - - this.optionalArgument = { - optional: this.optionalArgument.optional || [], - mandatory: this.optionalArgument.mandatory || {} - }; - - if (!this.preferSCTP) { - this.optionalArgument.optional.push({ - RtpDataChannels: true - }); - } - - log('optional-argument', toStr(this.optionalArgument)); - - if (!isNull(this.iceServers)) { - var iceCandidates = this.rtcMultiConnection.candidates; - - var stun = iceCandidates.stun; - var turn = iceCandidates.turn; - var host = iceCandidates.host; - - if (!isNull(iceCandidates.reflexive)) stun = iceCandidates.reflexive; - if (!isNull(iceCandidates.relay)) turn = iceCandidates.relay; - - if (!host && !stun && turn) { - this.rtcConfiguration.iceTransports = 'relay'; - } else if (!host && !stun && !turn) { - this.rtcConfiguration.iceTransports = 'none'; - } - - this.iceServers = { - iceServers: this.iceServers, - iceTransports: this.rtcConfiguration.iceTransports - }; - } else this.iceServers = null; - - log('rtc-configuration', toStr(this.iceServers)); - }, - onSdpError: function(e) { - var message = toStr(e); - - if (message && message.indexOf('RTP/SAVPF Expects at least 4 fields') != -1) { - message = 'It seems that you are trying to interop RTP-datachannels with SCTP. It is not supported!'; - } - error('onSdpError:', message); - }, - onSdpSuccess: function() { - log('sdp success'); - }, - onMediaError: function(err) { - error(toStr(err)); - }, - setRemoteDescription: function(sessionDescription, onSdpSuccess) { - if (!sessionDescription) throw 'Remote session description should NOT be NULL.'; - - if (!this.connection) return; - - log('setting remote description', sessionDescription.type, sessionDescription.sdp); - - var self = this; - this.connection.setRemoteDescription( - new RTCSessionDescription(sessionDescription), - onSdpSuccess || this.onSdpSuccess, - function(error) { - if (error.search(/STATE_SENTINITIATE|STATE_INPROGRESS/gi) == -1) { - self.onSdpError(error); - } - } - ); - }, - addIceCandidate: function(candidate) { - var self = this; - if (isPluginRTC) { - RTCIceCandidate(candidate, function(iceCandidate) { - onAddIceCandidate(iceCandidate); - }); - } else onAddIceCandidate(new RTCIceCandidate(candidate)); - - function onAddIceCandidate(iceCandidate) { - self.connection.addIceCandidate(iceCandidate, function() { - log('added:', candidate.sdpMid, candidate.candidate); - }, function() { - error('onIceFailure', arguments, candidate.candidate); - }); - } - }, - createDataChannel: function(channelIdentifier) { - // skip 2nd invocation of createDataChannel - if (this.channels && this.channels.length) return; - - var self = this; - - if (!this.channels) this.channels = []; - - // protocol: 'text/chat', preset: true, stream: 16 - // maxRetransmits:0 && ordered:false && outOfOrderAllowed: false - var dataChannelDict = {}; - - if (this.dataChannelDict) dataChannelDict = this.dataChannelDict; - - if (isChrome && !this.preferSCTP) { - dataChannelDict.reliable = false; // Deprecated! - } - - log('dataChannelDict', toStr(dataChannelDict)); - - if (this.type == 'answer' || isFirefox) { - this.connection.ondatachannel = function(event) { - self.setChannelEvents(event.channel); - }; - } - - if ((isChrome && this.type == 'offer') || isFirefox) { - this.setChannelEvents( - this.connection.createDataChannel(channelIdentifier || 'channel', dataChannelDict) - ); - } - }, - setChannelEvents: function(channel) { - var self = this; - - channel.binaryType = 'arraybuffer'; - - if (this.dataChannelDict.binaryType) { - channel.binaryType = this.dataChannelDict.binaryType; - } - - channel.onmessage = function(event) { - self.onmessage(event.data); - }; - - var numberOfTimes = 0; - channel.onopen = function() { - channel.push = channel.send; - channel.send = function(data) { - if (self.connection.iceConnectionState == 'disconnected') { - return; - } - - if (channel.readyState.search(/closing|closed/g) != -1) { - return; - } - - if (channel.readyState.search(/connecting|open/g) == -1) { - return; - } - - if (channel.readyState == 'connecting') { - numberOfTimes++; - return setTimeout(function() { - if (numberOfTimes < 20) { - channel.send(data); - } else throw 'Number of times exceeded to wait for WebRTC data connection to be opened.'; - }, 1000); - } - try { - channel.push(data); - } catch (e) { - numberOfTimes++; - warn('Data transmission failed. Re-transmitting..', numberOfTimes, toStr(e)); - if (numberOfTimes >= 20) throw 'Number of times exceeded to resend data packets over WebRTC data channels.'; - setTimeout(function() { - channel.send(data); - }, 100); - } - }; - self.onopen(channel); - }; - - channel.onerror = function(event) { - self.onerror(event); - }; - - channel.onclose = function(event) { - self.onclose(event); - }; - - this.channels.push(channel); - }, - addStream: function(stream) { - if (!stream.streamid && !isIE) { - stream.streamid = getRandomString(); - } - - // todo: maybe need to add isAudio/isVideo/isScreen if missing? - - log('attaching stream:', stream.streamid, isPluginRTC ? stream : toStr(stream)); - - this.connection.addStream(stream); - - this.sendStreamId(stream); - this.getStreamInfo(); - }, - attachMediaStreams: function() { - var streams = this.attachStreams; - for (var i = 0; i < streams.length; i++) { - this.addStream(streams[i]); - } - }, - getStreamInfo: function() { - this.streaminfo = ''; - var streams = this.connection.getLocalStreams(); - for (var i = 0; i < streams.length; i++) { - if (i == 0) { - this.streaminfo = JSON.stringify({ - streamid: streams[i].streamid || '', - isScreen: !!streams[i].isScreen, - isAudio: !!streams[i].isAudio, - isVideo: !!streams[i].isVideo, - preMuted: streams[i].preMuted || {} - }); - } else { - this.streaminfo += '----' + JSON.stringify({ - streamid: streams[i].streamid || '', - isScreen: !!streams[i].isScreen, - isAudio: !!streams[i].isAudio, - isVideo: !!streams[i].isVideo, - preMuted: streams[i].preMuted || {} - }); - } - } - }, - recreateOffer: function(renegotiate, callback) { - log('recreating offer'); - - this.type = 'offer'; - this.session = renegotiate; - - // todo: make sure this doesn't affect renegotiation scenarios - // this.setConstraints(); - - this.onSessionDescription = callback; - this.getStreamInfo(); - - // one can renegotiate data connection in existing audio/video/screen connection! - if (this.session.data) { - this.createDataChannel(); - } - - this.getLocalDescription('offer'); - }, - recreateAnswer: function(sdp, session, callback) { - // if(isFirefox) this.create(this.type, this); - - log('recreating answer'); - - this.type = 'answer'; - this.session = session; - - // todo: make sure this doesn't affect renegotiation scenarios - // this.setConstraints(); - - this.onSessionDescription = callback; - this.offerDescription = sdp; - this.getStreamInfo(); - - // one can renegotiate data connection in existing audio/video/screen connection! - if (this.session.data) { - this.createDataChannel(); - } - - this.getLocalDescription('answer'); - } - }; - } - - var FileSaver = { - SaveToDisk: invokeSaveAsDialog - }; - - - function invokeSaveAsDialog(fileUrl, fileName) { - /* - if (typeof navigator.msSaveOrOpenBlob !== 'undefined') { - return navigator.msSaveOrOpenBlob(file, fileFullName); - } else if (typeof navigator.msSaveBlob !== 'undefined') { - return navigator.msSaveBlob(file, fileFullName); - } - */ - - var hyperlink = document.createElement('a'); - hyperlink.href = fileUrl; - hyperlink.target = '_blank'; - hyperlink.download = fileName || fileUrl; - - if (!!navigator.mozGetUserMedia) { - hyperlink.onclick = function() { - (document.body || document.documentElement).removeChild(hyperlink); - }; - (document.body || document.documentElement).appendChild(hyperlink); - } - - var evt = new MouseEvent('click', { - view: window, - bubbles: true, - cancelable: true - }); - - hyperlink.dispatchEvent(evt); - - if (!navigator.mozGetUserMedia) { - URL.revokeObjectURL(hyperlink.href); - } - } - - var TextSender = { - send: function(config) { - var connection = config.connection; - - if (config.text instanceof ArrayBuffer || config.text instanceof DataView) { - return config.channel.send(config.text, config._channel); - } - - var channel = config.channel, - _channel = config._channel, - initialText = config.text, - packetSize = connection.chunkSize || 1000, - textToTransfer = '', - isobject = false; - - if (!isString(initialText)) { - isobject = true; - initialText = JSON.stringify(initialText); - } - - // uuid is used to uniquely identify sending instance - var uuid = getRandomString(); - var sendingTime = new Date().getTime(); - - sendText(initialText); - - function sendText(textMessage, text) { - var data = { - type: 'text', - uuid: uuid, - sendingTime: sendingTime - }; - - if (textMessage) { - text = textMessage; - data.packets = parseInt(text.length / packetSize); - } - - if (text.length > packetSize) - data.message = text.slice(0, packetSize); - else { - data.message = text; - data.last = true; - data.isobject = isobject; - } - - channel.send(data, _channel); - - textToTransfer = text.slice(data.message.length); - - if (textToTransfer.length) { - setTimeout(function() { - sendText(null, textToTransfer); - }, connection.chunkInterval || 100); - } - } - } - }; - - function TextReceiver(connection) { - var content = {}; - - function receive(data, userid, extra) { - // uuid is used to uniquely identify sending instance - var uuid = data.uuid; - if (!content[uuid]) content[uuid] = []; - - content[uuid].push(data.message); - if (data.last) { - var message = content[uuid].join(''); - if (data.isobject) message = JSON.parse(message); - - // latency detection - var receivingTime = new Date().getTime(); - var latency = receivingTime - data.sendingTime; - - var e = { - data: message, - userid: userid, - extra: extra, - latency: latency - }; - - if (message.preRecordedMediaChunk) { - if (!connection.preRecordedMedias[message.streamerid]) { - connection.shareMediaFile(null, null, message.streamerid); - } - connection.preRecordedMedias[message.streamerid].onData(message.chunk); - } else if (connection.autoTranslateText) { - e.original = e.data; - connection.Translator.TranslateText(e.data, function(translatedText) { - e.data = translatedText; - connection.onmessage(e); - }); - } else if (message.isPartOfScreen) { - connection.onpartofscreen(message); - } else connection.onmessage(e); - - delete content[uuid]; - } - } - - return { - receive: receive - }; - } - - // Last time updated at Sep 25, 2015, 08:32:23 - - // Latest file can be found here: https://cdn.webrtc-experiment.com/DetectRTC.js - - // Muaz Khan - www.MuazKhan.com - // MIT License - www.WebRTC-Experiment.com/licence - // Documentation - github.com/muaz-khan/DetectRTC - // ____________ - // DetectRTC.js - - // DetectRTC.hasWebcam (has webcam device!) - // DetectRTC.hasMicrophone (has microphone device!) - // DetectRTC.hasSpeakers (has speakers!) - - (function() { - - 'use strict'; - - var navigator = window.navigator; - - if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) { - // Firefox 38+ seems having support of enumerateDevices - // Thanks @xdumaine/enumerateDevices - navigator.enumerateDevices = function(callback) { - navigator.mediaDevices.enumerateDevices().then(callback); - }; - } - - if (typeof navigator !== 'undefined') { - if (typeof navigator.webkitGetUserMedia !== 'undefined') { - navigator.getUserMedia = navigator.webkitGetUserMedia; - } - - if (typeof navigator.mozGetUserMedia !== 'undefined') { - navigator.getUserMedia = navigator.mozGetUserMedia; - } - } else { - navigator = { - getUserMedia: function() {} - }; - } - - var isMobileDevice = !!navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i); - var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob); - - // this one can also be used: - // https://www.websocket.org/js/stuff.js (DetectBrowser.js) - - function getBrowserInfo() { - var nVer = navigator.appVersion; - var nAgt = navigator.userAgent; - var browserName = navigator.appName; - var fullVersion = '' + parseFloat(navigator.appVersion); - var majorVersion = parseInt(navigator.appVersion, 10); - var nameOffset, verOffset, ix; - - // In Opera, the true version is after 'Opera' or after 'Version' - if ((verOffset = nAgt.indexOf('Opera')) !== -1) { - browserName = 'Opera'; - fullVersion = nAgt.substring(verOffset + 6); - - if ((verOffset = nAgt.indexOf('Version')) !== -1) { - fullVersion = nAgt.substring(verOffset + 8); - } - } - // In MSIE, the true version is after 'MSIE' in userAgent - else if ((verOffset = nAgt.indexOf('MSIE')) !== -1) { - browserName = 'IE'; - fullVersion = nAgt.substring(verOffset + 5); - } - // In Chrome, the true version is after 'Chrome' - else if ((verOffset = nAgt.indexOf('Chrome')) !== -1) { - browserName = 'Chrome'; - fullVersion = nAgt.substring(verOffset + 7); - } - // In Safari, the true version is after 'Safari' or after 'Version' - else if ((verOffset = nAgt.indexOf('Safari')) !== -1) { - browserName = 'Safari'; - fullVersion = nAgt.substring(verOffset + 7); - - if ((verOffset = nAgt.indexOf('Version')) !== -1) { - fullVersion = nAgt.substring(verOffset + 8); - } - } - // In Firefox, the true version is after 'Firefox' - else if ((verOffset = nAgt.indexOf('Firefox')) !== -1) { - browserName = 'Firefox'; - fullVersion = nAgt.substring(verOffset + 8); - } - - // In most other browsers, 'name/version' is at the end of userAgent - else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) { - browserName = nAgt.substring(nameOffset, verOffset); - fullVersion = nAgt.substring(verOffset + 1); - - if (browserName.toLowerCase() === browserName.toUpperCase()) { - browserName = navigator.appName; - } - } - - if (isEdge) { - browserName = 'Edge'; - // fullVersion = navigator.userAgent.split('Edge/')[1]; - fullVersion = parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10); - } - - // trim the fullVersion string at semicolon/space if present - if ((ix = fullVersion.indexOf(';')) !== -1) { - fullVersion = fullVersion.substring(0, ix); - } - - if ((ix = fullVersion.indexOf(' ')) !== -1) { - fullVersion = fullVersion.substring(0, ix); - } - - majorVersion = parseInt('' + fullVersion, 10); - - if (isNaN(majorVersion)) { - fullVersion = '' + parseFloat(navigator.appVersion); - majorVersion = parseInt(navigator.appVersion, 10); - } - - return { - fullVersion: fullVersion, - version: majorVersion, - name: browserName - }; - } - - var isMobile = { - Android: function() { - return navigator.userAgent.match(/Android/i); - }, - BlackBerry: function() { - return navigator.userAgent.match(/BlackBerry/i); - }, - iOS: function() { - return navigator.userAgent.match(/iPhone|iPad|iPod/i); - }, - Opera: function() { - return navigator.userAgent.match(/Opera Mini/i); - }, - Windows: function() { - return navigator.userAgent.match(/IEMobile/i); - }, - any: function() { - return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows()); - }, - getOsName: function() { - var osName = 'Unknown OS'; - if (isMobile.Android()) { - osName = 'Android'; - } - - if (isMobile.BlackBerry()) { - osName = 'BlackBerry'; - } - - if (isMobile.iOS()) { - osName = 'iOS'; - } - - if (isMobile.Opera()) { - osName = 'Opera Mini'; - } - - if (isMobile.Windows()) { - osName = 'Windows'; - } - - return osName; - } - }; - - var osName = 'Unknown OS'; - - if (isMobile.any()) { - osName = isMobile.getOsName(); - } else { - if (navigator.appVersion.indexOf('Win') !== -1) { - osName = 'Windows'; - } - - if (navigator.appVersion.indexOf('Mac') !== -1) { - osName = 'MacOS'; - } - - if (navigator.appVersion.indexOf('X11') !== -1) { - osName = 'UNIX'; - } - - if (navigator.appVersion.indexOf('Linux') !== -1) { - osName = 'Linux'; - } - } - - - var isCanvasSupportsStreamCapturing = false; - var isVideoSupportsStreamCapturing = false; - ['captureStream', 'mozCaptureStream', 'webkitCaptureStream'].forEach(function(item) { - // asdf - if (item in document.createElement('canvas')) { - isCanvasSupportsStreamCapturing = true; - } - - if (item in document.createElement('video')) { - isVideoSupportsStreamCapturing = true; - } - }); - - // via: https://github.com/diafygi/webrtc-ips - function DetectLocalIPAddress(callback) { - getIPs(function(ip) { - //local IPs - if (ip.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/)) { - callback('Local: ' + ip); - } - - //assume the rest are public IPs - else { - callback('Public: ' + ip); - } - }); - } - - //get the IP addresses associated with an account - function getIPs(callback) { - var ipDuplicates = {}; - - //compatibility for firefox and chrome - var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; - var useWebKit = !!window.webkitRTCPeerConnection; - - // bypass naive webrtc blocking using an iframe - if (!RTCPeerConnection) { - var iframe = document.getElementById('iframe'); - if (!iframe) { - // - throw 'NOTE: you need to have an iframe in the page right above the script tag.'; - } - var win = iframe.contentWindow; - RTCPeerConnection = win.RTCPeerConnection || win.mozRTCPeerConnection || win.webkitRTCPeerConnection; - useWebKit = !!win.webkitRTCPeerConnection; - } - - //minimal requirements for data connection - var mediaConstraints = { - optional: [{ - RtpDataChannels: true - }] - }; - - //firefox already has a default stun server in about:config - // media.peerconnection.default_iceservers = - // [{"url": "stun:stun.services.mozilla.com"}] - var servers; - - //add same stun server for chrome - if (useWebKit) { - servers = { - iceServers: [{ - urls: 'stun:stun.services.mozilla.com' - }] - }; - - if (typeof DetectRTC !== 'undefined' && DetectRTC.browser.isFirefox && DetectRTC.browser.version <= 38) { - servers[0] = { - url: servers[0].urls - }; - } - } - - //construct a new RTCPeerConnection - var pc = new RTCPeerConnection(servers, mediaConstraints); - - function handleCandidate(candidate) { - //match just the IP address - var ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/; - var ipAddress = ipRegex.exec(candidate)[1]; - - //remove duplicates - if (ipDuplicates[ipAddress] === undefined) { - callback(ipAddress); - } - - ipDuplicates[ipAddress] = true; - } - - //listen for candidate events - pc.onicecandidate = function(ice) { - //skip non-candidate events - if (ice.candidate) { - handleCandidate(ice.candidate.candidate); - } - }; - - //create a bogus data channel - pc.createDataChannel(''); - - //create an offer sdp - pc.createOffer(function(result) { - - //trigger the stun server request - pc.setLocalDescription(result, function() {}, function() {}); - - }, function() {}); - - //wait for a while to let everything done - setTimeout(function() { - //read candidate info from local description - var lines = pc.localDescription.sdp.split('\n'); - - lines.forEach(function(line) { - if (line.indexOf('a=candidate:') === 0) { - handleCandidate(line); - } - }); - }, 1000); - } - - var MediaDevices = []; - - // ---------- Media Devices detection - var canEnumerate = false; - - /*global MediaStreamTrack:true */ - if (typeof MediaStreamTrack !== 'undefined' && 'getSources' in MediaStreamTrack) { - canEnumerate = true; - } else if (navigator.mediaDevices && !!navigator.mediaDevices.enumerateDevices) { - canEnumerate = true; - } - - var hasMicrophone = canEnumerate; - var hasSpeakers = canEnumerate; - var hasWebcam = canEnumerate; - - // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediadevices - // todo: switch to enumerateDevices when landed in canary. - function checkDeviceSupport(callback) { - // This method is useful only for Chrome! - - if (!navigator.enumerateDevices && window.MediaStreamTrack && window.MediaStreamTrack.getSources) { - navigator.enumerateDevices = window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack); - } - - if (!navigator.enumerateDevices && navigator.enumerateDevices) { - navigator.enumerateDevices = navigator.enumerateDevices.bind(navigator); - } - - if (!navigator.enumerateDevices) { - if (callback) { - callback(); - } - return; - } - - MediaDevices = []; - navigator.enumerateDevices(function(devices) { - devices.forEach(function(_device) { - var device = {}; - for (var d in _device) { - device[d] = _device[d]; - } - - var skip; - MediaDevices.forEach(function(d) { - if (d.id === device.id) { - skip = true; - } - }); - - if (skip) { - return; - } - - // if it is MediaStreamTrack.getSources - if (device.kind === 'audio') { - device.kind = 'audioinput'; - } - - if (device.kind === 'video') { - device.kind = 'videoinput'; - } - - if (!device.deviceId) { - device.deviceId = device.id; - } - - if (!device.id) { - device.id = device.deviceId; - } - - if (!device.label) { - device.label = 'Please invoke getUserMedia once.'; - if (!isHTTPs) { - device.label = 'HTTPs is required to get label of this ' + device.kind + ' device.'; - } - } - - if (device.kind === 'audioinput' || device.kind === 'audio') { - hasMicrophone = true; - } - - if (device.kind === 'audiooutput') { - hasSpeakers = true; - } - - if (device.kind === 'videoinput' || device.kind === 'video') { - hasWebcam = true; - } - - // there is no 'videoouput' in the spec. - - MediaDevices.push(device); - }); - - if (typeof DetectRTC !== 'undefined') { - DetectRTC.MediaDevices = MediaDevices; - DetectRTC.hasMicrophone = hasMicrophone; - DetectRTC.hasSpeakers = hasSpeakers; - DetectRTC.hasWebcam = hasWebcam; - } - - if (callback) { - callback(); - } - }); - } - - // check for microphone/camera support! - checkDeviceSupport(); - - var DetectRTC = {}; - - // ---------- - // DetectRTC.browser.name || DetectRTC.browser.version || DetectRTC.browser.fullVersion - DetectRTC.browser = getBrowserInfo(); - - // DetectRTC.isChrome || DetectRTC.isFirefox || DetectRTC.isEdge - DetectRTC.browser['is' + DetectRTC.browser.name] = true; - - var isHTTPs = location.protocol === 'https:'; - var isNodeWebkit = !!(window.process && (typeof window.process === 'object') && window.process.versions && window.process.versions['node-webkit']); - - // --------- Detect if system supports WebRTC 1.0 or WebRTC 1.1. - var isWebRTCSupported = false; - ['webkitRTCPeerConnection', 'mozRTCPeerConnection', 'RTCIceGatherer'].forEach(function(item) { - if (item in window) { - isWebRTCSupported = true; - } - }); - DetectRTC.isWebRTCSupported = isWebRTCSupported; - - //------- - DetectRTC.isORTCSupported = typeof RTCIceGatherer !== 'undefined'; - - // --------- Detect if system supports screen capturing API - var isScreenCapturingSupported = false; - if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 35) { - isScreenCapturingSupported = true; - } else if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 34) { - isScreenCapturingSupported = true; - } - - if (!isHTTPs) { - isScreenCapturingSupported = false; - } - DetectRTC.isScreenCapturingSupported = isScreenCapturingSupported; - - // --------- Detect if WebAudio API are supported - var webAudio = {}; - ['AudioContext', 'webkitAudioContext', 'mozAudioContext', 'msAudioContext'].forEach(function(item) { - if (webAudio.isSupported && webAudio.isCreateMediaStreamSourceSupported) { - return; - } - if (item in window) { - webAudio.isSupported = true; - - if ('createMediaStreamSource' in window[item].prototype) { - webAudio.isCreateMediaStreamSourceSupported = true; - } - } - }); - DetectRTC.isAudioContextSupported = webAudio.isSupported; - DetectRTC.isCreateMediaStreamSourceSupported = webAudio.isCreateMediaStreamSourceSupported; - - // ---------- Detect if SCTP/RTP channels are supported. - - var isRtpDataChannelsSupported = false; - if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 31) { - isRtpDataChannelsSupported = true; - } - DetectRTC.isRtpDataChannelsSupported = isRtpDataChannelsSupported; - - var isSCTPSupportd = false; - if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 28) { - isSCTPSupportd = true; - } else if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 25) { - isSCTPSupportd = true; - } else if (DetectRTC.browser.isOpera && DetectRTC.browser.version >= 11) { - isSCTPSupportd = true; - } - DetectRTC.isSctpDataChannelsSupported = isSCTPSupportd; - - // --------- - - DetectRTC.isMobileDevice = isMobileDevice; // "isMobileDevice" boolean is defined in "getBrowserInfo.js" - - // ------ - - DetectRTC.isWebSocketsSupported = 'WebSocket' in window && 2 === window.WebSocket.CLOSING; - DetectRTC.isWebSocketsBlocked = 'Checking'; - - if (DetectRTC.isWebSocketsSupported) { - /* CUSTOM CODE */ - var href = window.location.href; - var hostPatt = new RegExp(window.location.host +"/[^/]*"); - var res = hostPatt.exec(href); - var protocol = window.location.protocol.replace("http","ws"); - - var signalingServerPath = protocol + "//" + res + "/contact"; - var websocket = new WebSocket(signalingServerPath) - // var websocket = new WebSocket('wss://echo.websocket.org:443/'); - /* CUSTOM CODE */ - websocket.onopen = function() { - DetectRTC.isWebSocketsBlocked = false; - - if (DetectRTC.loadCallback) { - DetectRTC.loadCallback(); - } - }; - websocket.onerror = function() { - DetectRTC.isWebSocketsBlocked = true; - - if (DetectRTC.loadCallback) { - DetectRTC.loadCallback(); - } - }; - } - - // ------ - var isGetUserMediaSupported = false; - if (navigator.getUserMedia) { - isGetUserMediaSupported = true; - } else if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - isGetUserMediaSupported = true; - } - if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 47 && !isHTTPs) { - DetectRTC.isGetUserMediaSupported = 'Requires HTTPs'; - } - DetectRTC.isGetUserMediaSupported = isGetUserMediaSupported; - - // ----------- - DetectRTC.osName = osName; // "osName" is defined in "detectOSName.js" - - // ---------- - DetectRTC.isCanvasSupportsStreamCapturing = isCanvasSupportsStreamCapturing; - DetectRTC.isVideoSupportsStreamCapturing = isVideoSupportsStreamCapturing; - - // ------ - DetectRTC.DetectLocalIPAddress = DetectLocalIPAddress; - - // ------- - DetectRTC.load = function(callback) { - this.loadCallback = callback; - - checkDeviceSupport(callback); - }; - - DetectRTC.MediaDevices = MediaDevices; - DetectRTC.hasMicrophone = hasMicrophone; - DetectRTC.hasSpeakers = hasSpeakers; - DetectRTC.hasWebcam = hasWebcam; - - // ------ - var isSetSinkIdSupported = false; - if ('setSinkId' in document.createElement('video')) { - isSetSinkIdSupported = true; - } - DetectRTC.isSetSinkIdSupported = isSetSinkIdSupported; - - // ----- - var isRTPSenderReplaceTracksSupported = false; - if (DetectRTC.browser.isFirefox /*&& DetectRTC.browser.version > 39*/ ) { - /*global mozRTCPeerConnection:true */ - if ('getSenders' in mozRTCPeerConnection.prototype) { - isRTPSenderReplaceTracksSupported = true; - } - } else if (DetectRTC.browser.isChrome) { - /*global webkitRTCPeerConnection:true */ - if ('getSenders' in webkitRTCPeerConnection.prototype) { - isRTPSenderReplaceTracksSupported = true; - } - } - DetectRTC.isRTPSenderReplaceTracksSupported = isRTPSenderReplaceTracksSupported; - - //------ - var isRemoteStreamProcessingSupported = false; - if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 38) { - isRemoteStreamProcessingSupported = true; - } - DetectRTC.isRemoteStreamProcessingSupported = isRemoteStreamProcessingSupported; - - //------- - var isApplyConstraintsSupported = false; - - /*global MediaStreamTrack:true */ - if (typeof MediaStreamTrack !== 'undefined' && 'applyConstraints' in MediaStreamTrack.prototype) { - isApplyConstraintsSupported = true; - } - DetectRTC.isApplyConstraintsSupported = isApplyConstraintsSupported; - - //------- - var isMultiMonitorScreenCapturingSupported = false; - if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 43) { - // version 43 merely supports platforms for multi-monitors - // version 44 will support exact multi-monitor selection i.e. you can select any monitor for screen capturing. - isMultiMonitorScreenCapturingSupported = true; - } - DetectRTC.isMultiMonitorScreenCapturingSupported = isMultiMonitorScreenCapturingSupported; - - window.DetectRTC = DetectRTC; - - })(); - - // DetectRTC extender - var screenCallback; - - DetectRTC.screen = { - chromeMediaSource: 'screen', - extensionid: ReservedExtensionID, - getSourceId: function(callback) { - if (!callback) throw '"callback" parameter is mandatory.'; - - // make sure that chrome extension is installed. - if (!!DetectRTC.screen.status) { - onstatus(DetectRTC.screen.status); - } else DetectRTC.screen.getChromeExtensionStatus(onstatus); - - function onstatus(status) { - if (status == 'installed-enabled') { - screenCallback = callback; - window.postMessage('get-sourceId', '*'); - return; - } - - DetectRTC.screen.chromeMediaSource = 'screen'; - callback('No-Response'); // chrome extension isn't available - } - }, - onMessageCallback: function(data) { - if (!(isString(data) || !!data.sourceId)) return; - - log('chrome message', data); - - // "cancel" button is clicked - if (data == 'PermissionDeniedError') { - DetectRTC.screen.chromeMediaSource = 'PermissionDeniedError'; - if (screenCallback) return screenCallback('PermissionDeniedError'); - else throw new Error('PermissionDeniedError'); - } - - // extension notified his presence - if (data == 'rtcmulticonnection-extension-loaded') { - DetectRTC.screen.chromeMediaSource = 'desktop'; - if (DetectRTC.screen.onScreenCapturingExtensionAvailable) { - DetectRTC.screen.onScreenCapturingExtensionAvailable(); - - // make sure that this event isn't fired multiple times - DetectRTC.screen.onScreenCapturingExtensionAvailable = null; - } - } - - // extension shared temp sourceId - if (data.sourceId) { - DetectRTC.screen.sourceId = data.sourceId; - if (screenCallback) screenCallback(DetectRTC.screen.sourceId); - } - }, - getChromeExtensionStatus: function(extensionid, callback) { - function _callback(status) { - DetectRTC.screen.status = status; - callback(status); - } - - if (isFirefox) return _callback('not-chrome'); - - if (arguments.length != 2) { - callback = extensionid; - extensionid = this.extensionid; - } - - var image = document.createElement('img'); - image.src = 'chrome-extension://' + extensionid + '/icon.png'; - image.onload = function() { - DetectRTC.screen.chromeMediaSource = 'screen'; - window.postMessage('are-you-there', '*'); - setTimeout(function() { - if (DetectRTC.screen.chromeMediaSource == 'screen') { - _callback( - DetectRTC.screen.chromeMediaSource == 'desktop' ? 'installed-enabled' : 'installed-disabled' /* if chrome extension isn't permitted for current domain, then it will be installed-disabled all the time even if extension is enabled. */ - ); - } else _callback('installed-enabled'); - }, 2000); - }; - image.onerror = function() { - _callback('not-installed'); - }; - } - }; - - // if IE - if (!window.addEventListener) { - window.addEventListener = function(el, eventName, eventHandler) { - if (!el.attachEvent) return; - el.attachEvent('on' + eventName, eventHandler); - }; - } - - function listenEventHandler(eventName, eventHandler) { - window.removeEventListener(eventName, eventHandler); - window.addEventListener(eventName, eventHandler, false); - } - - window.addEventListener('message', function(event) { - if (event.origin != window.location.origin) { - return; - } - - DetectRTC.screen.onMessageCallback(event.data); - }); - - function setDefaults(connection) { - var DetectRTC = window.DetectRTC || {}; - - // www.RTCMultiConnection.org/docs/userid/ - connection.userid = getRandomString(); - - // www.RTCMultiConnection.org/docs/session/ - connection.session = { - audio: true, - video: true - }; - - // www.RTCMultiConnection.org/docs/maxParticipantsAllowed/ - connection.maxParticipantsAllowed = 256; - - // www.RTCMultiConnection.org/docs/direction/ - // 'many-to-many' / 'one-to-many' / 'one-to-one' / 'one-way' - connection.direction = 'many-to-many'; - - // www.RTCMultiConnection.org/docs/mediaConstraints/ - connection.mediaConstraints = { - mandatory: {}, // kept for backward compatibility - optional: [], // kept for backward compatibility - audio: { - mandatory: {}, - optional: [] - }, - video: { - mandatory: {}, - optional: [] - } - }; - - // www.RTCMultiConnection.org/docs/candidates/ - connection.candidates = { - host: true, - stun: true, - turn: true - }; - - connection.sdpConstraints = {}; - - // as @serhanters proposed in #225 - // it will auto fix "all" renegotiation scenarios - connection.sdpConstraints.mandatory = { - OfferToReceiveAudio: true, - OfferToReceiveVideo: true - }; - - connection.privileges = { - canStopRemoteStream: false, // user can stop remote streams - canMuteRemoteStream: false // user can mute remote streams - }; - - connection.iceProtocols = { - tcp: true, - udp: true - }; - - // www.RTCMultiConnection.org/docs/preferSCTP/ - connection.preferSCTP = isFirefox || chromeVersion >= 32 ? true : false; - connection.chunkInterval = isFirefox || chromeVersion >= 32 ? 100 : 500; // 500ms for RTP and 100ms for SCTP - connection.chunkSize = isFirefox || chromeVersion >= 32 ? 13 * 1000 : 1000; // 1000 chars for RTP and 13000 chars for SCTP - - // www.RTCMultiConnection.org/docs/fakeDataChannels/ - connection.fakeDataChannels = false; - - connection.waitUntilRemoteStreamStartsFlowing = null; // NULL == true - - // auto leave on page unload - connection.leaveOnPageUnload = true; - - // get ICE-servers from XirSys - connection.getExternalIceServers = isChrome; - - // www.RTCMultiConnection.org/docs/UA/ - connection.UA = { - isFirefox: isFirefox, - isChrome: isChrome, - isMobileDevice: isMobileDevice, - version: isChrome ? chromeVersion : firefoxVersion, - isNodeWebkit: isNodeWebkit, - isSafari: isSafari, - isIE: isIE, - isOpera: isOpera - }; - - // file queue: to store previous file objects in memory; - // and stream over newly connected peers - // www.RTCMultiConnection.org/docs/fileQueue/ - connection.fileQueue = {}; - - // this array is aimed to store all renegotiated streams' session-types - connection.renegotiatedSessions = {}; - - // www.RTCMultiConnection.org/docs/channels/ - connection.channels = {}; - - // www.RTCMultiConnection.org/docs/extra/ - connection.extra = {}; - - // www.RTCMultiConnection.org/docs/bandwidth/ - connection.bandwidth = { - screen: 300 // 300kbps (dirty workaround) - }; - - // www.RTCMultiConnection.org/docs/caniuse/ - connection.caniuse = { - RTCPeerConnection: DetectRTC.isWebRTCSupported, - getUserMedia: !!navigator.webkitGetUserMedia || !!navigator.mozGetUserMedia, - AudioContext: DetectRTC.isAudioContextSupported, - - // there is no way to check whether "getUserMedia" flag is enabled or not! - ScreenSharing: DetectRTC.isScreenCapturingSupported, - RtpDataChannels: DetectRTC.isRtpDataChannelsSupported, - SctpDataChannels: DetectRTC.isSctpDataChannelsSupported - }; - - // www.RTCMultiConnection.org/docs/snapshots/ - connection.snapshots = {}; - - // www.WebRTC-Experiment.com/demos/MediaStreamTrack.getSources.html - connection._mediaSources = {}; - - // www.RTCMultiConnection.org/docs/devices/ - connection.devices = {}; - - // www.RTCMultiConnection.org/docs/language/ (to see list of all supported languages) - connection.language = 'en'; - - // www.RTCMultiConnection.org/docs/autoTranslateText/ - connection.autoTranslateText = false; - - // please use your own Google Translate API key - // Google Translate is a paid service. - connection.googKey = 'AIzaSyCgB5hmFY74WYB-EoWkhr9cAGr6TiTHrEE'; - - connection.localStreamids = []; - connection.localStreams = {}; - - // this object stores pre-recorded media streaming uids - // multiple pre-recorded media files can be streamed concurrently. - connection.preRecordedMedias = {}; - - // www.RTCMultiConnection.org/docs/attachStreams/ - connection.attachStreams = []; - - // www.RTCMultiConnection.org/docs/detachStreams/ - connection.detachStreams = []; - - connection.optionalArgument = { - optional: [{ - DtlsSrtpKeyAgreement: true - }, { - googImprovedWifiBwe: true - }, { - googScreencastMinBitrate: 300 - }], - mandatory: {} - }; - - connection.dataChannelDict = {}; - - // www.RTCMultiConnection.org/docs/dontAttachStream/ - connection.dontAttachStream = false; - - // www.RTCMultiConnection.org/docs/dontCaptureUserMedia/ - connection.dontCaptureUserMedia = false; - - // this feature added to keep users privacy and - // make sure HTTPs pages NEVER auto capture users media - // isChrome && location.protocol == 'https:' - connection.preventSSLAutoAllowed = false; - - connection.autoReDialOnFailure = true; - connection.isInitiator = false; - - // access DetectRTC.js features directly! - connection.DetectRTC = DetectRTC; - - // you can falsify it to merge all ICE in SDP and share only SDP! - // such mechanism is useful for SIP/XMPP and XMLHttpRequest signaling - // bug: renegotiation fails if "trickleIce" is false - connection.trickleIce = true; - - // this object stores list of all sessions in current channel - connection.sessionDescriptions = {}; - - // this object stores current user's session-description - // it is set only for initiator - // it is set as soon as "open" method is invoked. - connection.sessionDescription = null; - - // resources used in RTCMultiConnection - connection.resources = { - // CUSTOM CODE // - /* Commenting this block as we do not wasnt external dependencies - * - RecordRTC: 'https://cdn.webrtc-experiment.com/RecordRTC.js', - PreRecordedMediaStreamer: 'https://cdn.webrtc-experiment.com/PreRecordedMediaStreamer.js', - customGetUserMediaBar: 'https://cdn.webrtc-experiment.com/navigator.customGetUserMediaBar.js', - html2canvas: 'https://cdn.webrtc-experiment.com/screenshot.js', - hark: 'https://cdn.webrtc-experiment.com/hark.js', - firebase: 'https://cdn.webrtc-experiment.com/firebase.js', - firebaseio: 'https://webrtc-signaling.firebaseio.com/', - - - - getConnectionStats: 'https://cdn.webrtc-experiment.com/getConnectionStats.js', - FileBufferReader: 'https://cdn.webrtc-experiment.com/FileBufferReader.js' - */ - - // CUSTOM CODE // - - - }; - - // www.RTCMultiConnection.org/docs/body/ - connection.body = document.body || document.documentElement; - connection.screenbody = null;// document.body || document.documentElement; - connection.videobody = null;//document.body || document.documentElement; - - // www.RTCMultiConnection.org/docs/peers/ - connection.peers = {}; - - // www.RTCMultiConnection.org/docs/firebase/ - connection.firebase = 'chat'; - - connection.numberOfSessions = 0; - connection.numberOfConnectedUsers = 0; - - // by default, data-connections will always be getting - // FileBufferReader.js if absent. - connection.enableFileSharing = true; - - // www.RTCMultiConnection.org/docs/autoSaveToDisk/ - // to make sure file-saver dialog is not invoked. - connection.autoSaveToDisk = false; - - connection.processSdp = function(sdp) { - // process sdp here - return sdp; - }; - - // www.RTCMultiConnection.org/docs/onmessage/ - connection.onmessage = function(e) { - log('onmessage', toStr(e)); - }; - - // www.RTCMultiConnection.org/docs/onopen/ - connection.onopen = function(e) { - log('Data connection is opened between you and', e.userid); - }; - - // www.RTCMultiConnection.org/docs/onerror/ - connection.onerror = function(e) { - error(onerror, toStr(e)); - }; - - // www.RTCMultiConnection.org/docs/onclose/ - connection.onclose = function(e) { - warn('onclose', toStr(e)); - - // todo: should we use "stop" or "remove"? - // BTW, it is remote user! - connection.streams.remove({ - userid: e.userid - }); - }; - - var progressHelper = {}; - - // www.RTCMultiConnection.org/docs/onFileStart/ - connection.onFileStart = function(file) { - var div = document.createElement('div'); - div.title = file.name; - div.innerHTML = ' '; - connection.body.insertBefore(div, connection.body.firstChild); - progressHelper[file.uuid] = { - div: div, - progress: div.querySelector('progress'), - label: div.querySelector('label') - }; - progressHelper[file.uuid].progress.max = file.maxChunks; - }; - - // www.RTCMultiConnection.org/docs/onFileProgress/ - connection.onFileProgress = function(chunk) { - var helper = progressHelper[chunk.uuid]; - if (!helper) return; - helper.progress.value = chunk.currentPosition || chunk.maxChunks || helper.progress.max; - updateLabel(helper.progress, helper.label); - }; - - // www.RTCMultiConnection.org/docs/onFileEnd/ - connection.onFileEnd = function(file) { - if (progressHelper[file.uuid]) progressHelper[file.uuid].div.innerHTML = '' + file.name + ''; - - // for backward compatibility - if (connection.onFileSent || connection.onFileReceived) { - if (connection.onFileSent) connection.onFileSent(file, file.uuid); - if (connection.onFileReceived) connection.onFileReceived(file.name, file); - } - }; - - function updateLabel(progress, label) { - if (progress.position == -1) return; - var position = +progress.position.toFixed(2).split('.')[1] || 100; - label.innerHTML = position + '%'; - } - - // www.RTCMultiConnection.org/docs/onstream/ - connection.onstream = function(e) { - // CUSTOM CODE // - - if(e.isVideo || e.isAudio) - { - var videoTag = e.mediaElement; - var videoType = e.type; - var parentDiv = connection.videobody; - - if(videoType == "local") - { - videoTag.style.top = "auto"; - videoTag.style.position = "absolute"; - //videoTag.style.left = (parentDiv.offsetWidth - 160) + "px"; - videoTag.style.height = "150px"; - videoTag.style.width = "150px"; - videoTag.style.zIndex = 1; - - } - else if(videoType == "remote") - { - videoTag.style.top = "auto"; - videoTag.style.position = "absolute"; - videoTag.style.zIndex = -1; - } - - parentDiv.appendChild(videoTag); - } - else if(e.isScreen) - { - var screenTag = e.mediaElement; - var screenType = e.type; - var parentDiv = connection.screenbody; - - if(screenType == "local") - { - // no need to display this because the person sharing his/her screen doesn't have to see whats being shared - // enabled for demo purposes - parentDiv.appendChild(screenTag); - } - else if(screenType == "remote") - { - parentDiv.appendChild(screenTag); - } - - - } - - else - connection.body.insertBefore(e.mediaElement, connection.body.firstChild); - - // CUSTOM CODE // - }; - - // www.RTCMultiConnection.org/docs/onStreamEndedHandler/ - connection.onstreamended = function(e) { - log('onStreamEndedHandler:', e); - - if (!e.mediaElement) { - return warn('Event.mediaElement is undefined', e); - } - if (!e.mediaElement.parentNode) { - e.mediaElement = document.getElementById(e.streamid); - - if (!e.mediaElement) { - return warn('Event.mediaElement is undefined', e); - } - - if (!e.mediaElement.parentNode) { - return warn('Event.mediElement.parentNode is null.', e); - } - } - - e.mediaElement.parentNode.removeChild(e.mediaElement); - }; - - // todo: need to write documentation link - connection.onSessionClosed = function(session) { - if (session.isEjected) { - warn(session.userid, 'ejected you.'); - } else warn('Session has been closed.', session); - }; - - // www.RTCMultiConnection.org/docs/onmute/ - connection.onmute = function(e) { - if (e.isVideo && e.mediaElement) { - e.mediaElement.pause(); - e.mediaElement.setAttribute('poster', e.snapshot || connection.resources.muted); - } - if (e.isAudio && e.mediaElement) { - e.mediaElement.muted = true; - } - }; - - // www.RTCMultiConnection.org/docs/onunmute/ - connection.onunmute = function(e) { - if (e.isVideo && e.mediaElement) { - e.mediaElement.play(); - e.mediaElement.removeAttribute('poster'); - } - if (e.isAudio && e.mediaElement) { - e.mediaElement.muted = false; - } - }; - - // www.RTCMultiConnection.org/docs/onleave/ - connection.onleave = function(e) { - log('onleave', toStr(e)); - }; - - connection.token = getRandomString; - - connection.peers[connection.userid] = { - drop: function() { - connection.drop(); - }, - renegotiate: function() {}, - addStream: function() {}, - hold: function() {}, - unhold: function() {}, - changeBandwidth: function() {}, - sharePartOfScreen: function() {} - }; - - connection._skip = ['stop', 'mute', 'unmute', '_private', '_selectStreams', 'selectFirst', 'selectAll', 'remove']; - - // www.RTCMultiConnection.org/docs/streams/ - connection.streams = { - mute: function(session) { - this._private(session, true); - }, - unmute: function(session) { - this._private(session, false); - }, - _private: function(session, enabled) { - if (session && !isString(session)) { - for (var stream in this) { - if (connection._skip.indexOf(stream) == -1) { - _muteOrUnMute(this[stream], session, enabled); - } - } - - function _muteOrUnMute(stream, session, isMute) { - if (session.local && stream.type != 'local') return; - if (session.remote && stream.type != 'remote') return; - - if (session.isScreen && !stream.isScreen) return; - if (session.isAudio && !stream.isAudio) return; - if (session.isVideo && !stream.isVideo) return; - - if (isMute) stream.mute(session); - else stream.unmute(session); - } - return; - } - - // implementation from #68 - for (var stream in this) { - if (connection._skip.indexOf(stream) == -1) { - this[stream]._private(session, enabled); - } - } - }, - stop: function(type) { - var _stream; - for (var stream in this) { - if (connection._skip.indexOf(stream) == -1) { - _stream = this[stream]; - - if (!type) _stream.stop(); - - else if (isString(type)) { - // connection.streams.stop('screen'); - var config = {}; - config[type] = true; - _stopStream(_stream, config); - } else _stopStream(_stream, type); - } - } - - function _stopStream(_stream, config) { - // connection.streams.stop({ remote: true, userid: 'remote-userid' }); - if (config.userid && _stream.userid != config.userid) return; - - if (config.local && _stream.type != 'local') return; - if (config.remote && _stream.type != 'remote') return; - - if (config.screen && !!_stream.isScreen) { - _stream.stop(); - } - - if (config.audio && !!_stream.isAudio) { - _stream.stop(); - } - - if (config.video && !!_stream.isVideo) { - _stream.stop(); - } - - // connection.streams.stop('local'); - if (!config.audio && !config.video && !config.screen) { - _stream.stop(); - } - } - }, - remove: function(type) { - var _stream; - for (var stream in this) { - if (connection._skip.indexOf(stream) == -1) { - _stream = this[stream]; - - if (!type) _stopAndRemoveStream(_stream, { - local: true, - remote: true - }); - - else if (isString(type)) { - // connection.streams.stop('screen'); - var config = {}; - config[type] = true; - _stopAndRemoveStream(_stream, config); - } else _stopAndRemoveStream(_stream, type); - } - } - - function _stopAndRemoveStream(_stream, config) { - // connection.streams.remove({ remote: true, userid: 'remote-userid' }); - if (config.userid && _stream.userid != config.userid) return; - - if (config.local && _stream.type != 'local') return; - if (config.remote && _stream.type != 'remote') return; - - if (config.screen && !!_stream.isScreen) { - endStream(_stream); - } - - if (config.audio && !!_stream.isAudio) { - endStream(_stream); - } - - if (config.video && !!_stream.isVideo) { - endStream(_stream); - } - - // connection.streams.remove('local'); - if (!config.audio && !config.video && !config.screen) { - endStream(_stream); - } - } - - function endStream(_stream) { - onStreamEndedHandler(_stream, connection); - delete connection.streams[_stream.streamid]; - } - }, - selectFirst: function(args) { - return this._selectStreams(args, false); - }, - selectAll: function(args) { - return this._selectStreams(args, true); - }, - _selectStreams: function(args, all) { - if (!args || isString(args) || isEmpty(args)) throw 'Invalid arguments.'; - - // if userid is used then both local/remote shouldn't be auto-set - if (isNull(args.local) && isNull(args.remote) && isNull(args.userid)) { - args.local = args.remote = true; - } - - if (!args.isAudio && !args.isVideo && !args.isScreen) { - args.isAudio = args.isVideo = args.isScreen = true; - } - - var selectedStreams = []; - for (var stream in this) { - if (connection._skip.indexOf(stream) == -1 && (stream = this[stream]) && ((args.local && stream.type == 'local') || (args.remote && stream.type == 'remote') || (args.userid && stream.userid == args.userid))) { - if (args.isVideo && stream.isVideo) { - selectedStreams.push(stream); - } - - if (args.isAudio && stream.isAudio) { - selectedStreams.push(stream); - } - - if (args.isScreen && stream.isScreen) { - selectedStreams.push(stream); - } - } - } - - return !!all ? selectedStreams : selectedStreams[0]; - } - }; - - var iceServers = []; - - // CUSTOM CODE // - // these servers are provided by research - iceServers.push({ - url: '' /*TODO To test this WebRTC with some open stun and turn test servers*/ - }); - - iceServers.push({ - url: 'turn:207.140.168.120:3478', - credential: 'xxx', - username: 'xxx' - }); - - iceServers.push({ - url: 'turn:207.140.168.120:443?transport=tcp', - credential: 'harmfulmustard', - username: 'ambient' - }); - - /* CHANGED: Fusion: These are servers for testing purposes - - iceServers.push({ - url: 'stun:stun.l.google.com:19302' - }); - - iceServers.push({ - url: 'stun:stun.anyfirewall.com:3478' - }); - - iceServers.push({ - url: 'turn:turn.bistri.com:80', - credential: 'homeo', - username: 'homeo' - }); - - iceServers.push({ - url: 'turn:turn.anyfirewall.com:443?transport=tcp', - credential: 'webrtc', - username: 'webrtc' - }); - - */ - // CUSTOM CODE // - connection.iceServers = iceServers; - - connection.rtcConfiguration = { - iceServers: null, - iceTransports: 'all', // none || relay || all - ref: http://goo.gl/40I39K - peerIdentity: false - }; - - // www.RTCMultiConnection.org/docs/media/ - connection.media = { - min: function(width, height) { - if (!connection.mediaConstraints.video) return; - - if (!connection.mediaConstraints.video.mandatory) { - connection.mediaConstraints.video.mandatory = {}; - } - connection.mediaConstraints.video.mandatory.minWidth = width; - connection.mediaConstraints.video.mandatory.minHeight = height; - }, - max: function(width, height) { - if (!connection.mediaConstraints.video) return; - - if (!connection.mediaConstraints.video.mandatory) { - connection.mediaConstraints.video.mandatory = {}; - } - - connection.mediaConstraints.video.mandatory.maxWidth = width; - connection.mediaConstraints.video.mandatory.maxHeight = height; - } - }; - - connection._getStream = function(event) { - var resultingObject = merge({ - sockets: event.socket ? [event.socket] : [] - }, event); - - resultingObject.stop = function() { - var self = this; - - self.sockets.forEach(function(socket) { - if (self.type == 'local') { - socket.send({ - streamid: self.streamid, - stopped: true - }); - } - - if (self.type == 'remote') { - socket.send({ - promptStreamStop: true, - streamid: self.streamid - }); - } - }); - - if (self.type == 'remote') return; - - var stream = self.stream; - if (stream) self.rtcMultiConnection.stopMediaStream(stream); - }; - - resultingObject.mute = function(session) { - this.muted = true; - this._private(session, true); - }; - - resultingObject.unmute = function(session) { - this.muted = false; - this._private(session, false); - }; - - function muteOrUnmuteLocally(session, isPause, mediaElement) { - if (!mediaElement) return; - var lastPauseState = mediaElement.onpause; - var lastPlayState = mediaElement.onplay; - mediaElement.onpause = mediaElement.onplay = function() {}; - - if (isPause) mediaElement.pause(); - else mediaElement.play(); - - mediaElement.onpause = lastPauseState; - mediaElement.onplay = lastPlayState; - } - - resultingObject._private = function(session, enabled) { - if (session && !isNull(session.sync) && session.sync == false) { - muteOrUnmuteLocally(session, enabled, this.mediaElement); - return; - } - - muteOrUnmute({ - root: this, - session: session, - enabled: enabled, - stream: this.stream - }); - }; - - resultingObject.startRecording = function(session) { - var self = this; - - if (!session) { - session = { - audio: true, - video: true - }; - } - - if (isString(session)) { - session = { - audio: session == 'audio', - video: session == 'video' - }; - } - - if (!window.RecordRTC) { - return loadScript(self.rtcMultiConnection.resources.RecordRTC, function() { - self.startRecording(session); - }); - } - - log('started recording session', session); - - self.videoRecorder = self.audioRecorder = null; - - if (isFirefox) { - // firefox supports both audio/video recording in single webm file - if (session.video) { - self.videoRecorder = RecordRTC(self.stream, { - type: 'video' - }); - } else if (session.audio) { - self.audioRecorder = RecordRTC(self.stream, { - type: 'audio' - }); - } - } else if (isChrome) { - // chrome supports recording in two separate files: WAV and WebM - if (session.video) { - self.videoRecorder = RecordRTC(self.stream, { - type: 'video' - }); - } - - if (session.audio) { - self.audioRecorder = RecordRTC(self.stream, { - type: 'audio' - }); - } - } - - if (self.audioRecorder) { - self.audioRecorder.startRecording(); - } - - if (self.videoRecorder) self.videoRecorder.startRecording(); - }; - - resultingObject.stopRecording = function(callback, session) { - if (!session) { - session = { - audio: true, - video: true - }; - } - - if (isString(session)) { - session = { - audio: session == 'audio', - video: session == 'video' - }; - } - - log('stopped recording session', session); - - var self = this; - - if (session.audio && self.audioRecorder) { - self.audioRecorder.stopRecording(function() { - if (session.video && self.videoRecorder) { - self.videoRecorder.stopRecording(function() { - callback({ - audio: self.audioRecorder.getBlob(), - video: self.videoRecorder.getBlob() - }); - }); - } else callback({ - audio: self.audioRecorder.getBlob() - }); - }); - } else if (session.video && self.videoRecorder) { - self.videoRecorder.stopRecording(function() { - callback({ - video: self.videoRecorder.getBlob() - }); - }); - } - }; - - resultingObject.takeSnapshot = function(callback) { - takeSnapshot({ - mediaElement: this.mediaElement, - userid: this.userid, - connection: connection, - callback: callback - }); - }; - - // redundant: kept only for backward compatibility - resultingObject.streamObject = resultingObject; - - return resultingObject; - }; - - // new RTCMultiConnection().set({properties}).connect() - connection.set = function(properties) { - for (var property in properties) { - this[property] = properties[property]; - } - return this; - }; - - // www.RTCMultiConnection.org/docs/onMediaError/ - connection.onMediaError = function(event) { - error('name', event.name); - error('constraintName', toStr(event.constraintName)); - error('message', event.message); - error('original session', event.session); - }; - - // www.RTCMultiConnection.org/docs/takeSnapshot/ - connection.takeSnapshot = function(userid, callback) { - takeSnapshot({ - userid: userid, - connection: connection, - callback: callback - }); - }; - - connection.saveToDisk = function(blob, fileName) { - if (blob.size && blob.type) FileSaver.SaveToDisk(URL.createObjectURL(blob), fileName || blob.name || blob.type.replace('/', '-') + blob.type.split('/')[1]); - else FileSaver.SaveToDisk(blob, fileName); - }; - - // www.RTCMultiConnection.org/docs/selectDevices/ - connection.selectDevices = function(device1, device2) { - if (device1) select(this.devices[device1]); - if (device2) select(this.devices[device2]); - - function select(device) { - if (!device) return; - connection._mediaSources[device.kind] = device.id; - } - }; - - // www.RTCMultiConnection.org/docs/getDevices/ - connection.getDevices = function(callback) { - // if, not yet fetched. - if (!DetectRTC.MediaDevices.length) { - return setTimeout(function() { - connection.getDevices(callback); - }, 1000); - } - - // loop over all audio/video input/output devices - DetectRTC.MediaDevices.forEach(function(device) { - connection.devices[device.deviceId] = device; - }); - - if (callback) callback(connection.devices); - }; - - connection.getMediaDevices = connection.enumerateDevices = function(callback) { - if (!callback) throw 'callback is mandatory.'; - connection.getDevices(function() { - callback(connection.DetectRTC.MediaDevices); - }); - }; - - // www.RTCMultiConnection.org/docs/onCustomMessage/ - connection.onCustomMessage = function(message) { - log('Custom message', message); - }; - - // www.RTCMultiConnection.org/docs/ondrop/ - connection.ondrop = function(droppedBy) { - log('Media connection is dropped by ' + droppedBy); - }; - - // www.RTCMultiConnection.org/docs/drop/ - connection.drop = function(config) { - config = config || {}; - connection.attachStreams = []; - - // "drop" should detach all local streams - for (var stream in connection.streams) { - if (connection._skip.indexOf(stream) == -1) { - stream = connection.streams[stream]; - if (stream.type == 'local') { - connection.detachStreams.push(stream.streamid); - onStreamEndedHandler(stream, connection); - } else onStreamEndedHandler(stream, connection); - } - } - - // www.RTCMultiConnection.org/docs/sendCustomMessage/ - connection.sendCustomMessage({ - drop: true, - dontRenegotiate: isNull(config.renegotiate) ? true : config.renegotiate - }); - }; - - // www.RTCMultiConnection.org/docs/Translator/ - connection.Translator = { - TranslateText: function(text, callback) { - // if(location.protocol === 'https:') return callback(text); - - var newScript = document.createElement('script'); - newScript.type = 'text/javascript'; - - var sourceText = encodeURIComponent(text); // escape - - var randomNumber = 'method' + connection.token(); - window[randomNumber] = function(response) { - if (response.data && response.data.translations[0] && callback) { - callback(response.data.translations[0].translatedText); - } - - if (response.error && response.error.message == 'Daily Limit Exceeded') { - warn('Text translation failed. Error message: "Daily Limit Exceeded."'); - - // returning original text - callback(text); - } - }; - - var source = 'https://www.googleapis.com/language/translate/v2?key=' + connection.googKey + '&target=' + (connection.language || 'en-US') + '&callback=window.' + randomNumber + '&q=' + sourceText; - newScript.src = source; - document.getElementsByTagName('head')[0].appendChild(newScript); - } - }; - - // you can easily override it by setting it NULL! - connection.setDefaultEventsForMediaElement = function(mediaElement, streamid) { - mediaElement.onpause = function() { - if (connection.streams[streamid] && !connection.streams[streamid].muted) { - connection.streams[streamid].mute(); - } - }; - - // todo: need to make sure that "onplay" EVENT doesn't play self-voice! - mediaElement.onplay = function() { - if (connection.streams[streamid] && connection.streams[streamid].muted) { - connection.streams[streamid].unmute(); - } - }; - - var volumeChangeEventFired = false; - mediaElement.onvolumechange = function() { - if (!volumeChangeEventFired) { - volumeChangeEventFired = true; - connection.streams[streamid] && setTimeout(function() { - var root = connection.streams[streamid]; - connection.streams[streamid].sockets.forEach(function(socket) { - socket.send({ - streamid: root.streamid, - isVolumeChanged: true, - volume: mediaElement.volume - }); - }); - volumeChangeEventFired = false; - }, 2000); - } - }; - }; - - // www.RTCMultiConnection.org/docs/onMediaFile/ - connection.onMediaFile = function(e) { - log('onMediaFile', e); - connection.body.appendChild(e.mediaElement); - }; - - // www.RTCMultiConnection.org/docs/shareMediaFile/ - // this method handles pre-recorded media streaming - connection.shareMediaFile = function(file, video, streamerid) { - streamerid = streamerid || connection.token(); - - if (!PreRecordedMediaStreamer) { - loadScript(connection.resources.PreRecordedMediaStreamer, function() { - connection.shareMediaFile(file, video, streamerid); - }); - return streamerid; - } - - return PreRecordedMediaStreamer.shareMediaFile({ - file: file, - video: video, - streamerid: streamerid, - connection: connection - }); - }; - - // www.RTCMultiConnection.org/docs/onpartofscreen/ - connection.onpartofscreen = function(e) { - var image = document.createElement('img'); - image.src = e.screenshot; - connection.body.appendChild(image); - }; - - connection.skipLogs = function() { - log = error = warn = function() {}; - }; - - // www.RTCMultiConnection.org/docs/hold/ - connection.hold = function(mLine) { - for (var peer in connection.peers) { - connection.peers[peer].hold(mLine); - } - }; - - // www.RTCMultiConnection.org/docs/onhold/ - connection.onhold = function(track) { - log('onhold', track); - - if (track.kind != 'audio') { - track.mediaElement.pause(); - track.mediaElement.setAttribute('poster', track.screenshot || connection.resources.muted); - } - if (track.kind == 'audio') { - track.mediaElement.muted = true; - } - }; - - // www.RTCMultiConnection.org/docs/unhold/ - connection.unhold = function(mLine) { - for (var peer in connection.peers) { - connection.peers[peer].unhold(mLine); - } - }; - - // www.RTCMultiConnection.org/docs/onunhold/ - connection.onunhold = function(track) { - log('onunhold', track); - - if (track.kind != 'audio') { - track.mediaElement.play(); - track.mediaElement.removeAttribute('poster'); - } - if (track.kind != 'audio') { - track.mediaElement.muted = false; - } - }; - - connection.sharePartOfScreen = function(args) { - var lastScreenshot = ''; - - function partOfScreenCapturer() { - // if stopped - if (connection.partOfScreen && !connection.partOfScreen.sharing) { - return; - } - - capturePartOfScreen({ - element: args.element, - connection: connection, - callback: function(screenshot) { - // don't share repeated content - if (screenshot != lastScreenshot) { - lastScreenshot = screenshot; - - for (var channel in connection.channels) { - connection.channels[channel].send({ - screenshot: screenshot, - isPartOfScreen: true - }); - } - } - - // "once" can be used to share single screenshot - !args.once && setTimeout(partOfScreenCapturer, args.interval || 200); - } - }); - } - - partOfScreenCapturer(); - - connection.partOfScreen = merge({ - sharing: true - }, args); - }; - - connection.pausePartOfScreenSharing = function() { - for (var peer in connection.peers) { - connection.peers[peer].pausePartOfScreenSharing = true; - } - - if (connection.partOfScreen) { - connection.partOfScreen.sharing = false; - } - }; - - connection.resumePartOfScreenSharing = function() { - for (var peer in connection.peers) { - connection.peers[peer].pausePartOfScreenSharing = false; - } - - if (connection.partOfScreen) { - connection.partOfScreen.sharing = true; - } - }; - - connection.stopPartOfScreenSharing = function() { - for (var peer in connection.peers) { - connection.peers[peer].stopPartOfScreenSharing = true; - } - - if (connection.partOfScreen) { - connection.partOfScreen.sharing = false; - } - }; - - connection.takeScreenshot = function(element, callback) { - if (!element || !callback) throw 'Invalid number of arguments.'; - - if (!window.html2canvas) { - return loadScript(connection.resources.html2canvas, function() { - connection.takeScreenshot(element); - }); - } - - if (isString(element)) { - element = document.querySelector(element); - if (!element) element = document.getElementById(element); - } - if (!element) throw 'HTML Element is inaccessible!'; - - // html2canvas.js is used to take screenshots - html2canvas(element, { - onrendered: function(canvas) { - callback(canvas.toDataURL()); - } - }); - }; - - // this event is fired when RTCMultiConnection detects that chrome extension - // for screen capturing is installed and available - connection.onScreenCapturingExtensionAvailable = function() { - log('It seems that screen capturing extension is installed and available on your system!'); - }; - - if (!isPluginRTC && DetectRTC.screen.onScreenCapturingExtensionAvailable) { - DetectRTC.screen.onScreenCapturingExtensionAvailable = function() { - connection.onScreenCapturingExtensionAvailable(); - }; - } - - connection.changeBandwidth = function(bandwidth) { - for (var peer in connection.peers) { - connection.peers[peer].changeBandwidth(bandwidth); - } - }; - - connection.convertToAudioStream = function(mediaStream) { - convertToAudioStream(mediaStream); - }; - - connection.onstatechange = function(state) { - log('on:state:change (' + state.userid + '):', state.name + ':', state.reason || ''); - }; - - connection.onfailed = function(event) { - if (!event.peer.numOfRetries) event.peer.numOfRetries = 0; - event.peer.numOfRetries++; - - error('ICE connectivity check is failed. Renegotiating peer connection.'); - event.peer.numOfRetries < 2 && event.peer.renegotiate(); - - if (event.peer.numOfRetries >= 2) event.peer.numOfRetries = 0; - }; - - connection.onconnected = function(event) { - // event.peer.addStream || event.peer.getConnectionStats - log('Peer connection has been established between you and', event.userid); - }; - - connection.ondisconnected = function(event) { - error('Peer connection seems has been disconnected between you and', event.userid); - - if (isEmpty(connection.channels)) return; - if (!connection.channels[event.userid]) return; - - // use WebRTC data channels to detect user's presence - connection.channels[event.userid].send({ - checkingPresence: true - }); - - // wait 5 seconds, if target peer didn't response, simply disconnect - setTimeout(function() { - // iceConnectionState == 'disconnected' occurred out of low-bandwidth - // or internet connectivity issues - if (connection.peers[event.userid].connected) { - delete connection.peers[event.userid].connected; - return; - } - - // to make sure this user's all remote streams are removed. - connection.streams.remove({ - remote: true, - userid: event.userid - }); - - connection.remove(event.userid); - }, 3000); - }; - - connection.onstreamid = function(event) { - // event.isScreen || event.isVideo || event.isAudio - log('got remote streamid', event.streamid, 'from', event.userid); - }; - - connection.stopMediaStream = function(mediaStream) { - if (!mediaStream) throw 'MediaStream argument is mandatory.'; - - if (connection.keepStreamsOpened) { - if (mediaStream.onended) mediaStream.onended(); - return; - } - - // remove stream from "localStreams" object - // when native-stop method invoked. - if (connection.localStreams[mediaStream.streamid]) { - delete connection.localStreams[mediaStream.streamid]; - } - - if (isFirefox) { - // Firefox don't yet support onended for any stream (remote/local) - if (mediaStream.onended) mediaStream.onended(); - } - - // Latest firefox does support mediaStream.getAudioTrack but doesn't support stop on MediaStreamTrack - var checkForMediaStreamTrackStop = Boolean( - (mediaStream.getAudioTracks || mediaStream.getVideoTracks) && ( - (mediaStream.getAudioTracks()[0] && !mediaStream.getAudioTracks()[0].stop) || - (mediaStream.getVideoTracks()[0] && !mediaStream.getVideoTracks()[0].stop) - ) - ); - - if (!mediaStream.getAudioTracks || checkForMediaStreamTrackStop) { - if (mediaStream.stop) { - mediaStream.stop(); - } - return; - } - - if (mediaStream.getAudioTracks().length && mediaStream.getAudioTracks()[0].stop) { - mediaStream.getAudioTracks().forEach(function(track) { - track.stop(); - }); - } - - if (mediaStream.getVideoTracks().length && mediaStream.getVideoTracks()[0].stop) { - mediaStream.getVideoTracks().forEach(function(track) { - track.stop(); - }); - } - }; - - connection.changeBandwidth = function(bandwidth) { - if (!bandwidth || isString(bandwidth) || isEmpty(bandwidth)) { - throw 'Invalid "bandwidth" arguments.'; - } - - forEach(connection.peers, function(peer) { - peer.peer.bandwidth = bandwidth; - }); - - connection.renegotiate(); - }; - - // www.RTCMultiConnection.org/docs/openSignalingChannel/ - // http://goo.gl/uvoIcZ - - // CUSTOM CODE - var href = window.location.href; - var hostPatt = new RegExp(window.location.host +"/[^/]*"); - var res = hostPatt.exec(href); - var protocol = window.location.protocol.replace("http","ws"); - - var signalingServerPath = protocol + "//" + res + "/webrtc"; - var SIGNALING_SERVER = signalingServerPath; //"ws://localhost:80/quantum/webrtc"; //"wss://localhost:80/quantum/webrtc"; --> ws for http and wss for https - - connection.openSignalingChannel = function(config) { - - - config.channel = config.channel || this.channel; - var websocket = new WebSocket(SIGNALING_SERVER); - websocket.channel = config.channel; - websocket.onopen = function() { - websocket.push(JSON.stringify({ - open: true, - channel: config.channel - })); - if (config.callback) - config.callback(websocket); - }; - websocket.onmessage = function(event) { - config.onmessage(JSON.parse(event.data)); - }; - websocket.push = websocket.send; - websocket.send = function(data) { - websocket.push(JSON.stringify({ - data: data, - channel: config.channel - })); - }; - - /* - // make sure firebase.js is loaded - if (!window.Firebase) { - return loadScript(connection.resources.firebase, function() { - connection.openSignalingChannel(config); - }); - } - - var channel = config.channel || connection.channel; - - if (connection.firebase) { - // for custom firebase instances - connection.resources.firebaseio = connection.resources.firebaseio.replace('//chat.', '//' + connection.firebase + '.'); - } - - var firebase = new Firebase(connection.resources.firebaseio + channel); - firebase.channel = channel; - firebase.on('child_added', function(data) { - config.onmessage(data.val()); - }); - - firebase.send = function(data) { - // a quick dirty workaround to make sure firebase - // shouldn't fail for NULL values. - for (var prop in data) { - if (isNull(data[prop]) || typeof data[prop] == 'function') { - data[prop] = false; - } - } - - this.push(data); - }; - - if (!connection.socket) - connection.socket = firebase; - - firebase.onDisconnect().remove(); - - setTimeout(function() { - config.callback(firebase); - }, 1); - - */ - // CUSTOM CODE // - - }; - - connection.Plugin = Plugin; - } - -})(); \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/fusion-sunny.css b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/fusion-sunny.css deleted file mode 100644 index c8306156..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/fusion-sunny.css +++ /dev/null @@ -1,362 +0,0 @@ - input, textarea, select, div { - font-family: Arial; - font-size: 11px; - font-weight: normal; - } - - form { - margin-top: 5px; - } - - - .applicationWindow { border-width: 0px 0px 1px 0px; - border-style: solid; - border-color: #959595; - box-shadow: inset 0 0 10px #000000; - margin-top: 10px; - margin-bottom: 10px; - margin-left: 10px; - margin-right: 10px; - } - - .feedbackMessage { width: 99%; - font-family: Arial; - font-size: 11px; - color: #1f1f1f; - padding: 3px; - border: 1px #eeb420 solid; - margin: 3px; - background: #fff9e5; - } - - .menubar { - border-width: 0px 0px 0px 1px; border-style: solid; border-color: #959595; - } - - .footer { - /*clear: both;*/ - border-width: 0px 1px 0px 1px; border-style: solid; border-color: #959595; - font-family: Verdana,Arial,Helvetica, sans-serif; - font-size: 9px; - padding: 10px 10px 30px 10px; - background: white; - } - - .pageTitle { - font-family: Arial; - font-size: 18px; - font-weight: bold; - margin-top: 5px; - } - - .content { - border-width: 0px 1px 0px 1px; - border-style: solid; - border-color: #959595; - font-family: Arial; - font-size: 11px; - padding: 5px; - background: white; - /*height: 600px;*/ - } - - .popupContent { - font-family: Arial; - font-size: 11px; - padding: 3px; - } - - .logo { - border-width: 0px 1px 0px 1px; - border-style: solid; - border-color: #959595; - text-align: right; - } - - .sep { - border: 1px solid black - } - - .attLogo { /*position: relative;*/ - float:left; - padding-top: 25px; - padding-left: 25px; - } - - .applicationLogo { float:right; - padding-top: 25px; - padding-right: 25px; - } - - .applinkWhite { font-family: Arial; - font-size: 13px; - font-weight: 900; - color: #FFFFFF; - text-decoration: none; } - - .terms { font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 9px; - } - - .broadcastMessage { color: red; } - .broadcastMessageList { color: red; } - - .button { - margin: 5px 1px 5px 1px; - padding: 3px; } - - .toolbarbutton:hover { - color:#005491; - } - - .headerText { font-family: Arial; - font-size: 15px; - font-weight: 700; - color: #000000; } - - .headerBackground { background: #336699; } - - .errorMessageText { font-family: Arial; - font-size: 11px; - font-weight: bold; - color: red; } - - - .normalText { font-family: Arial; - font-size: 11px; - color: #000000; } - - .normalTextRed { font-family: Arial; - font-size: 11px; - color: red; } - - - .smallNormalText { font-family: Arial; - font-size: 9px; - color: #000000; } - - .tableBorder { border:1px outset teal } - - .validationError { background: #b9eaff; } - - .templatebody { - background: url(../images/body_graphic.jpg) repeat-x; - /*margin: 40px 80px 40px 80px;*/ - } - - /*--------------------- General Content ------------------------------------*/ - - .relative { - position:relative; - } - - .clear{ - clear:both; - } - - .left { - float: left; - } - - .leftCentered{ - float: left; - text-align: center; - } - - .right { - float: right; - } - - .rightAligned{ - text-align: right; - } - - .centered { - text-align: center; - align: center; - } - - - .noWrap{ - white-space:nowrap; - } - - .disabled { - color:gray; - cursor:hand; - } - - /*--------------------- Tab styles -------------------------------------*/ - - .current { - font-weight: bold; - border-width: 1px 1px 1px 1px; - border-color: silver; - border-style: solid; - } - - .subTab { - font-weight:bold; - font-family: Arial; - font-size: 11px; - color: #0F3B82; - } - - - /*--------------------- Grid styles ------------------------------------*/ - - /* Grid navigation and header styles */ - .gridFilterLabel {font-size: 7pt; - font-align: justify; - font-weight: bold; - display: block;} - - .gridFilterText {height: 17px; - font-size: 8pt; - width: 60%; - font-align: justify;} - - .gridNavigationBar { font-family:Arial,Verdana; - font-size:11px; - font-weight:normal; - color:#000; - margin: 0px; - width: 100%; - vertical-align: middle; - } - - .gridNavigationBar .navLinks { float: left; - margin-right:15px; - padding-top: 2px; - height: 19px; - line-height: 19px; - } - - .gridNavigationBar .pageControls { float: left; - margin-right: 15px; - height: 19px; - line-height: 19px; - } - - .gridNavigationBar .pageControls input { font-size: 8pt; - height: 17px; - vertical-align: middle; - } - - .gridNavigationBar .pageInfo { float: right; - vertical-align: middle; - height: 19px; - line-height: 19px; - } - - .gridNavigationBar .pageInfo input { font-size: 8pt; - height: 17px; - vertical-align: middle; - } - - - .gridNavigationBar span { padding: 3px; } - - .gridNavigationBar a { - text-decoration:underline; - color:#000; - font-weight:normal; - } - - .gridNavigationBar img { vertical-align: middle; } - - .gridBulkUpdateRow { - height: 35px; - line-height: 35px; - } - - .gridBulkUpdateRow input { - vertical-align: middle; - } - - - /* dummy class used to lock the form elements of a grid - ex. bulk transaction processing */ - .alwaysEnabled {} - - .hidden { - display: none; - } - - .selectedPage { - background-color:#C4DFFB; - color: white; - border-style: solid; - border-width: 1px; - border-color: gray; - padding-left: 3px; - padding-right: 3px; - vertical-align: middle; - } - - .selectedRow{ - /*background-color:#C4DFFB;*/ - } - - /* Action Item styles */ - .actionList { - margin-left: -20px; - margin-right: -10px; - padding-left: 5px; - } - - .actionList li { - float:left; - padding-left: 3px; - padding-right: 3px; - } - - .actionList li a { - text-decoration:none; - color:#000; - } - - /* Filter Operator List styles */ - - .filterList { - margin: 0px; - } - - .filterList li { - list-style-type: none; - padding:3px 3px 3px 2px; - cursor:hand; - font-size:11px; - } - - .filterList li:hover { - background: #404040; - } - - .filterList li a { - color: #000; - text-decoration: none; - } - - .filterList li:hover a { - color: white; - } - - .filterList li a:hover { - text-decoration: none; - color: white; - } - - .filterListItem a { - text-decoration:none; - padding:3px 2px 3px 2px; - } - - - /*---------------------- Customized ZK Styles ------------------------------*/ - - .z-datebox input, .z-timebox input { - font-family: Arial; - font-size: 11px; - height: 15px; - margin-top:1px; - } diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/workflows/workflows.css b/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/workflows/workflows.css deleted file mode 100644 index b9d0146c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusion/styles/workflows/workflows.css +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -.scrolling-table{ - width: 1200px; -} -.scrolling-table .scroll-viewport { - height: 200px !important; - width: 99.5% !important; - background-color:white; -} - -.scrolling-table .scroll-overview{ - margin-top:-14px !important; -} - -.scrolling-table .scroll-viewport:hover{ - background-color:white; -} - -.scrolling-table #att-scroll-table-content{ - height:200px; - position: absolute !important; - width:700px; - padding-left: 0px; - padding-top: 0px; - padding-bottom: 0px; - padding-right:5px; -} - -.workflow-popup-body{ - position: relative; - padding: 30px; -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/drools-list-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/drools-list-controller.js deleted file mode 100644 index 4e624345..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/drools-list-controller.js +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller("droolsListController", function ($scope,$http,droolsService, modalService, $modal) { - // Table Data - droolsService.getDrools().then(function(data){ - - var j = data; - $scope.tableData = JSON.parse(j.data); - //$scope.resetMenu(); - - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - $scope.viewPerPage = 20; - $scope.scrollViewsPerPage = 2; - $scope.currentPage = 1; - $scope.totalPage; - $scope.searchCategory = ""; - $scope.searchString = ""; - /* modalService.showSuccess('','Modal Sample') ; */ - for(x in $scope.tableData){ - if($scope.tableData[x].active_yn=='Y') - $scope.tableData[x].active_yn=true; - else - $scope.tableData[x].active_yn=false; - } - $scope.openDialog = function(droolFile){ - droolsService.setSelectedFile(droolFile); - $modal.open({ - templateUrl: 'app/fusionapp/drools/view-models/droolsView.html', - controller: 'droolsViewController' - - }) - } - - - -}); - -function openInNewTab(url) { - var win = window.open(url, '_blank'); - win.focus(); -}; diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/drools-view-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/drools-view-controller.js deleted file mode 100644 index c475e175..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/drools-view-controller.js +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('droolsViewController', function ($scope,modalService,droolsService){ - - - $scope.resultsString = ""; - // Table Data - droolsService.getDroolDetails(droolsService.getSelectedFile()).then(function(data){ - - var j = data; - $scope.postDroolsBean = JSON.parse(j.data); - //execute($scope.postDroolsBean); - - },function(error){ - console.log("failed"); - //reloadPageOnce(); - }); - - - - $scope.execute = function(postDroolsBean) { - console.log(postDroolsBean); - var uuu = "post_drools/execute"; - var postData={postDroolsBean:postDroolsBean}; - $.ajax({ - type : 'POST', - url : uuu, - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify(postData), - success : function(data){ - $scope.$apply(function(){ - $scope.resultsString=data.resultsString; - console.log($scope.resultsString); - }); - }, - error : function(data){ - console.log(data); - modalService.showFailure("Fail","Error while executing: "+ data.responseText); - } - }); - - }; - - - - }); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/droolsController.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/droolsController.js deleted file mode 100644 index f9c0e234..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/controller/droolsController.js +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.config(function($routeProvider) { - $routeProvider - .when('/view', { - templateUrl: 'app/fusionapp/drools/view-models/droolsView.html', - controller : "droolsViewController" - }) - .otherwise({ - templateUrl: 'app/fusionapp/drools/view-models/droolsList.html', - controller : "droolsListController" - }); -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/services/droolsService.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/services/droolsService.js deleted file mode 100644 index d1dbfa6c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/services/droolsService.js +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.factory('droolsService', function ($http, $q) { - return { - getDrools: function() { - return $http.get('getDrools') - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getDroolDetails: function(selectedFile) { - return $http.get('getDroolDetails'+'?selectedFile=' + selectedFile ) - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getRole: function(roleId) { - - return $http.get('get_role?role_id=' + roleId) - .then(function(response) { - if (typeof response.data === 'object') { - return response.data; - } else { - return $q.reject(response.data); - } - - }, function(response) { - // something went wrong - return $q.reject(response.data); - }); - }, - - getSelectedFile: function() { - return this.selectedFile; - }, - - setSelectedFile: function(_selectedFile) { - this.selectedFile = _selectedFile; - } - }; -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsList.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsList.html deleted file mode 100644 index ca06b3c3..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsList.html +++ /dev/null @@ -1,47 +0,0 @@ - -
        -
        -

        Drools List

        -
        - - - - - - - - - - - - - - - - - - -
        Drools File NameClass NameRun Rule
        {{rowData.droolsFile}}{{rowData.className}} -
        -
        -
        -
        - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsSinglePage.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsSinglePage.html deleted file mode 100644 index 1d4f1bfd..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsSinglePage.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        -
        -
        -
        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsView.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsView.html deleted file mode 100644 index dbe9121a..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/drools/view-models/droolsView.html +++ /dev/null @@ -1,61 +0,0 @@ - - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sample-page-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sample-page-controller.js deleted file mode 100644 index 0ea98a9c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sample-page-controller.js +++ /dev/null @@ -1,80 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('samplePageController', function($scope, $http,ProfileService,modalService){ - $scope.tableData=[]; - $scope.viewPerPage=20; - $scope.scrollViewPerPage=2; - $scope.currentPage=1; - $scope.totalPage; - $scope.searchCategory; - $scope.searchString=""; - $scope.currentPageNum=1; - ProfileService.getProfilePagination(1,$scope.viewPerPage).then(function(data){ - var j = data; - $scope.data = JSON.parse(j.data); - $scope.tableData =JSON.parse($scope.data.profileList); - $scope.totalPages =JSON.parse($scope.data.totalPage); - for(x in $scope.tableData){ - if($scope.tableData[x].active_yn=='Y') - $scope.tableData[x].active_yn=true; - else - $scope.tableData[x].active_yn=false; - } - //$scope.resetMenu(); - },function(error){ - console.log("failed"); - reloadPageOnce(); - }); - - $scope.$watch('currentPageNum', function(val) { - - ProfileService.getProfilePagination(val,$scope.viewPerPage).then(function(data){ - var j = data; - $scope.data = JSON.parse(j.data); - $scope.tableData =JSON.parse($scope.data.profileList); - $scope.totalPages =JSON.parse($scope.data.totalPage); - for(x in $scope.tableData){ - if($scope.tableData[x].active_yn=='Y') - $scope.tableData[x].active_yn=true; - else - $scope.tableData[x].active_yn=false; - } - //$scope.resetMenu(); - },function(error){ - console.log("failed"); - }); - - }); - - $scope.editRow = function(profileId){ - window.location = 'userProfile#/profile/' + profileId; - } - - $scope.toggleProfileActive = function(rowData) { - modalService.popupConfirmWinWithCancel("Confirm","You are about to change user's active status. Do you want to continue?", - function(){ - $http.get("profile/toggleProfileActive?profile_id="+rowData.id).success(function(){}); - }, - function(){ - rowData.active=!rowData.active; - }) - }; - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sample-page-iframe-controller.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sample-page-iframe-controller.js deleted file mode 100644 index 4ff99cb4..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sample-page-iframe-controller.js +++ /dev/null @@ -1,23 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.controller('samplePageWithIframeController', function($scope, $http,ProfileService,modalService){ - - -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sampleController.js b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sampleController.js deleted file mode 100644 index 3d3daf5f..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/controller/sampleController.js +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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. - * ================================================================================ - */ -app.config(function($routeProvider) { - $routeProvider - .when('/iframe', { - templateUrl: 'app/fusionapp/scripts/view-models/sampleWithIframe.html', - controller : "samplePageWithIframeController" - }) - .otherwise({ - templateUrl: 'app/fusionapp/scripts/view-models/sample.html', - controller : "samplePageController" - }); -}); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/sample.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/sample.html deleted file mode 100644 index 5b555aa4..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/sample.html +++ /dev/null @@ -1,60 +0,0 @@ - -
        - -

        Profile Search

        - - - - - - - - - - - - - - - - - - - - - - - -
        User IDLast NameFirst NameEmailUser IDManager User ID
        - -
        - Rows Per Page: - -
        -
        - Current Page: - -
        -
        - Total Page(s): - -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/sampleWithIframe.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/sampleWithIframe.html deleted file mode 100644 index 612e6a8c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/sampleWithIframe.html +++ /dev/null @@ -1,22 +0,0 @@ - -
        - -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/singlePageSample.html b/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/singlePageSample.html deleted file mode 100644 index 7bded9d6..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/app/fusionapp/scripts/view-models/singlePageSample.html +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        -
        -
        -
        -
        -
        - - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/fusion-sunny.css b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/fusion-sunny.css deleted file mode 100644 index c8306156..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/fusion-sunny.css +++ /dev/null @@ -1,362 +0,0 @@ - input, textarea, select, div { - font-family: Arial; - font-size: 11px; - font-weight: normal; - } - - form { - margin-top: 5px; - } - - - .applicationWindow { border-width: 0px 0px 1px 0px; - border-style: solid; - border-color: #959595; - box-shadow: inset 0 0 10px #000000; - margin-top: 10px; - margin-bottom: 10px; - margin-left: 10px; - margin-right: 10px; - } - - .feedbackMessage { width: 99%; - font-family: Arial; - font-size: 11px; - color: #1f1f1f; - padding: 3px; - border: 1px #eeb420 solid; - margin: 3px; - background: #fff9e5; - } - - .menubar { - border-width: 0px 0px 0px 1px; border-style: solid; border-color: #959595; - } - - .footer { - /*clear: both;*/ - border-width: 0px 1px 0px 1px; border-style: solid; border-color: #959595; - font-family: Verdana,Arial,Helvetica, sans-serif; - font-size: 9px; - padding: 10px 10px 30px 10px; - background: white; - } - - .pageTitle { - font-family: Arial; - font-size: 18px; - font-weight: bold; - margin-top: 5px; - } - - .content { - border-width: 0px 1px 0px 1px; - border-style: solid; - border-color: #959595; - font-family: Arial; - font-size: 11px; - padding: 5px; - background: white; - /*height: 600px;*/ - } - - .popupContent { - font-family: Arial; - font-size: 11px; - padding: 3px; - } - - .logo { - border-width: 0px 1px 0px 1px; - border-style: solid; - border-color: #959595; - text-align: right; - } - - .sep { - border: 1px solid black - } - - .attLogo { /*position: relative;*/ - float:left; - padding-top: 25px; - padding-left: 25px; - } - - .applicationLogo { float:right; - padding-top: 25px; - padding-right: 25px; - } - - .applinkWhite { font-family: Arial; - font-size: 13px; - font-weight: 900; - color: #FFFFFF; - text-decoration: none; } - - .terms { font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 9px; - } - - .broadcastMessage { color: red; } - .broadcastMessageList { color: red; } - - .button { - margin: 5px 1px 5px 1px; - padding: 3px; } - - .toolbarbutton:hover { - color:#005491; - } - - .headerText { font-family: Arial; - font-size: 15px; - font-weight: 700; - color: #000000; } - - .headerBackground { background: #336699; } - - .errorMessageText { font-family: Arial; - font-size: 11px; - font-weight: bold; - color: red; } - - - .normalText { font-family: Arial; - font-size: 11px; - color: #000000; } - - .normalTextRed { font-family: Arial; - font-size: 11px; - color: red; } - - - .smallNormalText { font-family: Arial; - font-size: 9px; - color: #000000; } - - .tableBorder { border:1px outset teal } - - .validationError { background: #b9eaff; } - - .templatebody { - background: url(../images/body_graphic.jpg) repeat-x; - /*margin: 40px 80px 40px 80px;*/ - } - - /*--------------------- General Content ------------------------------------*/ - - .relative { - position:relative; - } - - .clear{ - clear:both; - } - - .left { - float: left; - } - - .leftCentered{ - float: left; - text-align: center; - } - - .right { - float: right; - } - - .rightAligned{ - text-align: right; - } - - .centered { - text-align: center; - align: center; - } - - - .noWrap{ - white-space:nowrap; - } - - .disabled { - color:gray; - cursor:hand; - } - - /*--------------------- Tab styles -------------------------------------*/ - - .current { - font-weight: bold; - border-width: 1px 1px 1px 1px; - border-color: silver; - border-style: solid; - } - - .subTab { - font-weight:bold; - font-family: Arial; - font-size: 11px; - color: #0F3B82; - } - - - /*--------------------- Grid styles ------------------------------------*/ - - /* Grid navigation and header styles */ - .gridFilterLabel {font-size: 7pt; - font-align: justify; - font-weight: bold; - display: block;} - - .gridFilterText {height: 17px; - font-size: 8pt; - width: 60%; - font-align: justify;} - - .gridNavigationBar { font-family:Arial,Verdana; - font-size:11px; - font-weight:normal; - color:#000; - margin: 0px; - width: 100%; - vertical-align: middle; - } - - .gridNavigationBar .navLinks { float: left; - margin-right:15px; - padding-top: 2px; - height: 19px; - line-height: 19px; - } - - .gridNavigationBar .pageControls { float: left; - margin-right: 15px; - height: 19px; - line-height: 19px; - } - - .gridNavigationBar .pageControls input { font-size: 8pt; - height: 17px; - vertical-align: middle; - } - - .gridNavigationBar .pageInfo { float: right; - vertical-align: middle; - height: 19px; - line-height: 19px; - } - - .gridNavigationBar .pageInfo input { font-size: 8pt; - height: 17px; - vertical-align: middle; - } - - - .gridNavigationBar span { padding: 3px; } - - .gridNavigationBar a { - text-decoration:underline; - color:#000; - font-weight:normal; - } - - .gridNavigationBar img { vertical-align: middle; } - - .gridBulkUpdateRow { - height: 35px; - line-height: 35px; - } - - .gridBulkUpdateRow input { - vertical-align: middle; - } - - - /* dummy class used to lock the form elements of a grid - ex. bulk transaction processing */ - .alwaysEnabled {} - - .hidden { - display: none; - } - - .selectedPage { - background-color:#C4DFFB; - color: white; - border-style: solid; - border-width: 1px; - border-color: gray; - padding-left: 3px; - padding-right: 3px; - vertical-align: middle; - } - - .selectedRow{ - /*background-color:#C4DFFB;*/ - } - - /* Action Item styles */ - .actionList { - margin-left: -20px; - margin-right: -10px; - padding-left: 5px; - } - - .actionList li { - float:left; - padding-left: 3px; - padding-right: 3px; - } - - .actionList li a { - text-decoration:none; - color:#000; - } - - /* Filter Operator List styles */ - - .filterList { - margin: 0px; - } - - .filterList li { - list-style-type: none; - padding:3px 3px 3px 2px; - cursor:hand; - font-size:11px; - } - - .filterList li:hover { - background: #404040; - } - - .filterList li a { - color: #000; - text-decoration: none; - } - - .filterList li:hover a { - color: white; - } - - .filterList li a:hover { - text-decoration: none; - color: white; - } - - .filterListItem a { - text-decoration:none; - padding:3px 2px 3px 2px; - } - - - /*---------------------- Customized ZK Styles ------------------------------*/ - - .z-datebox input, .z-timebox input { - font-family: Arial; - font-size: 11px; - height: 15px; - margin-top:1px; - } diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/jquery-ui.css b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/jquery-ui.css deleted file mode 100644 index 1c22746c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/jquery-ui.css +++ /dev/null @@ -1,1225 +0,0 @@ -/*! jQuery UI - v1.11.4 - 2015-03-11 -* http://jqueryui.com -* Includes: core.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, draggable.css, menu.css, progressbar.css, resizable.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px -* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { - display: none; -} -.ui-helper-hidden-accessible { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; -} -.ui-helper-reset { - margin: 0; - padding: 0; - border: 0; - outline: 0; - line-height: 1.3; - text-decoration: none; - font-size: 100%; - list-style: none; -} -.ui-helper-clearfix:before, -.ui-helper-clearfix:after { - content: ""; - display: table; - border-collapse: collapse; -} -.ui-helper-clearfix:after { - clear: both; -} -.ui-helper-clearfix { - min-height: 0; /* support: IE7 */ -} -.ui-helper-zfix { - width: 100%; - height: 100%; - top: 0; - left: 0; - position: absolute; - opacity: 0; - filter:Alpha(Opacity=0); /* support: IE8 */ -} - -.ui-front { - z-index: 100; -} - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { - cursor: default !important; -} - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { - display: block; - text-indent: -99999px; - overflow: hidden; - background-repeat: no-repeat; -} - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -.ui-accordion .ui-accordion-header { - display: block; - cursor: pointer; - position: relative; - margin: 2px 0 0 0; - padding: .5em .5em .5em .7em; - min-height: 0; /* support: IE7 */ - font-size: 100%; -} -.ui-accordion .ui-accordion-icons { - padding-left: 2.2em; -} -.ui-accordion .ui-accordion-icons .ui-accordion-icons { - padding-left: 2.2em; -} -.ui-accordion .ui-accordion-header .ui-accordion-header-icon { - position: absolute; - left: .5em; - top: 50%; - margin-top: -8px; -} -.ui-accordion .ui-accordion-content { - padding: 1em 2.2em; - border-top: 0; - overflow: auto; -} -.ui-autocomplete { - position: absolute; - top: 0; - left: 0; - cursor: default; -} -.ui-button { - display: inline-block; - position: relative; - padding: 0; - line-height: normal; - margin-right: .1em; - cursor: pointer; - vertical-align: middle; - text-align: center; - overflow: visible; /* removes extra width in IE */ -} -.ui-button, -.ui-button:link, -.ui-button:visited, -.ui-button:hover, -.ui-button:active { - text-decoration: none; -} -/* to make room for the icon, a width needs to be set here */ -.ui-button-icon-only { - width: 2.2em; -} -/* button elements seem to need a little more width */ -button.ui-button-icon-only { - width: 2.4em; -} -.ui-button-icons-only { - width: 3.4em; -} -button.ui-button-icons-only { - width: 3.7em; -} - -/* button text element */ -.ui-button .ui-button-text { - display: block; - line-height: normal; -} -.ui-button-text-only .ui-button-text { - padding: .4em 1em; -} -.ui-button-icon-only .ui-button-text, -.ui-button-icons-only .ui-button-text { - padding: .4em; - text-indent: -9999999px; -} -.ui-button-text-icon-primary .ui-button-text, -.ui-button-text-icons .ui-button-text { - padding: .4em 1em .4em 2.1em; -} -.ui-button-text-icon-secondary .ui-button-text, -.ui-button-text-icons .ui-button-text { - padding: .4em 2.1em .4em 1em; -} -.ui-button-text-icons .ui-button-text { - padding-left: 2.1em; - padding-right: 2.1em; -} -/* no icon support for input elements, provide padding by default */ -input.ui-button { - padding: .4em 1em; -} - -/* button icon element(s) */ -.ui-button-icon-only .ui-icon, -.ui-button-text-icon-primary .ui-icon, -.ui-button-text-icon-secondary .ui-icon, -.ui-button-text-icons .ui-icon, -.ui-button-icons-only .ui-icon { - position: absolute; - top: 50%; - margin-top: -8px; -} -.ui-button-icon-only .ui-icon { - left: 50%; - margin-left: -8px; -} -.ui-button-text-icon-primary .ui-button-icon-primary, -.ui-button-text-icons .ui-button-icon-primary, -.ui-button-icons-only .ui-button-icon-primary { - left: .5em; -} -.ui-button-text-icon-secondary .ui-button-icon-secondary, -.ui-button-text-icons .ui-button-icon-secondary, -.ui-button-icons-only .ui-button-icon-secondary { - right: .5em; -} - -/* button sets */ -.ui-buttonset { - margin-right: 7px; -} -.ui-buttonset .ui-button { - margin-left: 0; - margin-right: -.3em; -} - -/* workarounds */ -/* reset extra padding in Firefox, see h5bp.com/l */ -input.ui-button::-moz-focus-inner, -button.ui-button::-moz-focus-inner { - border: 0; - padding: 0; -} -.ui-datepicker { - width: 17em; - padding: .2em .2em 0; - display: none; -} -.ui-datepicker .ui-datepicker-header { - position: relative; - padding: .2em 0; -} -.ui-datepicker .ui-datepicker-prev, -.ui-datepicker .ui-datepicker-next { - position: absolute; - top: 2px; - width: 1.8em; - height: 1.8em; -} -.ui-datepicker .ui-datepicker-prev-hover, -.ui-datepicker .ui-datepicker-next-hover { - top: 1px; -} -.ui-datepicker .ui-datepicker-prev { - left: 2px; -} -.ui-datepicker .ui-datepicker-next { - right: 2px; -} -.ui-datepicker .ui-datepicker-prev-hover { - left: 1px; -} -.ui-datepicker .ui-datepicker-next-hover { - right: 1px; -} -.ui-datepicker .ui-datepicker-prev span, -.ui-datepicker .ui-datepicker-next span { - display: block; - position: absolute; - left: 50%; - margin-left: -8px; - top: 50%; - margin-top: -8px; -} -.ui-datepicker .ui-datepicker-title { - margin: 0 2.3em; - line-height: 1.8em; - text-align: center; -} -.ui-datepicker .ui-datepicker-title select { - font-size: 1em; - margin: 1px 0; -} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { - width: 45%; -} -.ui-datepicker table { - width: 100%; - font-size: .9em; - border-collapse: collapse; - margin: 0 0 .4em; -} -.ui-datepicker th { - padding: .7em .3em; - text-align: center; - font-weight: bold; - border: 0; -} -.ui-datepicker td { - border: 0; - padding: 1px; -} -.ui-datepicker td span, -.ui-datepicker td a { - display: block; - padding: .2em; - text-align: right; - text-decoration: none; -} -.ui-datepicker .ui-datepicker-buttonpane { - background-image: none; - margin: .7em 0 0 0; - padding: 0 .2em; - border-left: 0; - border-right: 0; - border-bottom: 0; -} -.ui-datepicker .ui-datepicker-buttonpane button { - float: right; - margin: .5em .2em .4em; - cursor: pointer; - padding: .2em .6em .3em .6em; - width: auto; - overflow: visible; -} -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { - float: left; -} - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { - width: auto; -} -.ui-datepicker-multi .ui-datepicker-group { - float: left; -} -.ui-datepicker-multi .ui-datepicker-group table { - width: 95%; - margin: 0 auto .4em; -} -.ui-datepicker-multi-2 .ui-datepicker-group { - width: 50%; -} -.ui-datepicker-multi-3 .ui-datepicker-group { - width: 33.3%; -} -.ui-datepicker-multi-4 .ui-datepicker-group { - width: 25%; -} -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { - border-left-width: 0; -} -.ui-datepicker-multi .ui-datepicker-buttonpane { - clear: left; -} -.ui-datepicker-row-break { - clear: both; - width: 100%; - font-size: 0; -} - -/* RTL support */ -.ui-datepicker-rtl { - direction: rtl; -} -.ui-datepicker-rtl .ui-datepicker-prev { - right: 2px; - left: auto; -} -.ui-datepicker-rtl .ui-datepicker-next { - left: 2px; - right: auto; -} -.ui-datepicker-rtl .ui-datepicker-prev:hover { - right: 1px; - left: auto; -} -.ui-datepicker-rtl .ui-datepicker-next:hover { - left: 1px; - right: auto; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane { - clear: right; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane button { - float: left; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, -.ui-datepicker-rtl .ui-datepicker-group { - float: right; -} -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { - border-right-width: 0; - border-left-width: 1px; -} -.ui-dialog { - overflow: hidden; - position: absolute; - top: 0; - left: 0; - padding: .2em; - outline: 0; -} -.ui-dialog .ui-dialog-titlebar { - padding: .4em 1em; - position: relative; -} -.ui-dialog .ui-dialog-title { - float: left; - margin: .1em 0; - white-space: nowrap; - width: 90%; - overflow: hidden; - text-overflow: ellipsis; -} -.ui-dialog .ui-dialog-titlebar-close { - position: absolute; - right: .3em; - top: 50%; - width: 20px; - margin: -10px 0 0 0; - padding: 1px; - height: 20px; -} -.ui-dialog .ui-dialog-content { - position: relative; - border: 0; - padding: .5em 1em; - background: none; - overflow: auto; -} -.ui-dialog .ui-dialog-buttonpane { - text-align: left; - border-width: 1px 0 0 0; - background-image: none; - margin-top: .5em; - padding: .3em 1em .5em .4em; -} -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { - float: right; -} -.ui-dialog .ui-dialog-buttonpane button { - margin: .5em .4em .5em 0; - cursor: pointer; -} -.ui-dialog .ui-resizable-se { - width: 12px; - height: 12px; - right: -5px; - bottom: -5px; - background-position: 16px 16px; -} -.ui-draggable .ui-dialog-titlebar { - cursor: move; -} -.ui-draggable-handle { - -ms-touch-action: none; - touch-action: none; -} -.ui-menu { - list-style: none; - padding: 0; - margin: 0; - display: block; - outline: none; -} -.ui-menu .ui-menu { - position: absolute; -} -.ui-menu .ui-menu-item { - position: relative; - margin: 0; - padding: 3px 1em 3px .4em; - cursor: pointer; - min-height: 0; /* support: IE7 */ - /* support: IE10, see #8844 */ - list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); -} -.ui-menu .ui-menu-divider { - margin: 5px 0; - height: 0; - font-size: 0; - line-height: 0; - border-width: 1px 0 0 0; -} -.ui-menu .ui-state-focus, -.ui-menu .ui-state-active { - margin: -1px; -} - -/* icon support */ -.ui-menu-icons { - position: relative; -} -.ui-menu-icons .ui-menu-item { - padding-left: 2em; -} - -/* left-aligned */ -.ui-menu .ui-icon { - position: absolute; - top: 0; - bottom: 0; - left: .2em; - margin: auto 0; -} - -/* right-aligned */ -.ui-menu .ui-menu-icon { - left: auto; - right: 0; -} -.ui-progressbar { - height: 2em; - text-align: left; - overflow: hidden; -} -.ui-progressbar .ui-progressbar-value { - margin: -1px; - height: 100%; -} -.ui-progressbar .ui-progressbar-overlay { - background: url("data:image/gif;base64,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"); - height: 100%; - filter: alpha(opacity=25); /* support: IE8 */ - opacity: 0.25; -} -.ui-progressbar-indeterminate .ui-progressbar-value { - background-image: none; -} -.ui-resizable { - position: relative; -} -.ui-resizable-handle { - position: absolute; - font-size: 0.1px; - display: block; - -ms-touch-action: none; - touch-action: none; -} -.ui-resizable-disabled .ui-resizable-handle, -.ui-resizable-autohide .ui-resizable-handle { - display: none; -} -.ui-resizable-n { - cursor: n-resize; - height: 7px; - width: 100%; - top: -5px; - left: 0; -} -.ui-resizable-s { - cursor: s-resize; - height: 7px; - width: 100%; - bottom: -5px; - left: 0; -} -.ui-resizable-e { - cursor: e-resize; - width: 7px; - right: -5px; - top: 0; - height: 100%; -} -.ui-resizable-w { - cursor: w-resize; - width: 7px; - left: -5px; - top: 0; - height: 100%; -} -.ui-resizable-se { - cursor: se-resize; - width: 12px; - height: 12px; - right: 1px; - bottom: 1px; -} -.ui-resizable-sw { - cursor: sw-resize; - width: 9px; - height: 9px; - left: -5px; - bottom: -5px; -} -.ui-resizable-nw { - cursor: nw-resize; - width: 9px; - height: 9px; - left: -5px; - top: -5px; -} -.ui-resizable-ne { - cursor: ne-resize; - width: 9px; - height: 9px; - right: -5px; - top: -5px; -} -.ui-selectable { - -ms-touch-action: none; - touch-action: none; -} -.ui-selectable-helper { - position: absolute; - z-index: 100; - border: 1px dotted black; -} -.ui-selectmenu-menu { - padding: 0; - margin: 0; - position: absolute; - top: 0; - left: 0; - display: none; -} -.ui-selectmenu-menu .ui-menu { - overflow: auto; - /* Support: IE7 */ - overflow-x: hidden; - padding-bottom: 1px; -} -.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup { - font-size: 1em; - font-weight: bold; - line-height: 1.5; - padding: 2px 0.4em; - margin: 0.5em 0 0 0; - height: auto; - border: 0; -} -.ui-selectmenu-open { - display: block; -} -.ui-selectmenu-button { - display: inline-block; - overflow: hidden; - position: relative; - text-decoration: none; - cursor: pointer; -} -.ui-selectmenu-button span.ui-icon { - right: 0.5em; - left: auto; - margin-top: -8px; - position: absolute; - top: 50%; -} -.ui-selectmenu-button span.ui-selectmenu-text { - text-align: left; - padding: 0.4em 2.1em 0.4em 1em; - display: block; - line-height: 1.4; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.ui-slider { - position: relative; - text-align: left; -} -.ui-slider .ui-slider-handle { - position: absolute; - z-index: 2; - width: 1.2em; - height: 1.2em; - cursor: default; - -ms-touch-action: none; - touch-action: none; -} -.ui-slider .ui-slider-range { - position: absolute; - z-index: 1; - font-size: .7em; - display: block; - border: 0; - background-position: 0 0; -} - -/* support: IE8 - See #6727 */ -.ui-slider.ui-state-disabled .ui-slider-handle, -.ui-slider.ui-state-disabled .ui-slider-range { - filter: inherit; -} - -.ui-slider-horizontal { - height: .8em; -} -.ui-slider-horizontal .ui-slider-handle { - top: -.3em; - margin-left: -.6em; -} -.ui-slider-horizontal .ui-slider-range { - top: 0; - height: 100%; -} -.ui-slider-horizontal .ui-slider-range-min { - left: 0; -} -.ui-slider-horizontal .ui-slider-range-max { - right: 0; -} - -.ui-slider-vertical { - width: .8em; - height: 100px; -} -.ui-slider-vertical .ui-slider-handle { - left: -.3em; - margin-left: 0; - margin-bottom: -.6em; -} -.ui-slider-vertical .ui-slider-range { - left: 0; - width: 100%; -} -.ui-slider-vertical .ui-slider-range-min { - bottom: 0; -} -.ui-slider-vertical .ui-slider-range-max { - top: 0; -} -.ui-sortable-handle { - -ms-touch-action: none; - touch-action: none; -} -.ui-spinner { - position: relative; - display: inline-block; - overflow: hidden; - padding: 0; - vertical-align: middle; -} -.ui-spinner-input { - border: none; - background: none; - color: inherit; - padding: 0; - margin: .2em 0; - vertical-align: middle; - margin-left: .4em; - margin-right: 22px; -} -.ui-spinner-button { - width: 16px; - height: 50%; - font-size: .5em; - padding: 0; - margin: 0; - text-align: center; - position: absolute; - cursor: default; - display: block; - overflow: hidden; - right: 0; -} -/* more specificity required here to override default borders */ -.ui-spinner a.ui-spinner-button { - border-top: none; - border-bottom: none; - border-right: none; -} -/* vertically center icon */ -.ui-spinner .ui-icon { - position: absolute; - margin-top: -8px; - top: 50%; - left: 0; -} -.ui-spinner-up { - top: 0; -} -.ui-spinner-down { - bottom: 0; -} - -/* TR overrides */ -.ui-spinner .ui-icon-triangle-1-s { - /* need to fix icons sprite */ - background-position: -65px -16px; -} -.ui-tabs { - position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ - padding: .2em; -} -.ui-tabs .ui-tabs-nav { - margin: 0; - padding: .2em .2em 0; -} -.ui-tabs .ui-tabs-nav li { - list-style: none; - float: left; - position: relative; - top: 0; - margin: 1px .2em 0 0; - border-bottom-width: 0; - padding: 0; - white-space: nowrap; -} -.ui-tabs .ui-tabs-nav .ui-tabs-anchor { - float: left; - padding: .5em 1em; - text-decoration: none; -} -.ui-tabs .ui-tabs-nav li.ui-tabs-active { - margin-bottom: -1px; - padding-bottom: 1px; -} -.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, -.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, -.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { - cursor: text; -} -.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { - cursor: pointer; -} -.ui-tabs .ui-tabs-panel { - display: block; - border-width: 0; - padding: 1em 1.4em; - background: none; -} -.ui-tooltip { - padding: 8px; - position: absolute; - z-index: 9999; - max-width: 300px; - -webkit-box-shadow: 0 0 5px #aaa; - box-shadow: 0 0 5px #aaa; -} -body .ui-tooltip { - border-width: 2px; -} - -/* Component containers -----------------------------------*/ -.ui-widget { - font-family: Verdana,Arial,sans-serif; - font-size: 1.1em; -} -.ui-widget .ui-widget { - font-size: 1em; -} -.ui-widget input, -.ui-widget select, -.ui-widget textarea, -.ui-widget button { - font-family: Verdana,Arial,sans-serif; - font-size: 1em; -} -.ui-widget-content { - border: 1px solid #aaaaaa; - background: #ffffff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x; - color: #222222; -} -.ui-widget-content a { - color: #222222; -} -.ui-widget-header { - border: 1px solid #aaaaaa; - background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x; - color: #222222; - font-weight: bold; -} -.ui-widget-header a { - color: #222222; -} - -/* Interaction states -----------------------------------*/ -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { - border: 1px solid #d3d3d3; - background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x; - font-weight: normal; - color: #555555; -} -.ui-state-default a, -.ui-state-default a:link, -.ui-state-default a:visited { - color: #555555; - text-decoration: none; -} -.ui-state-hover, -.ui-widget-content .ui-state-hover, -.ui-widget-header .ui-state-hover, -.ui-state-focus, -.ui-widget-content .ui-state-focus, -.ui-widget-header .ui-state-focus { - border: 1px solid #999999; - background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x; - font-weight: normal; - color: #212121; -} -.ui-state-hover a, -.ui-state-hover a:hover, -.ui-state-hover a:link, -.ui-state-hover a:visited, -.ui-state-focus a, -.ui-state-focus a:hover, -.ui-state-focus a:link, -.ui-state-focus a:visited { - color: #212121; - text-decoration: none; -} -.ui-state-active, -.ui-widget-content .ui-state-active, -.ui-widget-header .ui-state-active { - border: 1px solid #aaaaaa; - background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x; - font-weight: normal; - color: #212121; -} -.ui-state-active a, -.ui-state-active a:link, -.ui-state-active a:visited { - color: #212121; - text-decoration: none; -} - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, -.ui-widget-content .ui-state-highlight, -.ui-widget-header .ui-state-highlight { - border: 1px solid #fcefa1; - background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x; - color: #363636; -} -.ui-state-highlight a, -.ui-widget-content .ui-state-highlight a, -.ui-widget-header .ui-state-highlight a { - color: #363636; -} -.ui-state-error, -.ui-widget-content .ui-state-error, -.ui-widget-header .ui-state-error { - border: 1px solid #cd0a0a; - background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x; - color: #cd0a0a; -} -.ui-state-error a, -.ui-widget-content .ui-state-error a, -.ui-widget-header .ui-state-error a { - color: #cd0a0a; -} -.ui-state-error-text, -.ui-widget-content .ui-state-error-text, -.ui-widget-header .ui-state-error-text { - color: #cd0a0a; -} -.ui-priority-primary, -.ui-widget-content .ui-priority-primary, -.ui-widget-header .ui-priority-primary { - font-weight: bold; -} -.ui-priority-secondary, -.ui-widget-content .ui-priority-secondary, -.ui-widget-header .ui-priority-secondary { - opacity: .7; - filter:Alpha(Opacity=70); /* support: IE8 */ - font-weight: normal; -} -.ui-state-disabled, -.ui-widget-content .ui-state-disabled, -.ui-widget-header .ui-state-disabled { - opacity: .35; - filter:Alpha(Opacity=35); /* support: IE8 */ - background-image: none; -} -.ui-state-disabled .ui-icon { - filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */ -} - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { - width: 16px; - height: 16px; -} -.ui-icon, -.ui-widget-content .ui-icon { - background-image: url("images/ui-icons_222222_256x240.png"); -} -.ui-widget-header .ui-icon { - background-image: url("images/ui-icons_222222_256x240.png"); -} -.ui-state-default .ui-icon { - background-image: url("images/ui-icons_888888_256x240.png"); -} -.ui-state-hover .ui-icon, -.ui-state-focus .ui-icon { - background-image: url("images/ui-icons_454545_256x240.png"); -} -.ui-state-active .ui-icon { - background-image: url("images/ui-icons_454545_256x240.png"); -} -.ui-state-highlight .ui-icon { - background-image: url("images/ui-icons_2e83ff_256x240.png"); -} -.ui-state-error .ui-icon, -.ui-state-error-text .ui-icon { - background-image: url("images/ui-icons_cd0a0a_256x240.png"); -} - -/* positioning */ -.ui-icon-blank { background-position: 16px 16px; } -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-on { background-position: -96px -144px; } -.ui-icon-radio-off { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, -.ui-corner-top, -.ui-corner-left, -.ui-corner-tl { - border-top-left-radius: 4px; -} -.ui-corner-all, -.ui-corner-top, -.ui-corner-right, -.ui-corner-tr { - border-top-right-radius: 4px; -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-left, -.ui-corner-bl { - border-bottom-left-radius: 4px; -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-right, -.ui-corner-br { - border-bottom-right-radius: 4px; -} - -/* Overlays */ -.ui-widget-overlay { - background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x; - opacity: .3; - filter: Alpha(Opacity=30); /* support: IE8 */ -} -.ui-widget-shadow { - margin: -8px 0 0 -8px; - padding: 8px; - background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x; - opacity: .3; - filter: Alpha(Opacity=30); /* support: IE8 */ - border-radius: 8px; -} diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/layout/layout-default-latest.css b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/layout/layout-default-latest.css deleted file mode 100644 index aa382de3..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/css/layout/layout-default-latest.css +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Default Layout Theme - * - * Created for jquery.layout - * - * Copyright (c) 2010 - * Fabrizio Balliano (http://www.fabrizioballiano.net) - * Kevin Dalman (http://allpro.net) - * - * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) - * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. - * - * Last Updated: 2010-02-10 - * NOTE: For best code readability, view this with a fixed-space font and tabs equal to 4-chars - */ - -/* - * DEFAULT FONT - * Just to make demo-pages look better - not actually relevant to Layout! - */ -body { - font-family: Geneva, Arial, Helvetica, sans-serif; - font-size: 100%; - *font-size: 80%; -} - -/* - * PANES & CONTENT-DIVs - */ -.ui-layout-pane { /* all 'panes' */ - background: #FFF; - border: 1px solid #BBB; - padding: 10px; - overflow: auto; - /* DO NOT add scrolling (or padding) to 'panes' that have a content-div, - otherwise you may get double-scrollbars - on the pane AND on the content-div - - use ui-layout-wrapper class if pane has a content-div - - use ui-layout-container if pane has an inner-layout - */ - } - /* (scrolling) content-div inside pane allows for fixed header(s) and/or footer(s) */ - .ui-layout-content { - padding: 10px; - position: relative; /* contain floated or positioned elements */ - overflow: auto; /* add scrolling to content-div */ - } - -/* - * UTILITY CLASSES - * Must come AFTER pane-class above so will override - * These classes are NOT auto-generated and are NOT used by Layout - */ -.layout-child-container, -.layout-content-container { - padding: 0; - overflow: hidden; -} -.layout-child-container { - border: 0; /* remove border because inner-layout-panes probably have borders */ -} -.layout-scroll { - overflow: auto; -} -.layout-hide { - display: none; -} - -/* - * RESIZER-BARS - */ -.ui-layout-resizer { /* all 'resizer-bars' */ - background: #DDD; - border: 1px solid #BBB; - border-width: 0; - } - .ui-layout-resizer-drag { /* REAL resizer while resize in progress */ - } - .ui-layout-resizer-hover { /* affects both open and closed states */ - } - /* NOTE: It looks best when 'hover' and 'dragging' are set to the same color, - otherwise color shifts while dragging when bar can't keep up with mouse */ - .ui-layout-resizer-open-hover , /* hover-color to 'resize' */ - .ui-layout-resizer-dragging { /* resizer beging 'dragging' */ - background: #C4E1A4; - } - .ui-layout-resizer-dragging { /* CLONED resizer being dragged */ - border: 1px solid #BBB; - } - .ui-layout-resizer-north-dragging, - .ui-layout-resizer-south-dragging { - border-width: 1px 0; - } - .ui-layout-resizer-west-dragging, - .ui-layout-resizer-east-dragging { - border-width: 0 1px; - } - /* NOTE: Add a 'dragging-limit' color to provide visual feedback when resizer hits min/max size limits */ - .ui-layout-resizer-dragging-limit { /* CLONED resizer at min or max size-limit */ - background: #E1A4A4; /* red */ - } - - .ui-layout-resizer-closed-hover { /* hover-color to 'slide open' */ - background: #EBD5AA; - } - .ui-layout-resizer-sliding { /* resizer when pane is 'slid open' */ - opacity: .10; /* show only a slight shadow */ - filter: alpha(opacity=10); - } - .ui-layout-resizer-sliding-hover { /* sliding resizer - hover */ - opacity: 1.00; /* on-hover, show the resizer-bar normally */ - filter: alpha(opacity=100); - } - /* sliding resizer - add 'outside-border' to resizer on-hover - * this sample illustrates how to target specific panes and states */ - .ui-layout-resizer-north-sliding-hover { border-bottom-width: 1px; } - .ui-layout-resizer-south-sliding-hover { border-top-width: 1px; } - .ui-layout-resizer-west-sliding-hover { border-right-width: 1px; } - .ui-layout-resizer-east-sliding-hover { border-left-width: 1px; } - -/* - * TOGGLER-BUTTONS - */ -.ui-layout-toggler { - border: 1px solid #BBB; /* match pane-border */ - background-color: #BBB; - } - .ui-layout-resizer-hover .ui-layout-toggler { - opacity: .60; - filter: alpha(opacity=60); - } - .ui-layout-toggler-hover , /* need when NOT resizable */ - .ui-layout-resizer-hover .ui-layout-toggler-hover { /* need specificity when IS resizable */ - background-color: #FC6; - opacity: 1.00; - filter: alpha(opacity=100); - } - .ui-layout-toggler-north , - .ui-layout-toggler-south { - border-width: 0 1px; /* left/right borders */ - } - .ui-layout-toggler-west , - .ui-layout-toggler-east { - border-width: 1px 0; /* top/bottom borders */ - } - /* hide the toggler-button when the pane is 'slid open' */ - .ui-layout-resizer-sliding .ui-layout-toggler { - display: none; - } - /* - * style the text we put INSIDE the togglers - */ - .ui-layout-toggler .content { - color: #666; - font-size: 12px; - font-weight: bold; - width: 100%; - padding-bottom: 0.35ex; /* to 'vertically center' text inside text-span */ - } - -/* - * PANE-MASKS - * these styles are hard-coded on mask elems, but are also - * included here as !important to ensure will overrides any generic styles - */ -.ui-layout-mask { - border: none !important; - padding: 0 !important; - margin: 0 !important; - overflow: hidden !important; - position: absolute !important; - opacity: 0 !important; - filter: Alpha(Opacity="0") !important; -} -.ui-layout-mask-inside-pane { /* masks always inside pane EXCEPT when pane is an iframe */ - top: 0 !important; - left: 0 !important; - width: 100% !important; - height: 100% !important; -} -div.ui-layout-mask {} /* standard mask for iframes */ -iframe.ui-layout-mask {} /* extra mask for objects/applets */ - -/* - * Default printing styles - */ -@media print { - /* - * Unless you want to print the layout as it appears onscreen, - * these html/body styles are needed to allow the content to 'flow' - */ - html { - height: auto !important; - overflow: visible !important; - } - body.ui-layout-container { - position: static !important; - top: auto !important; - bottom: auto !important; - left: auto !important; - right: auto !important; - /* only IE6 has container width & height set by Layout */ - _width: auto !important; - _height: auto !important; - } - .ui-layout-resizer, .ui-layout-toggler { - display: none !important; - } - /* - * Default pane print styles disables positioning, borders and backgrounds. - * You can modify these styles however it suit your needs. - */ - .ui-layout-pane { - border: none !important; - background: transparent !important; - position: relative !important; - top: auto !important; - bottom: auto !important; - left: auto !important; - right: auto !important; - width: auto !important; - height: auto !important; - overflow: visible !important; - } -} \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/Rlogo.jpg b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/Rlogo.jpg deleted file mode 100644 index 656a6b1f144431e3b238e874de332bea78dbcf00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3173 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 Q77znZpKPs0K>T?8-{n}!bpQYW diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/Thumbs.db b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/Thumbs.db deleted file mode 100644 index f504b226e0c9df7df0a87443578ebea2feca7186..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102912 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 Hn}7Hdau=UZ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/action_icon.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/action_icon.png deleted file mode 100644 index f2d1bc0b6a4d6637faab32d4e15351a7de39de94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2388 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 a3_t)e diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/active.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/active.png deleted file mode 100644 index 4524177685d013019b7d6ff8c0b6a8a4b7d6f486..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 682 zcmV;b0#*HqP)djvRmvxnun58#g3e;_h37eVuR)H~l@~P}Eu>A$|#Rn;pz(^w~ zP0$FY4@PCCmqf@6U1oDbb5}PvHg&g$FhoY_dHitB`JB)BFgOajArppl@RXMY%KLcA z-D8g+mIy;eugOl?EEZsS%a4z1Q!+WMo-(xklDS5vgY-uRS7~;Mz0#!M zXJQHE*_8-HgP8d>>!XCa|D4bT1q2EhsAz+_C(h_GN`xUESJ_R3lNxdjc@Q}xp3S`g zOW4-QCRHQog2y5iO*>B3_2i@-n?^T0`-<~4S)5X?n1d~ZQJirK?^h-e-HCQiHmPF( zz=A>h?XngaI02XCTJ+BKx6eNOB8i;gaejK9>#C&zft_VoGD_f&tY9jr`Y1!)drJry zz{rbOORQpZH-tOq+h8xOa#2D@ThFy%ha@2KA~?ch=-V(Tq0R3aC$+yR(FiG&&@S4| zR>buf;(83WLK})D85O3p*uXkY7>eNajbTCax!+!y=-Xd1#SmWmYXkD;_NHPpTMI=&$sFP`xHcwj)Y)K@|vPu$l}alh1;I zi0J+N6x+#!!}sJzAf*8S#9t-`Vvd+RADUOJ<{D%PnaC4N@Gg#FL0fct9pilm#VK*- z`RN|#n>u}PyeTB-tkeJEGpU9b1}pCiRJbcpUZaFIkJNkBR6GFq4J)tFe*XqI Q5dZ)H07*qoM6N<$g1HzuTmS$7 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/add.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/add.png deleted file mode 100644 index 46d944b3d69a5c23fb13a0b5bbf88720424d2d05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 352 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
        4pD0wV z4K>@{wvMjF*v}q%WVd1>cw&Z`;F^X3M$*cTqirQM4n`|kxgkbj=ZI!_ouy}~WA)+H z*Ej`pm5VQko%S0WWC!D2T|JIZIlq$uchRr*h>iZ9)J`3iOGXIJmBfq)?Ke1M%S6Lr z7iC1VGL`1A?Fu*JrN4{rD!*7n@k0{AtdM%ZFkq;a;P&AsJGFhn-ImvCSk5oxRIu7# z!Z=wkT8+d4hD7n1g8At0i{Z~Smfm?tUa%0oiL0ye1$LdR1P4j+FtUx((G_6{wY;iK zXUmTZtnCU!!+b2`ze=KeXu4q6YlPAKBX~Akc0=xEHUp+!gpA)Fw3dDxO3WFVDcYMG zsz)?0*F~+we?HB%CCuWWp8PpAqWisY@bx8p4Tz&<^1Ejjz0~^YU_ZT)Vk#>pSrM6k z5%vAF`p!jq7F3JAw>*12R@adzl9>GrfF&Qv=e(2*2>+|OURw3T`HKJvBV_9wX``}S zPf)7~7+yrbG(u(_DP|t!zbqnda2fhQNb#YCGvUF!LiB=SHTo)Q#RW-m7HuJZoAs`l zj@tKvU_^=}jrnxBKB3hxzk*4RZk$P{r<1t~N7{JJ8; z+N5$f!Wvv?`>nb)ABgzL2r}cbN|>}>s);xXXmOSKOItEklkI+a2qZ}89ns82wYG&f z%jmc=6r$B9?8p^XvG7$%TBKPL{s`!U3@@|zr-CmI)TXq>*sie;A{3L&D`|^#gLZAZ zV!f4g&zRn+B^Ugb+tI#In8jWam&hgBE|o!87qnSrVXD~Bgx-8L(giL1?4VWrkWn_+xv7OM9J@rD0?o{eOucDp@1t9^tP$t z;n{MWIOxH>aTi+Y@mQ|Wd;ECq&ivUSh>He z@Vvl=@1G|I4mZiL1GcJ)Bcla=y_{MkYu+UraF{gxp*-Yq!p7_Sw#tj(g?a$!`rbRr z@Z56*mtpX;K2j=PN%Q2;4ReK6@{j8qVIkJ))7^Lh`((A2^-hL(?2-JB>{`wy?ghV*T-bgWRM#!%>6tk?A7!KmsDRtL`Wez|!YB;r7w0 z#w9Cr+ap$%kN=2pMN`?UGpP-^uN>~&zpsqfsTv+BL^!@;J^F%a^Q%ZlXR)%x99XG%-N0) zEi2;m#rNE8x6GkIZmla!vvFCyq_5llyeT(l_#k$anaX#U20Hqk5X?xSq(vXn6a~%4 z(WhtZW$r(wX|_L$jJzVsmq-6|9ufrcCpcJK2_i5?L1_f;7Qc%0nzOIq`iCDGe#aMI zHs5){F$>8ra+k8}n3L979PB*q8o2E2MnN5>$Tx6oS+mJ(}s84R5S$N z)5%3}Tr_k|%Tg*bbQUH4)GpwWp!fONtG_2NgM!m+MhpNS1{OrazsO&T`HR`X>7o90bIh2q`Vjy#=eMACc;8Cq&0@7qCO9gG8NZha1JO@HQIta$n*w#nkAPD*FSozN z)Epf7-Rw*&?H5LP3b7eOJ7tH;v6D??atA)I)_5kmt-IvH)*1$#UX<^o5CeEGc3Y!o z-#@@Hv`(xS>O&YV_BJKbENRG>$Y=_Re|=ggLnVrfe3PwAK49>(tAni zVbV)?sS5>9&|Owq{DvnJ@d8V*(>+E_Lqn?lbBsij2r19$+;?92Qn#;sRzMSpJf!o| zwh{$A#!q`5L#mJAPvh80!td|@`RRYjAMmvIY+HTIv|oqd@ALKE#h;Z-DicY?qkdFi^SAQ9zH10i z?JYIAaZbl+PbYva6HqgH8Z;X-Z@QlGFU(c`n^E>3r=G_lTW_pAZT&P8?YTenTqqZg z`-3!TZ*D{v8fy-5#2LhHAhUvne|N%o$0ZLBW^-z|PVQkM|0AT`&(MI`eB2)_r7&2W z-*_N~RGEt(b_7lH{V_*RQiGG*T1rCT#@Camvh{Si9{pjz1y5w2_0M6{6ch7nrCK(A z#OJlSxWD|@(}IV3Qyn$5SJ7vS0LK93nLZNFRiCPz0iyeWfR+C(WDzL1#2QyrJ}L|J zFmz-f3TS+!b9n!6GP9^`ylv&Z$U{@*lB-_XpK-((#i7PJ$`DobFo|GOj9 z39WseMR5<-Udi-^tcar8AMqH1P*LOvG{7CvzIF2fcGJ9hqvL`wyqx-9a0++XMY7Z8 zmO=>TuSvAPox8dJYY2QVr-2=4w;R)m)k|LkZ5%``Kn_tWxd_mHTN>%UpJzQFsiZ9% zPNE2EhY740qNtA{;&L63kbDa+&$k&b9{DP1wOT(ias{sG%=;{%2)m%L-nB-=LV2_b zbH(<<=@j7ee*K92y#+^QqN5z}&01V7vCcLvs) z0#OyW%RSaeUEvD+end#u)Yi>e3aY)cC3fDK8BimqOW-dN^su-vuZTK9I{@yl_Q4Qm zNDuPi0y+-3FSsFXuDxJo;|4*=VDYL*qnhQZ`ekQ$qF1(|t%2!${nsf)P&SHN1P(ww zz`+97YG}^(B>dmPyx$~YTBwoN>0p!t>6JZ*QL>eI`3aQr=4i*1_u{U0Z)b{U=M$hA zKi<8WGEd!OR(`RAI2Uc zImfeq+Fb?C08Y?0K9rC*y-n-&z0*$^_UfQtiMWo2nmP{H;-fV@w@~g)w8oQqS&p=& zrq&2nef@P-qI<_(W3VqrYD1OdGM!%-&*(wMe~+b)4B0RwQLYYLioSH_KGnZiyQeWa zu)A8F)t&r+4ntkOF+yE6 zex2$siB(}jdhf6FlkV8>Gh|QwzJDhPGKOQRz?_SsjpC3aJsd0C$B^aX)QeWyE%g=LnW{g|}#}N5^pF^$eyCYa&X#v2LYa#=rfPlm6!7E7sZl#C7ZH;$g>3K|KV_A(n6>ko&^o68axqGTXMLTVVHm)i@1q+Kv`K49$3jiOn)b>k(cZtgQ1>bs(@ z23JU7_v`!ER}m{OItDw)yih|)z^TI>wXCu9D-Bc@7~YTaIx;fRm3l(YeRh@o)=Ow;v{C)<@&9#vF*iKQd=QfWS{sSq z1e2QsXlOHN$m)yhg{ z6*gAVp_A9ZUhe|}7GtL=7XjkKrSiZpLnkZNF!!U@ZSG+k+Qs;D1%hD@nh>ZtXSfA7~m8m2c2C`Rjgom~}|s!>z29=}D@o4*H9 zjeF^DBrXo(;iF*&7pDP18||iy+*8juKvw`4qu}w;c3)84ql9~UbYGO)CyaDq6XbsV zV7iapDlCbnuKY5wTFbxIX>@GZz3m&YzVw8wA9g(uBb5DjYV9u98e<0m93QJ!_TQ2G z_qe>rhmo0X*z@)D!onn)61MN2k^L}CdiP+YiQ2{s5UXKD ze+vkS8ytfP_VoT|Qaf=qCwm-*QGErxl5`ljHId#%j`QaVd3+exR|=x z^Tf^VD{)w17wEi)cr~45ilv8v|LLy{C+M*kG)8kf%$ZXfnjzJeZ{X8Tf!$!(MaIv{ zQ@nV&G00(TJ$43oz|Z6N%Qh1)$PO-;)*> zuXb|l=W`qF-_Eo+Opge)Z1>|rl|OVMvmfS2{|>&Lshv440$dTaukk#*Ubx)pJD0Nt zqmTXBXXCJ1698Zu2ZXm6CQ>|5Zms)hS$3%Gx5+&#?R9oY%aNY~wabniF!=$mc3bHP zqiP`w<1J`vOsof*!6ge>h= zqnCC&C0gc|WbM(>D{oyX5doJMZu^C7Jm?BJ)|~MbN0A&?Y>j0_D?eua-FNRb1F=`ck-~12OMon1V|8x zYk2-V5qkd_L9oHhXCaNh$Iq~kF;pbuvlCW1|P6cr@wNCWt zKN8}%ur;xZE`ecyD13Xk^2+_;b`Q1sKd&qQ4WIGobfZDQdgL17z=hfe)*|^H9Mwh2 zfacGEY~1-IRr9u-- zhdf)NK_?hLg>Y?SIcbjW@KjK%k?89cNiURBZ0d364J<*xa>A_`GJ^zOYJbxV@`9J5 z3QgK?wei&i)mZieMA_k*Q~PpP4<7;~7p;zIo6ys@Eo_p*Zn3GixIO?7bgqhtD_Ld*YZ&UH%E@WdT2xRnj$I``8x>Y&b9q&8Ot|o z2L0Rd$A_gBwbkQOl7LS%=xU3HoQvB#ZrI%tP8zE38$W7g6gc9GTDv>d{+}iP-!}2T zEaUqwu7NLaQiF(|(xTWFKs-`%Mq9bSomHi=v-N)Qwm6q zi}wPN(yg!Zz+&fBx&;2Qe{Pv;$;msMd3w(e&lOI+q?S}NiIwRn3W^ZEn5tJlt*_Cq z0n4@vr5plY5~)f;gG5Ed6~$6dS0Jc-&LaV2yERvWo@Tfbuw1#M7XU}n@~>NHrj;;g}rS( z@uzj!ZQp|P3VR0&BvH+CPjgY_`f++4iy+vM!|1}x1{MEx-BcQ6970jQz1HBidhDRN zz>Kjqn&5c0$U!(RwCfct`8cN~ooc>zisA87o*(;OpEg=j^aM!^caMdwT4V&#c%5&k zwq}NZ&V~uHap}Vvn(tI*Mi(|* zDpy^I5bb<6ZV*_ttFp>Yzpz$LJACSw&0WjB*lp+^n+~Dwa64O*zEY{t2fLO8ZSEO% zQu)XEMs*d|Tuk~>yfA+@;`b3)x_;Gp6~8VzcjA5ev$8&TSU9zc*l*O`PZyYkkgv(Q zJi62g|LVhs#>o4APqzVNEX2Sd1pglgHX-CcPVWCr`M9fnbYQ7i@k6P95xde64nzq3 zgR}LSYQ$v!Kmy!ptspfuh0?3Fv$O8B{pZ#5=^r_%seNYe$?&m%{HNHEe7L_pguRP8)9rsy^)9`IpZfbb>2_a96RMxnNL9n&Q*X zWe~sRMRek;=d3)>9EMD%mqeUK8ydNb%TQ!r3N;1FNEFGDj+F0fo!sT&EjNr&gSBWY ztT}Vf1Hq{K36iP@fR5DydLNM86*7T3a4yr-@jjyR(+Qm6+WNsgEm0N}BBtZ!)gdJ@ zMlX3wqMeO||DGC$kfTp|NZSTcdt&zt*C#v0sAOay^;U1oqBu&{knWLUP*~NK`f}8# z%Y4;zuCrDy_T%_=6H9=_Us(5pvNOA((IDqdDYbp)=?;O#jV>Vkbn>1ha19xEAaLTk zhJ4q<&?xCQEs(PRX|86rt$v95>0Ejp&%c;Ta_!_xQR=+lO>2a(kBtNjk@ z|4b7Rq1)6oz~qH1Y| z@gYDQE{+c0Zn1LzQqu(C`8FJC-zWYHJ?}cm5^IcA$C8iPyCw-1Z!Kq?9xHyTh^jI9 zpS6iQ(DMtP_1%-sK24jWLW$UYg&GB;S&ZiocB0YWt>L)EhJDlX_QwZ2+oG)kdM_}o z-Cw68$oXp2!AT)^s#Ry|mR?}m7jecoWwk@C9XGYs=JK`o<2f+$6Wi|W+erVD)T@b) zC44#iR|=Pq6p+$W_}9Z7PM^9bK4f(vLHt>XUgeOrcN$C!0OB z@LURdltko`enq7|n7es7B4>^=NUeCtzAzf9m^iqP?HZue9wM$ff@HToHJ+G-bKi*^ zqxZ(9_$*+eqm?4opM*y=vSUWBP6On0gOXEEz~1DQyp@Nd7gl~^ABW@OA(7TcN2dD# zn8Qo>ed#!m^ zPmWHht}4*>>&EEXU4Stf-0)wz*X_{3v78cNo4FnV`*-ZAw*08dRVQ?C&SoVj*Sf=C zQa?cKnn%@luqr@C5M_V=UrcW6B(G~0(0<(ZnX6!l9kGllw0I0CK2SAx652@?0t$ua zV3I#bKs}+lzSS00V^uY^vlf0-|5-e2d#gs0xkyd)sRDS=Cga^vk)m65g}}< zzRbO3E?#9bSNh4|d*jh$^W0CAM()Eeh;%uks zqm=<^K)EwTYPB}$F({UHN_o4pw&}DlVsy-zb@dvF~+MTmNQ3RP6T6mGAdfI_EcW?^I8CC}B;% z#6=**UruzkNicIfa|^|qhUvtZDj$Fcd`gwR#M0$$WZb0i4=IIIZo{m$;>{>F?f_7% z$#3Iv^>)?iY#!HGx%THV#oiMA?f%f@O*}E#itEeE7*L-MD%Y)nx7%rH-N6~X7_(S9 z98mAr;+)y?gn7&L+fns#!Cch%iCearCE)15(yAU!61OLS`yQvv!7m}#{o}f6LsunP z-3igGk6``6QEMUFiFRPjNwr1|<0UzJcN(Yl-)q+o<#=)xSA=nfp{8-#uPNw{;fq(~9f{CEv=RC<`O zx&6d@X%q)g^N>4!C?Pqgd-vVL6qF)BxhwQ~YvcO;4Z4%(0rf8z^(52**&1mX+d!88yBff;(flq=a4eJW+)zHrox^UYg zIdhVrA=d5Z)B~JiIfULNU0ldGKG%uBWTNdH0JB$x=b86Ao%)0-CyK-wugwdV2DgTe zKj^j^{@7FA^6p=nqPlHSV`%$m(|CMii2Y$L;gtTsg#jnzIzp3ADVqZU2>1U3sB_WNBU8?;qb>f1!hdSdQHo zXi?=K{`|0ppgsKxuqddu)%Z60`5Ltr*_0W$<=cGS)=&?0Hd)wQG}4B zeX-2`(>p-5A=8xj1HcL$YZwrQz9qW8b+7X~`2u4lm)nExE%j9d`Wt{lL41{s=}v-! zb|_L8gzhB}!3J-s9zL!CrE-rut0*lEbbl%?(Xi+qQO15OM*jiCj^HL z1lZut;tq=~d--m??|t=N)xGsq-S@}qnwsvKnLg8fditFH)#-EQ?z}^`-xu_-VK~|g z76C$|n&4(mfd7=5|Ec8u15aE)w+I7gm!57?2SbSAwRgQOqjMYfgl4WPcmA&iM%VAZ zHtdbu<4%;XgM#50=LmE7PXdMGpMAWArsbihm)}ns`Ynh0819x1#oO6I4z3q z`;CpJlDkmno@f}%7kys*<`>=xLw#}Z_mxRf@NK)SaP5iuN{PCND7+T#S@7(iop)9; zADoA{oY&_V7aa1KaMrXC)T){meaMo)8K3XSd_xt&| zX3j0lgZU2Hdu9X)tz(9ydF5;CcYu6vzD@;vlDV!Bt6tR&`a2%tE@oQNhv5ICPqlmX z60)>}I6Vr@YSqfsyes$EXKY66jU+S1oHo>wrm=#-f(6Oe#qEQ?OjQ}+k{EmXW=sVew2=S7qn0XfNs(Jna3EW%r4xe~A5EKq$z-nwiM=?nGu7y9?Q+G(h}fj>PxaVUA$1^~+7_D`Tqc#gQZc*rt>C!%v% zJzIj$pm)?l>OIL!uYRuglwixx#};q3w{w7UT@CRGE+xZ>Tc(l~kyD;W+v9F8wfT-zj zu7{8Zm$1_&^Sk4dyqn%20rEtW2k~4OU^L}MCyQ}Xq~@F`xwP&%nd8#=uC-7tl;dDW zF{yP4YICi*2z(9*9J>_#Yc+Mqe`uBC@*r~1usi{;Xx8jQ&T@VV421HXzK0Dwq1ew> z`t84g+lr37zoMTu>0=Z-dT#iiBUSi0dl@qAb#Be^u$Xa7o84$0OflW(_z0ahZN2kv z1=I@7=Z-r~2PDqHgPj@rujMzMl^yA7^KPykStf;!~)&`OlMBh z_Fwk3Z36WO@wT5vjc^g8hu-sdRBxdbB^P@lW%Pnb0533 zqM*Wyy((;Uy=N8NMP+B%POfDyAOngv8$h2U@11VX>gdM< zhT7{oOu!e8lWa>9csm`Gjv(-@_f+e|Po2u8>vv1-aAL{)Sy(Du-dbEf_yzDA{x^5a~WZyXr==UEKt9HPJXLP7G}Ucoz64PXyJsU4(AP zvleMoigIu*a)oeb%@%^Ai?ld~$OZ0`5h(ul5qLU7LuouclCQqOA42J`S#F=!;4R!m zHI^@+PAZX`kTma)x0kHJ!2Z}t(KelXu5MfMwq2Mo#C*hU+XC{FFR_e=JUYL@+Sev z)vN$H2nvz&zvWz(*oar5AO>6)W_ChbmF?_%CB*t}`v0#9`9Ei+v8o8+|K}-HWS1r; zJIP^5Bq<*O0rB&H389Lp{}d$uC;6)oTHLY+n!SnEM0Y1dcPAioC-{#-Q%^W{dnFzG zD<&jdI#2!SSk-CfbJ}~w|JOk?>rM&jJ6C`8AZqo6_IIg6U5&w>l%t-xm7|~&au_>w zzSo;{vRTw*loKbkFUIS<*)lV@#oVWE`bn%cbU~p1CGpI(?Ktp@&~edTKtb@+$Wnio z$zRx{XWzLg91QUfSq6Yl;K9}_0cYUzl{VPp6co}A>u-3Z219G067>tdPx-P7MO0wN z|GR0A(EkWW_1{bP5&*1++77Md4>qqA9{-EIjqCqC0{{D`{)4?uxIhU46bYqbt?Tu>kX_s#iV-5upb zq_&QtR;(MKML_sK_Fr6>e~sFOfcU?v_TRn!%7tLIjuV!}yEFxMqPSuDRE77XZ(nnU zRK52^Z{rdZ5)u;Gb3!$r^3Mtj4__+QrZWwRIsuR`eq{K#Krn7 zO?aI-hmX%T@3_KpCg-n4FL;|}r6E0KDnvRqC$5gh$>dbS+mWp3%=U72?2_VpwjxiK z?D4ztJ~3w#QB?B>&>a(h_6;UmLw0kNLV7UHV@ds>bxAu_sC#l}eMm@zA?v3yK1*O6 zKl|ci$M1o`2xq)PDim+^;`{SzAvdG@zc5h_3VaSg&vSc++ORNDVY=#29;zE_8woAR z-EjU#$^~j}w*hAS7;j~FGo-$s)28j4%liW~3mhFePyElkRH7jWQP@AJ1q41HQG}0f zsjV$YX@a*FPp^-wsx!P*H=%*aNl$!ZjGv?`)yBVKlRFBNV>;%k4fHsN3;n}?h9G^Y z@($Pe9mHK7y~HRodrlahS3}idEVpG2PGbdO|Im_URM55LRJBDO5%0cdk&Xf1|)i6ayQ35u6 z8HPz?EUM%+RMP&%HZRvKNReH1w<9xnQ|=m1)4}+UE2E)?`78`EmLEp0N2K3BExJYa z13*x%?`nq-CRa%I%*ijX6<$ZfuOxSwEpK=ch3f0WnhO#Duv6|z_$FZ`qPeJUj#jP_ zJ5QlbIEn*q55`rN9nSGvNW{X{@Ru2Vfd;Ym0dm@YXyF7mk?#q^8yq$61oLFuQ=G5v zF&!k;b1vt>kLzJIg_PnUFKN+xtDFC#Q@hX(rGy?^w=tu!7t4_Zb?R!ADe18qLe0{J3Wb#%ZTC%jUrnx@D9d{lGsGhg3(bt>&WE@cBnL2sFfA# z&Y+cgYk83))mWWe*prVhY|6=x)dyC32{gtcO2cJI=av|;e(wvaWM;wb>-YqPrNnw> z_F!t-lj`GH0tu(7wd$%u;$!LDPZ%+Xz~wFs7I zHSC_${O_|kd+T;-VV=Xtxnm5cRFR<@%kB32ekz2nn9<_YmAff77%z^?Dgr`JTk0PbMFc4qu<=`eEBg&r_o{IcF)09iW=P9l@<+9v^Nh7hShj0od~zgXbyY@K;sq-Gp}oH?#g2gi^I>kLcz?tTx_ z$f-ApR~Ts=F+_${%fyEfXSN`(Bxxfhm#yz_K=u-n5qV}!PRO-%v9s#TI8k8NmfcCTvQ{W@F}5ux3VdG5Pz_EY4CyMmZH13F zU4>m@cLeovXR{r^HjTL3?`TigSyP-=1=|oz53#8m#2DIQT>SnKl+HsfaP(()YD{omRVe3eIOyx! zuj~}H2fL;pTtpNi1|LUcNu@@bqNx@wo%%!WXU>`+xRV8jz$6Y&^CH_0MG`Vu4DLPl z0OUEYWiqdD3gI+Im65-YnL)IY=~K$F91Q%uvUqvceaiVjB7q6li^<w;JEX2}T@;d=nhOy?rIv3?2B6dSo{KsYHviqtM(j$?wxrLqbE|ssxQI>%1Cb zou(*%ozhZ9Y;}|C|HZ7SWxiQp$TD@wiIG1qcSCl=W;ckUCW7mD=kbrFLw|j#%=_Ee zvBxQ^oGS1ks2xUb+z?psEWjscbU5GE{TQJ6kEA$&ZYyFG9n+gcAx!)XeqHJ9mfO61 zcdNZr*6qrp!5Vx2({R&dfq!Rl`Fh8U_G7LU6VcWOu{Orxfe9P^G|_&OG~mB>GgJP8 z>W#4=JF1SUV^p4hCE{U`+_Y~sx(FWK;a~xD5>QeLHf#a!nO)7Z&!Jl`M@*{q>$4el z^=Wv^YoyGpI~4mQoitWNt;3XL36+lP03lf>RQ!#1e@gsCJZYP1w`J|SN% zoquiQAG+*m`o*8*kg|tZWw|e}?xy|`m*BCEpGtvj4)(Y@5vp7;uC%|RGca>PD%_Kz}phja9u57s21|0Z_v!@#c%3)? zbiDN7#7C_}7Xs^@hRBv?&^3*xXXe0}3TR4ntd4`Yb(2DiHAuzFl&kyjYEabsHdq!* zW-P#I=<@v=g};P&Z0BkiRHh`{C;gu2mWV42AFn(VQonpEe%n$Jd-D!HGryS39F}^X zkQ2ocjJ@fK*?cN&d{A4p!e1q4=j7WI-6N4O7cdgY-=$%i1HeIS!<9Xzm|G+NW7kr8 zx6xS!{N+=+uUvz}@g#LfuR8bAY$q}RzPx-SgP{CrDsk;UX0_Eqa;E+DzLu|_oi;-j z==aP5_#sT(W;>vB+!{qD*TY+wb2LDUd9X=}aoxJn`Ae2JAsme^tHm8a;I#V^!i z{uVE`h*bY|TbHM>vljIa7I}1dqrry%vb=jFn=dCJt6IR*9c0TpR{!SXZ>G$uIJg_^*IhI0&BP6mj`7LmW?j?Ej3I1tE>b!pQ-|Up6Sasn& zq^C(gXA&nU0OjUF*d~sGVW>9L)vl9U&msJNv_~6&-TpNfwE9s}k)mW+S7OMNajVQ?kAdimrO#)uMtw7nf3kJ~T|)t}o5 zv5(!&0BY1D#JUquAA2(iutcI#KIn)@A(f;#(FVvJ`+<|tTEa`?Rr8>eSJ>=98a6mz zZWoL193xVh^VGU-ET%FzO5V$=Wp@6+Qb3jj+pj-qVv9w1f285i-q)0r5lSzsp0iyz z(LKG`WYjk}uQv)SS~j1rDBs~rQLl6GsK%e1z5IUfO)s>wDD^ME4LDW1=;KsT=Ol&= zBuJ(v8Sl_PIT-aXB3bR@^FoG2Rn8G&gPmo8;Q@tg&p)WnRVkYK;>D{~`W;8b;ypZY zcoUHyPL8Uc-*DK%@N;DcJcwQfLNubuD_x{E42$cHYz;{QOKM`$Y~Pjb=&vCAXcg%) zQ$)vL1dSV(pv$lRZ?C|h&F?SuwZ)({dV?FmF5h)T2vqgM?Jn>c<;l3D3Ie)33}`<&7&!wB!-Rqb)8C5-Uv@{ z<1Q0g4}AJwiwIsT;#3p0EjZo<-sdpKR!*Ev^OqgQFb@8bpW<3vYaGDT3kYW#@An}mS7i0-zs4VWN2bCXizIKwzQpn&Y+ zx{Irg!mnaGgbd-iRY{P+vX3zw)JI(3ZYdXNb)8MIwt-C5)$2+Hjg|2I%^9cZsnM|0 zNtA0!G8H~U3&7yb;JZuiu(n+vzYfcugpf6mjF=1lK#ACrZZku zO*swL-tpcU~?O zL0Hm&U!0MamrpL@oQZ+b>6*C_3*rRzm_d$)Y*z9y{EU|CYwmg(YKdLaCbZzhAB_|G z86ic5Zp6i)(8JWm<0_eG=8$@?>i2LI9$KRwb@mX5pJzle*TC@yxo4gxTP)tIxV$3Pha?^ zlXPu@QRRqogWH{3u~Wse+gHq95nIGf9`g)l1xcerg;|zTM6xM0dBl5Pc(+&|8Dk&j zE%?vKqy!ORM#XPvS`ge?Z*#{_YOF<%x=ueIb`qpS{5x4@`|IF&G3=HQ*@3aaD9ZHK zE070}P=-+(q=v@oCO~MBGmjK{wsQ!WH!ru}l_74`b;1ZuBSkFfy@=JzEvxk8XgJ`h=fhQAE5sK^Xj=QOmQ(qV{C1H1D`DG0 zj=-{bA%eDB313Wn$I{Por*}LRpP%Xf6&$IY^~UO@97RD2Y7DpdobO8R@o>8OH4((< zy@T&kN8CW)KKLbC+%3d)o$X}rFxacIwLD048_=a-zO;ktLmW2e^fT6KNyt-6e$Kt8 z2Jn5&EOtioI`WP+rj21tl1PHCMG52a+6k@zJHC~4dwHLb@eGJOV$Gzgmvc#Sc*OUk z^yQ#pQH&6Rv_9|+ysEUx6Z=&r2L=>aL?pEeus9?CO-ihAN5R- zuCOJA0bCfR=pz57>^PLk3%^J)-=gC@`>4AR(Yytr$bG(w=o!bkMH?wUYCNA>*9;VM zv=hh~AXD9I81U88d~ka<@;RSQpHb(4w|)A3w|v=&b(5&Z(>|@BtaUN&^i?^FKF^&B z|0;tz&O~<=rNu71hs)RNfqJJH+fD)r2^aC14_ zpLpXKKx|s5`}?q$6)0&TJ$HL}tNuXe5zrrLURuugxoO&EF}tiKmXKlSjVO$l$3J&uHacIs% ziyYZ`&#>jEvS70oGUDumpii!jMD#Ejk?0_SEW=MEl&vz0(x+sS`9*}g3~~0O`-e{O z=Y}{?QHkPW?H|%BjP2`n8kv6gUSqa(a%)-4%&RQZnvWlgbAXlD%Z--bDf3zmAYmr= z{S_)VMBm(-xIzez38Ygtq|@OU_l45wLM2HUwrYulyVo%I)4TLrg)tOCDN;wfBS?+X zU=o8t`A4(IFX66LIjWQ9v_c-_gkya!nj}1``uYGcPR-B?$J>PjYWkGld@4t3T2DjXL0{__!=33_D zrw9L}TTH$#Iu<&zauR0F!g=CSpdS=fP-{bCGR7X}1KlO_w+W5Xkt&{YiO{EvQ{SKI z`$>Yp${(}+Z(rT>>_TaBajYnDOX-a-Kw$XFaVLgO=O=T=8e0nsUvA#o#7fvV;DE!& zPFhX8A5%jJ>Q-4F7f}`mh1I^k!L*XE%ATxHU3#gw+`EUCC}MuOmltc%y$_{B^x!|t z^PN@Txo#rwCViT7qrapAuf&t#Aa<5Slrh-yfAFgiqPeJ#Ja-IKNU0aqO{u=aI9-(@ z)!ax_hxFsCenBC8hzeA;yDc&iostVBiPOcU65VZ88HgT*3H!beYIM~P%m1ipEJ{34 zGrdf=MYmVj`E(%%qIQ=c2i(AKN;3RPEUD}dnn#1o?bYQAKHH>P(24%E z{&P+eKg@w5+XI_b-Iz5+=6vS z6U`)$B&bEdU+mwa2Lx*E9B}~sk-c+jd`n#@^N;>`)j#3snGr^x|EflfI`fd zoW8|>OqHhi)eQx7(pP0ph~%~^c(ia%-ngdFcK^>%q>A967x$%>b;my!Cx}arQx^4} z!iY9q%p8B7BL?uOc6wSQ=w6H&JAtbK3}CTgrEier)80b?PU+4kSL?)=WRRWzwm3zx>VWlg`^4h6b&93Tf#PfR~luDCJG` zy^2}FNVs6t?eU?Nt*7=j0AH0qm>mbnv>-Q~mL|(6!f~kfRWQ<{Sg)^DAx*OQ>5G#E z%lrUW4B)c=7>IUyjR)dMr;1!lFcBzSxf8x1h?-mn{`zIocXJ7+#5plZlz;Aa}!0U?)zR4u(MD(PUuhnje@B0F^T887L)Y%T^}o&)p` zxlh6(y-cR$G4gL#Rw8~f#9{XiVPHigivRCwnnn%|BeppOgRkdLVaEyCruC${iR*&gJ>e1%o3SiN8GJ z3wmEIMbhbY<+;y2+;LbKG|wfcX><=5P< za4mt$zoH*tuS??;>8nXRh(k!Z6&&I3j!)*fS$EPxXI9ff6XMTM`ca*H4SON=$6b4g zVyRvxG{t#wlJHGv&kOox^^`y8GJN*7DCqq81E;G*X*h-PN_w0Li{lat_#fmfk9k}Eo;pTdt2x&H6n+oKq^=T8ve#9dmeQb?h|D~ULFm3a}T=#s= zG=_;8OUaSbr6R7hL8im+Ao(d2JHv=WA$@gfTn1;$8+pbZ-yq9qIYFLnFSAt-JM_e$ zLR&n5nNZ+CGbY@fFfXz*sjqW9;S`BMd0Xq#6^C?sH~N>wRohWb@K|m2-r>$QjS==X z!HHQ%JHTpng^bI;C1cN9b%lSVRnS1sSn$`qiCfeUU(I7u***v^6UKQ$OdS`gjR&z- zF7lwV{nI7n&wB#-a?%;%zZdgs`31=F6?-i!w2ez?laoc(MAJ%DBmD9 zWgcGqe(k+gRZ%O+hN`Zl*5BL^o@YYRUWsv6Ka zk__n=pkQ@Dm8n5tTGbO2{?h zPqw-^fXP*Ey3=feO2(r!;|#Z3xkMeS&(_p_iLb-6KQjg$N6h@mJoiM@_8xJv9=uJn z$dwG1>^R;(B`uu(`NFjWqu?Bn45S%Xen_AAM)BrvSC5y&Ec(^xA1hK7MKO;;OhWup z4K3U2r_pOu6^jn7ma;?K--X8nPJo*2l#D`Fy2eGrnmD-=S2gwTYTh zi&oqMMpOT4tnxpnQjCikb;}`D*?j2XJWQoRUMWLZ#Z%WnPI(;VWATVI*vKLF(@Z5W zAQi``2$3(Aw5C@3c)RlechJ9C7090Ja}jxT0sQTx*Jy9>n+qn5Y0rE|NVO)_8RZGd6?t4eIfc0GrPHO7p^gU^BbPikTNdiUZtPO|j!EffuwSlW`~iCN zq97}&Qy|dVnhj7koqeZK zFw4wN>uJE^s*M|zdh{#Z=p*CNK}On>U1ZvcKXCB=_w|Gkrlm3m8Rle_zWjXma>`3| zBGGIBlO;XQhfx;xjoHvuc)S0pY>_)lu0Q%W!`q%_N_Vq8^I`$L;hwe45CZt%OL?DG zeZ?P+{qaD%G`pzFDf&v=`(N(}#e6Zoy&{_8r-kg;uaSVqzlZRtwp4E-H7dKnRa-Lr z>qmf>`;Wp{=Tr8*QtwhjsQ%FPva1&yt%U6+>ZM1>9c1r5Kk>ysXAFvdPRZY zzUkG=7;DoDt~L^?=X|$=11KaITEoS4vnI!ox}mQJ40j_bcYpKFID6GI>2-a_ZaBpF zfr+vNtw{n%CDUVb{cEmMGG-~q#xnz_capstxGvuR!lMtOoX;e~5P=9Y*vYEYf(r~0 zwbZTRCkRdC4|63GC%@Zlgy_@3Cjacp?j4a|Vz`jC*L3wu-J|JS5s8Q^wnfP?W~1f4HqRV?ute|d6@KTp;u{%MK3(Wrm(2*X zw$rk0-23;4xWBq@)h`73`8<{RWAc|zAV~Wxrf&|+(q$;3WjQ%zj4zaUn{i{(G8K(3xDx?9K@ zl$#6*r6lILshA?bm@V@5x0UktZo+Xz)qR4qg_o0O*Fe(KL91iUEai$Ch;`fBcSG#=!`eA`CGFkG<^SDVF@xeXB7duSm z@7q>Y^w=%Zdp#RdK~csaY6N0I)03PyHzJK|uIQ+pvq;^S0Vn4T;J5UzHUQp2SWmZb z@6}W|e!6Mde1;G0Q!>?)>ZXWep|IQZVrVlB-Zo{T>Egqdr^CM_cVFZ8axrDWl<-oL zZvPrwF!+hxf}DBbpiwPm=0$AYwexQAW}cHB>$Z9n-qpPwk~N|lPYoP?!qU&w`WaWj zyUou=mz)tS5#k-=&}ivZAU*%Md8_g1w>}HZ4-QUBF75>fv;qW(I7f8#C08EiE|x^SM% zaMAkp(J!YFC;oni>~zvt`#BcPpNfw#oNN}sdxQ7Pc#(61Mzr9f8PMs@v8^{d!Awtk zN3QQj4$_+qo|TG+uFF%k#?x&*mOM*bVA9`h*IQLWnTu4y3$gJ#1#f%l84g<{N3#Tk|9riFl-hB#+atoe-PiW*@3OE3KnQ~+7{doFQV_E zBOfdWdiF6~9HA{4rciK7=0(jPXg@=s44V{zXb#=>=<{ce9$Pr_uVk}(p^UmuCg{dR z$-jznMx;-t*u-;Ac+P=rnW!+nkz?a>H1~p-$YHli2WBjf2BFp-IhnCq)(~Nwode>o zqHG~~=hc&RKkl@OhmQbHv@8#Ed3t{zotAJna}h0ke54x4tKDxHm`_GKC0S&|ME2O3 zjs*uKG7O`ixL~fFaxPn2C-(kKw+eAhbKh&LYoJ4*8*SDwQD7DCb8S5yOZ`+o+=G!i z-zKKu-~CqL=jWdvRgrqJwq8}{ji7&-W!ns4&PJ6xab(ac1I9WZ{R8)(RO}e1R%eE6 zm`>d61YY+E%=&qzeCA8^%$Nn4YRVg6`SdqbsDtE`r2tx=0S(r!u{btwudT%$)-Va| z^41fRTUX1IMA;Vklz$y#AA-y5DdB0jv{VEhnrMYq%dAz1{Y25K z@HPqfRd3mlR@E|vUcn@T*MkzrY%joj|CwY`sh4siBl(m`p<-X>JB9paH>DxrQ^b~~ z2ga}I%J8qEk7@BG)ZqRQ>X$g);N>Xt!c)7_#u<@@=PM^SNrQ`@jA?rF2Bach^_qZ4 z;wC7R3a{|mKj++$i*2OEn}3MPu;%;J;z2admdtIAC2#*o{_^#owGUR2nNkdN!Rv5q z@lj86XSnx1r3r+3KU>gS=(?vhlVZCgb|V6$bLbxvBPC*kO|PF~FSaOCg)KI* zO&KxBn|k_{sU#_F9URmr4NITn=^lpW+8X~0d49>$wRJ$V`>d#^gO{F4&n3wxM;+?H ziv}hNeBN3;mfX!gbaE*2?a;oM*~(h;;uobl=TI9grcE?@D!;w1(W>woeZu=@9)vSu zUp+M~9;f{&SJ(B`XTmQb6V%Y7-?Kj!2x)IeaArqWY7Vru4IcLiVLdX&C!5{(qyzZg zA3*i;;==b2zER6(%QaRw(Fr6)>*Oy6NxN*3+MKsU34fAsc4w>~Jc!9?dR^W8)j}il z2B3e+N)~Q7Fqb;+S?rpc!k1-`rv%zE`|H)n?7_WbKI?Yv=8S%oVNLkP%>|xqeH-_s zHP+l#w{}w_sioOHu@_PU8cPFVBTtihX3zjahuShF_H5}{f1Lh+eD^e3)V|uj30y}! zs?HqT#n3`RP6vwi+6?~A?lR)9E2r#(kvtTs zmqEmv1q>2>N|a(lDL$wl5{$JMOa3VG6Qe~BlaJC#jKk0A=sL+aGiwh@<~uR{*zW31KO9!%8XFQh$7 z4@v4i*zQ_wv}MG;3W#z%Pix^DVy>`ck!Q0I$22Vvvaj?8=(IV*d#G~ftz(IU>^I_| zr#N@e_oVqZC=tqE*g@EvpbxJT^~KL|Yc*Ii#cxoj^N<)VpF?%!c^!FpXe(T-0K0sl z(GAu&u`dSsnu0++W8(KHMLL-bC0k!s_N%G-D{*0%ay6rv(>Jd#WlXC5qjI}21wAJj z0)L!Uc1IomgtXNgrm?uMDR2tXkpwjmh!SFzc1{LWHq%9Ph;$JR3g(z{ zt=b-Xt|vZ>NEgMx`*&%v#gD#7#f9v%w{_OPEuQ>l3TLv(*E_8tHIG~$Oa$Rx;DcmN>hjF-K{N>A9lZyA_6j^^nR)-xqBRpQE*wZt~P7}Y! z;$qTLie+g-+ucGxqaF?|=vHV?V1NkWXE9o+D7=w+L&sE+5TRs1-29Yji*^}<9=Zvx z*gKXGHKAi-{7R7aPBG*C*Y)DGE}4L1IVl{`-h9Qx6q)a7S~?M5&G@O`$7#sE#dVJc zQR*CpN5simt~x-73`9Z_czq->s5=~HWWaKC5{{!bCq zf>L^IMHV(Xwu*Ljhm_CClXlZ-%+#H(1aO~#D4#0I8+fOlMh47vH(^R-La929Am0=A z>yNo$V@)?KonbU){qErT7|2OKmO}}7z z6Hx28Vi$Zl9VZ#&vp4b1Gv+#~OGlvjcypFm8rF2;vFTjfeZFWNhA&QG<^m!8?#P#H zZneI1opO#zZBhHU3YV5sVH}jE9-@Y?l|c9TbUfE4C#$jOTvu27MYSUsc5$_%&MK_6 zw^yMtchlVqEk{eI=TrN{=^UHQP>N|*BhriYWbchU)*oLLOFt}|UHPzgo5KC>*HFVk a5t{~9nuOMuz5ZjDwW6$=Oudv@#Qy*)VLAo? diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/addicon.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/addicon.png deleted file mode 100644 index 6cb5042f2be71e2fbc5bc1beef88d79df0003c0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 463 zcmV;=0WkiFP)hG98X{hTw1Nz|2if|P_3OO^-P3|u|S*iLP7I%Yp0e29LRxeuHV1P zn;#QK6OoeHd-rLc&b*ljIXB$lpriXd!O%<7@x`002ovPDHLk FV1m0e&c6Tv diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/application_window_bg.jpg b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/application_window_bg.jpg deleted file mode 100644 index c559e590a06c4c0e393928c37ffa6f55f5da99d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 914 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<ECr+Na zbot8FYu9hwy!G(W<0ns_J%91?)yGetzkL1n{m0K=Ab&9e{RsmQkD>WX5a=%^78Yg} zc96dqnaY8fS&)TQ(U48ZF_1m6P*};Rkwe63;=+vwIhBorK8Pk2UE~r|F?p!^5#%+n z&xrF_6Inikdko>PTMRtRjKIia7G$tz_-;M#Yk%>*E)C{+*Xkc1^FREv>)DD$4Yqk* l8Vi_465gP{|B0sgANKzYjv|2$VrzGY9o?R#v4H>oO#q+WG|~V7 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/backButton.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/backButton.png deleted file mode 100644 index e27ea8cdf9a4f3b35c78f6bb0a407a4047e72e12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 816 zcmV-01JC@4P)bjHXOOu;C=bm%!b8qQKFBYiNkNO|%7ySIJu2Y@Z0Ra$@|h{{KDF!wUiay4ePIl$1|oy7p)(1ow7 zpJZTzo@Ujo_5>tq2Mlrozr48EHFO7XNgA_29ANiNAo}}5{S52Sbo1IDYVdhwS+_Wy zoKFX!%mpCCX3~4hOG}-xdkE2FW}D0a0cPL4n(>DQ$e1)=fCCL&TtG%ONRX*&K$Hs1 z^0Wo3~(tBk?t!FTGG|Z4oXdx zId|<57s|Dp6h>m#K}vyEsFVO0D?%#V(Rz3m{w?xMP4Uv?Xp}Cb@AZxCtZ0}cc6*JNbM-_bh@vw>o;~9>&@|ZG&9()b uZiGWt*08@evNu^#lbM`SC`$WRfB^uXx!j#d-gDys0000n0!c8w1!9Ll93Kn`z9sP? z1S~L^pj#XQamYEB5Xc9zBRjTY8_SZlTHC9YytA{To{ygXs;V4%dNq=E7hBBu4-clB zp8EBB_1>$l682XaI1YRjXaXkycbDf<;0(|P{tlc4g1rWnJ?_r|-vJ&6J^`)(G0@%T z1sgyCSOo3>eh<6?j6MzYPT(Z)5pW66fSs`Y9LUWXkMl*~C*yJUgnk8h1~?6bfVuC% zFW>dGZ+!p6Lr0G<&6P@Cvw3L#W?H-584iO{^6oolFaPbYFQ56~+-sKr1(bltfZqWB z+6{Uy@N?jQKw3YzSbg%RFMRvxvEzpa!&nDlYK*ovPRuRd7Ca@&5h>4k>cG6`oPG0+ zk6$|Zv%g&1zS1MhffeAFz=cU@8F&$R8;I_{|Is_2e)i;dqr`LigIMnq(p^=p6dcEi z(%(M+<3Fukczq2h0>^--fFOtd05}W`8;4r8U;OHoANoB=(p$aywDLS9mATaX`nm6& z>UP$BU>>*({J|MtJVBPF=0{Ke?(t!KpfrlKO||8AEsBkeQb$&fKYI78|NQeCWC^(f z{KF-yy)__taOLYqi0iZo8m-Mtt{8?y6>@jR?nY4Kjxfpf&0m7&>nl_o5wb{ zM#(gQxx#Q{Rv!7*(be;(-yd`Cb%6uG5Rh{1NF$2Usdzc5+M#=zWJ#-mx=U712~Z5< zq8r7jnKraks1(MW7!Y?%x23sSc^GJIZ#!T2meI% z8z*{}&>c<=)z(@YCuWvVGYQQk*eII0rxva+$Ogn{JyTEf@ZyR{-hXW}liba89g~%e z1vFS=wEbM?)Bq+;XBu8j9$xYZw%FMP7r3cp01P75&K7$;d-Dml#+XYV_ip)eo0i6$ zost1sDDE|jJX zb%qzV#!x8~3O!XSl|B)XqKFu_U;PM2n5rpjt^eP35iue%S1cCW3RorExg|+&^|JKd z>Y!j+ruuJgCB3yPWV?tmuvF?%Juh zFv+Hf3>u9_?EC&Zj@DY&>vcw>(P1F6I#SN?TwB>V`b~#o6f~k?~(L3 zfwqVQtyat5*w{E{j4=*?F~(SH2hC>l;BYw17IYJ%uD#ut&KVyQ8Brj5kW#FAC?(`= zQ?!*}J&?E^$<}Kfwf4tLYU@86SiLPGZKYIiad9!~cDwHdK@h-Ai`l}$!a}W9`_lUQ z`n(^SXR&e#|)r*}@ zr!&dfby@K|&s$nrTB_A*&0eqP_WONLYwbl*RJ7LSd(B)%L~OBGj9k}EDwRr7tyWXt z_uCsA8yiWI+;W_-?^@=0p4VtJ8ns%j=DMz1E|<%DJsSi;kfv$s`@Y}pcDuX5a{V82 W2G{K9;uqEc0000aSnFK7aoF(W6HP4jg#$EgwUD^{#1EG#TK`lABq0ppS&zhH*dH!?59vUyuRT(|De+n=95ANYH~_0J#I$C)#q zBuKnHmbo#FjqUIg@4B5+++FR=wPXcZc4Tfi4b*;La5lf3&Xx3m8j>Mf|*d8T;ci}%UJ`QaWM+v0>aK3K@!Dp2%y&6BnL z=LH;U4w+2dvt;wL$Jra__BjW=-uyjp?K<1cud{+Z9p7F1=*@KXt#$PBL$z$1j;&Z? z81CY7G4-gS#Ci*+%>lY!xU{1FsrdMYuk2Qvm^yPtNt#%~+Qr>k6PdRe^4}L*bz_Q+ z|DxujOCOxpo^HPSp_}raeH$ffva5G&=B|J9R$fLPx#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy24YJ`L;wH)0002_L%V+f000SaNLh0L002k;002k;M#*bF000A! zNklWLoRe2amMwcOvJfRWl=FTb~mmCvxeera6#A`Gj9O^2msvtt%PFU zNc_9w&8+PN*ESpc*;bbyJIgH+*I6``A?qi`#r0G?_%@70kM3@* zsE0g#xwOMRnkxl4rypW$NEVqPN^)r#`7}^o3*h^GVcVf(JN$&;>L+qe+8fkbH>ndC z`NuWy>e5=6wR;?etcscQNs>-Vq`udIZFk{$E?DS+F@}RKLwPeOBu(ROb;Mke+BSdX zzk2vw%L?R^Ifa}n>O_-#>{}fiIt~C1LzAE>5p;!PJf(|>3tDNoXFE=GnsyGO=bIK1 zDy8D(Q!(;%P9wMHwy;!cV!AMhLOz9)lS80XgR06HJR+0rMi-CP>qB-gnx>u~X54X?c%#RPO!0+k6&T|#B2sfA%UMg`}LN1=$KkThFe z?2`a{2Oj(MdH_}a4ZRMx~x#R0@)6h71NVBJA;-xtFjS1rK!OQWD<0 zkVd89A~_&oY)}P}b+o%2wU!J`(J_+Xb&b0BXu{-wO^ir?lnp-d>q1@WSgLsSg<(t{ zH%U6laU=#9x{8e&5ldwO+cC*Rn)s=tdnXF4W%&u^i{HiQpnYkw7IOC{X7Dp4-7wuYUHa%Wo1OR@xaSJlDG$)LmYaFnvwN`Mx>yXiq zDLRBEVutRG4eO1}Fq>6K>-&xM`T5f?z7|}%bn%H60B-;E9SGr)$FvcyPPO`q)5XVL-^93YUR$_Df&i_MrSNGiaJRqP&9!7$ey3!e$n;Fh z)Z`nghz!rL49$?b^hoz~OV@O%w-#xhW@(xx)vA%|sg|m#QrZ$Jo?9H#T|pu zMj9=er3_WgF?V&B^2b;zGdFdUvI_;5YOd-kxCe^2F6N>x*dq@x=_U^R1A#-R5d#`Z zp2ERkw2?+jD!IC*=BSxekoaRPm8z+bD|Vsa(nL+jk)#O#E}j!KZi$jSz@(cvV8SpC zp+*d7I>Ca2!Du5bwW4~>H8n@r7(wEXu~aHj3vAY36wO9!pUsjAs>!|9+eBH6O**yh z#&97w9%}gwRyk-UAcJNM@14&D3uZGZLMz1HyL*m(cxjEwg8blbADb~YEemQk%ES2UP)?>W_kNBNuc5uPZ!6Kia9wKHgYj5 z@-#fOsS;xs6ghhE=*{azB?68Ik3QA=7L~b`k^MhE569l}_q9DAf5{e{Q&dXMF%Iy0 zm~GY^wffpGlLeQfjF088^-qq>-p_k&amm5+7ao~EnX`0?zo^raDG&1JT6<}x&)uN) vyyhzB7y0zL2FExQbEZCHV_^9IpP7Lx=JN&nMiT>|dl)=j{an^LB{Ts51xH>~ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/close_container.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/close_container.gif deleted file mode 100644 index e2f67d72efc158da4e069822cbe338915761e396..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85 zcmZ?wbhEHbz lf$Gy9znh?Y?^x%Bps9Cfw!UsJn!aoAS>7kV)`>G%0|4uCA&me4 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/collapsed-icon.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/collapsed-icon.png deleted file mode 100644 index 000cbec5ad9e0fd1df366ec901aafe54065fa805..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1379 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ za0`Jj+tIX_n~5oC^DMQ#CujeSKy zVsdtBi9%9pdS;%jl7fPQl0s&Rtx~wDuYqrYb81GWM^#a3aFt(3a#eP+Wr~u$9hXgo z6;N|-YDuC(MQ%=Bu~mhw64*>DAR8pCucQE0Qj%?}1aWkPZ-9bxeo?A|iJqZuvVpOQ zf{B@)k-3qjxtWeaaAJvqS7M%mk-37AfdP;(vNANZGBE@?1`L$!xPY`xQA(Oskc%7C zP9V=#DWjyMz)D}gyu4hm+*mKaC|%#s($Z4jz)0W7NEfI=x41H|B(Xv_uUHvk2+SOp z)Z*l#%mQ$5fy_-z$}cUkRZ;?31P4&hB^JOf$}5Hj9xxd7D-sLz4fPE4;U)t$+5iQu zz!8yO6q28xV}~WqY(P3u6d`Oy=udS?EJ?KkhKGf&fswAEd5D3Lm9d$XiD?v)euyG8 z?Y{XbnQ4_s+KqLMOhODTtqcsTOpKt~krY9-+vtM=0x4j?p$_sBnz#ai082@RhgU&q zQ4Tm-Qj+ykb5e6t^Gb?=VP=RLW+};5Y57IDi6wTKxryni`UQFEHu?xbyzYaz8kj7A z$xhYxrBYctQ72>n$?(tJ=cGd^JfrQaW+x-&bkTrAO396adujxx{^8MWN{owWf;`jdL`2Ohm{_Fbw?fd`l{QvO% z|4GLg6aWAKCrLy>RCr$9zy$$-FaQ9s-4*R0mLAOOal4!j+cFJZ)f8D01wZxyqrm{I TO5f>(00000NkvXXu0mjf7cErM diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/customers-add.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/customers-add.png deleted file mode 100644 index 127cdac404209bf7d70a321fdc02d228eeb628d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 755 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyVz z7A7|uDHQeq0013nR9JLFZ*6U5Zgc_CX>@2HM@dakWG-a~0006? zNklGT6vscm*>T*RMH2t5L6nEkbRF!U1zLgNp^lymDUrgAg0dnALhw|0 z&_i81m=wfPM#m5dv5>$Z>`+Qe9mGH>WnFijnVtPPGaXWq+^Adc^4{aU@Ap04_rd=* z@wbMKdu6wP^MC{fA6@w|@Xze+17$6@V-4o##0zhFY1qB__~7c<{<6bcd(_`SM&Hop z#Ci7(9re+CM@a~w2+>$~QhWYtunTyflc4tQU`wR5q~}y~Q^@sPMn*#{ttAL#=Me}Z zk#bd4^IFgJM=n3P@jaVsgUhhPQCxlR_jvBn28u68q4}4o$1rUMaitK3nTe)q6 zn%?_6@`J(S=mpAxz6f<=1n`DE40My;xLP-M{llLvZO!j}U8L35Ubzx=u72 z1z>u58q2aUO_Qu`zf-qd{~Er3!OLa>s^^MyVv4r5Hh@h4fMFQux(+}r7CWjMeM3>- z^EzwxRd&@FwOTr$DYK@7<2cOC&29S)+qO4j$8k`7&+BYF)^I7jyCN^1ktD4QtI~sT zEn{P2ghC;7U8kz53V?V#j%8WcwvA`nv#L;(bAerZ@;126oEP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyVz z7CJ7NHQ{Rj0013nR9JLFZ*6U5Zgc_CX>@2HM@dakWG-a~0009g zNklJ3co%^ZB+w9-El#YxMi)0zHq&?E^>X=?n63zXz`j7t^O%SpAe&o;k^bvBRW` z=P~ravE6;cGk-2#(g76UM02Ry6YM*TudRi%i+|Ba;Jqo(Stix)jcx!zzC{ou$WrH+tG_D5q3 z?B2)Hb(z0z7Vvp3$&zNqSk{xl6rLGPtIjWU4kL%SE$XGF6*p-Q;S? zKni!chA}|fnLM$JC8kGD@>JHER;-HtPA5nisum=*YX-0{m*e~ y^)m#}1cbNd-RRwVI(MkkKRgntzWKX62*5uqu~dT1h5Q}>0000i7f7Z2at6g=k znyx)m)b5HYN})zXKG=&T1P1*{AwohAMi4|{FGUYZKd(zzNk2v}L6r3*A_!ShB4j8; z;x4x9?#kW0yZ6qWndUC8Sz$eR;9~~P`Mz`Jn;FCygY|>}>kRb2g7&+f%X~S1u%Ke*sy3f;k<#B!LOY8-miVl)X4{DO9dOfwd{F&Pxkp3i9-nzfiF+_%;z0RMf z3o(QQgc_=vZO`8YJ9%#0s$~rQE)cjGY*mU1uO4nXm`^By*F*UbHDe$eA%0c_ic%~| zlH7K(SLqtKxL{EFw}~Bls;ly%n4$y~&~ASvdi7BQgIGwz+`RN1#Rn2Zq(+;=-@gh$9Dz0+BTi&>-OGMP|F7ryVEWy(ES(sTQ zpy4zqt_Y-w3QRDNe|xp;aws)ZGoMX~6a9?R4&SbwoxaL|O%-jzx0DXtA82ej22N_g z?MtkkB%a#5C)YMl;}&MX0E) zhs10FJbHOYFEWP=Yhn|#7*5kC5)y>7Vp)Yexuin^bHBKGx$mW#1R^?xMT3G@DQ9uC zFEnz!|H$$!s2mZ=OeLR=3_d%))^p}Y!#u~Fp~pyCd&swwxm@eDlI&-4a45^`TCvj6 fI@xN0p8^a30zf2z)9rq)00000NkvXXu0mjf`VUaC diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/decrypted.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/decrypted.png deleted file mode 100644 index 236cbeb8098f5b2a7c63493fcf451f3c97ed4c19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 628 zcmV-)0*n2LP)wXB?l|(f7e%yOHCB3(%J#gSXAJ316^8)unmP)0{ z;o;%;lamwEXf*V}!NIq3xm*FD#_Z=~b93_@5mBvH`%$e{_bQdjr`_G%4iVAT*4F#~ zis$C$o?l#C(E9rNX8;c~qv^G^wU3=nhnAO@UuHEtTNI1M*X?#2M@L6*0rWDXUsqRG z`>j?BD=RCn{t1|!oqbxb*KMIt$SncD)YR02BuRQpOG}TkeVHwekB>jh%*;I5-rj!m zH-LzkwU&ipD8>Q2g@uL3=jZ3mv$M0WtE;Oof*{}k5Cp+IV~iMMQNQ00CMPEgi;Ii% zmzS4u*50#nxx5$0F~xCA-ENm|Zf?jJL)jP%2GndeX=7ufmUCc?QCe#+iX!xSJ@os1 zIOpK|K0MEZQVPEB!&-}WyN&DX>*?GPl~N>x!0qiVthE4uG);4vBngNJLI_Ct=X9f& zloDENSZk3aNiI3(aL&Ow2gVpU=Xroq3Q|hk-QB@CHxfGMa?3-&SO=cx!59N;Eu3?Z zQi3ry{6Y{BthL~r-v=nA5QZU)G0<8gO;ZRVM&jWOwASF9k7ij1Y+_;pLI^O%;CWsy zrIZjtfQS%95yCLc1G?Sr&z+r}{YIlP;GFAmfHX~EtpySJr>Cc1hJfEJnJ&`MhuE)JdVKcur&D_$9Xs@X@7lN9mp`TOuh-9hux`FM;^CzHw__ZHsnD0tA4daEVtMn%+};(%M(Za32$ zZY0}WO|rWdZFD6_{j#s(B~O`)?vfW=#m+klp0ngQW6VHZp!k!8RRn0H4#-%LpBUIy zJ2Vt{=ty;QpIILAD?#k|!-OMi!rYsa51(3V)-^?IxkHK0%qb5SuCkD_y4pM;Doa{W zQn1sK$zq1MJCCf2ioBu^pOjCetAJdqys&^zw~w2sLaUqrBSWmKgtCgVG>`KFCvK_5 z$`Twdq0<8RT2vH7SzM>qtI7$<&lYqO?_?-htRledA875EL2H=$(dCq ZG}DDYHa6b9B(^qim6wlSfU6^eH2~($fK~ti diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/excelicon_multi.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/excelicon_multi.gif deleted file mode 100644 index 1a4fbaabdef98c6958b0f44e3b52c2e51d8d5202..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1028 zcmZ?wbhEHb!b)qDdy}i44Ywv_D6M8rIc5dnH-O$^$sjG2IWAB>Y_OzkX_H}$RVt6W>T zaNfe2RW$`G3Z_n-I%U$7$&)6hEJ;aToSe2WEo)v@;=;tl1&LiWA`P_yHI*zC8Fx0&0hV z;!hSv5r+Q^It)Mn$`cG64;fCcdDxtOUe2cS&x?h^&*mRCjrD4I!0?!jn^$*6j^l<0 z@e6o(vL0{8e|N&9B*kBbo+9^GFjb`L)*Sj zgDHjCp@rA!$(2lo1FTb*bbdJ_@j&%li$eK{3mYbU_E=;im-5B&vzwEkqrP0iL9P{t zIZcz#ED=1|+AEegG2*^oMwqa;3DITb5ykhRs=XMVq)V8o@2tcd1;rJcG#AT zg^N_VI%Iu?{#r9E+4}l=`z(cD+aGvNQr=Pg_}j<)iHGZ3ggE8x<^(QoV6X-NwpWjC diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/expanded-icon.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/expanded-icon.png deleted file mode 100644 index 490e068f5a9fae5651fb3d6febc434b7e0e3470b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1372 zcmcIkO=uHA7~RkkYD`51+teQ%w}>80W_Ob&&61=|o7PrLscpolV7u9!rc0CEWp``R zQmpY1tWwc~(t{o_4?J;!S;do2V()OL4;`tZ8bm^EhnJ@|8t!%MZ+)*Y$AW1>d5iqG4WuCp3JY~O86 z)4QchD>%4c?}+OC@{pe5R73;?Ifg)|sG^jtj%c90-#PQKvkK$(7`S#7ak?l=AR;Ca z!9dyrsb+9@E{c=wG62!=NtTzB4$jbVq>~EaYe_2{KZ0}+Lvc~^lK=n`h=QLy(-fw{ zN;?`ByT(=2Ki(7J$47XtK(+)dzBG%;Nu+ZiolHm?oA#4=O&0HsFeE`9qL28=LebH1 zFKCxl1Y8c<&QneoaJe0fhw*yc$3Q=)gA<$t7!P153V#@urdbz_i^&f%V8N?T6^7Wp zP-ihGKKaRET~}BLQ>m0A<#fnu9MWE|7g7vl7&}JTwJ}NO(soH}EQqY@gpkIoqLR1E z(B)$CsO~38BT;D-FUKjRM3PoC58DXSoC0YF1xw19=)*xa-w0Wa$Z{g^m!A0y<_1tX zYnhKioQ?w6k7hf?*lACMVpyk}bv2!<;1@uf=wVq9hsG-CPCMg@&|a3JSQk^ISAdFi zA2f`pFedN1ai>jj@E^kjzT}rOswVPn5qO9aD2XIp!=BL_Jrj6#NLG`a9uSjU96?2j z`(Qcv&-w~g<7a`NB`m$m_0mhN+>%Y%_brhxh;C()rUQKf{(H=Hhk}vjX?|sGt)=Sl z&~pp!!$h_sgT7>*r0z$r_wpe!6geI%b+PUDs?4HruMRI@`KD zx!QUB>n?#JXQcjLABTklPcjSi)xh-_48G zx1Tak;DyYy8<}*~U>3Z{&Nk!-b#d{?gN%nDzTI@cs=pKH!Zi}z9X+APZG%_-0IiX3 Axc~qF diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/file-add.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/file-add.png deleted file mode 100644 index 076bd8986edcacf8a5eed2548d83b5299c84535f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 675 zcmV;U0$lxxP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;8A(JzRCwB?kv~Y3aTv!xzxRFb&a?A~BT&hRM01Lu zY-wl-hZ+MIH5j)tc8pa`-WY$}{Wq9LRpf@;VX!KE4`GDVL}y?gJy_s{Ro(_nWJ zXazm{=fn5=eUymsKNnno4zC_Pyah}E#ed{t;KA9kD_7O2OH)1hj^gU@=tai*Ka$V+ zeQfzF>xHDohJ4|uodUym7??PhJm5LP1StD#awu+WP#3AVJd73_?-BWOku7{#5TX=-MZyQ_1|CsQO= z@T(oLe2%WAgCxDL&j%gJMAySh8-G3_dLC(E|4oe2=^}4oLpt>zv>s#MB!qH!cJ3Las@(e|}d`i-jrJp0}2_43@x w#CyH^a$o&lVEojZ25g-BK7dmw;I9A!0CuTRyqGS&b^rhX07*qoM6N<$f_!8YPyhe` diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/filter_icon.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/filter_icon.png deleted file mode 100644 index c36ad2c23764324a90f6d61bf76ab56f10dd1e86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29069 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 WZvfRJyZV3D-l{5UD%8lCNBjo?pEA<` diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_add.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_add.png deleted file mode 100644 index 83761c296f342bf0fcfbc22f12f2421833d6ce0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 772 zcmV+f1N;1mP)wAQ5gRIIcIj=)oi^5 zrD-Zz5^5x3y>_vnAVL!CA%dXnAu2JDAP9OYBYG&YUWDkuvdcrzgY;@4qPV6=Vv{bV znPPd_HTN>7|IBzJ3i_FUX3l@U|Nc>b%Yh$uJQ`4T0$RurAR)gJ8Hf4g)h4V6IgbQU z*NRzc=d!w1AQpE)LZJ8lsca51K(yw&8iNxU(wrhgZgK)B+h*q_M2DN86v51{#-6$- zfI+KS-IsDd(nPTNbe1qh1y|B79gqt1g^%wA;*)Py!MXzCK;-;upbew&3STP>g=VA0 zc>(T6BNGuWi`yl!)-rz#Vc>K3N6dsK_^6x!M74~SDBA4pyAk}*7W-IE)8Lop(QgBYKRwMpJL z<|f9FnzIv#Sg@x%bPgvMi6jW^D12xgc#8HJbre5hW9^vu)iEQv#$XuY40!;nZ>pv@Edwf^WP@n&)>@6B~VI$ zb)%z5)|!UrBi$&?2g1DV(u^jABfzd)hTFI(ZAEjumek^?e;*!I1xwC#jJON_tJp^mq1_tC$=pn!bF`895AYd_Gk8H90RIwR9{kFK{PVAK ztMA}$ayqIt9W-^cb9)2o3I8uVHe{_kPqBu63ornQFypdoHl1n!0000 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_closed.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_closed.png deleted file mode 100644 index 1b365fd8a17bbb7d6cd53600d76dcf5184b3fd8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 559 zcmV+~0?_@5P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyY( z6D=;0!+w+i00FN_L_t(I%cYY)YZOrw#ee6{o87o^AV?&jDA=i>k$eTCZ3;UJD~m1s zCRT!ovCzg3U?Y~6cIsxEXptz0XpCTX$^M;r*J5VT&8i@K;5P5wKkuA-p4^>zV9bfo z-dukc^U;RK0svWplF*jyGH5zm)rrL9F2sDavD$nB}^-f>p&*HL)5R0<8zP&L^@AsT%vGBUz1}juv9EA9G@Z*^D&Jy4IYanE0r07 ztkTBIAY!IJuP&slHXmP&`FJ_V1bK&9!Af{BF2f_Z1Ep{JpWeLMKNwvM=-*awtAlE& zD#RlIKX$ijANB_Cf{rwh3CF6XC)kwN9I4d(`%bHS``+6@NdXwfQ`GGPrB8{5EK;oXif@dU&lPVixlPkFjF<_XZNU x>|pKA%d_oA*E<5P0Lg#;p&V$H-kS3}{{%M$nMDzvmXZJf002ovPDHLkV1gm9?|A?K diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_delete.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_delete.png deleted file mode 100644 index bb56a9e6f9b274f40000c2b79208c7343c61c651..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 767 zcmV>wa6MEbuIXhZn!v0Gs} z6iwDtdYO+CnciYpOqYxtW!{7#FhBGaze3A=RJs6B8^=nVIAo4--}*8IunoiQ6p;F< z3~EAfa0&%p6TWLq$fg;YVgP2cA@g@aTHgSAQgO^Nz9ta zuRv0qM0Cpu!!PkT6=^!@P^S~lz!;S)yORPHRwFt-h3{*L9?A2@ z#_|F@6{mo$AnervouqLZrsga1CFZ+F5$>OX<0AAUub~9Do{YTG6k_2;l$}1$THL3!g}I4o3^$#7D4a3H!Vw%eb{KFcKm}g5qO5rU zPZ5^-rcmuGhx#3X{WAo$9)a&@8I+;!N?Xwe!}J86KZ7GGl~a$_08Cbgn`ty&1)6W< zbp7cK)R#$pu6xi{Q=hWZY4wk6Z3R0TPsRQ5;&=5`9w;ltJ+`$z$i<3Wia}0vHw9|% z49sR{wBNE@E_&Y1uEnoc6*xUqP+Vkg!$LS=^=c_|kQWXFI diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_edit.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_edit.png deleted file mode 100644 index fe774a62c05e53701780c26c3a9eec0042b1cfa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 829 zcmV-D1H$}?P)cJi&*(l1Sryz(fM)V?NW*MYm*h@wT1y{OOp+%U<434xF@~^G znEA?Jtb1ixHo!Tqr$9&z2T2k>)t*Wrk}r&{Vj~>10GE|1#^p^WfzWjVFC#c~4?-{~ zDW%ABH3OVQRt^6|xRMpP>&lZPMRJmo9@z{M0h-uA^Ac3wn@F&sfDsWh+eV-co^jcn z|2pOmW~bZ9j}fUYk}R^zq*cpQaf#z+&v(p@dZ}xW>g4bQq-Yu0=~4Y)q1G?~mLNqL z1hTnQST%#Edl0d93o=T`lAs)MvKysg;I<0EIr!#^rzi-lM+Zx`VkN7KzxT1Z>$;0Bb@b#L@`K|3^UTV6mX%Rx=7qw+g=I6(U zXN?`pxq31?H>7Hs0oHY){hnJ2JgCfjZF3d^GxI=KE$aKS;2!gq#m6ev>XvVA0=vzl zY&3RPwEqaN8!6hMqGBWm7H~8t4h?gdxujH?3_pTT8SAYQkra%asw>Z1e00000NkvXX Hu0mjfgbI9H diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_open.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_open.png deleted file mode 100644 index f1ed9abe0338be5a0401f4aee1b3bb168b4d815f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 632 zcmV-;0*C#HP)4gUbq(tw1lgoXx`HVs0gK|-QT;Nk*gBnKlTn_z-{ zmhYU)-7d3t&KJ-ik94}dotgJ$-pr9P27{QufTqgxGmAP3uNoaE7bGM|sxpx{$6x!S zseeO+ZJ)Bq=VzY*TTvP$C03r?ILjc0=nnu+A|W7D<`Wa0NdS!2oVvxShDKmPGuu1Z{X#D3g|-0BZ&qN9*G%zO46N zD4sVu^%@Qrc`Ds1baRPAMG7LbeA>HftOGIA&>{S+y14WB!(!4xyYUUh=}X*79hA*; zs@NUjK4So91b$-;-y6->tMfCSvO&Q{3%OG#fnJLTF^s=9aIa;Dv9bIfwI98O6QfM# z&RzC+V0j(IuuEljHs;@Ei!vnIlXu^Ym7iYmY~+PRvHvr>_inmd1OCpx1sDLU%fF)P S!b7P50000 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_user.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/folder_user.png deleted file mode 100644 index 2cd28412b415b4491c3a15106b647feba5f572b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 887 zcmV--1Bm>IP)^ETwEew!5>tv%51pGoINkjSqU}-g!7T=XcKi-*ePp-?Qh!hTju~0kJ8= zM45U>DdS$eX)0wKqA95(Aq*<32~dv<2W`9 zqLV=wz9OJdw=$df+2cZ1SWCCjeW^7gS1-}%C(3F8D8GHY**&?MVo^l zyr`RHc~eB*Y@D9P)G4Veg<%NRPV(XYk9ndyMP^9{#S&b&I8Og}L+seOvA*u^MG_GM z!YYQNq-*%@YLt8}iiee z+SDX`&6h|qP{9m<_%ho4H@yZU5zx6Ey!NO~BqmTDK?d9sg zAjxEsa?xQjd!3KIdYAm=Gfd1@zt{5KIFsX~R&J1+OcT!iLhO?zVnWvH5p88TT9Ou|`hN`^j(pMtp_R%?Z-?u7&!DsP9T6l_*p__MhI(H{<(Qz4AVyz@=K6 zA(2RNY`BNla!2w{9nCswu=X6wo-qeJ}IgO@~#1kO_!wJLl`yqVX%%Ra(uAWBJy2MT(-nt z;)OK|w^Gr%>(JRP@AP(bd44vCn>>=%EIJi8*X{gtbt=vDw2Lpg?maf&`=X5&;D~Kg zskrE&FSq}(>A=r_&A0h23))xAa^cEimS*hM@Z36W&X?l+@Ep}j4JCkuC_{zZrae}j zdY|OYGjEu8J$h8SP5*oPnv52tp>hLnEB@cove(Ve@PAp1z4ng)0|55|Noj(bCItWh N002ovPDHLkV1oM`ug(Af diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/funnel.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/funnel.png deleted file mode 100644 index 35f1d2596041194e48eb476b141bbd22ff247594..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 543 zcmV+)0^t3LP)$2syY3<$ zJPP75Pag6Tcqj;hJ%!@Eg}QX?5CsJZ-6iZ#=#tSX2>*u&B0`~yr$sNj<|o?B>gGqQ z1r5wT-kUeSH($$*MkDx-2=vi3ZMRmdMXS{+bUGd9TxE>Oe!m}r!Qeoa<*uSAU0gf3 z|0tKs_ul}NXr)pq4F&@n&~CS()#`#_d;-sV5Fi0Mf+PijfV#eSFc$$yCX>;N#bU`c zO>}O7X1S|A9b?X0RQghC-G6i$yYg83Bi>kjrgf;rvib&`&3Nl{C)Nk+MX@TvhCC*s?!g^Dj_&2LH?40 zBhHKue;s9xn*WQ0r-lWO_U^wY;0wLD7<()?q)hiy}*jE hQ`Hxh{7An97yzXKrVmzF7S8|x002ovPDHLkV1kLD?DYTu diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/fusion.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/fusion.gif deleted file mode 100644 index 368319e6d8136be080ea9afd6f7925df58912563..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8821 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 aT$$Ye!XrQWer2&no4WplgGn?1==>iO8RL8a diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/grayButton.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/grayButton.png deleted file mode 100644 index 83f2c45e7e128763d0171d9225d7c53a209b0f17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1361 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 F{u`nG-e>>- diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/headerChatIcon.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/headerChatIcon.png deleted file mode 100644 index 9b0840ad94c08535d8d899c66efb67776e8bf78d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 465 zcmV;?0WSWDP)P000;W0ssI2fY-s100001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0cJ@=K~zXfV_>V= zLM=3M&El)uma*>Q=IbwBe*XFI-+v%@{q^UrTdxW?UlDEEfu|EMB5yGsVLqz!w8LYYV46YrB5N6$c{ROIoXz=CdAGmfPLYPIW2O$8i z9f%NSLDCUP;O{>iX5D&2vL7!${{+_#LZLoim00000NkvXX Hu0mjfyKc%{ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/icon_remove_all.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/icon_remove_all.gif deleted file mode 100644 index 0912b4a368eec3241d14daa06fc3d7691697edd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 982 zcmYk5U1%It7>1uSGnE<|EeZKPF) zIP2^}C;>MmS5n!n=Ax8%_?{=do!QTjGfL+el+R7?VtVN?8KRg;Wvhtep;G1Gd6W$a`4r` zvD0I@_i}5EwW$kJ=8OB#QsfuV2e_xCkp>-Aq9V{Bqh$ZiLY1@?_p2>G|3Pb(1)l*D zTVPdSDbEWWhlk*R(k{7W;x3$^!p1&9BUd%B9#(duNP1+s8are~$TC>fBscO-L?NUN!+#Q#Q>imFlsVbi9@)cv$m zgh1V<(2}guuwuHRK^?NH3y1VgzisF=oPy`o${1saTO#%k8gVNg=2I-U-_G!f^H7Td zErWT9wLMs2w5fwxrC1>F@!cpeIga#^k)kLGB>oY)75sS2P}|wP(m@d7E1>y)YJb^Q z9M+0tk0exfsg4-h$d=^yqEW|=J>J)NPZJ(i=dQ|`6Hy z&h|JS*1v&uz5VsiN!3_5s9x6t{}}3BHPaDIMgPPm^D}mt_hzO`S3}d<{n9tn=gP+B z&AT(@PN9$L+s%yQp2IM^ny#6T^^k8pbj=Cb#v<}=gsnW;iD(){cb4;^etc9mkcf?ziPU(EAHU8eq@!%CVf0w2oyH)z+mpn~R?pQq8IX7qg`_$6>TW*@}{{W6F B1gii5 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/inactive.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/inactive.png deleted file mode 100644 index e9920bf47d78cdf4c3ab8f7642cbf3bd981ced21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 842 zcmV-Q1GW5#P))_`%oDz7N*vvT4qUVYa}$i$!RF&xK8@m>Xi~}+|C=4xYM~~k8C>R{xUVr}QXmr9(By2m8 zu&*9C@Drf?AN*%Le%GFxv+Z-|?9W1>5kL@LhMuU;_d1#e*)09>_`q~;@7Q*eFtkh! z4P9yI?+>xI22Lk2ulGaX1yO)D-_p{tmM2e;o0_0lB-Gj2wl9-;g$@C?*y+`#N`6NpGTPtzu&sW=Eeq|x;m6yyFd_d$?|hCw>y^B^?SEVr3GnZd}W&7-!aX5t?TO@u22Xi7zD#W6a?phstzt`+M*ON&4}%E z;!ss+Y$Th@u`)Bmr-mBEtV~Qecv$I?*m8MW3{3Xoiy1VT; zw_D#0Cw6#7M<0yb^mvSot}gpDTmynno2|os|5#WM-rNCxrah7rf7jY{=a+ofB*jffq@{A zXV3mCDgCdi`oC`7|A!C%fB*hJD(Zhp$$t)x|7XtpU$_vY5o8z!Q2fclD#9SapaYTt z*~!4VKtZi9C39NWLxzTAjprG>9HJtw2?EWfQ7p|%78F>Bw4P{rpvyP1NYBS8)S@7Xjyn&8L6KX*B+5P!sKHo-zpZ(mho7GVKFK>=KKW(G{ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/leftButton.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/leftButton.png deleted file mode 100644 index edf02c6c1bd2eb7b9a9cfb5e38a055811b7279fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 681 zcmV;a0#^NrP)lldTuqI$8;8G+yn&0H?` zu23k1qR}XQW`n_i^?JQ|zu$i}8jYSG1i4%;wOXxyZZ?~O&*x(fhl5$IRyLo{*<>J67Ac(BY_>Oix7+RGbrw$Y`TT84>|(JvSPTl8|Ifov zDwR4-CX*V(2#DU<0YxH_Q+Pz8`E)up?Xb1D63qnXTa`Fs2x)fvw z1fRS?r6ek|(U5j>`vvoJ)1y|aT}Rpfm#!d-3y}RHyVv&K@diI5WKQLweK7}kbnrSR_iW2`+FNg1p(v*8QRe4rb^;| zyO~a>-(so(5YBfzdk7ONhVTB(p9miJe=Z)6AES$YLk}ANg3cgX|0}=%-#1t%MEx6~ P00000NkvXXu0mjfK3FXE diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/loading_bar.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/loading_bar.gif deleted file mode 100644 index eed8a505e7772839854a867ea79a3733fbc10755..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28954 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 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/login_button.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/login_button.gif deleted file mode 100644 index 990b52276cce04bb52b03aac671c0ab8301539a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1222 zcmZ?wbhEHbRAmrl_|Cxa9|->a`}g#>%%N7lSKy#Dp!^=}TZ`gElK>yhS9hkD)}n)~{|$}b12 z-tX&qx2Najo~3VgPkz2*{^wo!FSkv6wq^FGE%8q`&G@t_^5e#cR~yQntef(2L)5!< z;cwQ3KU&%QWM%iG72S_lbU$5L`*KCr)AHvtBv7T8bUAE23@Z9 zyHw?KsnX|axx=M$ul;rQXDe+km3dw+wYyN_cCpCvLXq=@Ld&BiRu>8!FBI7CF15ap zXMZlw_FRtT`5dzYg%;;>thW_ep35*llVN%WNT!*dNi*J_V|Fgp@N}y2fpp^&DMrVV z4UZ-p9#1wpoM?C`$zVsa;lV_M{qY8y6Abpo>FnWPj{ChdS73y=27TFWQb%@KC*oh~J;pYmX$ z+p_cX^9#7H2s~t)J>MgBnxWzaW==!T#Z`ZpRfRhEU0)QOIUM@R-@Yznj=;sIeAjJs zqcZNCXgS!tDOb{B=ix=`T5P=E&Epl};N%g>JyTTr;DOF$1`ZCM7eWmTjEv2A9p7k zO~Gq(HGP~doNdjLV?&SitKT}U@a>}7jrp3622xMfXxv<=85_=9?k~NnOtm6VI@D53 zSyn76EO=kD`hf!nPEXakaN$CxtJszr6&GEBjWrr?cc_>8O4=H0WjeHI*htn_yw?*mdhTW9O%;1XbxWLd|-vw_c*SBZW7ll9zOLJ!$Rn4ZS6hzY)6P-PR7e9FYiBF?8HXSrjJ zM#BS9#wGzZmd1xiPqi~M6^H~JTF_*s8MA`r!=prwcJ5e~fC(2_53%aGIq)zwv~)Id raEqxJJaB05_GxCi67lKaF=h=_l^+LgW-zp|g$E@tDl7?9V6X-N@P@)S diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/mail.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/mail.png deleted file mode 100644 index bcf7d25482f8b02d730264f6c8844194eee51345..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 449 zcmV;y0Y3hTP)oSdB4*x2OcFMd7o}I|Z$oTj5;NRP#qM_d1 z*u=!detv%C<>jHFozKtDwY9OhxV5#lwcp?0%*)2~^z^8wq^PK-o}QlA*3sYI*t@&C zzP-Dio}Ap;)u^ba_4W1h^YfXRm!+kp`1ttw`T6VX>$kVJ`1tp_y0^Kxw#37~{QUdS z&&rLBjQsrkq@<+T*V5M2&iniO%F4>q)6<8Chk}BF!NI|rnwt9h`s?cD$;ru+lat2A z#_;g)dU|?`i;I<&m4ShQgM)*BfPgbJ-n;++00DGTPE!Ct=GbNc004zaL_t(|UcJe~ z6+=-J1<-Tfw-wvAZKMBok`)ZnK=yRwPuMRY!6f27qAUR9Vsf0`)KotNWUaBG5S566 zPTC3s5fWX;e7;$9MM?r1Q7>b7LoZ)wP0JOaTB|pj+cxWTHT9?ufQzn-ILV&a{7jzn r3t+igZ+QR9ZhsJf(^>F+U2pdXFNF=whC;kt00000NkvXXu0mjfrX~bE diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/map.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/map.png deleted file mode 100644 index 9ecb79abe6dbbe5c7995d03d93b8a884223e0a7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 611 zcmV-p0-XJcP)X&c)Rx=`*9wEGOQHJxO4U4IRT*X zDE9`L^b(eXD|ly4aChqnMn~9bf5Or5I2oPN8V4tbM1XUGGdafY;jVKCQUOjwN&f}( ze+?j&yfA-j`= zh~Q$9$&^58DkGAJX)LzO<2c5jD4HXfwQ&+sQi2l_4OW|pIA~GxNNw885zN{Q)02iy xg%tQ%JbUo+zb;auM7oXJ^?H5b>-<-M0RXPuEzWw!vCIGf002ovPDHLkV1fp46B7Uc diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/no_favorites_star.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/no_favorites_star.png deleted file mode 100644 index 4db054031d187067e3b427256b28391e9cfa90ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2794 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 EAJ~1Lm;e9( diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/note-add.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/note-add.png deleted file mode 100644 index 96bbaf47179ac01a243a54720f171370bcbf74f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 589 zcmV-T0nke zCx~cFaP7rI1viYgOwnF_MN@$+kQ8GGOpe9%ZN#L)1u7#bQcY~mBf3*eMT(nrMhIyA z^zaM3v(Z6NhPONoE*!U(>IM^y8MK$4jv;WgxwZ+dWk~rKNx2S=Yzk+t;cPa}fkXFb zm!RyXkW{v&Kzn%^ruYp-aIo)5kkH8pfhVx_VjWOrtahwEm2ZP3I>}=@M+hQ7Qnt@> zof4eUP09--)T{*y+nE1$Ylz+srJx+nPmba9pHM0k(D9JK5ZO+p1WR+ko9`>}`u^+V zy9B~sKW{Ct1GXxdaF~MaWcKU5<6Jvnj=i%V9JEVz!dJ?sEb(%-RvvtR_fio!j_9-I z6KFqODTg+~Xa9Uq6+zN?3}pzEJkGwhC45p;6(8h0RD=38c0RwqUuLg~$*BYzJLe<6 b{s=GtV*W%U)U3y`00000NkvXXu0mjfoOk^b diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/note-search.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/note-search.png deleted file mode 100644 index dbdab172b1f7304de5f3f50ba0a8bded20f691a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 876 zcmV-y1C#uTP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi00007bV*G`2iyVz z5IF>FE(gp200QhuL_t(I%XO1aXk1kk#(($Tca!;>naSjtWF})$GA*Sc6I%+RB>^p{ z6)Uc!n^HnI?LtLxr7jetP$*f5D0E?Kk>W~33PFO{7A+A?CQ3<5#xzOOPNvhCCS%Ra zym{|F7r{)6`0dW({P@ntcLcz>_xJe#RabL!ql?mJ4992yT4jUo&^o*0C0dosqZ<8a zT3G)MI}Ux!*)J|)bO*6)jzF{Nik9 z0;H5kC5U%*BK#3H7XM`Yr^UwrFU7la1fmh@HHUhwfidQ>un+>R6`@2N;S4b|_YH$v z86$xmk@ghQQaFzL-(>*b2Mnr36KLyUb-mtnU}^2?7O8w82m~|@S7Hf+kOI#$7_)Uo zFw}za6spxi$|l<~#=G%wqdb&J_w%5liH0>TVL?Os_{K-o!5BbDw53>DTp^Xz+W=`i zb7^fkPckXV_9d6#M%|MZDDsvl5w~*JHg&;pa}rR%7tle{Q3)#*cN10 zrz8^>^d}|hlp@_F2?ivS-(6y}TwssgY^1vRd%k+~VB&+RnFXp&oQVA-Lmh&_Hc4Md z5OCnPWtje9f?Jbc6TUr(wLHnDYGeH8(uWp6SE$0fqx%^9@&fZy6I|`h(bn0El#;*h zFR{9Goy}5#@ZBl&-}8)qc8zl<4>hX{kjn=7lo&jHg-_pj9tvxu zLnC}%=s`UC&i|+4Y8BTPtd<|3Or3{!E6l0^0R92jd=Ngo8nm+j0000A#`G))4fTZz_EQHMIXRRv2Vb`c$llXC@kaTc5e2SE`3g1WnigDwtYwMumr zEhgW5{k=KJIB-uHC~rnJo<-ga>B^ZDF!oHH{PZcZEjv98>D=Z1DROAtF?2~dy# z7C{4O#591Gm=yStaTadR1JDN$exad*$1n{z%~1_F$x$tdMF*1tq|2~o{jnW@hs8&C zF!NMAs4318n36(9>-;4o`|tpOWV9~MF$^ka1?_Bo&|f z!c22aGBg#eegDm;kDvMSHL|+#lFCqRPXjAidi56RuHwD+lVb?9+b39AS>wX>Wnh^1 zZyxet>GE!XNS9O7lXyMQPqtKm=A>d9=KzM;-rC~l@(re@4glc)0;-KMs2aREI|ZczX9Z?bA(S(w@41{m!*|mCcQHjvnmdoafu>I#=)I?hl$Y VU4|W={|o>C002ovPDHLkV1iI00`33+ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/notes.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/notes.png deleted file mode 100644 index f54a9e8d4ef19dcdfa41f100b74e48a631d05336..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 673 zcmV;S0$%-zP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyVz z5eETWLxKqa00JRNL_t(I%bn7{OO;U=!13>M?)%r}4)BL0k7p2Jegl5#WFd_$v4qk_cQGMEN!|&70Au`@(^$ zqqIK7;_N#z8H4%+yd_N{dV2c^uo&a8rBx&o?myYs$e>=oJ%Zg?;pLON9F!A?2%C$u ze4Tj3|8N3TM_YRbXD<#g@%HtBIRPjxDPb#{;62SpI_W!q8PwKxbY;|*2#v+3)!nE= zY7hdvBg_fig`+fb!XN|cP-jsr_!Q?7@?EFMWer*nh=HF!7MYtGr;%gSqP|REJo(lv zuDT5_LS4e#_c9{80rj4yLxy9;BI}#;dmK>VrQ4kqp_E0{MYN!893m+zznznvL8vwrnfsIRHqM;Tp00000NkvXX Hu0mjf*E}WQ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/offline.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/offline.png deleted file mode 100644 index 4519ff3228887a44a47c76f8f3b2821d4507da78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3483 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 LM=>`K2ZJ>L3sRJQ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/profile.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/profile.png deleted file mode 100644 index a3998fca6945bc0a43c58e9eeaf1e64e2818ba99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmV;<0WtoGP)*!?eEmp*ZKPTGg*C9Yj$8_W>ac**xB39(9-z$_z5plOKN~LQ)!2X zhlPcO0001WdV61akw18!($dm@e}932fti_^01q>Wi;plZExF3z(AVCHkCnQ{)rW_N zKv!cZB_$F#T)D;6kCvC8sJVy0=UPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyS$ z5*02*;+$Oo00E&%L_t(I%cYY|YZFlvhMzN&J9j2h+}5QVLGTNmWyB)XVxWyn-Ksmm zwWtsS;zscY_#=u{Xk%I{DGo7mo8c|F`0Xh3rX!X6BqWZ?&7@9J?G^;qN*IF z0*+Xf@ninkhu69D4S-50E1gFRH_8N8pRQ{t^7j41`K7`H&iTg6yER_isWEceC=*|P z($?0ki{#EPPOKmT58mvsH*l!;6XGkaw%%Vl$IpI_*Afo`pc)(c&LfA!bFH@CTRg+_ z&JNi~0WCK%GKOpj2MKenHNAc9bpGng4`z~>p%X+(Oa#SRL*}$#*v;C>Y~x!$sU{Xx z$eb1?+y|(FHHKeK3JrtYVWNn{3#!V{2h(z(L?&e5{{l82FQm(#zbEHstHd@Yww9qz z0VrT2!>HKM-ELk_mp6Kxowe9_4ETqMhkpRNTg`g~1ydX&A134Pb9yH@-#@xd4RYWCOh^ j_j3tws@f|6{v}EvA00000NkvXXu0mjfKo#o9 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-first-disabled.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-first-disabled.png deleted file mode 100644 index f5610ff53a54ccf2547b935f831f2f8c85b7d030..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 421 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgfrQ6p($X9!NApgv=6gP`x=pDm_0-`>qD%T;9esQ@RW5Y6Mp}R ztNHZq;f`I?0~bu;dz>a%xVb}Lbs_hj%4r_k0}q6}jLl~KR35Np+kxmnrSNuDh6b^A z_GOZDn8O#j=<$2Gx!+Oivp<@&!lky;_`#Z62U23A7p6vR58QBV;p?6>nH>>)N0ch; z)=rJyd+|O;(I<Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyS$ z5*8~Sr8^M-00EszL_t(I%cYY~YZO5c#eda1y*;xU#G76{D1xX+j*$e32?*0Dg!NgGmhg$3W1VuwNkP&0`J;JL~N9lm|1*PImTU>Qr=hy?XUtwWunm z3BxHP$djeFtqreQ@2)OO*~7&*JL{>}20&0TpIR^OJ}59qeO7Niyv6NT+odxNy*A!I zp5w!lIlRvr6C-2_2mO?1_pdYGoCMJ<<7nV{zOj!;sRl|sRNl4sd0M~5!U+%o`aYu; z+JbPSTm%v?%tRp{zyIdZ($#dK`9;SO;smPJmb)N8?3G&Ns6~#>&wj8ne<{B6dS?U@ zd&M~m=%fn(NoI(gMMSVw%OD*VM)>0eXD#EaQ`mz<4WV;{F673A8f)KvMcviq*&JYy z2~}H}#z0Bb;6lfh^MQL70(Y)*K0-AbW|YuPgf^?$F(9P1ig+yi63c(<9b5T)Z_wp|gNtbBnaV+beFIoJEYn-VcPt zB4(U8v-rYM$+WWMC!zYrpa1Teub6gBOL0R|g=f))SN2}dJ}n4Sx_)?X+WR^+OBM!w zb-7>De;;pao*D9V_GH~RF}9Z3zb45X6O}JK+CD{Vi&udChI5$>ciVgqdFd7@rSsPr zzSVF@>}&~=Qjb}~AmGl()terdR`EaOyGYF3Ze{tSuje)1h*3WLcK-1d+%Hy7_6&I2 zXSibOr)|#X@{}0nl)6h?K3I_J6o3JG`E_mT`KZV{^1wBXb2}()mh(LkiY%%(aKNKof*;&dWXx3_!%b6ywB70|Cr3OtW=Br>YHu=!;rz# L)z4*}Q$iB}=3S=@ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-next-active.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-next-active.png deleted file mode 100644 index 3c0793645478e59a102f8010dd394a213e974ff7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgf zi?z4($&*hfZ4~S-u=LAMSUvY=o$>y=f}yJ35=L%13yP|$H`Wy`Ryy>-leOblb5?Hk z)UAt`{afAKc*xy6sXn_iNLSM65VPtF&Gfb6-&S=`5mwm9Ajt9iP|Ne8e_zh!r7CJ& zUzeo#GlD_j%haZHLB{`EXW!R6%l7O?RQxI=s;>R_;j>B~=A3g;FybpVo*c8y`cAKgUj?i4 zxxUL8Ha#JJED}Gy%wFsAG=AfbT#<>Q3gY25bMzyx|CF};m~j2#lbl*$@G*G0`njxg HN@xNA(vPNT diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-next-disabled.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-next-disabled.png deleted file mode 100644 index 12f6d6b6cbd2daee899d27075b13232b2678323f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgfH&7IPeb5hME_^wnZUhPpAn=v8h z*jmZuj6OU(@myi|l5Y4r7&8Nb^0qrCPMpX%00ce0#=ENAyfzy%tXtv8!1lMQ66hla MPgg&ebxsLQ0J#2mEdT%j diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-prev-active.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-prev-active.png deleted file mode 100644 index 2c7246af9ad2de6dc92af38dc3cf4af56ba13eac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 421 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgflFzu{gan z*w*`SfQYU6##&F;nAb0qIO-bGLUg!9xo?)1UY)OSq+!<&{y&1UF0+1Jj1rj3^Mt=6 zuTSrihi}oGT{E_reLFDs-tOmj%g^m}5_;@#c!q~yhsUaIe)$o$yZ8RN&hq-W+}*vR zE`>?ybNzX;?-kg}-SYnN!p&nwaC6t|j|buo{JhJ3D4*%U3l`DsC;z^xDf#%NPxG>a zzF0?!{ghvao}Dx;zn*sZTK09FnOrIY$Bs1o%i-O(NTM}KFilCJGj36DUh?mZ+pFyN z%{={7h$rWAaEA2bina?+UVEnr2&po%3W;LP?K1M$#E9loTEc%$9ZDX4d4GcpD MPgg&ebxsLQ07dhy5C8xG diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-prev-disabled.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/results-prev-disabled.png deleted file mode 100644 index 46c82bd5480ef8dd0300cf8b0b80c0f15328cb9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgf6i{|9?)(X{det?f>P) zS0yEY;NM?$LmnBa?f>UXE$vfjy2~Q=W>)#1`9e$E#LRe(NItl-=`%<%XP)3XvibMx zy*^xF_mUEl5`HxKGAdW)r5urac#MaKr~d!{|MiUv7?&_H$lr1DSyjiv2=onur>mdK II;Vst0L^!Oy#N3J diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/resultset_last.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/resultset_last.png deleted file mode 100644 index b8c4f09990c51a9bae5efb6e1d0eaaf2b14ae663..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 506 zcmV$fj#M<>ll;!(6K7G7 ze^i58;W1t zFf$Uu&FiNw$2#u_)HsnP1iCp8wgA;ACWaN<m0ulzrhr3SHOj9(hWTN|k&%H{h4KIp%WqAvZ|=+?HGa wo!2N;XXPj0M{dH2TaeF26kP)U#jgMZ0FN`6$`slega7~l07*qoM6N<$f|~o?6#xJL diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/resultset_previous.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/resultset_previous.png deleted file mode 100644 index 73b833268095f41bfbc7773b6df99f661ece5160..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 381 zcmV-@0fPRCP)`03#zK z26k@U_1~>+_a?GjVB4_$e`BN(!=JzZe6h*1;L~j1xcz^QuO7quZ+{s6{URUT|vJ`9H!&@%!HU z-#EEA*%?5w{Qd8L1|0gahry3Oe;HWW*cdqfF*1PC$*+G*#7E=48h4X*M;~zNOK>r8 zuyX)0JHxO4Oe7_wvj^%uP1fzbz@RI^&cMzAGvGf-v2b>Oy_d5TsFtOqc z1AGYy=n^lJZQBkrFtc+5V}Xf*{{q!sAZP%o b03g5sqVZ>I!}s|T00000NkvXXu0mjfIohn% diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/return_to_top.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/return_to_top.gif deleted file mode 100644 index f02defb98f0cd06e56f9bf014579557b75cb1779..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 846 zcmcJOp^BDa5QUFm_}yFZS2P(kEF2KUVi0wM)ovNsCT`lMSo8*j!Jx?|2wKFVV4N(j z3$|@0ikoFcqd!tlRCjhqx4Si2RabUJm%B8@tj_F= zPIqd0qdKx9I^3Zdb+xk{ZMOwdt6JHLmRlrX0}U3#bZhoZWK~qTO0$+Mvob1OsbN7e zvLY&6p&>=Dvm9lY1xH3pS&EWNY=t#okcK6+sIeGqpuu8TBWQ9WGM%Z>$6B(83}kJXj1i(3%rXH)V1{Tnr=8 z$67LL9>@5)?mfkI!m)W>WqOy<meE;8Z@$czV(obEPMe|Q+b6I<5ws+sX{_^C9O?v{_e|L&yO~bK5ZT!e}1;Tbbhi3- zNu^T5bUJ;h-|zoC4J329T(1CfYPH(M0}7eX=R_)%5~Wf}qm_5N-J8{F^#IR1yr6J6 z{KDaIs92U=K$Z^$(g+dh*;cD{tzNGm;JpziC>RVr*6DO)I-PPJ3Z#+Y7@Ezdt=(=X zxj=H6Ot$c2oy=x4al75O;ad`^zCQt)OeSPF916N(yWLL8_XdN(Ye^swV2`SLQ_(sr6bd~Ue?fF=M?x{H(bR9~ zcXr!@jJ|IT!t^MiUoUS3LVJy((dhj%&{iP7-~UuYhuEP+LC_H&&q2$^i!nEgxqk8Z z4Q>QMAvWR5Eh!zLVnGs#WEP1;_EfaXIV2c_!S;3s;_I2F5D1#|3ucj%x5Nzw!;f_k zhGG6-amG&V6}W!~zD@Wb82UBryj?DHS40a6u$R=x;}HDy7d!8+lCBXULUGyR@%Tfe z`HKQ^DJ*tf63?#l-4N&Qr-Bd6c?iX(MHbOwvG@UdKR2aAM}YndFaYaz&%Qpd1~dQw N002ovPDHLkV1lWAO%ebA diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/search_profile.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/search_profile.png deleted file mode 100644 index 28852144d684d2bfd0c97248250395f8a4d80d0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 880 zcmV-$1CRWPP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi00007bV*G`2iyVz z5Dgboy0zs100QtyL_t(I%Z1TfXq$By$MNs~{~mJco1{6cOAoBD%`=U&J1JVH;KnXQ zP#DuOVS-3SkX?D z(?>q|5M?HC){hZ%GAN~RSC?p%FA<>51X^YFY5 z;r=-B!7T046)e#PK+^5fml#Bv2JLnSrPM8#Mr%M}*cQR)Fito`Hq-lvY1%fHEzv>{ z3|jadi76C93c6i|QoS`oVH?#oFajo0${V&BFeQyznUSH5tgKo%5eqva@TEp8jp2b( zfRI?G!9uabU}ga5HI=b&i0a}+l1a&?QG;08zzs`8#6b6%#1aPSv`IQ8Nyg#oeopoVBt)=lh8bb;qHkcZ!*C7A-Nt)#X3FE$-fN2;U-1ihm zj=qb#=91m@5aUCFv?b9%rLM^@!Y|+ED9)WAa&?aRkG`apInV15!%re=o4SaEaz$1tNc5z*?K<(A%@TKe-opvj+rhn}KA4RDYb(a+OMP zmTDo75D<>U**G{%Y$Qcx=@{BEIez$Y_P_cD?;T8O6TlAGOisSY|K+Fc_wdf)$DmMU zC_KSTVHhzzJ*_>@`_I90xs2<&xUNg9Qlf9^43~|&0r&^af+i}u=Oxkr0000m$ K%U{6^4Auajc@G-^ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/spacer.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/spacer.gif deleted file mode 100644 index fc2560981ee1caca400e225e48d282106f907f2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43 ucmZ?wbhEHbWMp7uXkcLY|NlP&1B2pE7Df>utpmhBaYhCPCMFj~25SJyItL8^ diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/success_type.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/success_type.gif deleted file mode 100644 index 2f72242ba038e0f7304cbe18f08df3a319e0038a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 260 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 Mjv^=WK|lZiJIGe)lmGw# diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/tab-hm.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/tab-hm.png deleted file mode 100644 index 1e75d8d468a3b91c1b0035550ed6b9d628331423..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 249 zcmVHoOt|Gn$~!S4UX?*FUg|I6_It>*vF^8eEG|JC&W*!2I|_W$1W z|K0Zg;r9RJ_y6Yj|LOSu>-zug`Tw!z|MC0(@%;b&{{Mce#-T7tSpWb40d!JMQvg8b z*k%9#07^+jK~#8Nz0QXXfG_~WKqsO0-pl@D@a<1imW07!Ywxs-!WcmQKJ&V`W6qO`TW!zV6e!u{tM+irYJ zQ}becm^XbjmP~&D-Ukl=D*`A~0o;|+#{B?5B2xv>B7o<`x}U4Ez56OqR1O+Y-@UDxgsh zsjJjxMz5eWO%GL7U7l}YpCrj?P7kc=`#uQ6a5oHtvBf@$qO+{@uLo9jUB_sOsrkXo zRM#~XMM2;C)dQ=v*2Z9RhCv+1^iMdK=Q$&Rfh7(tk?XohK&ow9wlP2gux18;Z4Ar| zY!f(+GbU)7hHYm6);a;0PXe16;Jis74}|fErgtz`V8E)fEENXgdEVk7f@R diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/table-add.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/table-add.png deleted file mode 100644 index 0c1385767ddd1ebedbcabb6d2dfd8331d22fd5dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3314 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 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/table-delete.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/table-delete.png deleted file mode 100644 index 917d7d28543503da51d5a4bf8f9d70809b88089c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3342 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 diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/toolButton.gif b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/toolButton.gif deleted file mode 100644 index 6d3923efc8c59dd706f82c0d3d86650f1900079b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 414 zcmZ?wbhEHb6kw2LxXQp_U}hInwbUbXdQI+o7rze2B^+1U-V+UM*Dh)RztURv6@ z*uf*Dddk*_%=+Ypm2R=sE-C$;3-;x-uWg&WxU_$BazRsk?XrgHJIw=%Jwg(EQ<_84 zn|c=Rvv&5Wo3N^N_MV<8OI@O>0^S9hKuSYc zPG?Yj(f|Md8At?*KUr8s81xx*K>9#_Vqn{S;ClC@4-9=C{!L0XYbC_4qQtRc(`HT9QRkn(VBtb_b@64(SF8{aU|hRy{dy%Ot}R=)ZBt@p+P!D*URGAN zLx+zXQB^&9^6>Ffr_P)`dj7&;Ny*Dcu3o=#?H1crrn{2TnzuBinOSbJFzd6k2tGK< XB*?<XP)jRN0wp49Q(=>PDt*)$slfyumne%b( zz|EDmc8?ij_jlE^RtksgiA*+sdbDScPbgMuxUjI6 zOpi*k5;8`CeTxq1O4AK9k*=H_fvm=@_3rB0s}O|M9z>S6HqK}fecy~112Ui z10wSU>iHI#2|x@`7(fV+`@#U30eMIt(F7j$61oA8l)wWNego&gF+>an0WwEVaNLge z-WCMN3{2`t5FoS6A_}A)CLBQR6glAw6OLdKP(4xJ9KEFIfC@mrx`;IlIe;Q36GqVW zgj&`2Qb|)T&g9%ygZO^~$W|&$$qMLm`LVZ`2j6q}U(52?wV-N$^>tyVa(R8YE zS$(d*cwVOu(Dm3zIx#y}QdG6^>Htl)debpBD)z4*}Q$iB}<+eS( diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/users.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/users.png deleted file mode 100644 index 13fec65e4830ca3ad6f139b614f290fc80209200..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 938 zcmV;b16BNqP)-4uF*Y|gQCQB|0osNYB008sr=j_nEyM$Tfqj2MzVYh8ElYDDQ zF&u_)RIzwuu61CVVNQKYIALI96#xLZgK&{pMSx*Qo>v~7Rvd|ALw;sQ90veiK^;_7 zR906`XE7gFCl$rZr9(qQ@z}}v=Gnsj{u*bea$87#V@;PAw_06#Bx|4{aMrLnN zT~a%Tc2sqBbyr?QT|O9BR$B1TyY_Utv~N zSV~xDGh>4iKx6HBbRMSpYOt02Va> z06cvMOpG=e3I;xL2TF$kICks~L16#@06uh5PE!B?BodS95-=n=*6Hap;P2JY@a*;VEbzXh0002VNkl(UF(Ww4Y>dn<@)|E0{&H}I++}0`#mvFS2ve0g;ew9?ecec?zzY7^?d#K++LgGVj?2NTyQZB ze4CoGd?%A1XDz0w$w7<7_ z#Z7#XP}?G&7Vv;?SK z7cs72ICwjMtz`$<7nWzVNU`oO`lf0n diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/webphone.ico b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/webphone.ico deleted file mode 100644 index d58e62ab7e13eb1b7ae8dba910a61da1e6be3608..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 241 zcmVwd6H#(;Oki_wC3j4JW@jZ>7$E>V;y!fT diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/whiteButton.png b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/images/whiteButton.png deleted file mode 100644 index ce8c9cb48c2c3108e1f641d7de361e525745fc36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1430 zcmV;H1!?+;P)c?MQO$1h5Z<-2w)R9vTw}kdyB@6m?)2KI9N2J=8#u(XJHWfZ2Ji&v1C0X) z=m9Cfe@^m)E-8Zol8}M`jQ8`~9fX=>$tlORJYIUHS{~LDK)D#NM0xd3qZ76!9pgzuDWvN$`_?l=^o$$=YaQt z?hyJLU>@k4KYxCqTrU5v-EQ~dIDW>f=ap^SRwk2ii^bygN~N*_WPnxRuaf-uJaIi< zU0wamvMhNS;802_D~@9`KR^EogWx(1d~5^1Vz5PmYuB#5T`U$)2SE_-6)-QVIF7aJ zx=yp%>{Tk2Z-EYA3Gg1^0O7rR_dfMJ@5sw~xLd2MtE~$cF8m?k1PYi=Mj)Q&O~r8> zA2zg5C}bG~Z4BfUU;!cE>O_YPRZ1xaYZ?He61th2oBK(>-+$rl@jNodgbbWBK&$`_ z7{_sx*7~3{_kSy~D+x=hA$<^RFTYI=kV&9Mjs0N4P(2PEjbsu*G;Tj>qXRiM#^@hu zdQl=W%)iDMGm$_7*uf08%;wt-d6(EX!C*sa`UQxY=w5{O~S%D6P}!L=3Z$Qa#IYoGk{y zq^s3xdlH^LeE6`Lq*+O&QY|Z;PH%{aD{m5sI@kWi;GpuvSJZA;<|3#0v<8A zxdoL<<(s>A@76fPsl9XOPHkyv>Awu#ET(`*mhb!Pp64}0BovW$sZ{!^Ua$8K!^@40 zjb5o#`cg!;L?rY)ui^Xtx*f-HoX_Xk-rk-Ef^N4f_wU~i&z?Q|N;aF_>-pxnf!D8J zU#i#ZE0$$_FCyt|Hv4s>(Wu)1yQX70@GTX z+qZ9T+_-ULd2@4fT|_oSq_eQF&|F(vd!V(}qr8_N=%?%J>uF<*XN)-pC$+jeVy ze!k=T{&%%ntv2lNOoq?r^ZA8^g*To)ed_wYKcltI09j*9nn8Ipywi@L44&yC5!nVh zmSt__a=G@=qep|4m6by -.grid { - width: 100%; - height: 400; -} -.no-rows { - position: absolute; - top: 0; - bottom: 0; - width: 100%; - background: rgba(0, 0, 0, 0.4); -} - -.no-rows .msg { - opacity: 1; - position: absolute; - top: 20%; - left: 20%; - width: 60%; - height: 50%; - line-height: 200%; - background-color: #eee; - border-radius: 4px; - border: 1px solid #555; - text-align: center; - font-size: 24px; - display: table; -} - -.no-rows .msg span { - display: table-cell; - vertical-align: middle; -} -.grid .ui-grid-header-cell { - text-align:center; -} - - - -

        -

        {{reportData.reportName}} - -     -     - - -

        -
        Loading...
        - -
        - -

        - -
        - Back - -
        -
        -
        -
        -
        - {{reportData.message}} -
        -
        -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_run.js b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_run.js deleted file mode 100644 index 0df56796..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_run.js +++ /dev/null @@ -1,293 +0,0 @@ -app.controller("reportRunController", ['$scope','$rootScope','$routeParams','$http','dateFilter', '$window', '$timeout', 'rowSorter', - function ($scope,$rootScope,$routeParams,$http,dateFilter,$window,$timeout,rowSorter) { - $scope.dateformat = "MM/dd/yyyy"; - $scope.datetimeformat = "MM/dd/yyyy hh:mm a"; - $scope.showFormFields = false; - $scope.showGrid = false; - $scope.showChart = false; - $scope.showBackButton = false; - $scope.reportData = {}; - $scope.reportData.allowEdit = false; - $scope.formFieldSelectedValues = {}; - $scope.showFormFieldIds = false; - - $scope.isInProgress = true; - - if($routeParams.reportUrlParams.indexOf("parent___params===")>-1) { - $scope.showBackButton = true; - $scope.parentReportUrlParams = $routeParams.reportUrlParams.substring($routeParams.reportUrlParams.indexOf("parent___params===")+18); - $scope.currentReportUrlParams = $routeParams.reportUrlParams.substring(0,$routeParams.reportUrlParams.indexOf("parent___params===")); - } else { - $scope.currentReportUrlParams = $routeParams.reportUrlParams; - } - console.log($routeParams.reportUrlParams); - var parseQueryString = function( queryString ) { - var params = {}, queries, temp, i, l; - // Split into key/value pairs - queries = queryString.split("&"); - // Convert the array of strings into an object - for ( i = 0, l = queries.length; i < l; i++ ) { - temp = queries[i].split('='); - //console.log(temp[0]); - //console.log(temp[0] != "refresh"); - if(temp[0] && temp[0] != "refresh") - params[temp[0]] = temp[1]; - } - return params; - }; - - var convertQueryString = function(queryString) { - var keys = ""; var str = ""; - keys = Object.keys(queryString); - //console.log(keys); - for ( i = 0, l = keys.length; i < l; i++ ) { - str += keys[i]+"="+queryString[keys[i]] + "&"; - - } - return str; - //queryString = - } - - - - - $scope.urlParams = parseQueryString($scope.currentReportUrlParams); - - $scope.reportChartURL = 'report#/report_chart_wizard/'+$scope.urlParams.c_master; - - $scope.reportEditURL = 'report_wizard.htm?action=report.edit&c_master='+$scope.urlParams.c_master; - - - $http.get('raptor.htm?action=report.run.container&'+$scope.currentReportUrlParams).then( - function(response){ - console.log(response); - $scope.isInProgress = false; - $scope.reportData = response.data; - if(!$scope.urlParams.hideChart && $scope.reportData.chartAvailable && $scope.reportData.totalRows>1){ - console.log('raptor.htm?action=chart.run&'+convertQueryString($scope.urlParams)); - $http.get('raptor.htm?action=chart.run&'+convertQueryString($scope.urlParams)).then( - function(response){ - $scope.showChart = true; - document.getElementById('chartiframe').contentWindow.document.write(response.data); - document.getElementById('chartiframe').contentWindow.document.close(); - }); - } - - if($scope.reportData.displayForm && $scope.reportData.formFieldList && $scope.reportData.formFieldList.length>0 && !$scope.urlParams.hideFormFields){ - $scope.showFormFields = true; - } - }); - $scope.getFormFieldSelectedValuesAsURL = function(){ - var formFieldsUrl = ''; - $scope.reportData.formFieldList.forEach(function(formField) { - if(formField.fieldType==='LIST_BOX') { - if($scope.formFieldSelectedValues && $scope.formFieldSelectedValues[formField.fieldId] && $scope.formFieldSelectedValues[formField.fieldId].value != '') { - formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId].value+'&'; - } - } else if(formField.fieldType==='LIST_MULTI_SELECT') { - if($scope.formFieldSelectedValues[formField.fieldId].length >0) { - for (var i = 0; i < $scope.formFieldSelectedValues[formField.fieldId].length; i++) { - if($scope.formFieldSelectedValues[formField.fieldId][i].defaultValue){ - formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId][i].value+'&'; - } - } - } - } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && formField.validationType === 'DATE'){ - formFieldsUrl = formFieldsUrl+formField.fieldId+'='+dateFilter($scope.formFieldSelectedValues[formField.fieldId],$scope.dateformat)+'&'; - } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && formField.validationType === 'TIMESTAMP_MIN'){ - formFieldsUrl = formFieldsUrl+formField.fieldId+'='+dateFilter($scope.formFieldSelectedValues[formField.fieldId],$scope.datetimeformat)+'&'; - } else if((formField.fieldType === 'text' || formField.fieldType === 'TEXT') && $scope.formFieldSelectedValues[formField.fieldId] && $scope.formFieldSelectedValues[formField.fieldId] != ''){ - formFieldsUrl = formFieldsUrl+formField.fieldId+'='+$scope.formFieldSelectedValues[formField.fieldId]+'&'; - } - }); - return formFieldsUrl; - - } - - $scope.runReport = function(pagination){ - - var formFieldsUrl = $scope.getFormFieldSelectedValuesAsURL(); - console.log("pagination"); - if(!pagination) { - console.log("refreshed ..."); - $scope.gridOptions.pageNumber = 1; - $scope.gridOptions.paginationPageSizes= [$scope.reportData.pageSize]; - $scope.gridOptions.paginationPageSize= $scope.reportData.pageSize; - if($scope.reportData.totalRows<14){ - $scope.gridHeight = ($scope.reportData.totalRows+7)*30+'px'; - } else{ - $scope.gridHeight = '400px'; - } - $scope.gridOptions.totalItems = $scope.reportData.totalRows; - $scope.gridOptions.data= $scope.reportData.reportDataRows; - $scope.gridOptions.exporterPdfHeader.text= $scope.reportData.reportName; - - } - $scope.currentReportUrlParams = 'c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'&display_content=Y&r_page='+(paginationOptions.pageNumber-1); - console.log('raptor.htm?action=report.run.container&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)); - $http.get('raptor.htm?action=report.run.container&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'refresh=Y&display_content=Y&r_page='+(paginationOptions.pageNumber-1)).then( - function(response){ - $scope.reportData = response.data; - if($scope.reportData.errormessage) { - document.getElementById('errorDiv').innerHTML = $scope.reportData.errormessage; - console.log(document.getElementById('errorDiv').innerHtml); - console.log($scope.reportData.errormessage); - } - if(!pagination) { - if(!$scope.urlParams.hideChart && $scope.reportData.chartAvailable && $scope.reportData.totalRows>1){ - console.log('raptor.htm?action=chart.run&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'display_content=Y&r_page='+(paginationOptions.pageNumber-1)); - $http.get('raptor.htm?action=chart.run&c_master='+$scope.urlParams.c_master+'&'+formFieldsUrl+'display_content=Y&r_page='+(paginationOptions.pageNumber-1)).then( - function(response) { - console.log(response.data); - $scope.showChart = true; - document.getElementById('chartiframe').contentWindow.document.write(response.data); - document.getElementById('chartiframe').contentWindow.document.close(); - }); - } else { - $scope.showChart = false; - } - } - if($scope.reportData.displayForm && $scope.reportData.formFieldList && $scope.reportData.formFieldList.length>0 && !$scope.urlParams.hideFormFields){ - $scope.showFormFields = true; - } else { - $scope.showFormFields = false; - } - }); - }; - - var paginationOptions = { - pageNumber: 1, - pageSize: 5, - sort: null - }; - - $scope.gridOptions = { - pageNumber: 1, - sort : null, - paginationPageSizes: [5], - paginationPageSize: 5, - useExternalPagination: true, - columnDefs: [], - data: [], - enableGridMenu: true, - enableSelectAll: true, - gridMenuCustomItems : [ - { title : 'All Reports', - action : function($event) { - $window.open('report.htm','_self'); - }, order : 210 }, - { title : 'Edit Report', - action : function($event) { - $window.open($scope.reportEditURL,'_self'); - }, order : 211 }, - { title : 'Export All data as Excel 2007', - action : function($event) { - $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.excel2007.session','_self'); - }, order : 212 }, - { title : 'Export All data as Excel', - action : function($event) { - $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.excel.session','_self'); - }, order : 213 }, - { title : 'Export All data as CSV', - action : function($event) { - $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.csv.session','_self'); - }, order : 214 }, - { title : 'Export All data as PDF', - action : function($event) { - $window.open('raptor.htm?c_master='+$scope.reportData.reportID+'&r_action=report.download.pdf.session','_self'); - }, order : 215 } ], - exporterMenuPdf: false, - exporterMenuCsv: false, - exporterCsvFilename: 'myFile.csv', - exporterPdfDefaultStyle: {fontSize: 9}, - exporterPdfTableStyle: {margin: [30, 30, 30, 30]}, - exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'}, - exporterPdfHeader: { text: "My Header", style: 'headerStyle' }, - exporterPdfFooter: function ( currentPage, pageCount ) { - return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' }; - }, - exporterPdfCustomFormatter: function ( docDefinition ) { - docDefinition.styles.headerStyle = { fontSize: 22, bold: true }; - docDefinition.styles.footerStyle = { fontSize: 10, bold: true }; - return docDefinition; - }, - exporterPdfOrientation: 'portrait', - exporterPdfPageSize: 'LETTER', - exporterPdfMaxGridWidth: 500, - exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")), - onRegisterApi: function(gridApi) { - $scope.gridApi = gridApi; - gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) { - paginationOptions.pageNumber = newPage; - paginationOptions.pageSize = pageSize; - $scope.runReport(true); - }); - } - }; - - $scope.uiGridRefresh = function(){ - var columnDefsArray = []; - var columnFreezeEndColumn = $scope.reportData.colIdxTobeFreezed; - var doColumnNeedToFreeze = false; - if(columnFreezeEndColumn && columnFreezeEndColumn.length>0) { - doColumnNeedToFreeze = true; - } - $scope.reportData.reportDataColumns.forEach(function(entry) { - var tempColumnDef = { displayName: entry.columnTitle, field: entry.colId, enableSorting: entry.sortable, - sortingAlgorithm: function(a, b) { - return rowSorter.sortAlpha(a.displayValue, b.displayValue); - }, - cellTemplate: '
        '+ - '
        {{COL_FIELD.displayValue}}
        ' + - ' {{COL_FIELD.displayValue}}' + - '
        '}; - if(entry.columnWidth && entry.columnWidth!='null' && entry.columnWidth!='pxpx' && entry.columnWidth!='nullpx' && entry.columnWidth!='nullpxpx'){ - tempColumnDef['minWidth'] = entry.columnWidth.substring(0, entry.columnWidth.length - 2); - } else { - tempColumnDef['minWidth'] = '100'; - } - if(doColumnNeedToFreeze) { - tempColumnDef['pinnedLeft']= true; - if(columnFreezeEndColumn === entry.colId){ - doColumnNeedToFreeze = false; - } - } - columnDefsArray.push(tempColumnDef); - }); - - $scope.gridOptions.paginationPageSizes= [$scope.reportData.pageSize]; - $scope.gridOptions.paginationPageSize= $scope.reportData.pageSize; - if($scope.reportData.totalRows<14){ - $scope.gridHeight = ($scope.reportData.totalRows+5)*30+'px'; - }else{ - $scope.gridHeight = '400px'; - } - $scope.gridOptions.totalItems = $scope.reportData.totalRows; - $scope.gridOptions.columnDefs= columnDefsArray; - $scope.gridOptions.data= $scope.reportData.reportDataRows; - $scope.gridOptions.exporterPdfHeader.text= $scope.reportData.reportName; - }; - - $scope.$watch("reportData",function(newValue,oldValue) { - if(!$scope.urlParams.hideGrid){ - if($scope.reportData){ - if($scope.reportData.displayData && $scope.reportData.reportDataColumns){ - $scope.showGrid = true; - $scope.uiGridRefresh(); - } - } - } - }); - - $scope.triggerOtherFormFields = function(){ - console.log("report_run"); - var formFieldsUrl = $scope.getFormFieldSelectedValuesAsURL(); - $http.get('raptor.htm?action=report.formfields.run.container&c_master='+$scope.reportData.reportID+'&'+formFieldsUrl).then( - function(response){ - $scope.reportData = response.data; - }); - }; - $timeout(function() { - $rootScope.isViewRendering = false; - }); -}]); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_search.html b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_search.html deleted file mode 100644 index db00037c..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_search.html +++ /dev/null @@ -1,34 +0,0 @@ - -

        Report search

        -
        -
        - -
        -
        -
        -
        - -
        - - -
        -
        -
        -
        - -
        - -
        -
        -
        diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_search.js b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_search.js deleted file mode 100644 index d2194224..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/ebz/report_search.js +++ /dev/null @@ -1,136 +0,0 @@ -app.controller("reportSearchController", ['$scope','$rootScope','$http','$timeout',function ($scope,$rootScope,$http,$timeout) { - - $http.get('raptor.htm?action=report.search.execute&r_page=0').then( - function(result){$scope.searchdData = result.data; - }); - - $scope.runReport = function(){ - var searchParams = ''; - if($scope.reportId && $scope.reportId!=''){ - searchParams = '&rep_id='+$scope.reportId+'&rep_id_options='+$scope.operatorRepId.index; - } - if($scope.reportName && $scope.reportName!=''){ - searchParams = searchParams+'&rep_name='+$scope.reportName+'&rep_name_options='+$scope.operatorRepName.index; - } - - console.log('raptor.htm?action=report.search.execute&r_page='+(paginationOptions.pageNumber-1)+searchParams); - $http.get('raptor.htm?action=report.search.execute&r_page='+(paginationOptions.pageNumber-1)+searchParams).then( - function(result){$scope.searchdData = result.data; - }); - //quantum/raptor.htm?action=report.search.execute&rep_id=1000&rep_id_options=2&rep_name=cross&rep_name_options=2 - }; - - - var paginationOptions = { - pageNumber: 1, - pageSize: 5, - sort: null - }; - - $scope.gridOptions = { - paginationPageSizes: [5], - paginationPageSize: 5, - useExternalPagination: true, - columnDefs: [], - data: [], - enableGridMenu: true, - enableSelectAll: true, - exporterMenuPdf: false, - exporterMenuCsv: false, - exporterCsvFilename: 'myFile.csv', - exporterPdfDefaultStyle: {fontSize: 9}, - exporterPdfTableStyle: {margin: [30, 30, 30, 30]}, - exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'}, - exporterPdfHeader: { text: "My Header", style: 'headerStyle' }, - exporterPdfFooter: function ( currentPage, pageCount ) { - return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' }; - }, - exporterPdfCustomFormatter: function ( docDefinition ) { - docDefinition.styles.headerStyle = { fontSize: 22, bold: true }; - docDefinition.styles.footerStyle = { fontSize: 10, bold: true }; - return docDefinition; - }, - exporterPdfOrientation: 'portrait', - exporterPdfPageSize: 'LETTER', - exporterPdfMaxGridWidth: 500, - exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")), - onRegisterApi: function(gridApi) { - $scope.gridApi = gridApi; - gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) { - paginationOptions.pageNumber = newPage; - paginationOptions.pageSize = pageSize; - $scope.runReport(); - }); - } - }; - - - var getPage = function() { - $scope.gridOptions.columnDefs = []; - $scope.searchdData.columns[0].forEach(function(entry) { - if(entry.columnTitle=='Run'){ - $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', enableSorting: false, - cellTemplate: '
        ' - }); - } else if(entry.columnTitle=='Edit'){ - $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', enableSorting: false, - cellTemplate: '
        ' - }); - } else if(entry.columnTitle=='Delete'){ - $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', enableSorting: false, - cellTemplate: '
        ' - }); - } else if(entry.columnTitle=='Copy'){ - $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', enableSorting: false, - cellTemplate: '
        ' - }); - } else if(entry.columnTitle=='Schedule'){ - //$scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==drillDownLink', - // cellTemplate: '
        ' - //}); - } else if(entry.columnTitle=='No'){ - } else { - $scope.gridOptions.columnDefs.push({ displayName: entry.columnTitle, field: entry.columnId+'==displayValue'}); - } - }); - $scope.gridOptions.data = $scope.searchdData.rows[0]; - $scope.gridOptions.paginationPageSizes= [$scope.searchdData.metaReport.pageSize]; - $scope.gridOptions.paginationPageSize= $scope.searchdData.metaReport.pageSize; - $scope.gridOptions.totalItems = $scope.searchdData.metaReport.totalSize; - }; - - $scope.$watch("searchdData",function(newValue,oldValue) { - if($scope.searchdData){ - getPage(); - } - }); - - $scope.operatorsRepId = [{index: 0, value: 'Equal To', title: 'Equal To', alias:'Equal To'}, - {index: 1, value: 'Less Than', title: 'Less Than', alias:'Less Than'}, - {index: 2, value: 'Greater Than', title: 'Greater Than', alias:'Greater Than'}]; - $scope.operatorsRepName = [{index: 0, value: 'Starts With', title: 'Starts With', alias:'Starts With'}, - {index:1, value: 'Ends With', title: 'Ends With', alias:'Ends With'}, - {index: 2, value: 'Contains', title: 'Contains', alias:'Contains'}]; - - $scope.deleteReport = function(reportDeleteUrl,row) { - if (confirm("Please confirm: Are you sure you want to delete report #" + reportDeleteUrl.substr(41) + "?")) { - $http.get(reportDeleteUrl).then( - function(result){ - if(result.data=='deleted:true'){ - var index = $scope.gridOptions.data.indexOf(row.entity); - $scope.gridOptions.data.splice(index, 1); - alert("Report deleted."); - } else { - alert("Report not deleted."); - } - } - ); - } - }; - - $timeout(function() { - $rootScope.isViewRendering = false; - }); - - -}]); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/other_scripts.js b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/other_scripts.js deleted file mode 100644 index 3784600b..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/js/other_scripts.js +++ /dev/null @@ -1,331 +0,0 @@ -//Reusable Asset Library - CSS Positioning Version (v3.3) -//Release Date: 1/26/07 - - -//begin: quick help ======================================= -var uitmpl_qhId; -var uitmpl_cookieVal; -var qhRule; -var qhCookie; - -//sets cookie value and qhId -qhCookie=document.cookie; -var pos=qhCookie.indexOf("qhId="); - -if(pos==-1){ -document.cookie="qhId=0"; -uitmpl_qhId="0"; -qhCookie=document.cookie; -pos=qhCookie.indexOf("qhId="); -} -//reads cookie if value is present and sets qhId accordingly -var start=pos+5; -var end=qhCookie.indexOf(";", start); -if (end==-1) end=qhCookie.length; -uitmpl_cookieVal=qhCookie.substring(start,end); -if(uitmpl_cookieVal!=0){ - uitmpl_qhId=1; -}else{ -uitmpl_qhId=0; -} - - -//loops through all qh divs and toggles display based on qhId -function uitmpl_qhPageInit(){ -var getTag = document.getElementsByTagName("div"); - for (i=0;i5) { -strDay = strDate.substr(0, 2); -strMonth = strDate.substr(2, 2); -strYear = strDate.substr(4); - } -} -if (strYear.length == 2) { -strYear = '20' + strYear; -} -// US style -if (strDatestyle == "US") { -strTemp = strDay; -strDay = strMonth; -strMonth = strTemp; -} -intday = parseInt(strDay, 10); -if (isNaN(intday)) { -err = 2; -return false; -} -intMonth = parseInt(strMonth, 10); -if (isNaN(intMonth)) { -for (i = 0;i<12;i++) { -if (strMonth.toUpperCase() == strMonthArray[i].toUpperCase()) { -intMonth = i+1; -strMonth = strMonthArray[i]; -i = 12; - } -} -if (isNaN(intMonth)) { -err = 3; -return false; - } -} -intYear = parseInt(strYear, 10); -if (isNaN(intYear)) { -err = 4; -return false; -} -if (intMonth>12 || intMonth<1) { -err = 5; -return false; -} -if ((intMonth == 1 || intMonth == 3 || intMonth == 5 || intMonth == 7 || intMonth == 8 || intMonth == 10 || intMonth == 12) && (intday > 31 || intday < 1)) { -err = 6; -return false; -} -if ((intMonth == 4 || intMonth == 6 || intMonth == 9 || intMonth == 11) && (intday > 30 || intday < 1)) { -err = 7; -return false; -} -if (intMonth == 2) { -if (intday < 1) { -err = 8; -return false; -} -if (LeapYear(intYear) == true) { -if (intday > 29) { -err = 9; -return false; -} -} -else { -if (intday > 28) { -err = 10; -return false; -} -} -} -//if (strDatestyle == "US") { -//datefield.value = strMonthArray[intMonth-1] + " " + intday+" " + strYear; -//} -//else { -//datefield.value = intday + " " + strMonthArray[intMonth-1] + " " + strYear; -//} -return true; -} -function LeapYear(intYear) { -if (intYear % 100 == 0) { -if (intYear % 400 == 0) { return true; } -} -else { -if ((intYear % 4) == 0) { return true; } -} -return false; -} - -//range validation -function uitmpl_errRangeVal(obj, minNum, maxNum){ -if (obj.value>=minNum&&obj.value<=maxNum||obj.value==""){ -return true; -}else{ -alert("Please input a number within the range of "+minNum+" and "+maxNum+"!"); -obj.focus(); -obj.select(); -} -} - -//end: error validation ======================================= -//begin: popup windows ======================================= -function uitmpl_popUpReg(url) { - window.open(url); -} -function uitmpl_popUpConfig(url, name, w, h, sc, rsz) { - var features = "width="+w+",height="+h+",scrollbars="+sc+",resizable="+rsz+"menubar=0,status=1"; - var newWin = window.open(url, name, features); - newWin.focus(); -//popups from nav links: -} - - -function uitmpl_contact(){ -uitmpl_popUpReg(""); -} -function uitmpl_bizDirect(){ -uitmpl_popUpReg(""); -} - -//function uitmpl_closeApp(){ -//if(window.confirm("You did NOT save your data. Do you want to close 'application name' without saving your data?")) { -//window.close(); - -function uitmpl_closeApp(name){ -if (name != "") { -var cAppName=name; -} -else { -var cAppName="the current application"; -} -if(window.confirm("You did NOT save your data. Do you want to close\n" + cAppName + " without saving your data?")) { -window.close(); -} -} -//end: popup windows ======================================= - - - - - -//Select all checkboxes on a form===================================== -function uitmpl_chkBoxSelect(formName,btnOn,btnOff) { - - document.getElementById(btnOff).style.display = "block"; - document.getElementById(btnOn).style.display = "none"; - - var f = formName; - for (i=0; i < f.elements.length; i++) { - if (f.elements[i].type=="checkbox") { - var e = f.elements[i]; - e.checked = true; - } - } -} - - -//Clear all checkboxes on a form====================================== -function uitmpl_chkBoxClear(formName,btnOn, btnOff) { - - document.getElementById(btnOff).style.display = "none"; - document.getElementById(btnOn).style.display = "block"; - - var f = formName; - for (i=0; i < f.elements.length; i++) { - if (f.elements[i].type=="checkbox") { - var e = f.elements[i]; - e.checked = false; - } - } -} - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.js b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.js deleted file mode 100644 index 531485ce..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/raptor/uigrid/ui-grid.js +++ /dev/null @@ -1,26735 +0,0 @@ -/*! - * ui-grid - v3.0.7 - 2015-10-06 - * Copyright (c) 2015 ; License: MIT - */ - -(function () { - 'use strict'; - angular.module('ui.grid.i18n', []); - angular.module('ui.grid', ['ui.grid.i18n']); -})(); -(function () { - 'use strict'; - angular.module('ui.grid').constant('uiGridConstants', { - LOG_DEBUG_MESSAGES: true, - LOG_WARN_MESSAGES: true, - LOG_ERROR_MESSAGES: true, - CUSTOM_FILTERS: /CUSTOM_FILTERS/g, - COL_FIELD: /COL_FIELD/g, - MODEL_COL_FIELD: /MODEL_COL_FIELD/g, - TOOLTIP: /title=\"TOOLTIP\"/g, - DISPLAY_CELL_TEMPLATE: /DISPLAY_CELL_TEMPLATE/g, - TEMPLATE_REGEXP: /<.+>/, - FUNC_REGEXP: /(\([^)]*\))?$/, - DOT_REGEXP: /\./g, - APOS_REGEXP: /'/g, - BRACKET_REGEXP: /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/, - COL_CLASS_PREFIX: 'ui-grid-col', - events: { - GRID_SCROLL: 'uiGridScroll', - COLUMN_MENU_SHOWN: 'uiGridColMenuShown', - ITEM_DRAGGING: 'uiGridItemDragStart', // For any item being dragged - COLUMN_HEADER_CLICK: 'uiGridColumnHeaderClick' - }, - // copied from http://www.lsauer.com/2011/08/javascript-keymap-keycodes-in-json.html - keymap: { - TAB: 9, - STRG: 17, - CAPSLOCK: 20, - CTRL: 17, - CTRLRIGHT: 18, - CTRLR: 18, - SHIFT: 16, - RETURN: 13, - ENTER: 13, - BACKSPACE: 8, - BCKSP: 8, - ALT: 18, - ALTR: 17, - ALTRIGHT: 17, - SPACE: 32, - WIN: 91, - MAC: 91, - FN: null, - PG_UP: 33, - PG_DOWN: 34, - UP: 38, - DOWN: 40, - LEFT: 37, - RIGHT: 39, - ESC: 27, - DEL: 46, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123 - }, - ASC: 'asc', - DESC: 'desc', - filter: { - STARTS_WITH: 2, - ENDS_WITH: 4, - EXACT: 8, - CONTAINS: 16, - GREATER_THAN: 32, - GREATER_THAN_OR_EQUAL: 64, - LESS_THAN: 128, - LESS_THAN_OR_EQUAL: 256, - NOT_EQUAL: 512, - SELECT: 'select', - INPUT: 'input' - }, - - aggregationTypes: { - sum: 2, - count: 4, - avg: 8, - min: 16, - max: 32 - }, - - // TODO(c0bra): Create full list of these somehow. NOTE: do any allow a space before or after them? - CURRENCY_SYMBOLS: ['ƒ', '$', '£', '$', '¤', '¥', '៛', '₩', '₱', '฿', '₫'], - - scrollDirection: { - UP: 'up', - DOWN: 'down', - LEFT: 'left', - RIGHT: 'right', - NONE: 'none' - - }, - - dataChange: { - ALL: 'all', - EDIT: 'edit', - ROW: 'row', - COLUMN: 'column', - OPTIONS: 'options' - }, - scrollbars: { - NEVER: 0, - ALWAYS: 1 - //WHEN_NEEDED: 2 - } - }); - -})(); -angular.module('ui.grid').directive('uiGridCell', ['$compile', '$parse', 'gridUtil', 'uiGridConstants', function ($compile, $parse, gridUtil, uiGridConstants) { - var uiGridCell = { - priority: 0, - scope: false, - require: '?^uiGrid', - compile: function() { - return { - pre: function($scope, $elm, $attrs, uiGridCtrl) { - function compileTemplate() { - var compiledElementFn = $scope.col.compiledElementFn; - - compiledElementFn($scope, function(clonedElement, scope) { - $elm.append(clonedElement); - }); - } - - // If the grid controller is present, use it to get the compiled cell template function - if (uiGridCtrl && $scope.col.compiledElementFn) { - compileTemplate(); - } - // No controller, compile the element manually (for unit tests) - else { - if ( uiGridCtrl && !$scope.col.compiledElementFn ){ - // gridUtil.logError('Render has been called before precompile. Please log a ui-grid issue'); - - $scope.col.getCompiledElementFn() - .then(function (compiledElementFn) { - compiledElementFn($scope, function(clonedElement, scope) { - $elm.append(clonedElement); - }); - }); - } - else { - var html = $scope.col.cellTemplate - .replace(uiGridConstants.MODEL_COL_FIELD, 'row.entity.' + gridUtil.preEval($scope.col.field)) - .replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)'); - - var cellElement = $compile(html)($scope); - $elm.append(cellElement); - } - } - }, - post: function($scope, $elm, $attrs, uiGridCtrl) { - var initColClass = $scope.col.getColClass(false); - $elm.addClass(initColClass); - - var classAdded; - var updateClass = function( grid ){ - var contents = $elm; - if ( classAdded ){ - contents.removeClass( classAdded ); - classAdded = null; - } - - if (angular.isFunction($scope.col.cellClass)) { - classAdded = $scope.col.cellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex); - } - else { - classAdded = $scope.col.cellClass; - } - contents.addClass(classAdded); - }; - - if ($scope.col.cellClass) { - updateClass(); - } - - // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs - var dataChangeDereg = $scope.grid.registerDataChangeCallback( updateClass, [uiGridConstants.dataChange.COLUMN, uiGridConstants.dataChange.EDIT]); - - // watch the col and row to see if they change - which would indicate that we've scrolled or sorted or otherwise - // changed the row/col that this cell relates to, and we need to re-evaluate cell classes and maybe other things - var cellChangeFunction = function( n, o ){ - if ( n !== o ) { - if ( classAdded || $scope.col.cellClass ){ - updateClass(); - } - - // See if the column's internal class has changed - var newColClass = $scope.col.getColClass(false); - if (newColClass !== initColClass) { - $elm.removeClass(initColClass); - $elm.addClass(newColClass); - initColClass = newColClass; - } - } - }; - - // TODO(c0bra): Turn this into a deep array watch -/* shouldn't be needed any more given track by col.name - var colWatchDereg = $scope.$watch( 'col', cellChangeFunction ); -*/ - var rowWatchDereg = $scope.$watch( 'row', cellChangeFunction ); - - - var deregisterFunction = function() { - dataChangeDereg(); -// colWatchDereg(); - rowWatchDereg(); - }; - - $scope.$on( '$destroy', deregisterFunction ); - $elm.on( '$destroy', deregisterFunction ); - } - }; - } - }; - - return uiGridCell; -}]); - - -(function(){ - -angular.module('ui.grid') -.service('uiGridColumnMenuService', [ 'i18nService', 'uiGridConstants', 'gridUtil', -function ( i18nService, uiGridConstants, gridUtil ) { -/** - * @ngdoc service - * @name ui.grid.service:uiGridColumnMenuService - * - * @description Services for working with column menus, factored out - * to make the code easier to understand - */ - - var service = { - /** - * @ngdoc method - * @methodOf ui.grid.service:uiGridColumnMenuService - * @name initialize - * @description Sets defaults, puts a reference to the $scope on - * the uiGridController - * @param {$scope} $scope the $scope from the uiGridColumnMenu - * @param {controller} uiGridCtrl the uiGridController for the grid - * we're on - * - */ - initialize: function( $scope, uiGridCtrl ){ - $scope.grid = uiGridCtrl.grid; - - // Store a reference to this link/controller in the main uiGrid controller - // to allow showMenu later - uiGridCtrl.columnMenuScope = $scope; - - // Save whether we're shown or not so the columns can check - $scope.menuShown = false; - }, - - - /** - * @ngdoc method - * @methodOf ui.grid.service:uiGridColumnMenuService - * @name setColMenuItemWatch - * @description Setup a watch on $scope.col.menuItems, and update - * menuItems based on this. $scope.col needs to be set by the column - * before calling the menu. - * @param {$scope} $scope the $scope from the uiGridColumnMenu - * @param {controller} uiGridCtrl the uiGridController for the grid - * we're on - * - */ - setColMenuItemWatch: function ( $scope ){ - var deregFunction = $scope.$watch('col.menuItems', function (n, o) { - if (typeof(n) !== 'undefined' && n && angular.isArray(n)) { - n.forEach(function (item) { - if (typeof(item.context) === 'undefined' || !item.context) { - item.context = {}; - } - item.context.col = $scope.col; - }); - - $scope.menuItems = $scope.defaultMenuItems.concat(n); - } - else { - $scope.menuItems = $scope.defaultMenuItems; - } - }); - - $scope.$on( '$destroy', deregFunction ); - }, - - - /** - * @ngdoc boolean - * @name enableSorting - * @propertyOf ui.grid.class:GridOptions.columnDef - * @description (optional) True by default. When enabled, this setting adds sort - * widgets to the column header, allowing sorting of the data in the individual column. - */ - /** - * @ngdoc method - * @methodOf ui.grid.service:uiGridColumnMenuService - * @name sortable - * @description determines whether this column is sortable - * @param {$scope} $scope the $scope from the uiGridColumnMenu - * - */ - sortable: function( $scope ) { - if ( $scope.grid.options.enableSorting && typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.enableSorting) { - return true; - } - else { - return false; - } - }, - - /** - * @ngdoc method - * @methodOf ui.grid.service:uiGridColumnMenuService - * @name isActiveSort - * @description determines whether the requested sort direction is current active, to - * allow highlighting in the menu - * @param {$scope} $scope the $scope from the uiGridColumnMenu - * @param {string} direction the direction that we'd have selected for us to be active - * - */ - isActiveSort: function( $scope, direction ){ - return (typeof($scope.col) !== 'undefined' && typeof($scope.col.sort) !== 'undefined' && - typeof($scope.col.sort.direction) !== 'undefined' && $scope.col.sort.direction === direction); - - }, - - /** - * @ngdoc method - * @methodOf ui.grid.service:uiGridColumnMenuService - * @name suppressRemoveSort - * @description determines whether we should suppress the removeSort option - * @param {$scope} $scope the $scope from the uiGridColumnMenu - * - */ - suppressRemoveSort: function( $scope ) { - if ($scope.col && $scope.col.suppressRemoveSort) { - return true; - } - else { - return false; - } - }, - - - /** - * @ngdoc boolean - * @name enableHiding - * @propertyOf ui.grid.class:GridOptions.columnDef - * @description (optional) True by default. When set to false, this setting prevents a user from hiding the column - * using the column menu or the grid menu. - */ - /** - * @ngdoc method - * @methodOf ui.grid.service:uiGridColumnMenuService - * @name hideable - * @description determines whether a column can be hidden, by checking the enableHiding columnDef option - * @param {$scope} $scope the $scope from the uiGridColumnMenu - * - */ - hideable: function( $scope ) { - if (typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.colDef && $scope.col.colDef.enableHiding === false ) { - return false; - } - else { - return true; - } - }, - - - /** - * @ngdoc method - * @methodOf ui.grid.service:uiGridColumnMenuService - * @name getDefaultMenuItems - * @description returns the default menu items for a column menu - * @param {$scope} $scope the $scope from the uiGridColumnMenu - * - */ - getDefaultMenuItems: function( $scope ){ - return [ - { - title: i18nService.getSafeText('sort.ascending'), - icon: 'ui-grid-icon-sort-alt-up', - action: function($event) { - $event.stopPropagation(); - $scope.sortColumn($event, uiGridConstants.ASC); - }, - shown: function () { - return service.sortable( $scope ); - }, - active: function() { - return service.isActiveSort( $scope, uiGridConstants.ASC); - } - }, - { - title: i18nService.getSafeText('sort.descending'), - icon: 'ui-grid-icon-sort-alt-down', - action: function($event) { - $event.stopPropagation(); - $scope.sortColumn($event, uiGridConstants.DESC); - }, - shown: function() { - return service.sortable( $scope ); - }, - active: function() { - return service.isActiveSort( $scope, uiGridConstants.DESC); - } - }, - { - title: i18nService.getSafeText('sort.remove'), - icon: 'ui-grid-icon-cancel', - action: function ($event) { - $event.stopPropagation(); - $scope.unsortColumn(); - }, - shown: function() { - return service.sortable( $scope ) && - typeof($scope.col) !== 'undefined' && (typeof($scope.col.sort) !== 'undefined' && - typeof($scope.col.sort.direction) !== 'undefined') && $scope.col.sort.direction !== null && - !service.suppressRemoveSort( $scope ); - } - }, - { - title: i18nService.getSafeText('column.hide'), - icon: 'ui-grid-icon-cancel', - shown: function() { - return service.hideable( $scope ); - }, - action: function ($event) { - $event.stopPropagation(); - $scope.hideColumn(); - } - }, - { - title: i18nService.getSafeText('columnMenu.close'), - screenReaderOnly: true, - shown: function(){ - return true; - }, - action: function($event){ - $event.stopPropagation(); - } - } - ]; - }, - - - /** - * @ngdoc method - * @methodOf ui.grid.service:uiGridColumnMenuService - * @name getColumnElementPosition - * @description gets the position information needed to place the column - * menu below the column header - * @param {$scope} $scope the $scope from the uiGridColumnMenu - * @param {GridCol} column the column we want to position below - * @param {element} $columnElement the column element we want to position below - * @returns {hash} containing left, top, offset, height, width - * - */ - getColumnElementPosition: function( $scope, column, $columnElement ){ - var positionData = {}; - positionData.left = $columnElement[0].offsetLeft; - positionData.top = $columnElement[0].offsetTop; - positionData.parentLeft = $columnElement[0].offsetParent.offsetLeft; - - // Get the grid scrollLeft - positionData.offset = 0; - if (column.grid.options.offsetLeft) { - positionData.offset = column.grid.options.offsetLeft; - } - - positionData.height = gridUtil.elementHeight($columnElement, true); - positionData.width = gridUtil.elementWidth($columnElement, true); - - return positionData; - }, - - - /** - * @ngdoc method - * @methodOf ui.grid.service:uiGridColumnMenuService - * @name repositionMenu - * @description Reposition the menu below the new column. If the menu has no child nodes - * (i.e. it's not currently visible) then we guess it's width at 100, we'll be called again - * later to fix it - * @param {$scope} $scope the $scope from the uiGridColumnMenu - * @param {GridCol} column the column we want to position below - * @param {hash} positionData a hash containing left, top, offset, height, width - * @param {element} $elm the column menu element that we want to reposition - * @param {element} $columnElement the column element that we want to reposition underneath - * - */ - repositionMenu: function( $scope, column, positionData, $elm, $columnElement ) { - var menu = $elm[0].querySelectorAll('.ui-grid-menu'); - var containerId = column.renderContainer ? column.renderContainer : 'body'; - var renderContainer = column.grid.renderContainers[containerId]; - - // It's possible that the render container of the column we're attaching to is - // offset from the grid (i.e. pinned containers), we need to get the difference in the offsetLeft - // between the render container and the grid - var renderContainerElm = gridUtil.closestElm($columnElement, '.ui-grid-render-container'); - var renderContainerOffset = renderContainerElm.getBoundingClientRect().left - $scope.grid.element[0].getBoundingClientRect().left; - - var containerScrollLeft = renderContainerElm.querySelectorAll('.ui-grid-viewport')[0].scrollLeft; - - // default value the last width for _this_ column, otherwise last width for _any_ column, otherwise default to 170 - var myWidth = column.lastMenuWidth ? column.lastMenuWidth : ( $scope.lastMenuWidth ? $scope.lastMenuWidth : 170); - var paddingRight = column.lastMenuPaddingRight ? column.lastMenuPaddingRight : ( $scope.lastMenuPaddingRight ? $scope.lastMenuPaddingRight : 10); - - if ( menu.length !== 0 ){ - var mid = menu[0].querySelectorAll('.ui-grid-menu-mid'); - if ( mid.length !== 0 && !angular.element(mid).hasClass('ng-hide') ) { - myWidth = gridUtil.elementWidth(menu, true); - $scope.lastMenuWidth = myWidth; - column.lastMenuWidth = myWidth; - - // TODO(c0bra): use padding-left/padding-right based on document direction (ltr/rtl), place menu on proper side - // Get the column menu right padding - paddingRight = parseInt(gridUtil.getStyles(angular.element(menu)[0])['paddingRight'], 10); - $scope.lastMenuPaddingRight = paddingRight; - column.lastMenuPaddingRight = paddingRight; - } - } - - var left = positionData.left + renderContainerOffset - containerScrollLeft + positionData.parentLeft + positionData.width - myWidth + paddingRight; - if (left < positionData.offset){ - left = positionData.offset; - } - - $elm.css('left', left + 'px'); - $elm.css('top', (positionData.top + positionData.height) + 'px'); - } - - }; - - return service; -}]) - - -.directive('uiGridColumnMenu', ['$timeout', 'gridUtil', 'uiGridConstants', 'uiGridColumnMenuService', '$document', -function ($timeout, gridUtil, uiGridConstants, uiGridColumnMenuService, $document) { -/** - * @ngdoc directive - * @name ui.grid.directive:uiGridColumnMenu - * @description Provides the column menu framework, leverages uiGridMenu underneath - * - */ - - var uiGridColumnMenu = { - priority: 0, - scope: true, - require: '^uiGrid', - templateUrl: 'ui-grid/uiGridColumnMenu', - replace: true, - link: function ($scope, $elm, $attrs, uiGridCtrl) { - var self = this; - - uiGridColumnMenuService.initialize( $scope, uiGridCtrl ); - - $scope.defaultMenuItems = uiGridColumnMenuService.getDefaultMenuItems( $scope ); - - // Set the menu items for use with the column menu. The user can later add additional items via the watch - $scope.menuItems = $scope.defaultMenuItems; - uiGridColumnMenuService.setColMenuItemWatch( $scope ); - - - /** - * @ngdoc method - * @methodOf ui.grid.directive:uiGridColumnMenu - * @name showMenu - * @description Shows the column menu. If the menu is already displayed it - * calls the menu to ask it to hide (it will animate), then it repositions the menu - * to the right place whilst hidden (it will make an assumption on menu width), - * then it asks the menu to show (it will animate), then it repositions the menu again - * once we can calculate it's size. - * @param {GridCol} column the column we want to position below - * @param {element} $columnElement the column element we want to position below - */ - $scope.showMenu = function(column, $columnElement, event) { - // Swap to this column - $scope.col = column; - - // Get the position information for the column element - var colElementPosition = uiGridColumnMenuService.getColumnElementPosition( $scope, column, $columnElement ); - - if ($scope.menuShown) { - // we want to hide, then reposition, then show, but we want to wait for animations - // we set a variable, and then rely on the menu-hidden event to call the reposition and show - $scope.colElement = $columnElement; - $scope.colElementPosition = colElementPosition; - $scope.hideThenShow = true; - - $scope.$broadcast('hide-menu', { originalEvent: event }); - } else { - self.shown = $scope.menuShown = true; - uiGridColumnMenuService.repositionMenu( $scope, column, colElementPosition, $elm, $columnElement ); - - $scope.colElement = $columnElement; - $scope.colElementPosition = colElementPosition; - $scope.$broadcast('show-menu', { originalEvent: event }); - } - }; - - - /** - * @ngdoc method - * @methodOf ui.grid.directive:uiGridColumnMenu - * @name hideMenu - * @description Hides the column menu. - * @param {boolean} broadcastTrigger true if we were triggered by a broadcast - * from the menu itself - in which case don't broadcast again as we'll get - * an infinite loop - */ - $scope.hideMenu = function( broadcastTrigger ) { - $scope.menuShown = false; - if ( !broadcastTrigger ){ - $scope.$broadcast('hide-menu'); - } - }; - - - $scope.$on('menu-hidden', function() { - if ( $scope.hideThenShow ){ - delete $scope.hideThenShow; - - uiGridColumnMenuService.repositionMenu( $scope, $scope.col, $scope.colElementPosition, $elm, $scope.colElement ); - $scope.$broadcast('show-menu'); - - $scope.menuShown = true; - } else { - $scope.hideMenu( true ); - - if ($scope.col) { - //Focus on the menu button - gridUtil.focus.bySelector($document, '.ui-grid-header-cell.' + $scope.col.getColClass()+ ' .ui-grid-column-menu-button', $scope.col.grid, false); - } - } - }); - - $scope.$on('menu-shown', function() { - $timeout( function() { - uiGridColumnMenuService.repositionMenu( $scope, $scope.col, $scope.colElementPosition, $elm, $scope.colElement ); - delete $scope.colElementPosition; - delete $scope.columnElement; - }, 200); - }); - - - /* Column methods */ - $scope.sortColumn = function (event, dir) { - event.stopPropagation(); - - $scope.grid.sortColumn($scope.col, dir, true) - .then(function () { - $scope.grid.refresh(); - $scope.hideMenu(); - }); - }; - - $scope.unsortColumn = function () { - $scope.col.unsort(); - - $scope.grid.refresh(); - $scope.hideMenu(); - }; - - //Since we are hiding this column the default hide action will fail so we need to focus somewhere else. - var setFocusOnHideColumn = function(){ - $timeout(function(){ - // Get the UID of the first - var focusToGridMenu = function(){ - return gridUtil.focus.byId('grid-menu', $scope.grid); - }; - - var thisIndex; - $scope.grid.columns.some(function(element, index){ - if (angular.equals(element, $scope.col)) { - thisIndex = index; - return true; - } - }); - - var previousVisibleCol; - // Try and find the next lower or nearest column to focus on - $scope.grid.columns.some(function(element, index){ - if (!element.visible){ - return false; - } // This columns index is below the current column index - else if ( index < thisIndex){ - previousVisibleCol = element; - } // This elements index is above this column index and we haven't found one that is lower - else if ( index > thisIndex && !previousVisibleCol) { - // This is the next best thing - previousVisibleCol = element; - // We've found one so use it. - return true; - } // We've reached an element with an index above this column and the previousVisibleCol variable has been set - else if (index > thisIndex && previousVisibleCol) { - // We are done. - return true; - } - }); - // If found then focus on it - if (previousVisibleCol){ - var colClass = previousVisibleCol.getColClass(); - gridUtil.focus.bySelector($document, '.ui-grid-header-cell.' + colClass+ ' .ui-grid-header-cell-primary-focus', true).then(angular.noop, function(reason){ - if (reason !== 'canceled'){ // If this is canceled then don't perform the action - //The fallback action is to focus on the grid menu - return focusToGridMenu(); - } - }); - } else { - // Fallback action to focus on the grid menu - focusToGridMenu(); - } - }); - }; - - $scope.hideColumn = function () { - $scope.col.colDef.visible = false; - $scope.col.visible = false; - - $scope.grid.queueGridRefresh(); - $scope.hideMenu(); - $scope.grid.api.core.notifyDataChange( uiGridConstants.dataChange.COLUMN ); - $scope.grid.api.core.raise.columnVisibilityChanged( $scope.col ); - - // We are hiding so the default action of focusing on the button that opened this menu will fail. - setFocusOnHideColumn(); - }; - }, - - - - controller: ['$scope', function ($scope) { - var self = this; - - $scope.$watch('menuItems', function (n, o) { - self.menuItems = n; - }); - }] - }; - - return uiGridColumnMenu; - -}]); - -})(); - -(function(){ - 'use strict'; - - angular.module('ui.grid').directive('uiGridFilter', ['$compile', '$templateCache', 'i18nService', 'gridUtil', function ($compile, $templateCache, i18nService, gridUtil) { - - return { - compile: function() { - return { - pre: function ($scope, $elm, $attrs, controllers) { - $scope.col.updateFilters = function( filterable ){ - $elm.children().remove(); - if ( filterable ){ - var template = $scope.col.filterHeaderTemplate; - - $elm.append($compile(template)($scope)); - } - }; - - $scope.$on( '$destroy', function() { - delete $scope.col.updateFilters; - }); - }, - post: function ($scope, $elm, $attrs, controllers){ - $scope.aria = i18nService.getSafeText('headerCell.aria'); - $scope.removeFilter = function(colFilter, index){ - colFilter.term = null; - //Set the focus to the filter input after the action disables the button - gridUtil.focus.bySelector($elm, '.ui-grid-filter-input-' + index); - }; - } - }; - } - }; - }]); -})(); - -(function () { - 'use strict'; - - angular.module('ui.grid').directive('uiGridFooterCell', ['$timeout', 'gridUtil', 'uiGridConstants', '$compile', - function ($timeout, gridUtil, uiGridConstants, $compile) { - var uiGridFooterCell = { - priority: 0, - scope: { - col: '=', - row: '=', - renderIndex: '=' - }, - replace: true, - require: '^uiGrid', - compile: function compile(tElement, tAttrs, transclude) { - return { - pre: function ($scope, $elm, $attrs, uiGridCtrl) { - var cellFooter = $compile($scope.col.footerCellTemplate)($scope); - $elm.append(cellFooter); - }, - post: function ($scope, $elm, $attrs, uiGridCtrl) { - //$elm.addClass($scope.col.getColClass(false)); - $scope.grid = uiGridCtrl.grid; - - var initColClass = $scope.col.getColClass(false); - $elm.addClass(initColClass); - - // apply any footerCellClass - var classAdded; - var updateClass = function( grid ){ - var contents = $elm; - if ( classAdded ){ - contents.removeClass( classAdded ); - classAdded = null; - } - - if (angular.isFunction($scope.col.footerCellClass)) { - classAdded = $scope.col.footerCellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex); - } - else { - classAdded = $scope.col.footerCellClass; - } - contents.addClass(classAdded); - }; - - if ($scope.col.footerCellClass) { - updateClass(); - } - - $scope.col.updateAggregationValue(); - - // Watch for column changes so we can alter the col cell class properly -/* shouldn't be needed any more, given track by col.name - $scope.$watch('col', function (n, o) { - if (n !== o) { - // See if the column's internal class has changed - var newColClass = $scope.col.getColClass(false); - if (newColClass !== initColClass) { - $elm.removeClass(initColClass); - $elm.addClass(newColClass); - initColClass = newColClass; - } - } - }); -*/ - - - // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs - var dataChangeDereg = $scope.grid.registerDataChangeCallback( updateClass, [uiGridConstants.dataChange.COLUMN]); - // listen for visible rows change and update aggregation values - $scope.grid.api.core.on.rowsRendered( $scope, $scope.col.updateAggregationValue ); - $scope.grid.api.core.on.rowsRendered( $scope, updateClass ); - $scope.$on( '$destroy', dataChangeDereg ); - } - }; - } - }; - - return uiGridFooterCell; - }]); - -})(); - -(function () { - 'use strict'; - - angular.module('ui.grid').directive('uiGridFooter', ['$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', function ($templateCache, $compile, uiGridConstants, gridUtil, $timeout) { - - return { - restrict: 'EA', - replace: true, - // priority: 1000, - require: ['^uiGrid', '^uiGridRenderContainer'], - scope: true, - compile: function ($elm, $attrs) { - return { - pre: function ($scope, $elm, $attrs, controllers) { - var uiGridCtrl = controllers[0]; - var containerCtrl = controllers[1]; - - $scope.grid = uiGridCtrl.grid; - $scope.colContainer = containerCtrl.colContainer; - - containerCtrl.footer = $elm; - - var footerTemplate = $scope.grid.options.footerTemplate; - gridUtil.getTemplate(footerTemplate) - .then(function (contents) { - var template = angular.element(contents); - - var newElm = $compile(template)($scope); - $elm.append(newElm); - - if (containerCtrl) { - // Inject a reference to the footer viewport (if it exists) into the grid controller for use in the horizontal scroll handler below - var footerViewport = $elm[0].getElementsByClassName('ui-grid-footer-viewport')[0]; - - if (footerViewport) { - containerCtrl.footerViewport = footerViewport; - } - } - }); - }, - - post: function ($scope, $elm, $attrs, controllers) { - var uiGridCtrl = controllers[0]; - var containerCtrl = controllers[1]; - - // gridUtil.logDebug('ui-grid-footer link'); - - var grid = uiGridCtrl.grid; - - // Don't animate footer cells - gridUtil.disableAnimations($elm); - - containerCtrl.footer = $elm; - - var footerViewport = $elm[0].getElementsByClassName('ui-grid-footer-viewport')[0]; - if (footerViewport) { - containerCtrl.footerViewport = footerViewport; - } - } - }; - } - }; - }]); - -})(); -(function () { - 'use strict'; - - angular.module('ui.grid').directive('uiGridGridFooter', ['$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', function ($templateCache, $compile, uiGridConstants, gridUtil, $timeout) { - - return { - restrict: 'EA', - replace: true, - // priority: 1000, - require: '^uiGrid', - scope: true, - compile: function ($elm, $attrs) { - return { - pre: function ($scope, $elm, $attrs, uiGridCtrl) { - - $scope.grid = uiGridCtrl.grid; - - - - var footerTemplate = $scope.grid.options.gridFooterTemplate; - gridUtil.getTemplate(footerTemplate) - .then(function (contents) { - var template = angular.element(contents); - - var newElm = $compile(template)($scope); - $elm.append(newElm); - }); - }, - - post: function ($scope, $elm, $attrs, controllers) { - - } - }; - } - }; - }]); - -})(); -(function(){ - 'use strict'; - - angular.module('ui.grid').directive('uiGridGroupPanel', ["$compile", "uiGridConstants", "gridUtil", function($compile, uiGridConstants, gridUtil) { - var defaultTemplate = 'ui-grid/ui-grid-group-panel'; - - return { - restrict: 'EA', - replace: true, - require: '?^uiGrid', - scope: false, - compile: function($elm, $attrs) { - return { - pre: function ($scope, $elm, $attrs, uiGridCtrl) { - var groupPanelTemplate = $scope.grid.options.groupPanelTemplate || defaultTemplate; - - gridUtil.getTemplate(groupPanelTemplate) - .then(function (contents) { - var template = angular.element(contents); - - var newElm = $compile(template)($scope); - $elm.append(newElm); - }); - }, - - post: function ($scope, $elm, $attrs, uiGridCtrl) { - $elm.bind('$destroy', function() { - // scrollUnbinder(); - }); - } - }; - } - }; - }]); - -})(); -(function(){ - 'use strict'; - - angular.module('ui.grid').directive('uiGridHeaderCell', ['$compile', '$timeout', '$window', '$document', 'gridUtil', 'uiGridConstants', 'ScrollEvent', 'i18nService', - function ($compile, $timeout, $window, $document, gridUtil, uiGridConstants, ScrollEvent, i18nService) { - // Do stuff after mouse has been down this many ms on the header cell - var mousedownTimeout = 500; - var changeModeTimeout = 500; // length of time between a touch event and a mouse event being recognised again, and vice versa - - var uiGridHeaderCell = { - priority: 0, - scope: { - col: '=', - row: '=', - renderIndex: '=' - }, - require: ['^uiGrid', '^uiGridRenderContainer'], - replace: true, - compile: function() { - return { - pre: function ($scope, $elm, $attrs) { - var cellHeader = $compile($scope.col.headerCellTemplate)($scope); - $elm.append(cellHeader); - }, - - post: function ($scope, $elm, $attrs, controllers) { - var uiGridCtrl = controllers[0]; - var renderContainerCtrl = controllers[1]; - - $scope.i18n = { - headerCell: i18nService.getSafeText('headerCell'), - sort: i18nService.getSafeText('sort') - }; - $scope.getSortDirectionAriaLabel = function(){ - var col = $scope.col; - //Trying to recreate this sort of thing but it was getting messy having it in the template. - //Sort direction {{col.sort.direction == asc ? 'ascending' : ( col.sort.direction == desc ? 'descending':'none')}}. {{col.sort.priority ? {{columnPriorityText}} {{col.sort.priority}} : ''} - var sortDirectionText = col.sort.direction === uiGridConstants.ASC ? $scope.i18n.sort.ascending : ( col.sort.direction === uiGridConstants.DESC ? $scope.i18n.sort.descending : $scope.i18n.sort.none); - var label = sortDirectionText; - //Append the priority if it exists - if (col.sort.priority) { - label = label + '. ' + $scope.i18n.headerCell.priority + ' ' + col.sort.priority; - } - return label; - }; - - $scope.grid = uiGridCtrl.grid; - - $scope.renderContainer = uiGridCtrl.grid.renderContainers[renderContainerCtrl.containerId]; - - var initColClass = $scope.col.getColClass(false); - $elm.addClass(initColClass); - - // Hide the menu by default - $scope.menuShown = false; - - // Put asc and desc sort directions in scope - $scope.asc = uiGridConstants.ASC; - $scope.desc = uiGridConstants.DESC; - - // Store a reference to menu element - var $colMenu = angular.element( $elm[0].querySelectorAll('.ui-grid-header-cell-menu') ); - - var $contentsElm = angular.element( $elm[0].querySelectorAll('.ui-grid-cell-contents') ); - - - // apply any headerCellClass - var classAdded; - var previousMouseX; - - // filter watchers - var filterDeregisters = []; - - - /* - * Our basic approach here for event handlers is that we listen for a down event (mousedown or touchstart). - * Once we have a down event, we need to work out whether we have a click, a drag, or a - * hold. A click would sort the grid (if sortable). A drag would be used by moveable, so - * we ignore it. A hold would open the menu. - * - * So, on down event, we put in place handlers for move and up events, and a timer. If the - * timer expires before we see a move or up, then we have a long press and hence a column menu open. - * If the up happens before the timer, then we have a click, and we sort if the column is sortable. - * If a move happens before the timer, then we are doing column move, so we do nothing, the moveable feature - * will handle it. - * - * To deal with touch enabled devices that also have mice, we only create our handlers when - * we get the down event, and we create the corresponding handlers - if we're touchstart then - * we get touchmove and touchend, if we're mousedown then we get mousemove and mouseup. - * - * We also suppress the click action whilst this is happening - otherwise after the mouseup there - * will be a click event and that can cause the column menu to close - * - */ - - $scope.downFn = function( event ){ - event.stopPropagation(); - - if (typeof(event.originalEvent) !== 'undefined' && event.originalEvent !== undefined) { - event = event.originalEvent; - } - - // Don't show the menu if it's not the left button - if (event.button && event.button !== 0) { - return; - } - previousMouseX = event.pageX; - - $scope.mousedownStartTime = (new Date()).getTime(); - $scope.mousedownTimeout = $timeout(function() { }, mousedownTimeout); - - $scope.mousedownTimeout.then(function () { - if ( $scope.colMenu ) { - uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm, event); - } - }); - - uiGridCtrl.fireEvent(uiGridConstants.events.COLUMN_HEADER_CLICK, {event: event, columnName: $scope.col.colDef.name}); - - $scope.offAllEvents(); - if ( event.type === 'touchstart'){ - $document.on('touchend', $scope.upFn); - $document.on('touchmove', $scope.moveFn); - } else if ( event.type === 'mousedown' ){ - $document.on('mouseup', $scope.upFn); - $document.on('mousemove', $scope.moveFn); - } - }; - - $scope.upFn = function( event ){ - event.stopPropagation(); - $timeout.cancel($scope.mousedownTimeout); - $scope.offAllEvents(); - $scope.onDownEvents(event.type); - - var mousedownEndTime = (new Date()).getTime(); - var mousedownTime = mousedownEndTime - $scope.mousedownStartTime; - - if (mousedownTime > mousedownTimeout) { - // long click, handled above with mousedown - } - else { - // short click - if ( $scope.sortable ){ - $scope.handleClick(event); - } - } - }; - - $scope.moveFn = function( event ){ - // Chrome is known to fire some bogus move events. - var changeValue = event.pageX - previousMouseX; - if ( changeValue === 0 ){ return; } - - // we're a move, so do nothing and leave for column move (if enabled) to take over - $timeout.cancel($scope.mousedownTimeout); - $scope.offAllEvents(); - $scope.onDownEvents(event.type); - }; - - $scope.clickFn = function ( event ){ - event.stopPropagation(); - $contentsElm.off('click', $scope.clickFn); - }; - - - $scope.offAllEvents = function(){ - $contentsElm.off('touchstart', $scope.downFn); - $contentsElm.off('mousedown', $scope.downFn); - - $document.off('touchend', $scope.upFn); - $document.off('mouseup', $scope.upFn); - - $document.off('touchmove', $scope.moveFn); - $document.off('mousemove', $scope.moveFn); - - $contentsElm.off('click', $scope.clickFn); - }; - - $scope.onDownEvents = function( type ){ - // If there is a previous event, then wait a while before - // activating the other mode - i.e. if the last event was a touch event then - // don't enable mouse events for a wee while (500ms or so) - // Avoids problems with devices that emulate mouse events when you have touch events - - switch (type){ - case 'touchmove': - case 'touchend': - $contentsElm.on('click', $scope.clickFn); - $contentsElm.on('touchstart', $scope.downFn); - $timeout(function(){ - $contentsElm.on('mousedown', $scope.downFn); - }, changeModeTimeout); - break; - case 'mousemove': - case 'mouseup': - $contentsElm.on('click', $scope.clickFn); - $contentsElm.on('mousedown', $scope.downFn); - $timeout(function(){ - $contentsElm.on('touchstart', $scope.downFn); - }, changeModeTimeout); - break; - default: - $contentsElm.on('click', $scope.clickFn); - $contentsElm.on('touchstart', $scope.downFn); - $contentsElm.on('mousedown', $scope.downFn); - } - }; - - - var updateHeaderOptions = function( grid ){ - var contents = $elm; - if ( classAdded ){ - contents.removeClass( classAdded ); - classAdded = null; - } - - if (angular.isFunction($scope.col.headerCellClass)) { - classAdded = $scope.col.headerCellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex); - } - else { - classAdded = $scope.col.headerCellClass; - } - contents.addClass(classAdded); - - var rightMostContainer = $scope.grid.renderContainers['right'] ? $scope.grid.renderContainers['right'] : $scope.grid.renderContainers['body']; - $scope.isLastCol = ( $scope.col === rightMostContainer.visibleColumnCache[ rightMostContainer.visibleColumnCache.length - 1 ] ); - - // Figure out whether this column is sortable or not - if (uiGridCtrl.grid.options.enableSorting && $scope.col.enableSorting) { - $scope.sortable = true; - } - else { - $scope.sortable = false; - } - - // Figure out whether this column is filterable or not - var oldFilterable = $scope.filterable; - if (uiGridCtrl.grid.options.enableFiltering && $scope.col.enableFiltering) { - $scope.filterable = true; - } - else { - $scope.filterable = false; - } - - if ( oldFilterable !== $scope.filterable){ - if ( typeof($scope.col.updateFilters) !== 'undefined' ){ - $scope.col.updateFilters($scope.filterable); - } - - // if column is filterable add a filter watcher - if ($scope.filterable) { - $scope.col.filters.forEach( function(filter, i) { - filterDeregisters.push($scope.$watch('col.filters[' + i + '].term', function(n, o) { - if (n !== o) { - uiGridCtrl.grid.api.core.raise.filterChanged(); - uiGridCtrl.grid.api.core.notifyDataChange( uiGridConstants.dataChange.COLUMN ); - uiGridCtrl.grid.queueGridRefresh(); - } - })); - }); - $scope.$on('$destroy', function() { - filterDeregisters.forEach( function(filterDeregister) { - filterDeregister(); - }); - }); - } else { - filterDeregisters.forEach( function(filterDeregister) { - filterDeregister(); - }); - } - - } - - // figure out whether we support column menus - if ($scope.col.grid.options && $scope.col.grid.options.enableColumnMenus !== false && - $scope.col.colDef && $scope.col.colDef.enableColumnMenu !== false){ - $scope.colMenu = true; - } else { - $scope.colMenu = false; - } - - /** - * @ngdoc property - * @name enableColumnMenu - * @propertyOf ui.grid.class:GridOptions.columnDef - * @description if column menus are enabled, controls the column menus for this specific - * column (i.e. if gridOptions.enableColumnMenus, then you can control column menus - * using this option. If gridOptions.enableColumnMenus === false then you get no column - * menus irrespective of the value of this option ). Defaults to true. - * - */ - /** - * @ngdoc property - * @name enableColumnMenus - * @propertyOf ui.grid.class:GridOptions.columnDef - * @description Override for column menus everywhere - if set to false then you get no - * column menus. Defaults to true. - * - */ - - $scope.offAllEvents(); - - if ($scope.sortable || $scope.colMenu) { - $scope.onDownEvents(); - - $scope.$on('$destroy', function () { - $scope.offAllEvents(); - }); - } - }; - -/* - $scope.$watch('col', function (n, o) { - if (n !== o) { - // See if the column's internal class has changed - var newColClass = $scope.col.getColClass(false); - if (newColClass !== initColClass) { - $elm.removeClass(initColClass); - $elm.addClass(newColClass); - initColClass = newColClass; - } - } - }); -*/ - updateHeaderOptions(); - - // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs - var dataChangeDereg = $scope.grid.registerDataChangeCallback( updateHeaderOptions, [uiGridConstants.dataChange.COLUMN]); - - $scope.$on( '$destroy', dataChangeDereg ); - - $scope.handleClick = function(event) { - // If the shift key is being held down, add this column to the sort - var add = false; - if (event.shiftKey) { - add = true; - } - - // Sort this column then rebuild the grid's rows - uiGridCtrl.grid.sortColumn($scope.col, add) - .then(function () { - if (uiGridCtrl.columnMenuScope) { uiGridCtrl.columnMenuScope.hideMenu(); } - uiGridCtrl.grid.refresh(); - }); - }; - - - $scope.toggleMenu = function(event) { - event.stopPropagation(); - - // If the menu is already showing... - if (uiGridCtrl.columnMenuScope.menuShown) { - // ... and we're the column the menu is on... - if (uiGridCtrl.columnMenuScope.col === $scope.col) { - // ... hide it - uiGridCtrl.columnMenuScope.hideMenu(); - } - // ... and we're NOT the column the menu is on - else { - // ... move the menu to our column - uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm); - } - } - // If the menu is NOT showing - else { - // ... show it on our column - uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm); - } - }; - } - }; - } - }; - - return uiGridHeaderCell; - }]); - -})(); - -(function(){ - 'use strict'; - - angular.module('ui.grid').directive('uiGridHeader', ['$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', 'ScrollEvent', - function($templateCache, $compile, uiGridConstants, gridUtil, $timeout, ScrollEvent) { - var defaultTemplate = 'ui-grid/ui-grid-header'; - var emptyTemplate = 'ui-grid/ui-grid-no-header'; - - return { - restrict: 'EA', - // templateUrl: 'ui-grid/ui-grid-header', - replace: true, - // priority: 1000, - require: ['^uiGrid', '^uiGridRenderContainer'], - scope: true, - compile: function($elm, $attrs) { - return { - pre: function ($scope, $elm, $attrs, controllers) { - var uiGridCtrl = controllers[0]; - var containerCtrl = controllers[1]; - - $scope.grid = uiGridCtrl.grid; - $scope.colContainer = containerCtrl.colContainer; - - updateHeaderReferences(); - - var headerTemplate; - if (!$scope.grid.options.showHeader) { - headerTemplate = emptyTemplate; - } - else { - headerTemplate = ($scope.grid.options.headerTemplate) ? $scope.grid.options.headerTemplate : defaultTemplate; - } - - gridUtil.getTemplate(headerTemplate) - .then(function (contents) { - var template = angular.element(contents); - - var newElm = $compile(template)($scope); - $elm.replaceWith(newElm); - - // And update $elm to be the new element - $elm = newElm; - - updateHeaderReferences(); - - if (containerCtrl) { - // Inject a reference to the header viewport (if it exists) into the grid controller for use in the horizontal scroll handler below - var headerViewport = $elm[0].getElementsByClassName('ui-grid-header-viewport')[0]; - - - if (headerViewport) { - containerCtrl.headerViewport = headerViewport; - angular.element(headerViewport).on('scroll', scrollHandler); - $scope.$on('$destroy', function () { - angular.element(headerViewport).off('scroll', scrollHandler); - }); - } - } - - $scope.grid.queueRefresh(); - }); - - function updateHeaderReferences() { - containerCtrl.header = containerCtrl.colContainer.header = $elm; - - var headerCanvases = $elm[0].getElementsByClassName('ui-grid-header-canvas'); - - if (headerCanvases.length > 0) { - containerCtrl.headerCanvas = containerCtrl.colContainer.headerCanvas = headerCanvases[0]; - } - else { - containerCtrl.headerCanvas = null; - } - } - - function scrollHandler(evt) { - if (uiGridCtrl.grid.isScrollingHorizontally) { - return; - } - var newScrollLeft = gridUtil.normalizeScrollLeft(containerCtrl.headerViewport, uiGridCtrl.grid); - var horizScrollPercentage = containerCtrl.colContainer.scrollHorizontal(newScrollLeft); - - var scrollEvent = new ScrollEvent(uiGridCtrl.grid, null, containerCtrl.colContainer, ScrollEvent.Sources.ViewPortScroll); - scrollEvent.newScrollLeft = newScrollLeft; - if ( horizScrollPercentage > -1 ){ - scrollEvent.x = { percentage: horizScrollPercentage }; - } - - uiGridCtrl.grid.scrollContainers(null, scrollEvent); - } - }, - - post: function ($scope, $elm, $attrs, controllers) { - var uiGridCtrl = controllers[0]; - var containerCtrl = controllers[1]; - - // gridUtil.logDebug('ui-grid-header link'); - - var grid = uiGridCtrl.grid; - - // Don't animate header cells - gridUtil.disableAnimations($elm); - - function updateColumnWidths() { - // this styleBuilder always runs after the renderContainer, so we can rely on the column widths - // already being populated correctly - - var columnCache = containerCtrl.colContainer.visibleColumnCache; - - // Build the CSS - // uiGridCtrl.grid.columns.forEach(function (column) { - var ret = ''; - var canvasWidth = 0; - columnCache.forEach(function (column) { - ret = ret + column.getColClassDefinition(); - canvasWidth += column.drawnWidth; - }); - - containerCtrl.colContainer.canvasWidth = canvasWidth; - - // Return the styles back to buildStyles which pops them into the `customStyles` scope variable - return ret; - } - - containerCtrl.header = $elm; - - var headerViewport = $elm[0].getElementsByClassName('ui-grid-header-viewport')[0]; - if (headerViewport) { - containerCtrl.headerViewport = headerViewport; - } - - //todo: remove this if by injecting gridCtrl into unit tests - if (uiGridCtrl) { - uiGridCtrl.grid.registerStyleComputation({ - priority: 15, - func: updateColumnWidths - }); - } - } - }; - } - }; - }]); - -})(); - -(function(){ - -angular.module('ui.grid') -.service('uiGridGridMenuService', [ 'gridUtil', 'i18nService', 'uiGridConstants', function( gridUtil, i18nService, uiGridConstants ) { - /** - * @ngdoc service - * @name ui.grid.gridMenuService - * - * @description Methods for working with the grid menu - */ - - var service = { - /** - * @ngdoc method - * @methodOf ui.grid.gridMenuService - * @name initialize - * @description Sets up the gridMenu. Most importantly, sets our - * scope onto the grid object as grid.gridMenuScope, allowing us - * to operate when passed only the grid. Second most importantly, - * we register the 'addToGridMenu' and 'removeFromGridMenu' methods - * on the core api. - * @param {$scope} $scope the scope of this gridMenu - * @param {Grid} grid the grid to which this gridMenu is associated - */ - initialize: function( $scope, grid ){ - grid.gridMenuScope = $scope; - $scope.grid = grid; - $scope.registeredMenuItems = []; - - // not certain this is needed, but would be bad to create a memory leak - $scope.$on('$destroy', function() { - if ( $scope.grid && $scope.grid.gridMenuScope ){ - $scope.grid.gridMenuScope = null; - } - if ( $scope.grid ){ - $scope.grid = null; - } - if ( $scope.registeredMenuItems ){ - $scope.registeredMenuItems = null; - } - }); - - $scope.registeredMenuItems = []; - - /** - * @ngdoc function - * @name addToGridMenu - * @methodOf ui.grid.core.api:PublicApi - * @description add items to the grid menu. Used by features - * to add their menu items if they are enabled, can also be used by - * end users to add menu items. This method has the advantage of allowing - * remove again, which can simplify management of which items are included - * in the menu when. (Noting that in most cases the shown and active functions - * provide a better way to handle visibility of menu items) - * @param {Grid} grid the grid on which we are acting - * @param {array} items menu items in the format as described in the tutorial, with - * the added note that if you want to use remove you must also specify an `id` field, - * which is provided when you want to remove an item. The id should be unique. - * - */ - grid.api.registerMethod( 'core', 'addToGridMenu', service.addToGridMenu ); - - /** - * @ngdoc function - * @name removeFromGridMenu - * @methodOf ui.grid.core.api:PublicApi - * @description Remove an item from the grid menu based on a provided id. Assumes - * that the id is unique, removes only the last instance of that id. Does nothing if - * the specified id is not found - * @param {Grid} grid the grid on which we are acting - * @param {string} id the id we'd like to remove from the menu - * - */ - grid.api.registerMethod( 'core', 'removeFromGridMenu', service.removeFromGridMenu ); - }, - - - /** - * @ngdoc function - * @name addToGridMenu - * @propertyOf ui.grid.gridMenuService - * @description add items to the grid menu. Used by features - * to add their menu items if they are enabled, can also be used by - * end users to add menu items. This method has the advantage of allowing - * remove again, which can simplify management of which items are included - * in the menu when. (Noting that in most cases the shown and active functions - * provide a better way to handle visibility of menu items) - * @param {Grid} grid the grid on which we are acting - * @param {array} items menu items in the format as described in the tutorial, with - * the added note that if you want to use remove you must also specify an `id` field, - * which is provided when you want to remove an item. The id should be unique. - * - */ - addToGridMenu: function( grid, menuItems ) { - if ( !angular.isArray( menuItems ) ) { - gridUtil.logError( 'addToGridMenu: menuItems must be an array, and is not, not adding any items'); - } else { - if ( grid.gridMenuScope ){ - grid.gridMenuScope.registeredMenuItems = grid.gridMenuScope.registeredMenuItems ? grid.gridMenuScope.registeredMenuItems : []; - grid.gridMenuScope.registeredMenuItems = grid.gridMenuScope.registeredMenuItems.concat( menuItems ); - } else { - gridUtil.logError( 'Asked to addToGridMenu, but gridMenuScope not present. Timing issue? Please log issue with ui-grid'); - } - } - }, - - - /** - * @ngdoc function - * @name removeFromGridMenu - * @methodOf ui.grid.gridMenuService - * @description Remove an item from the grid menu based on a provided id. Assumes - * that the id is unique, removes only the last instance of that id. Does nothing if - * the specified id is not found. If there is no gridMenuScope or registeredMenuItems - * then do nothing silently - the desired result is those menu items not be present and they - * aren't. - * @param {Grid} grid the grid on which we are acting - * @param {string} id the id we'd like to remove from the menu - * - */ - removeFromGridMenu: function( grid, id ){ - var foundIndex = -1; - - if ( grid && grid.gridMenuScope ){ - grid.gridMenuScope.registeredMenuItems.forEach( function( value, index ) { - if ( value.id === id ){ - if (foundIndex > -1) { - gridUtil.logError( 'removeFromGridMenu: found multiple items with the same id, removing only the last' ); - } else { - - foundIndex = index; - } - } - }); - } - - if ( foundIndex > -1 ){ - grid.gridMenuScope.registeredMenuItems.splice( foundIndex, 1 ); - } - }, - - - /** - * @ngdoc array - * @name gridMenuCustomItems - * @propertyOf ui.grid.class:GridOptions - * @description (optional) An array of menu items that should be added to - * the gridMenu. Follow the format documented in the tutorial for column - * menu customisation. The context provided to the action function will - * include context.grid. An alternative if working with dynamic menus is to use the - * provided api - core.addToGridMenu and core.removeFromGridMenu, which handles - * some of the management of items for you. - * - */ - /** - * @ngdoc boolean - * @name gridMenuShowHideColumns - * @propertyOf ui.grid.class:GridOptions - * @description true by default, whether the grid menu should allow hide/show - * of columns - * - */ - /** - * @ngdoc method - * @methodOf ui.grid.gridMenuService - * @name getMenuItems - * @description Decides the menu items to show in the menu. This is a - * combination of: - * - * - the default menu items that are always included, - * - any menu items that have been provided through the addMenuItem api. These - * are typically added by features within the grid - * - any menu items included in grid.options.gridMenuCustomItems. These can be - * changed dynamically, as they're always recalculated whenever we show the - * menu - * @param {$scope} $scope the scope of this gridMenu, from which we can find all - * the information that we need - * @returns {array} an array of menu items that can be shown - */ - getMenuItems: function( $scope ) { - var menuItems = [ - // this is where we add any menu items we want to always include - ]; - - if ( $scope.grid.options.gridMenuCustomItems ){ - if ( !angular.isArray( $scope.grid.options.gridMenuCustomItems ) ){ - gridUtil.logError( 'gridOptions.gridMenuCustomItems must be an array, and is not'); - } else { - menuItems = menuItems.concat( $scope.grid.options.gridMenuCustomItems ); - } - } - - var clearFilters = [{ - title: i18nService.getSafeText('gridMenu.clearAllFilters'), - action: function ($event) { - $scope.grid.clearAllFilters(undefined, true, undefined); - }, - shown: function() { - return $scope.grid.options.enableFiltering; - }, - order: 100 - }]; - menuItems = menuItems.concat( clearFilters ); - - menuItems = menuItems.concat( $scope.registeredMenuItems ); - - if ( $scope.grid.options.gridMenuShowHideColumns !== false ){ - menuItems = menuItems.concat( service.showHideColumns( $scope ) ); - } - - menuItems.sort(function(a, b){ - return a.order - b.order; - }); - - return menuItems; - }, - - - /** - * @ngdoc array - * @name gridMenuTitleFilter - * @propertyOf ui.grid.class:GridOptions - * @description (optional) A function that takes a title string - * (usually the col.displayName), and converts it into a display value. The function - * must return either a string or a promise. - * - * Used for internationalization of the grid menu column names - for angular-translate - * you can pass $translate as the function, for i18nService you can pass getSafeText as the - * function - * @example - *
        -     *   gridOptions = {
        -     *     gridMenuTitleFilter: $translate
        -     *   }
        -     * 
        - */ - /** - * @ngdoc method - * @methodOf ui.grid.gridMenuService - * @name showHideColumns - * @description Adds two menu items for each of the columns in columnDefs. One - * menu item for hide, one menu item for show. Each is visible when appropriate - * (show when column is not visible, hide when column is visible). Each toggles - * the visible property on the columnDef using toggleColumnVisibility - * @param {$scope} $scope of a gridMenu, which contains a reference to the grid - */ - showHideColumns: function( $scope ){ - var showHideColumns = []; - if ( !$scope.grid.options.columnDefs || $scope.grid.options.columnDefs.length === 0 || $scope.grid.columns.length === 0 ) { - return showHideColumns; - } - - // add header for columns - showHideColumns.push({ - title: i18nService.getSafeText('gridMenu.columns'), - order: 300 - }); - - $scope.grid.options.gridMenuTitleFilter = $scope.grid.options.gridMenuTitleFilter ? $scope.grid.options.gridMenuTitleFilter : function( title ) { return title; }; - - $scope.grid.options.columnDefs.forEach( function( colDef, index ){ - if ( colDef.enableHiding !== false ){ - // add hide menu item - shows an OK icon as we only show when column is already visible - var menuItem = { - icon: 'ui-grid-icon-ok', - action: function($event) { - $event.stopPropagation(); - service.toggleColumnVisibility( this.context.gridCol ); - }, - shown: function() { - return this.context.gridCol.colDef.visible === true || this.context.gridCol.colDef.visible === undefined; - }, - context: { gridCol: $scope.grid.getColumn(colDef.name || colDef.field) }, - leaveOpen: true, - order: 301 + index * 2 - }; - service.setMenuItemTitle( menuItem, colDef, $scope.grid ); - showHideColumns.push( menuItem ); - - // add show menu item - shows no icon as we only show when column is invisible - menuItem = { - icon: 'ui-grid-icon-cancel', - action: function($event) { - $event.stopPropagation(); - service.toggleColumnVisibility( this.context.gridCol ); - }, - shown: function() { - return !(this.context.gridCol.colDef.visible === true || this.context.gridCol.colDef.visible === undefined); - }, - context: { gridCol: $scope.grid.getColumn(colDef.name || colDef.field) }, - leaveOpen: true, - order: 301 + index * 2 + 1 - }; - service.setMenuItemTitle( menuItem, colDef, $scope.grid ); - showHideColumns.push( menuItem ); - } - }); - return showHideColumns; - }, - - - /** - * @ngdoc method - * @methodOf ui.grid.gridMenuService - * @name setMenuItemTitle - * @description Handles the response from gridMenuTitleFilter, adding it directly to the menu - * item if it returns a string, otherwise waiting for the promise to resolve or reject then - * putting the result into the title - * @param {object} menuItem the menuItem we want to put the title on - * @param {object} colDef the colDef from which we can get displayName, name or field - * @param {Grid} grid the grid, from which we can get the options.gridMenuTitleFilter - * - */ - setMenuItemTitle: function( menuItem, colDef, grid ){ - var title = grid.options.gridMenuTitleFilter( colDef.displayName || gridUtil.readableColumnName(colDef.name) || colDef.field ); - - if ( typeof(title) === 'string' ){ - menuItem.title = title; - } else if ( title.then ){ - // must be a promise - menuItem.title = ""; - title.then( function( successValue ) { - menuItem.title = successValue; - }, function( errorValue ) { - menuItem.title = errorValue; - }); - } else { - gridUtil.logError('Expected gridMenuTitleFilter to return a string or a promise, it has returned neither, bad config'); - menuItem.title = 'badconfig'; - } - }, - - /** - * @ngdoc method - * @methodOf ui.grid.gridMenuService - * @name toggleColumnVisibility - * @description Toggles the visibility of an individual column. Expects to be - * provided a context that has on it a gridColumn, which is the column that - * we'll operate upon. We change the visibility, and refresh the grid as appropriate - * @param {GridCol} gridCol the column that we want to toggle - * - */ - toggleColumnVisibility: function( gridCol ) { - gridCol.colDef.visible = !( gridCol.colDef.visible === true || gridCol.colDef.visible === undefined ); - - gridCol.grid.refresh(); - gridCol.grid.api.core.notifyDataChange( uiGridConstants.dataChange.COLUMN ); - gridCol.grid.api.core.raise.columnVisibilityChanged( gridCol ); - } - }; - - return service; -}]) - - - -.directive('uiGridMenuButton', ['gridUtil', 'uiGridConstants', 'uiGridGridMenuService', 'i18nService', -function (gridUtil, uiGridConstants, uiGridGridMenuService, i18nService) { - - return { - priority: 0, - scope: true, - require: ['^uiGrid'], - templateUrl: 'ui-grid/ui-grid-menu-button', - replace: true, - - link: function ($scope, $elm, $attrs, controllers) { - var uiGridCtrl = controllers[0]; - - // For the aria label - $scope.i18n = { - aria: i18nService.getSafeText('gridMenu.aria') - }; - - uiGridGridMenuService.initialize($scope, uiGridCtrl.grid); - - $scope.shown = false; - - $scope.toggleMenu = function () { - if ( $scope.shown ){ - $scope.$broadcast('hide-menu'); - $scope.shown = false; - } else { - $scope.menuItems = uiGridGridMenuService.getMenuItems( $scope ); - $scope.$broadcast('show-menu'); - $scope.shown = true; - } - }; - - $scope.$on('menu-hidden', function() { - $scope.shown = false; - gridUtil.focus.bySelector($elm, '.ui-grid-icon-container'); - }); - } - }; - -}]); - -})(); - -(function(){ - -/** - * @ngdoc directive - * @name ui.grid.directive:uiGridMenu - * @element style - * @restrict A - * - * @description - * Allows us to interpolate expressions in ` - I am in a box. -
        - - - it('should apply the right class to the element', function () { - element(by.css('.blah')).getCssValue('border-top-width') - .then(function(c) { - expect(c).toContain('1px'); - }); - }); - - - */ - - - angular.module('ui.grid').directive('uiGridStyle', ['gridUtil', '$interpolate', function(gridUtil, $interpolate) { - return { - // restrict: 'A', - // priority: 1000, - // require: '?^uiGrid', - link: function($scope, $elm, $attrs, uiGridCtrl) { - // gridUtil.logDebug('ui-grid-style link'); - // if (uiGridCtrl === undefined) { - // gridUtil.logWarn('[ui-grid-style link] uiGridCtrl is undefined!'); - // } - - var interpolateFn = $interpolate($elm.text(), true); - - if (interpolateFn) { - $scope.$watch(interpolateFn, function(value) { - $elm.text(value); - }); - } - - // uiGridCtrl.recalcRowStyles = function() { - // var offset = (scope.options.offsetTop || 0) - (scope.options.excessRows * scope.options.rowHeight); - // var rowHeight = scope.options.rowHeight; - - // var ret = ''; - // var rowStyleCount = uiGridCtrl.minRowsToRender() + (scope.options.excessRows * 2); - // for (var i = 1; i <= rowStyleCount; i++) { - // ret = ret + ' .grid' + scope.gridId + ' .ui-grid-row:nth-child(' + i + ') { top: ' + offset + 'px; }'; - // offset = offset + rowHeight; - // } - - // scope.rowStyles = ret; - // }; - - // uiGridCtrl.styleComputions.push(uiGridCtrl.recalcRowStyles); - - } - }; - }]); - -})(); - -(function(){ - 'use strict'; - - angular.module('ui.grid').directive('uiGridViewport', ['gridUtil','ScrollEvent','uiGridConstants', '$log', - function(gridUtil, ScrollEvent, uiGridConstants, $log) { - return { - replace: true, - scope: {}, - controllerAs: 'Viewport', - templateUrl: 'ui-grid/uiGridViewport', - require: ['^uiGrid', '^uiGridRenderContainer'], - link: function($scope, $elm, $attrs, controllers) { - // gridUtil.logDebug('viewport post-link'); - - var uiGridCtrl = controllers[0]; - var containerCtrl = controllers[1]; - - $scope.containerCtrl = containerCtrl; - - var rowContainer = containerCtrl.rowContainer; - var colContainer = containerCtrl.colContainer; - - var grid = uiGridCtrl.grid; - - $scope.grid = uiGridCtrl.grid; - - // Put the containers in scope so we can get rows and columns from them - $scope.rowContainer = containerCtrl.rowContainer; - $scope.colContainer = containerCtrl.colContainer; - - // Register this viewport with its container - containerCtrl.viewport = $elm; - - - $elm.on('scroll', scrollHandler); - - var ignoreScroll = false; - - function scrollHandler(evt) { - //Leaving in this commented code in case it can someday be used - //It does improve performance, but because the horizontal scroll is normalized, - // using this code will lead to the column header getting slightly out of line with columns - // - //if (ignoreScroll && (grid.isScrollingHorizontally || grid.isScrollingHorizontally)) { - // //don't ask for scrollTop if we just set it - // ignoreScroll = false; - // return; - //} - //ignoreScroll = true; - - var newScrollTop = $elm[0].scrollTop; - var newScrollLeft = gridUtil.normalizeScrollLeft($elm, grid); - - var vertScrollPercentage = rowContainer.scrollVertical(newScrollTop); - var horizScrollPercentage = colContainer.scrollHorizontal(newScrollLeft); - - var scrollEvent = new ScrollEvent(grid, rowContainer, colContainer, ScrollEvent.Sources.ViewPortScroll); - scrollEvent.newScrollLeft = newScrollLeft; - scrollEvent.newScrollTop = newScrollTop; - if ( horizScrollPercentage > -1 ){ - scrollEvent.x = { percentage: horizScrollPercentage }; - } - - if ( vertScrollPercentage > -1 ){ - scrollEvent.y = { percentage: vertScrollPercentage }; - } - - grid.scrollContainers($scope.$parent.containerId, scrollEvent); - } - - if ($scope.$parent.bindScrollVertical) { - grid.addVerticalScrollSync($scope.$parent.containerId, syncVerticalScroll); - } - - if ($scope.$parent.bindScrollHorizontal) { - grid.addHorizontalScrollSync($scope.$parent.containerId, syncHorizontalScroll); - grid.addHorizontalScrollSync($scope.$parent.containerId + 'header', syncHorizontalHeader); - grid.addHorizontalScrollSync($scope.$parent.containerId + 'footer', syncHorizontalFooter); - } - - function syncVerticalScroll(scrollEvent){ - containerCtrl.prevScrollArgs = scrollEvent; - var newScrollTop = scrollEvent.getNewScrollTop(rowContainer,containerCtrl.viewport); - $elm[0].scrollTop = newScrollTop; - - } - - function syncHorizontalScroll(scrollEvent){ - containerCtrl.prevScrollArgs = scrollEvent; - var newScrollLeft = scrollEvent.getNewScrollLeft(colContainer, containerCtrl.viewport); - $elm[0].scrollLeft = gridUtil.denormalizeScrollLeft(containerCtrl.viewport,newScrollLeft, grid); - } - - function syncHorizontalHeader(scrollEvent){ - var newScrollLeft = scrollEvent.getNewScrollLeft(colContainer, containerCtrl.viewport); - if (containerCtrl.headerViewport) { - containerCtrl.headerViewport.scrollLeft = gridUtil.denormalizeScrollLeft(containerCtrl.viewport,newScrollLeft, grid); - } - } - - function syncHorizontalFooter(scrollEvent){ - var newScrollLeft = scrollEvent.getNewScrollLeft(colContainer, containerCtrl.viewport); - if (containerCtrl.footerViewport) { - containerCtrl.footerViewport.scrollLeft = gridUtil.denormalizeScrollLeft(containerCtrl.viewport,newScrollLeft, grid); - } - } - - - }, - controller: ['$scope', function ($scope) { - this.rowStyle = function (index) { - var rowContainer = $scope.rowContainer; - var colContainer = $scope.colContainer; - - var styles = {}; - - if (index === 0 && rowContainer.currentTopRow !== 0) { - // The row offset-top is just the height of the rows above the current top-most row, which are no longer rendered - var hiddenRowWidth = (rowContainer.currentTopRow) * rowContainer.grid.options.rowHeight; - - // return { 'margin-top': hiddenRowWidth + 'px' }; - styles['margin-top'] = hiddenRowWidth + 'px'; - } - - if (colContainer.currentFirstColumn !== 0) { - if (colContainer.grid.isRTL()) { - styles['margin-right'] = colContainer.columnOffset + 'px'; - } - else { - styles['margin-left'] = colContainer.columnOffset + 'px'; - } - } - - return styles; - }; - }] - }; - } - ]); - -})(); - -(function() { - -angular.module('ui.grid') -.directive('uiGridVisible', function uiGridVisibleAction() { - return function ($scope, $elm, $attr) { - $scope.$watch($attr.uiGridVisible, function (visible) { - // $elm.css('visibility', visible ? 'visible' : 'hidden'); - $elm[visible ? 'removeClass' : 'addClass']('ui-grid-invisible'); - }); - }; -}); - -})(); -(function () { - 'use strict'; - - angular.module('ui.grid').controller('uiGridController', ['$scope', '$element', '$attrs', 'gridUtil', '$q', 'uiGridConstants', - '$templateCache', 'gridClassFactory', '$timeout', '$parse', '$compile', - function ($scope, $elm, $attrs, gridUtil, $q, uiGridConstants, - $templateCache, gridClassFactory, $timeout, $parse, $compile) { - // gridUtil.logDebug('ui-grid controller'); - - var self = this; - - self.grid = gridClassFactory.createGrid($scope.uiGrid); - - //assign $scope.$parent if appScope not already assigned - self.grid.appScope = self.grid.appScope || $scope.$parent; - - $elm.addClass('grid' + self.grid.id); - self.grid.rtl = gridUtil.getStyles($elm[0])['direction'] === 'rtl'; - - - // angular.extend(self.grid.options, ); - - //all properties of grid are available on scope - $scope.grid = self.grid; - - if ($attrs.uiGridColumns) { - $attrs.$observe('uiGridColumns', function(value) { - self.grid.options.columnDefs = value; - self.grid.buildColumns() - .then(function(){ - self.grid.preCompileCellTemplates(); - - self.grid.refreshCanvas(true); - }); - }); - } - - - // if fastWatch is set we watch only the length and the reference, not every individual object - var deregFunctions = []; - if (self.grid.options.fastWatch) { - self.uiGrid = $scope.uiGrid; - if (angular.isString($scope.uiGrid.data)) { - deregFunctions.push( $scope.$parent.$watch($scope.uiGrid.data, dataWatchFunction) ); - deregFunctions.push( $scope.$parent.$watch(function() { - if ( self.grid.appScope[$scope.uiGrid.data] ){ - return self.grid.appScope[$scope.uiGrid.data].length; - } else { - return undefined; - } - }, dataWatchFunction) ); - } else { - deregFunctions.push( $scope.$parent.$watch(function() { return $scope.uiGrid.data; }, dataWatchFunction) ); - deregFunctions.push( $scope.$parent.$watch(function() { return $scope.uiGrid.data.length; }, dataWatchFunction) ); - } - deregFunctions.push( $scope.$parent.$watch(function() { return $scope.uiGrid.columnDefs; }, columnDefsWatchFunction) ); - deregFunctions.push( $scope.$parent.$watch(function() { return $scope.uiGrid.columnDefs.length; }, columnDefsWatchFunction) ); - } else { - if (angular.isString($scope.uiGrid.data)) { - deregFunctions.push( $scope.$parent.$watchCollection($scope.uiGrid.data, dataWatchFunction) ); - } else { - deregFunctions.push( $scope.$parent.$watchCollection(function() { return $scope.uiGrid.data; }, dataWatchFunction) ); - } - deregFunctions.push( $scope.$parent.$watchCollection(function() { return $scope.uiGrid.columnDefs; }, columnDefsWatchFunction) ); - } - - - function columnDefsWatchFunction(n, o) { - if (n && n !== o) { - self.grid.options.columnDefs = n; - self.grid.buildColumns({ orderByColumnDefs: true }) - .then(function(){ - - self.grid.preCompileCellTemplates(); - - self.grid.callDataChangeCallbacks(uiGridConstants.dataChange.COLUMN); - }); - } - } - - function dataWatchFunction(newData) { - // gridUtil.logDebug('dataWatch fired'); - var promises = []; - - if ( self.grid.options.fastWatch ){ - if (angular.isString($scope.uiGrid.data)) { - newData = self.grid.appScope[$scope.uiGrid.data]; - } else { - newData = $scope.uiGrid.data; - } - } - - if (newData) { - // columns length is greater than the number of row header columns, which don't count because they're created automatically - var hasColumns = self.grid.columns.length > (self.grid.rowHeaderColumns ? self.grid.rowHeaderColumns.length : 0); - - if ( - // If we have no columns - !hasColumns && - // ... and we don't have a ui-grid-columns attribute, which would define columns for us - !$attrs.uiGridColumns && - // ... and we have no pre-defined columns - self.grid.options.columnDefs.length === 0 && - // ... but we DO have data - newData.length > 0 - ) { - // ... then build the column definitions from the data that we have - self.grid.buildColumnDefsFromData(newData); - } - - // If we haven't built columns before and either have some columns defined or some data defined - if (!hasColumns && (self.grid.options.columnDefs.length > 0 || newData.length > 0)) { - // Build the column set, then pre-compile the column cell templates - promises.push(self.grid.buildColumns() - .then(function() { - self.grid.preCompileCellTemplates(); - })); - } - - $q.all(promises).then(function() { - self.grid.modifyRows(newData) - .then(function () { - // if (self.viewport) { - self.grid.redrawInPlace(true); - // } - - $scope.$evalAsync(function() { - self.grid.refreshCanvas(true); - self.grid.callDataChangeCallbacks(uiGridConstants.dataChange.ROW); - }); - }); - }); - } - } - - var styleWatchDereg = $scope.$watch(function () { return self.grid.styleComputations; }, function() { - self.grid.refreshCanvas(true); - }); - - $scope.$on('$destroy', function() { - deregFunctions.forEach( function( deregFn ){ deregFn(); }); - styleWatchDereg(); - }); - - self.fireEvent = function(eventName, args) { - // Add the grid to the event arguments if it's not there - if (typeof(args) === 'undefined' || args === undefined) { - args = {}; - } - - if (typeof(args.grid) === 'undefined' || args.grid === undefined) { - args.grid = self.grid; - } - - $scope.$broadcast(eventName, args); - }; - - self.innerCompile = function innerCompile(elm) { - $compile(elm)($scope); - }; - - }]); - -/** - * @ngdoc directive - * @name ui.grid.directive:uiGrid - * @element div - * @restrict EA - * @param {Object} uiGrid Options for the grid to use - * - * @description Create a very basic grid. - * - * @example - - - var app = angular.module('app', ['ui.grid']); - - app.controller('MainCtrl', ['$scope', function ($scope) { - $scope.data = [ - { name: 'Bob', title: 'CEO' }, - { name: 'Frank', title: 'Lowly Developer' } - ]; - }]); - - -
        -
        -
        -
        -
        - */ -angular.module('ui.grid').directive('uiGrid', uiGridDirective); - -uiGridDirective.$inject = ['$compile', '$templateCache', '$timeout', '$window', 'gridUtil', 'uiGridConstants']; -function uiGridDirective($compile, $templateCache, $timeout, $window, gridUtil, uiGridConstants) { - return { - templateUrl: 'ui-grid/ui-grid', - scope: { - uiGrid: '=' - }, - replace: true, - transclude: true, - controller: 'uiGridController', - compile: function () { - return { - post: function ($scope, $elm, $attrs, uiGridCtrl) { - var grid = uiGridCtrl.grid; - // Initialize scrollbars (TODO: move to controller??) - uiGridCtrl.scrollbars = []; - grid.element = $elm; - - - // See if the grid has a rendered width, if not, wait a bit and try again - var sizeCheckInterval = 100; // ms - var maxSizeChecks = 20; // 2 seconds total - var sizeChecks = 0; - - // Setup (event listeners) the grid - setup(); - - // And initialize it - init(); - - // Mark rendering complete so API events can happen - grid.renderingComplete(); - - // If the grid doesn't have size currently, wait for a bit to see if it gets size - checkSize(); - - /*-- Methods --*/ - - function checkSize() { - // If the grid has no width and we haven't checked more than times, check again in milliseconds - if ($elm[0].offsetWidth <= 0 && sizeChecks < maxSizeChecks) { - setTimeout(checkSize, sizeCheckInterval); - sizeChecks++; - } - else { - $timeout(init); - } - } - - // Setup event listeners and watchers - function setup() { - // Bind to window resize events - angular.element($window).on('resize', gridResize); - - // Unbind from window resize events when the grid is destroyed - $elm.on('$destroy', function () { - angular.element($window).off('resize', gridResize); - }); - - // If we add a left container after render, we need to watch and react - $scope.$watch(function () { return grid.hasLeftContainer();}, function (newValue, oldValue) { - if (newValue === oldValue) { - return; - } - grid.refreshCanvas(true); - }); - - // If we add a right container after render, we need to watch and react - $scope.$watch(function () { return grid.hasRightContainer();}, function (newValue, oldValue) { - if (newValue === oldValue) { - return; - } - grid.refreshCanvas(true); - }); - } - - // Initialize the directive - function init() { - grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm); - - // Default canvasWidth to the grid width, in case we don't get any column definitions to calculate it from - grid.canvasWidth = uiGridCtrl.grid.gridWidth; - - grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm); - - // If the grid isn't tall enough to fit a single row, it's kind of useless. Resize it to fit a minimum number of rows - if (grid.gridHeight < grid.options.rowHeight && grid.options.enableMinHeightCheck) { - autoAdjustHeight(); - } - - // Run initial canvas refresh - grid.refreshCanvas(true); - } - - // Set the grid's height ourselves in the case that its height would be unusably small - function autoAdjustHeight() { - // Figure out the new height - var contentHeight = grid.options.minRowsToShow * grid.options.rowHeight; - var headerHeight = grid.options.showHeader ? grid.options.headerRowHeight : 0; - var footerHeight = grid.calcFooterHeight(); - - var scrollbarHeight = 0; - if (grid.options.enableHorizontalScrollbar === uiGridConstants.scrollbars.ALWAYS) { - scrollbarHeight = gridUtil.getScrollbarWidth(); - } - - var maxNumberOfFilters = 0; - // Calculates the maximum number of filters in the columns - angular.forEach(grid.options.columnDefs, function(col) { - if (col.hasOwnProperty('filter')) { - if (maxNumberOfFilters < 1) { - maxNumberOfFilters = 1; - } - } - else if (col.hasOwnProperty('filters')) { - if (maxNumberOfFilters < col.filters.length) { - maxNumberOfFilters = col.filters.length; - } - } - }); - - if (grid.options.enableFiltering) { - var allColumnsHaveFilteringTurnedOff = grid.options.columnDefs.every(function(col) { - return col.enableFiltering === false; - }); - - if (!allColumnsHaveFilteringTurnedOff) { - maxNumberOfFilters++; - } - } - - var filterHeight = maxNumberOfFilters * headerHeight; - - var newHeight = headerHeight + contentHeight + footerHeight + scrollbarHeight + filterHeight; - - $elm.css('height', newHeight + 'px'); - - grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm); - } - - // Resize the grid on window resize events - function gridResize($event) { - grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm); - grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm); - - grid.refreshCanvas(true); - } - } - }; - } - }; -} - -})(); - -(function(){ - 'use strict'; - - // TODO: rename this file to ui-grid-pinned-container.js - - angular.module('ui.grid').directive('uiGridPinnedContainer', ['gridUtil', function (gridUtil) { - return { - restrict: 'EA', - replace: true, - template: '
        ', - scope: { - side: '=uiGridPinnedContainer' - }, - require: '^uiGrid', - compile: function compile() { - return { - post: function ($scope, $elm, $attrs, uiGridCtrl) { - // gridUtil.logDebug('ui-grid-pinned-container ' + $scope.side + ' link'); - - var grid = uiGridCtrl.grid; - - var myWidth = 0; - - $elm.addClass('ui-grid-pinned-container-' + $scope.side); - - // Monkey-patch the viewport width function - if ($scope.side === 'left' || $scope.side === 'right') { - grid.renderContainers[$scope.side].getViewportWidth = monkeyPatchedGetViewportWidth; - } - - function monkeyPatchedGetViewportWidth() { - /*jshint validthis: true */ - var self = this; - - var viewportWidth = 0; - self.visibleColumnCache.forEach(function (column) { - viewportWidth += column.drawnWidth; - }); - - var adjustment = self.getViewportAdjustment(); - - viewportWidth = viewportWidth + adjustment.width; - - return viewportWidth; - } - - function updateContainerWidth() { - if ($scope.side === 'left' || $scope.side === 'right') { - var cols = grid.renderContainers[$scope.side].visibleColumnCache; - var width = 0; - for (var i = 0; i < cols.length; i++) { - var col = cols[i]; - width += col.drawnWidth || col.width || 0; - } - - return width; - } - } - - function updateContainerDimensions() { - var ret = ''; - - // Column containers - if ($scope.side === 'left' || $scope.side === 'right') { - myWidth = updateContainerWidth(); - - // gridUtil.logDebug('myWidth', myWidth); - - // TODO(c0bra): Subtract sum of col widths from grid viewport width and update it - $elm.attr('style', null); - - // var myHeight = grid.renderContainers.body.getViewportHeight(); // + grid.horizontalScrollbarHeight; - - ret += '.grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ', .grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ' .ui-grid-render-container-' + $scope.side + ' .ui-grid-viewport { width: ' + myWidth + 'px; } '; - } - - return ret; - } - - grid.renderContainers.body.registerViewportAdjuster(function (adjustment) { - myWidth = updateContainerWidth(); - - // Subtract our own width - adjustment.width -= myWidth; - adjustment.side = $scope.side; - - return adjustment; - }); - - // Register style computation to adjust for columns in `side`'s render container - grid.registerStyleComputation({ - priority: 15, - func: updateContainerDimensions - }); - } - }; - } - }; - }]); -})(); - -(function(){ - -angular.module('ui.grid') -.factory('Grid', ['$q', '$compile', '$parse', 'gridUtil', 'uiGridConstants', 'GridOptions', 'GridColumn', 'GridRow', 'GridApi', 'rowSorter', 'rowSearcher', 'GridRenderContainer', '$timeout','ScrollEvent', - function($q, $compile, $parse, gridUtil, uiGridConstants, GridOptions, GridColumn, GridRow, GridApi, rowSorter, rowSearcher, GridRenderContainer, $timeout, ScrollEvent) { - - /** - * @ngdoc object - * @name ui.grid.core.api:PublicApi - * @description Public Api for the core grid features - * - */ - - /** - * @ngdoc function - * @name ui.grid.class:Grid - * @description Grid is the main viewModel. Any properties or methods needed to maintain state are defined in - * this prototype. One instance of Grid is created per Grid directive instance. - * @param {object} options Object map of options to pass into the grid. An 'id' property is expected. - */ - var Grid = function Grid(options) { - var self = this; - // Get the id out of the options, then remove it - if (options !== undefined && typeof(options.id) !== 'undefined' && options.id) { - if (!/^[_a-zA-Z0-9-]+$/.test(options.id)) { - throw new Error("Grid id '" + options.id + '" is invalid. It must follow CSS selector syntax rules.'); - } - } - else { - throw new Error('No ID provided. An ID must be given when creating a grid.'); - } - - self.id = options.id; - delete options.id; - - // Get default options - self.options = GridOptions.initialize( options ); - - /** - * @ngdoc object - * @name appScope - * @propertyOf ui.grid.class:Grid - * @description reference to the application scope (the parent scope of the ui-grid element). Assigned in ui-grid controller - *
        - * use gridOptions.appScopeProvider to override the default assignment of $scope.$parent with any reference - */ - self.appScope = self.options.appScopeProvider; - - self.headerHeight = self.options.headerRowHeight; - - - /** - * @ngdoc object - * @name footerHeight - * @propertyOf ui.grid.class:Grid - * @description returns the total footer height gridFooter + columnFooter - */ - self.footerHeight = self.calcFooterHeight(); - - - /** - * @ngdoc object - * @name columnFooterHeight - * @propertyOf ui.grid.class:Grid - * @description returns the total column footer height - */ - self.columnFooterHeight = self.calcColumnFooterHeight(); - - self.rtl = false; - self.gridHeight = 0; - self.gridWidth = 0; - self.columnBuilders = []; - self.rowBuilders = []; - self.rowsProcessors = []; - self.columnsProcessors = []; - self.styleComputations = []; - self.viewportAdjusters = []; - self.rowHeaderColumns = []; - self.dataChangeCallbacks = {}; - self.verticalScrollSyncCallBackFns = {}; - self.horizontalScrollSyncCallBackFns = {}; - - // self.visibleRowCache = []; - - // Set of 'render' containers for self grid, which can render sets of rows - self.renderContainers = {}; - - // Create a - self.renderContainers.body = new GridRenderContainer('body', self); - - self.cellValueGetterCache = {}; - - // Cached function to use with custom row templates - self.getRowTemplateFn = null; - - - //representation of the rows on the grid. - //these are wrapped references to the actual data rows (options.data) - self.rows = []; - - //represents the columns on the grid - self.columns = []; - - /** - * @ngdoc boolean - * @name isScrollingVertically - * @propertyOf ui.grid.class:Grid - * @description set to true when Grid is scrolling vertically. Set to false via debounced method - */ - self.isScrollingVertically = false; - - /** - * @ngdoc boolean - * @name isScrollingHorizontally - * @propertyOf ui.grid.class:Grid - * @description set to true when Grid is scrolling horizontally. Set to false via debounced method - */ - self.isScrollingHorizontally = false; - - /** - * @ngdoc property - * @name scrollDirection - * @propertyOf ui.grid.class:Grid - * @description set one of the uiGridConstants.scrollDirection values (UP, DOWN, LEFT, RIGHT, NONE), which tells - * us which direction we are scrolling. Set to NONE via debounced method - */ - self.scrollDirection = uiGridConstants.scrollDirection.NONE; - - //if true, grid will not respond to any scroll events - self.disableScrolling = false; - - - function vertical (scrollEvent) { - self.isScrollingVertically = false; - self.api.core.raise.scrollEnd(scrollEvent); - self.scrollDirection = uiGridConstants.scrollDirection.NONE; - } - - var debouncedVertical = gridUtil.debounce(vertical, self.options.scrollDebounce); - var debouncedVerticalMinDelay = gridUtil.debounce(vertical, 0); - - function horizontal (scrollEvent) { - self.isScrollingHorizontally = false; - self.api.core.raise.scrollEnd(scrollEvent); - self.scrollDirection = uiGridConstants.scrollDirection.NONE; - } - - var debouncedHorizontal = gridUtil.debounce(horizontal, self.options.scrollDebounce); - var debouncedHorizontalMinDelay = gridUtil.debounce(horizontal, 0); - - - /** - * @ngdoc function - * @name flagScrollingVertically - * @methodOf ui.grid.class:Grid - * @description sets isScrollingVertically to true and sets it to false in a debounced function - */ - self.flagScrollingVertically = function(scrollEvent) { - if (!self.isScrollingVertically && !self.isScrollingHorizontally) { - self.api.core.raise.scrollBegin(scrollEvent); - } - self.isScrollingVertically = true; - if (self.options.scrollDebounce === 0 || !scrollEvent.withDelay) { - debouncedVerticalMinDelay(scrollEvent); - } - else { - debouncedVertical(scrollEvent); - } - }; - - /** - * @ngdoc function - * @name flagScrollingHorizontally - * @methodOf ui.grid.class:Grid - * @description sets isScrollingHorizontally to true and sets it to false in a debounced function - */ - self.flagScrollingHorizontally = function(scrollEvent) { - if (!self.isScrollingVertically && !self.isScrollingHorizontally) { - self.api.core.raise.scrollBegin(scrollEvent); - } - self.isScrollingHorizontally = true; - if (self.options.scrollDebounce === 0 || !scrollEvent.withDelay) { - debouncedHorizontalMinDelay(scrollEvent); - } - else { - debouncedHorizontal(scrollEvent); - } - }; - - self.scrollbarHeight = 0; - self.scrollbarWidth = 0; - if (self.options.enableHorizontalScrollbar === uiGridConstants.scrollbars.ALWAYS) { - self.scrollbarHeight = gridUtil.getScrollbarWidth(); - } - - if (self.options.enableVerticalScrollbar === uiGridConstants.scrollbars.ALWAYS) { - self.scrollbarWidth = gridUtil.getScrollbarWidth(); - } - - - - self.api = new GridApi(self); - - /** - * @ngdoc function - * @name refresh - * @methodOf ui.grid.core.api:PublicApi - * @description Refresh the rendered grid on screen. - * The refresh method re-runs both the columnProcessors and the - * rowProcessors, as well as calling refreshCanvas to update all - * the grid sizing. In general you should prefer to use queueGridRefresh - * instead, which is basically a debounced version of refresh. - * - * If you only want to resize the grid, not regenerate all the rows - * and columns, you should consider directly calling refreshCanvas instead. - * - */ - self.api.registerMethod( 'core', 'refresh', this.refresh ); - - /** - * @ngdoc function - * @name queueGridRefresh - * @methodOf ui.grid.core.api:PublicApi - * @description Request a refresh of the rendered grid on screen, if multiple - * calls to queueGridRefresh are made within a digest cycle only one will execute. - * The refresh method re-runs both the columnProcessors and the - * rowProcessors, as well as calling refreshCanvas to update all - * the grid sizing. In general you should prefer to use queueGridRefresh - * instead, which is basically a debounced version of refresh. - * - */ - self.api.registerMethod( 'core', 'queueGridRefresh', this.queueGridRefresh ); - - /** - * @ngdoc function - * @name refreshRows - * @methodOf ui.grid.core.api:PublicApi - * @description Runs only the rowProcessors, columns remain as they were. - * It then calls redrawInPlace and refreshCanvas, which adjust the grid sizing. - * @returns {promise} promise that is resolved when render completes? - * - */ - self.api.registerMethod( 'core', 'refreshRows', this.refreshRows ); - - /** - * @ngdoc function - * @name queueRefresh - * @methodOf ui.grid.core.api:PublicApi - * @description Requests execution of refreshCanvas, if multiple requests are made - * during a digest cycle only one will run. RefreshCanvas updates the grid sizing. - * @returns {promise} promise that is resolved when render completes? - * - */ - self.api.registerMethod( 'core', 'queueRefresh', this.queueRefresh ); - - /** - * @ngdoc function - * @name handleWindowResize - * @methodOf ui.grid.core.api:PublicApi - * @description Trigger a grid resize, normally this would be picked - * up by a watch on window size, but in some circumstances it is necessary - * to call this manually - * @returns {promise} promise that is resolved when render completes? - * - */ - self.api.registerMethod( 'core', 'handleWindowResize', this.handleWindowResize ); - - - /** - * @ngdoc function - * @name addRowHeaderColumn - * @methodOf ui.grid.core.api:PublicApi - * @description adds a row header column to the grid - * @param {object} column def - * - */ - self.api.registerMethod( 'core', 'addRowHeaderColumn', this.addRowHeaderColumn ); - - /** - * @ngdoc function - * @name scrollToIfNecessary - * @methodOf ui.grid.core.api:PublicApi - * @description Scrolls the grid to make a certain row and column combo visible, - * in the case that it is not completely visible on the screen already. - * @param {GridRow} gridRow row to make visible - * @param {GridCol} gridCol column to make visible - * @returns {promise} a promise that is resolved when scrolling is complete - * - */ - self.api.registerMethod( 'core', 'scrollToIfNecessary', function(gridRow, gridCol) { return self.scrollToIfNecessary(gridRow, gridCol);} ); - - /** - * @ngdoc function - * @name scrollTo - * @methodOf ui.grid.core.api:PublicApi - * @description Scroll the grid such that the specified - * row and column is in view - * @param {object} rowEntity gridOptions.data[] array instance to make visible - * @param {object} colDef to make visible - * @returns {promise} a promise that is resolved after any scrolling is finished - */ - self.api.registerMethod( 'core', 'scrollTo', function (rowEntity, colDef) { return self.scrollTo(rowEntity, colDef);} ); - - /** - * @ngdoc function - * @name registerRowsProcessor - * @methodOf ui.grid.core.api:PublicApi - * @description - * Register a "rows processor" function. When the rows are updated, - * the grid calls each registered "rows processor", which has a chance - * to alter the set of rows (sorting, etc) as long as the count is not - * modified. - * - * @param {function(renderedRowsToProcess, columns )} processorFunction rows processor function, which - * is run in the context of the grid (i.e. this for the function will be the grid), and must - * return the updated rows list, which is passed to the next processor in the chain - * @param {number} priority the priority of this processor. In general we try to do them in 100s to leave room - * for other people to inject rows processors at intermediate priorities. Lower priority rowsProcessors run earlier. - * - * At present allRowsVisible is running at 50, sort manipulations running at 60-65, filter is running at 100, - * sort is at 200, grouping and treeview at 400-410, selectable rows at 500, pagination at 900 (pagination will generally want to be last) - */ - self.api.registerMethod( 'core', 'registerRowsProcessor', this.registerRowsProcessor ); - - /** - * @ngdoc function - * @name registerColumnsProcessor - * @methodOf ui.grid.core.api:PublicApi - * @description - * Register a "columns processor" function. When the columns are updated, - * the grid calls each registered "columns processor", which has a chance - * to alter the set of columns as long as the count is not - * modified. - * - * @param {function(renderedColumnsToProcess, rows )} processorFunction columns processor function, which - * is run in the context of the grid (i.e. this for the function will be the grid), and must - * return the updated columns list, which is passed to the next processor in the chain - * @param {number} priority the priority of this processor. In general we try to do them in 100s to leave room - * for other people to inject columns processors at intermediate priorities. Lower priority columnsProcessors run earlier. - * - * At present allRowsVisible is running at 50, filter is running at 100, sort is at 200, grouping at 400, selectable rows at 500, pagination at 900 (pagination will generally want to be last) - */ - self.api.registerMethod( 'core', 'registerColumnsProcessor', this.registerColumnsProcessor ); - - - - /** - * @ngdoc function - * @name sortHandleNulls - * @methodOf ui.grid.core.api:PublicApi - * @description A null handling method that can be used when building custom sort - * functions - * @example - *
        -     *   mySortFn = function(a, b) {
        -     *   var nulls = $scope.gridApi.core.sortHandleNulls(a, b);
        -     *   if ( nulls !== null ){
        -     *     return nulls;
        -     *   } else {
        -     *     // your code for sorting here
        -     *   };
        -     * 
        - * @param {object} a sort value a - * @param {object} b sort value b - * @returns {number} null if there were no nulls/undefineds, otherwise returns - * a sort value that should be passed back from the sort function - * - */ - self.api.registerMethod( 'core', 'sortHandleNulls', rowSorter.handleNulls ); - - - /** - * @ngdoc function - * @name sortChanged - * @methodOf ui.grid.core.api:PublicApi - * @description The sort criteria on one or more columns has - * changed. Provides as parameters the grid and the output of - * getColumnSorting, which is an array of gridColumns - * that have sorting on them, sorted in priority order. - * - * @param {$scope} scope The scope of the controller. This is used to deregister this event when the scope is destroyed. - * @param {Function} callBack Will be called when the event is emited. The function passes back an array of columns with - * sorts on them, in priority order. - * - * @example - *
        -     *      gridApi.core.on.sortChanged( $scope, function(sortColumns){
        -     *        // do something
        -     *      });
        -     * 
        - */ - self.api.registerEvent( 'core', 'sortChanged' ); - - /** - * @ngdoc function - * @name columnVisibilityChanged - * @methodOf ui.grid.core.api:PublicApi - * @description The visibility of a column has changed, - * the column itself is passed out as a parameter of the event. - * - * @param {$scope} scope The scope of the controller. This is used to deregister this event when the scope is destroyed. - * @param {Function} callBack Will be called when the event is emited. The function passes back the GridCol that has changed. - * - * @example - *
        -     *      gridApi.core.on.columnVisibilityChanged( $scope, function (column) {
        -     *        // do something
        -     *      } );
        -     * 
        - */ - self.api.registerEvent( 'core', 'columnVisibilityChanged' ); - - /** - * @ngdoc method - * @name notifyDataChange - * @methodOf ui.grid.core.api:PublicApi - * @description Notify the grid that a data or config change has occurred, - * where that change isn't something the grid was otherwise noticing. This - * might be particularly relevant where you've changed values within the data - * and you'd like cell classes to be re-evaluated, or changed config within - * the columnDef and you'd like headerCellClasses to be re-evaluated. - * @param {string} type one of the - * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN), which tells - * us which refreshes to fire. - * - */ - self.api.registerMethod( 'core', 'notifyDataChange', this.notifyDataChange ); - - /** - * @ngdoc method - * @name clearAllFilters - * @methodOf ui.grid.core.api:PublicApi - * @description Clears all filters and optionally refreshes the visible rows. - * @param {object} refreshRows Defaults to true. - * @param {object} clearConditions Defaults to false. - * @param {object} clearFlags Defaults to false. - * @returns {promise} If `refreshRows` is true, returns a promise of the rows refreshing. - */ - self.api.registerMethod('core', 'clearAllFilters', this.clearAllFilters); - - self.registerDataChangeCallback( self.columnRefreshCallback, [uiGridConstants.dataChange.COLUMN]); - self.registerDataChangeCallback( self.processRowsCallback, [uiGridConstants.dataChange.EDIT]); - self.registerDataChangeCallback( self.updateFooterHeightCallback, [uiGridConstants.dataChange.OPTIONS]); - - self.registerStyleComputation({ - priority: 10, - func: self.getFooterStyles - }); - }; - - Grid.prototype.calcFooterHeight = function () { - if (!this.hasFooter()) { - return 0; - } - - var height = 0; - if (this.options.showGridFooter) { - height += this.options.gridFooterHeight; - } - - height += this.calcColumnFooterHeight(); - - return height; - }; - - Grid.prototype.calcColumnFooterHeight = function () { - var height = 0; - - if (this.options.showColumnFooter) { - height += this.options.columnFooterHeight; - } - - return height; - }; - - Grid.prototype.getFooterStyles = function () { - var style = '.grid' + this.id + ' .ui-grid-footer-aggregates-row { height: ' + this.options.columnFooterHeight + 'px; }'; - style += ' .grid' + this.id + ' .ui-grid-footer-info { height: ' + this.options.gridFooterHeight + 'px; }'; - return style; - }; - - Grid.prototype.hasFooter = function () { - return this.options.showGridFooter || this.options.showColumnFooter; - }; - - /** - * @ngdoc function - * @name isRTL - * @methodOf ui.grid.class:Grid - * @description Returns true if grid is RightToLeft - */ - Grid.prototype.isRTL = function () { - return this.rtl; - }; - - - /** - * @ngdoc function - * @name registerColumnBuilder - * @methodOf ui.grid.class:Grid - * @description When the build creates columns from column definitions, the columnbuilders will be called to add - * additional properties to the column. - * @param {function(colDef, col, gridOptions)} columnBuilder function to be called - */ - Grid.prototype.registerColumnBuilder = function registerColumnBuilder(columnBuilder) { - this.columnBuilders.push(columnBuilder); - }; - - /** - * @ngdoc function - * @name buildColumnDefsFromData - * @methodOf ui.grid.class:Grid - * @description Populates columnDefs from the provided data - * @param {function(colDef, col, gridOptions)} rowBuilder function to be called - */ - Grid.prototype.buildColumnDefsFromData = function (dataRows){ - this.options.columnDefs = gridUtil.getColumnsFromData(dataRows, this.options.excludeProperties); - }; - - /** - * @ngdoc function - * @name registerRowBuilder - * @methodOf ui.grid.class:Grid - * @description When the build creates rows from gridOptions.data, the rowBuilders will be called to add - * additional properties to the row. - * @param {function(row, gridOptions)} rowBuilder function to be called - */ - Grid.prototype.registerRowBuilder = function registerRowBuilder(rowBuilder) { - this.rowBuilders.push(rowBuilder); - }; - - - /** - * @ngdoc function - * @name registerDataChangeCallback - * @methodOf ui.grid.class:Grid - * @description When a data change occurs, the data change callbacks of the specified type - * will be called. The rules are: - * - * - when the data watch fires, that is considered a ROW change (the data watch only notices - * added or removed rows) - * - when the api is called to inform us of a change, the declared type of that change is used - * - when a cell edit completes, the EDIT callbacks are triggered - * - when the columnDef watch fires, the COLUMN callbacks are triggered - * - when the options watch fires, the OPTIONS callbacks are triggered - * - * For a given event: - * - ALL calls ROW, EDIT, COLUMN, OPTIONS and ALL callbacks - * - ROW calls ROW and ALL callbacks - * - EDIT calls EDIT and ALL callbacks - * - COLUMN calls COLUMN and ALL callbacks - * - OPTIONS calls OPTIONS and ALL callbacks - * - * @param {function(grid)} callback function to be called - * @param {array} types the types of data change you want to be informed of. Values from - * the uiGridConstants.dataChange values ( ALL, EDIT, ROW, COLUMN, OPTIONS ). Optional and defaults to - * ALL - * @returns {function} deregister function - a function that can be called to deregister this callback - */ - Grid.prototype.registerDataChangeCallback = function registerDataChangeCallback(callback, types, _this) { - var uid = gridUtil.nextUid(); - if ( !types ){ - types = [uiGridConstants.dataChange.ALL]; - } - if ( !Array.isArray(types)){ - gridUtil.logError("Expected types to be an array or null in registerDataChangeCallback, value passed was: " + types ); - } - this.dataChangeCallbacks[uid] = { callback: callback, types: types, _this:_this }; - - var self = this; - var deregisterFunction = function() { - delete self.dataChangeCallbacks[uid]; - }; - return deregisterFunction; - }; - - /** - * @ngdoc function - * @name callDataChangeCallbacks - * @methodOf ui.grid.class:Grid - * @description Calls the callbacks based on the type of data change that - * has occurred. Always calls the ALL callbacks, calls the ROW, EDIT, COLUMN and OPTIONS callbacks if the - * event type is matching, or if the type is ALL. - * @param {number} type the type of event that occurred - one of the - * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN, OPTIONS) - */ - Grid.prototype.callDataChangeCallbacks = function callDataChangeCallbacks(type, options) { - angular.forEach( this.dataChangeCallbacks, function( callback, uid ){ - if ( callback.types.indexOf( uiGridConstants.dataChange.ALL ) !== -1 || - callback.types.indexOf( type ) !== -1 || - type === uiGridConstants.dataChange.ALL ) { - if (callback._this) { - callback.callback.apply(callback._this,this); - } - else { - callback.callback( this ); - } - } - }, this); - }; - - /** - * @ngdoc function - * @name notifyDataChange - * @methodOf ui.grid.class:Grid - * @description Notifies us that a data change has occurred, used in the public - * api for users to tell us when they've changed data or some other event that - * our watches cannot pick up - * @param {string} type the type of event that occurred - one of the - * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN) - */ - Grid.prototype.notifyDataChange = function notifyDataChange(type) { - var constants = uiGridConstants.dataChange; - if ( type === constants.ALL || - type === constants.COLUMN || - type === constants.EDIT || - type === constants.ROW || - type === constants.OPTIONS ){ - this.callDataChangeCallbacks( type ); - } else { - gridUtil.logError("Notified of a data change, but the type was not recognised, so no action taken, type was: " + type); - } - }; - - - /** - * @ngdoc function - * @name columnRefreshCallback - * @methodOf ui.grid.class:Grid - * @description refreshes the grid when a column refresh - * is notified, which triggers handling of the visible flag. - * This is called on uiGridConstants.dataChange.COLUMN, and is - * registered as a dataChangeCallback in grid.js - * @param {string} name column name - */ - Grid.prototype.columnRefreshCallback = function columnRefreshCallback( grid ){ - grid.buildColumns(); - grid.queueGridRefresh(); - }; - - - /** - * @ngdoc function - * @name processRowsCallback - * @methodOf ui.grid.class:Grid - * @description calls the row processors, specifically - * intended to reset the sorting when an edit is called, - * registered as a dataChangeCallback on uiGridConstants.dataChange.EDIT - * @param {string} name column name - */ - Grid.prototype.processRowsCallback = function processRowsCallback( grid ){ - grid.queueGridRefresh(); - }; - - - /** - * @ngdoc function - * @name updateFooterHeightCallback - * @methodOf ui.grid.class:Grid - * @description recalculates the footer height, - * registered as a dataChangeCallback on uiGridConstants.dataChange.OPTIONS - * @param {string} name column name - */ - Grid.prototype.updateFooterHeightCallback = function updateFooterHeightCallback( grid ){ - grid.footerHeight = grid.calcFooterHeight(); - grid.columnFooterHeight = grid.calcColumnFooterHeight(); - }; - - - /** - * @ngdoc function - * @name getColumn - * @methodOf ui.grid.class:Grid - * @description returns a grid column for the column name - * @param {string} name column name - */ - Grid.prototype.getColumn = function getColumn(name) { - var columns = this.columns.filter(function (column) { - return column.colDef.name === name; - }); - return columns.length > 0 ? columns[0] : null; - }; - - /** - * @ngdoc function - * @name getColDef - * @methodOf ui.grid.class:Grid - * @description returns a grid colDef for the column name - * @param {string} name column.field - */ - Grid.prototype.getColDef = function getColDef(name) { - var colDefs = this.options.columnDefs.filter(function (colDef) { - return colDef.name === name; - }); - return colDefs.length > 0 ? colDefs[0] : null; - }; - - /** - * @ngdoc function - * @name assignTypes - * @methodOf ui.grid.class:Grid - * @description uses the first row of data to assign colDef.type for any types not defined. - */ - /** - * @ngdoc property - * @name type - * @propertyOf ui.grid.class:GridOptions.columnDef - * @description the type of the column, used in sorting. If not provided then the - * grid will guess the type. Add this only if the grid guessing is not to your - * satisfaction. One of: - * - 'string' - * - 'boolean' - * - 'number' - * - 'date' - * - 'object' - * - 'numberStr' - * Note that if you choose date, your dates should be in a javascript date type - * - */ - Grid.prototype.assignTypes = function(){ - var self = this; - self.options.columnDefs.forEach(function (colDef, index) { - - //Assign colDef type if not specified - if (!colDef.type) { - var col = new GridColumn(colDef, index, self); - var firstRow = self.rows.length > 0 ? self.rows[0] : null; - if (firstRow) { - colDef.type = gridUtil.guessType(self.getCellValue(firstRow, col)); - } - else { - colDef.type = 'string'; - } - } - }); - }; - - - /** - * @ngdoc function - * @name isRowHeaderColumn - * @methodOf ui.grid.class:Grid - * @description returns true if the column is a row Header - * @param {object} column column - */ - Grid.prototype.isRowHeaderColumn = function isRowHeaderColumn(column) { - return this.rowHeaderColumns.indexOf(column) !== -1; - }; - - /** - * @ngdoc function - * @name addRowHeaderColumn - * @methodOf ui.grid.class:Grid - * @description adds a row header column to the grid - * @param {object} column def - */ - Grid.prototype.addRowHeaderColumn = function addRowHeaderColumn(colDef) { - var self = this; - var rowHeaderCol = new GridColumn(colDef, gridUtil.nextUid(), self); - rowHeaderCol.isRowHeader = true; - if (self.isRTL()) { - self.createRightContainer(); - rowHeaderCol.renderContainer = 'right'; - } - else { - self.createLeftContainer(); - rowHeaderCol.renderContainer = 'left'; - } - - // relies on the default column builder being first in array, as it is instantiated - // as part of grid creation - self.columnBuilders[0](colDef,rowHeaderCol,self.options) - .then(function(){ - rowHeaderCol.enableFiltering = false; - rowHeaderCol.enableSorting = false; - rowHeaderCol.enableHiding = false; - self.rowHeaderColumns.push(rowHeaderCol); - self.buildColumns() - .then( function() { - self.preCompileCellTemplates(); - self.queueGridRefresh(); - }); - }); - }; - - /** - * @ngdoc function - * @name getOnlyDataColumns - * @methodOf ui.grid.class:Grid - * @description returns all columns except for rowHeader columns - */ - Grid.prototype.getOnlyDataColumns = function getOnlyDataColumns() { - var self = this; - var cols = []; - self.columns.forEach(function (col) { - if (self.rowHeaderColumns.indexOf(col) === -1) { - cols.push(col); - } - }); - return cols; - }; - - /** - * @ngdoc function - * @name buildColumns - * @methodOf ui.grid.class:Grid - * @description creates GridColumn objects from the columnDefinition. Calls each registered - * columnBuilder to further process the column - * @param {object} options An object contains options to use when building columns - * - * * **orderByColumnDefs**: defaults to **false**. When true, `buildColumns` will reorder existing columns according to the order within the column definitions. - * - * @returns {Promise} a promise to load any needed column resources - */ - Grid.prototype.buildColumns = function buildColumns(opts) { - var options = { - orderByColumnDefs: false - }; - - angular.extend(options, opts); - - // gridUtil.logDebug('buildColumns'); - var self = this; - var builderPromises = []; - var headerOffset = self.rowHeaderColumns.length; - var i; - - // Remove any columns for which a columnDef cannot be found - // Deliberately don't use forEach, as it doesn't like splice being called in the middle - // Also don't cache columns.length, as it will change during this operation - for (i = 0; i < self.columns.length; i++){ - if (!self.getColDef(self.columns[i].name)) { - self.columns.splice(i, 1); - i--; - } - } - - //add row header columns to the grid columns array _after_ columns without columnDefs have been removed - self.rowHeaderColumns.forEach(function (rowHeaderColumn) { - self.columns.unshift(rowHeaderColumn); - }); - - - // look at each column def, and update column properties to match. If the column def - // doesn't have a column, then splice in a new gridCol - self.options.columnDefs.forEach(function (colDef, index) { - self.preprocessColDef(colDef); - var col = self.getColumn(colDef.name); - - if (!col) { - col = new GridColumn(colDef, gridUtil.nextUid(), self); - self.columns.splice(index + headerOffset, 0, col); - } - else { - // tell updateColumnDef that the column was pre-existing - col.updateColumnDef(colDef, false); - } - - self.columnBuilders.forEach(function (builder) { - builderPromises.push(builder.call(self, colDef, col, self.options)); - }); - }); - - /*** Reorder columns if necessary ***/ - if (!!options.orderByColumnDefs) { - // Create a shallow copy of the columns as a cache - var columnCache = self.columns.slice(0); - - // We need to allow for the "row headers" when mapping from the column defs array to the columns array - // If we have a row header in columns[0] and don't account for it we'll overwrite it with the column in columnDefs[0] - - // Go through all the column defs, use the shorter of columns length and colDefs.length because if a user has given two columns the same name then - // columns will be shorter than columnDefs. In this situation we'll avoid an error, but the user will still get an unexpected result - var len = Math.min(self.options.columnDefs.length, self.columns.length); - for (i = 0; i < len; i++) { - // If the column at this index has a different name than the column at the same index in the column defs... - if (self.columns[i + headerOffset].name !== self.options.columnDefs[i].name) { - // Replace the one in the cache with the appropriate column - columnCache[i + headerOffset] = self.getColumn(self.options.columnDefs[i].name); - } - else { - // Otherwise just copy over the one from the initial columns - columnCache[i + headerOffset] = self.columns[i + headerOffset]; - } - } - - // Empty out the columns array, non-destructively - self.columns.length = 0; - - // And splice in the updated, ordered columns from the cache - Array.prototype.splice.apply(self.columns, [0, 0].concat(columnCache)); - } - - return $q.all(builderPromises).then(function(){ - if (self.rows.length > 0){ - self.assignTypes(); - } - }); - }; - -/** - * @ngdoc function - * @name preCompileCellTemplates - * @methodOf ui.grid.class:Grid - * @description precompiles all cell templates - */ - Grid.prototype.preCompileCellTemplates = function() { - var self = this; - - var preCompileTemplate = function( col ) { - var html = col.cellTemplate.replace(uiGridConstants.MODEL_COL_FIELD, self.getQualifiedColField(col)); - html = html.replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)'); - - var compiledElementFn = $compile(html); - col.compiledElementFn = compiledElementFn; - - if (col.compiledElementFnDefer) { - col.compiledElementFnDefer.resolve(col.compiledElementFn); - } - }; - - this.columns.forEach(function (col) { - if ( col.cellTemplate ){ - preCompileTemplate( col ); - } else if ( col.cellTemplatePromise ){ - col.cellTemplatePromise.then( function() { - preCompileTemplate( col ); - }); - } - }); - }; - - /** - * @ngdoc function - * @name getGridQualifiedColField - * @methodOf ui.grid.class:Grid - * @description Returns the $parse-able accessor for a column within its $scope - * @param {GridColumn} col col object - */ - Grid.prototype.getQualifiedColField = function (col) { - return 'row.entity.' + gridUtil.preEval(col.field); - }; - - /** - * @ngdoc function - * @name createLeftContainer - * @methodOf ui.grid.class:Grid - * @description creates the left render container if it doesn't already exist - */ - Grid.prototype.createLeftContainer = function() { - if (!this.hasLeftContainer()) { - this.renderContainers.left = new GridRenderContainer('left', this, { disableColumnOffset: true }); - } - }; - - /** - * @ngdoc function - * @name createRightContainer - * @methodOf ui.grid.class:Grid - * @description creates the right render container if it doesn't already exist - */ - Grid.prototype.createRightContainer = function() { - if (!this.hasRightContainer()) { - this.renderContainers.right = new GridRenderContainer('right', this, { disableColumnOffset: true }); - } - }; - - /** - * @ngdoc function - * @name hasLeftContainer - * @methodOf ui.grid.class:Grid - * @description returns true if leftContainer exists - */ - Grid.prototype.hasLeftContainer = function() { - return this.renderContainers.left !== undefined; - }; - - /** - * @ngdoc function - * @name hasRightContainer - * @methodOf ui.grid.class:Grid - * @description returns true if rightContainer exists - */ - Grid.prototype.hasRightContainer = function() { - return this.renderContainers.right !== undefined; - }; - - - /** - * undocumented function - * @name preprocessColDef - * @methodOf ui.grid.class:Grid - * @description defaults the name property from field to maintain backwards compatibility with 2.x - * validates that name or field is present - */ - Grid.prototype.preprocessColDef = function preprocessColDef(colDef) { - var self = this; - - if (!colDef.field && !colDef.name) { - throw new Error('colDef.name or colDef.field property is required'); - } - - //maintain backwards compatibility with 2.x - //field was required in 2.x. now name is required - if (colDef.name === undefined && colDef.field !== undefined) { - // See if the column name already exists: - var newName = colDef.field, - counter = 2; - while (self.getColumn(newName)) { - newName = colDef.field + counter.toString(); - counter++; - } - colDef.name = newName; - } - }; - - // Return a list of items that exist in the `n` array but not the `o` array. Uses optional property accessors passed as third & fourth parameters - Grid.prototype.newInN = function newInN(o, n, oAccessor, nAccessor) { - var self = this; - - var t = []; - for (var i = 0; i < n.length; i++) { - var nV = nAccessor ? n[i][nAccessor] : n[i]; - - var found = false; - for (var j = 0; j < o.length; j++) { - var oV = oAccessor ? o[j][oAccessor] : o[j]; - if (self.options.rowEquality(nV, oV)) { - found = true; - break; - } - } - if (!found) { - t.push(nV); - } - } - - return t; - }; - - /** - * @ngdoc function - * @name getRow - * @methodOf ui.grid.class:Grid - * @description returns the GridRow that contains the rowEntity - * @param {object} rowEntity the gridOptions.data array element instance - * @param {array} rows [optional] the rows to look in - if not provided then - * looks in grid.rows - */ - Grid.prototype.getRow = function getRow(rowEntity, lookInRows) { - var self = this; - - lookInRows = typeof(lookInRows) === 'undefined' ? self.rows : lookInRows; - - var rows = lookInRows.filter(function (row) { - return self.options.rowEquality(row.entity, rowEntity); - }); - return rows.length > 0 ? rows[0] : null; - }; - - - /** - * @ngdoc function - * @name modifyRows - * @methodOf ui.grid.class:Grid - * @description creates or removes GridRow objects from the newRawData array. Calls each registered - * rowBuilder to further process the row - * @param {array} newRawData Modified set of data - * - * This method aims to achieve three things: - * 1. the resulting rows array is in the same order as the newRawData, we'll call - * rowsProcessors immediately after to sort the data anyway - * 2. if we have row hashing available, we try to use the rowHash to find the row - * 3. no memory leaks - rows that are no longer in newRawData need to be garbage collected - * - * The basic logic flow makes use of the newRawData, oldRows and oldHash, and creates - * the newRows and newHash - * - * ``` - * newRawData.forEach newEntity - * if (hashing enabled) - * check oldHash for newEntity - * else - * look for old row directly in oldRows - * if !oldRowFound // must be a new row - * create newRow - * append to the newRows and add to newHash - * run the processors - * ``` - * - * Rows are identified using the hashKey if configured. If not configured, then rows - * are identified using the gridOptions.rowEquality function - * - * This method is useful when trying to select rows immediately after loading data without - * using a $timeout/$interval, e.g.: - * - * $scope.gridOptions.data = someData; - * $scope.gridApi.grid.modifyRows($scope.gridOptions.data); - * $scope.gridApi.selection.selectRow($scope.gridOptions.data[0]); - * - * OR to persist row selection after data update (e.g. rows selected, new data loaded, want - * originally selected rows to be re-selected)) - */ - Grid.prototype.modifyRows = function modifyRows(newRawData) { - var self = this; - var oldRows = self.rows.slice(0); - var oldRowHash = self.rowHashMap || self.createRowHashMap(); - self.rowHashMap = self.createRowHashMap(); - self.rows.length = 0; - - newRawData.forEach( function( newEntity, i ) { - var newRow; - if ( self.options.enableRowHashing ){ - // if hashing is enabled, then this row will be in the hash if we already know about it - newRow = oldRowHash.get( newEntity ); - } else { - // otherwise, manually search the oldRows to see if we can find this row - newRow = self.getRow(newEntity, oldRows); - } - - // if we didn't find the row, it must be new, so create it - if ( !newRow ){ - newRow = self.processRowBuilders(new GridRow(newEntity, i, self)); - } - - self.rows.push( newRow ); - self.rowHashMap.put( newEntity, newRow ); - }); - - self.assignTypes(); - - var p1 = $q.when(self.processRowsProcessors(self.rows)) - .then(function (renderableRows) { - return self.setVisibleRows(renderableRows); - }); - - var p2 = $q.when(self.processColumnsProcessors(self.columns)) - .then(function (renderableColumns) { - return self.setVisibleColumns(renderableColumns); - }); - - return $q.all([p1, p2]); - }; - - - /** - * Private Undocumented Method - * @name addRows - * @methodOf ui.grid.class:Grid - * @description adds the newRawData array of rows to the grid and calls all registered - * rowBuilders. this keyword will reference the grid - */ - Grid.prototype.addRows = function addRows(newRawData) { - var self = this; - - var existingRowCount = self.rows.length; - for (var i = 0; i < newRawData.length; i++) { - var newRow = self.processRowBuilders(new GridRow(newRawData[i], i + existingRowCount, self)); - - if (self.options.enableRowHashing) { - var found = self.rowHashMap.get(newRow.entity); - if (found) { - found.row = newRow; - } - } - - self.rows.push(newRow); - } - }; - - /** - * @ngdoc function - * @name processRowBuilders - * @methodOf ui.grid.class:Grid - * @description processes all RowBuilders for the gridRow - * @param {GridRow} gridRow reference to gridRow - * @returns {GridRow} the gridRow with all additional behavior added - */ - Grid.prototype.processRowBuilders = function processRowBuilders(gridRow) { - var self = this; - - self.rowBuilders.forEach(function (builder) { - builder.call(self, gridRow, self.options); - }); - - return gridRow; - }; - - /** - * @ngdoc function - * @name registerStyleComputation - * @methodOf ui.grid.class:Grid - * @description registered a styleComputation function - * - * If the function returns a value it will be appended into the grid's `
        " - ); - - - $templateCache.put('ui-grid/uiGridCell', - "
        {{COL_FIELD CUSTOM_FILTERS}}
        " - ); - - - $templateCache.put('ui-grid/uiGridColumnMenu', - "
        " - ); - - - $templateCache.put('ui-grid/uiGridFooterCell', - "
        {{ col.getAggregationText() + ( col.getAggregationValue() CUSTOM_FILTERS ) }}
        " - ); - - - $templateCache.put('ui-grid/uiGridHeaderCell', - "
        {{ col.displayName CUSTOM_FILTERS }} {{col.sort.priority}}
         
        " - ); - - - $templateCache.put('ui-grid/uiGridMenu', - "
        " - ); - - - $templateCache.put('ui-grid/uiGridMenuItem', - "" - ); - - - $templateCache.put('ui-grid/uiGridRenderContainer', - "
        " - ); - - - $templateCache.put('ui-grid/uiGridViewport', - "
        " - ); - - - $templateCache.put('ui-grid/cellEditor', - "
        " - ); - - - $templateCache.put('ui-grid/dropdownEditor', - "
        " - ); - - - $templateCache.put('ui-grid/fileChooserEditor', - "
        " - ); - - - $templateCache.put('ui-grid/expandableRow', - "
        " - ); - - - $templateCache.put('ui-grid/expandableRowHeader', - "
        " - ); - - - $templateCache.put('ui-grid/expandableScrollFiller', - "
        " - ); - - - $templateCache.put('ui-grid/expandableTopRowHeader', - "
        " - ); - - - $templateCache.put('ui-grid/csvLink', - "LINK_LABEL" - ); - - - $templateCache.put('ui-grid/importerMenuItem', - "
      • " - ); - - - $templateCache.put('ui-grid/importerMenuItemContainer', - "
        " - ); - - - $templateCache.put('ui-grid/pagination', - "
        0\">/ {{ paginationApi.getTotalPages() }}
        1\"> {{sizesLabel}}
        {{grid.options.paginationPageSize}} {{sizesLabel}}
        0\">{{showingLow}} - {{showingHigh}} {{paginationOf}} {{grid.options.totalItems}} {{totalItemsLabel}}
        " - ); - - - $templateCache.put('ui-grid/columnResizer', - "
        " - ); - - - $templateCache.put('ui-grid/gridFooterSelectedItems', - "({{\"search.selectedItems\" | t}} {{grid.selection.selectedCount}})" - ); - - - $templateCache.put('ui-grid/selectionHeaderCell', - "
        " - ); - - - $templateCache.put('ui-grid/selectionRowHeader', - "
        " - ); - - - $templateCache.put('ui-grid/selectionRowHeaderButtons', - "
         
        " - ); - - - $templateCache.put('ui-grid/selectionSelectAllButtons', - "
        " - ); - - - $templateCache.put('ui-grid/treeBaseExpandAllButtons', - "
        0 && grid.treeBase.expandAll, 'ui-grid-icon-plus-squared': grid.treeBase.numberLevels > 0 && !grid.treeBase.expandAll}\" ng-click=\"headerButtonClick($event)\">
        " - ); - - - $templateCache.put('ui-grid/treeBaseHeaderCell', - "
        " - ); - - - $templateCache.put('ui-grid/treeBaseRowHeader', - "
        " - ); - - - $templateCache.put('ui-grid/treeBaseRowHeaderButtons', - "
        -1 }\" ng-click=\"treeButtonClick(row, $event)\"> -1 ) || ( row.treeNode.children && row.treeNode.children.length > 0 ) ) && row.treeNode.state === 'expanded', 'ui-grid-icon-plus-squared': ( ( grid.options.showTreeExpandNoChildren && row.treeLevel > -1 ) || ( row.treeNode.children && row.treeNode.children.length > 0 ) ) && row.treeNode.state === 'collapsed'}\" ng-style=\"{'padding-left': grid.options.treeIndent * row.treeLevel + 'px'}\">  
        " - ); - -}]); diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/sample/css/welcome.css b/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/sample/css/welcome.css deleted file mode 100644 index 559db709..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/fusion/sample/css/welcome.css +++ /dev/null @@ -1,169 +0,0 @@ -/* Area Chart */ - -#areaChart { - overflow: hidden;} - -#lineChart { - overflow: hidden; -} - -#areaChart svg { - height: 200px; - width: 380px; - min-width: 100px; - min-height: 100px; -} - -#lineChart svg { - height: 200px; - width: 380px; - min-width: 100px; - min-height: 100px; -} - -#areaChart tr.z-row-over>td.z-row-inner, tr.z-row-over>.z-cell { - background-color: rgb(255, 255, 255); -} - -#lineChart tr.z-row-over>td.z-row-inner, tr.z-row-over>.z-cell { - background-color: rgb(255, 255, 255); -} - -#areaChart .nodatadiv { - display: table-cell; - width: 700px; - height: 370px; - text-align: center; - vertical-align: middle; -} - -#lineChart .nodatadiv { - display: table-cell; - width: 700px; - height: 370px; - text-align: center; - vertical-align: middle; -} - -#areaChart .nodatainner { - padding: 10px; -} - -#lineChart .nodatainner { - padding: 10px; -} - -/* Area Chart END */ - -.button--small, [class*=bg-] .button--small { - font-size: 14px; - }; - -/* Gridster (EBIZ) */ - -.gridster-item-container .gridster-item-body{ -bottom:0px; -} -.gridster-item-container{ -min-height:50px; -} -.att-accordion { - border-width: 0px; -} - -/* End Gridster */ - -#myGallery { - width: 100%; - height: 400px; -} - -#myGallery img { - border: 2px solid #52697E; -} - -a.loading { - background: #fff url(../images/ajax_small.gif) no-repeat center; -} - -.center { - margin-left: auto; - margin-right: auto; -} - - -#selectedTrafficDay ul { - list-style: none; - padding: 0; - margin: 0; -} - -#selectedTrafficDay li { - float: left; - border: 1px solid #000; - border-bottom-width: 0; - margin: 3px 3px 3px 3px; - padding: 5px 5px 5px 5px; - background-color: #F2F2F2; - color: #696969; -} - -#SelectedTrafficeDayView { - padding: 0 1em; -} - -#selectedTrafficDay .active1 { - background-color: #FFF; - color: #000; -} - -#BusyHourTraffic ul { - list-style: none; - padding: 0; - margin: 0; -} - -#BusyHourTraffic li { - float: left; - border: 1px solid #000; - border-bottom-width: 0; - margin: 3px 3px 3px 3px; - padding: 5px 5px 5px 5px; - background-color: #F2F2F2; - color: #696969; -} - -#BusyHourTrafficView { - padding: 0 1em; -} - -#BusyHourTraffic .active2 { - background-color: #FFF; - color: #000; -} - -#slider { - width: 600px; - margin: 0 auto; - clear: left; -} - -@media only screen and (device-width: 768px) { - #slider { - width: 400px; - } -} - -#container { - -} - -#title { - float:left; - width:100%; - height:30px; - margin:; - color:#222222; - text-shadow: 1px 1px 2px #A0A0A0; -} - diff --git a/ecomp-sdk/sdk-app/src/main/webapp/static/js/search.js b/ecomp-sdk/sdk-app/src/main/webapp/static/js/search.js deleted file mode 100644 index 70cb166b..00000000 --- a/ecomp-sdk/sdk-app/src/main/webapp/static/js/search.js +++ /dev/null @@ -1,829 +0,0 @@ - - - - app.directive('afterRender', [ function() { - var def = { - restrict : 'A', - terminal : true, - transclude : false, - link : function(scope, element, attrs) { - if (attrs) { scope.$eval(attrs.afterRender) } - scope.$emit('onAfterRender') - } - }; - return def; - }]); - - app.directive("search", function() { - return { - // replace custom element with html5 markup - template: '
        ' - //+ '' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + ' ' - + '
        ' - + '
        ' - + ' ' - + ' ' - + ' ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' , - replace: true, - // restrict usage to element only since we use attributes for APIs - restrict: 'EA', - require: 'ngModel', - // new isolate scope - scope: { - mSearch : '=ngModel' - ,updateparent: '&' - ,jsonForOption : '=' - ,jsonForOperator : '=' - ,searchId : '=' - }, - link: function(scope, iElement, iAttrs){ - scope.optionsSizeArray = []; - scope.sId = ''; - //scope.options = JSON.parse(JSON.stringify(iAttrs.jsonForOption)); - //scope.operators = JSON.parse(iAttrs.operators); - - scope.$watch("jsonForOption", function(newval, oldval) { - scope.options = JSON.parse(JSON.stringify(oldval)); - console.log('1'); - scope.evalRepeatIndex(scope.options.length); - console.log('2'); - - }); - - scope.evalRepeatIndex = function(size){ - for(index = 0; index < size; index++) { - scope.optionsSizeArray.push(index); - } - }; - - scope.$watch("jsonForOperator", function(newval, oldval) { - scope.operators = JSON.parse(JSON.stringify(oldval)); - - }); - - if(getParameterByName("search")!=null && getParameterByName("search")!=''){ - if((getParameterByName("location")!=null && getParameterByName("location")!='')){ - scope.searchValue[0]=JSON.parse(JSON.stringify(getParameterByName("location"))); - scope.valueOptions[0]={index:0,value:'Location Name',title:"Location Name",alias:'Location Name'}; - scope.compareOptions[0]={index:1,value:'Contains',title:"Contains",alias:'Contains'}; - }else if((getParameterByName("userLastName")!=null && getParameterByName("userLastName")!='')){ - scope.searchValue[0]=JSON.parse(JSON.stringify(getParameterByName("userLastName"))); - scope.valueOptions[0]= {index: 0, value: 'Last Name', title: 'Last Name', alias:'Last Name'}; - scope.compareOptions[0]={index:1,value:'Contains',title:"Contains",alias:'Contains'}; - } - } - scope.$watch("searchId", function(newval, oldval) { - scope.sId = oldval; - scope.hideDiv(); - }); - - scope.showHide = function(div){ - if(div != 0){ - $("#s1").css('display', 'none'); - } - return true; - }; - - - scope.hideDiv = function(){ - console.log('3'); - console.log(scope.optionsSizeArray); - - - for (i = 1; i < scope.optionsSizeArray.length; i++) { - var element = "#"+scope.sId+i; - $(element).css('display', 'none'); - } - - console.log('4'); - - }; - - - $(function() { - scope.hideDiv(); - }); - - }, - - controller: function ($scope) { - - $scope.addSearch = function(searchId, index, optionsLength){ - console.log('5'); - - for(var i = 0; i<=optionsLength.length ;i++){ - var element = "#"+searchId+i; - if($(element).css('display') == 'none'){ - $(element).css('display', 'inline'); - break; - } - }; - console.log('6'); - - }; - - $scope.remove = function(searchId, index){ - var remove = "#"+searchId+index; - if(index!=0) - $(remove).css("display", "none"); - var v ={ - index: 0, - value: '', - title: 'Select', - alias:'' - }; - $scope.valueOptions[index]=v; - $scope.compareOptions[index]=v; - $scope.searchValue[index]=""; - }; - - $scope.search = function() { - var data = { - valueOptions : $scope.valueOptions, - compareOptions : $scope.compareOptions, - searchValue : $scope.searchValue - }; - }; - - var data = { - valueOptions : $scope.valueOptions, - compareOptions : $scope.compareOptions, - searchValue : $scope.searchValue - }; - - $scope.mSearch = data; - $scope.valueOptions=[]; - $scope.compareOptions=[]; - $scope.searchValue=[]; - } - } - - }); - - app.directive('phoneNumberMask', [function(){ - return { - restrict: 'A', - require: '?ngModel', - scope: { - ngModel : '=' - }, - link: function(scope, el, attrs){ - scope.$watch(attrs.phoneNumberMask, function(newValue, oldValue) { - - if(scope.ngModel) - scope.ngModel= scope.ngModel.replace(/(\+1)?(\d{3})(\d{3})(\d{4})/, '$2.$3.$4'); - $(el).mask("999.999.9999"); - }); - scope.$watch("ngModel", function() { - var current = $(el).val(); - if(scope.ngModel && /^(\+1)?\d{3,}$/.test(scope.ngModel)) - scope.ngModel= scope.ngModel.replace(/(\+1)?(\d{3})(\d{3})(\d{4})/, '$2.$3.$4'); - - }); - }, - }; - }]); - - app.directive('allowOnlyNumber', [function(){ - return { - require: 'ngModel', - link: function(scope, element, attrs, modelCtrl) { - modelCtrl.$parsers.push(function (inputValue) { - if (inputValue == undefined) return ''; - var transformedInput = inputValue.replace(/[^0-9]/g, ''); - if (transformedInput!=inputValue) { - modelCtrl.$setViewValue(transformedInput); - modelCtrl.$render(); - } - - return transformedInput; - }); - } - }; - }]); - - app.directive('showProcessing', function(){ - return { - restrict: 'A', - link: function(scope, elem, attrs) { - elem.bind('click', function() { - $(".overlayed").css("display","inline"); - $(".loadingId").css("display","inline"); - }); - } - } - }); - -app.directive("searchCriteria", function() { - return { - // replace custom element with html5 markup - template: '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + '
        ' - + ' ' - + '
        ' - + '
        ' - + '
        ' - + ' ' - + ' ' - + ' ' - + '
        ' - + '
        ' - + '
        ' , - replace: true, - // restrict usage to element only since we use attributes for APIs - restrict: 'EA', - require: 'ngModel', - // new isolate scope - scope: { - mSearch : '=ngModel', - updateparent: '&' - ,options : '=jsonForOption' - ,operators : '=jsonForOperator' - }, - - controller: function ($scope) { - $scope.isShown = [true]; - $scope.searchCriterion = []; - $scope.valueOptions=[]; - $scope.compareOptions=[]; - $scope.searchValue=[]; - $scope.availableOperators=[]; - $scope.availableValues=[]; - $scope.availableOptions = []; - //init - $scope.insertEmptyOption = function(arr){ - var hasEmpty = false; - $.each(arr, function(i, a){ - if(a.value ===''){ - hasEmpty = true; - } - }); - if(!hasEmpty){ - $.each(arr, function(i, a){ - a.index +=1; - }); - arr.unshift({index: 0, value: '', title: 'Select', alias:'Select'}); - } - }; - $scope.findFirstOption = function(arr){ - - }; - $scope.insertEmptyOption($scope.options); - $scope.insertEmptyOption($scope.operators); - - for(var i = 0, l= $scope.options.length; i 0){ - $.each($scope.valueOptions, function(i, a){ - if(a){ - var v = a.value; - if(v){ - var s= $.grep(selectedOptions, function(e){ return e.value === v }); - - if(s.length ===1){ - s[0].occurs += 1; - }else{ - selectedOptions.push({value: v, occurs:1}); - } - } - var o= $.grep($scope.options, function(e){ return e.value === v }); - if(o.length ===1){ - if("operators" in o[0]){ - $scope.availableOperators[i]=o[0].operators; - $scope.insertEmptyOption($scope.availableOperators[i]); - }else{ - $scope.availableOperators[i]=$scope.operators; - } - if("values" in o[0]){ - $scope.availableValues[i]=o[0].values; - }else{ - $scope.availableValues[i]=[]; - } - } - } - }); - for(var j = 0 , l = $scope.availableOptions.length; j 0 && s[0].occurs >= maxOccurs && ($scope.valueOptions[j] && $scope.valueOptions[j].value !== s[0].value)){// reach limit - }else{ - newOptions.push({index: aoi, value: a.value, title: a.title, alias:a.alias}); - aoi += 1; - } - }); - $scope.availableOptions[j] = newOptions; - if(isFirst){ - if($scope.availableValues[j].length>0) - $scope.searchValue[j]= $scope.availableValues[j][0]; - else - $scope.searchValue[j]=""; - - $scope.compareOptions[j]= $scope.availableOperators[j][0]; - } - }; - - } - if(typeof index !== 'undefined' && !isFirst){ - if($scope.availableValues[index].length>0) - $scope.searchValue[index]= $scope.availableValues[index][0]; - else - $scope.searchValue[index]=""; - } - }; - - $scope.updateAvailableOptions(undefined, true); - $.each($scope.availableOptions, function(j, a){ - $scope.valueOptions[j]= a[0]; - }); - $scope.addSearchCriteria = function(index){ - for(var i = 0 , l =$scope.isShown.length; i ' - + '' - + '' - + ' ' - + ' ' - + ' ' - + ' ' - + '' - + '' - + '' - + '' - + ' ' - + '' - + ' ' - + ' ' - + '' - + '
        {{availableTitle}}{{userTitle}}
        ' - + '
        ' - + ' ' - + '
        ' - + '
        ' - + ' ' - + ' ' - + '

        ' - + ' ' - + '

        ' - + ' ' - + '

        ' - + ' ' - + '
        ' - + '
        ' - + ' ' - + '
        ' - + '
        ' - + '', - replace: true, - // restrict usage to element only since we use attributes for APIs - restrict: 'EA', - // new isolate scope - scope: { - chosenIds : '=assignedUsers' - ,availableUsers : '=' - ,userTitle : '=' - ,availableTitle : '=' - ,oneMax : '=?' - }, - link: function(scope, iElement, attrs){ - - scope.$watch("userTitle", function(newval, oldval) { - scope.userTitle = newval; - }); - scope.$watch("availableTitle", function(newval, oldval) { - scope.availableTitle = newval; - }); - - scope.$watch("availableUsers", function(newval, oldval) { - scope.availableUsers = newval; - scope.canditateIds= scope.getArrayRemoved(scope.availableUsers, scope.chosenIds); - }); - - }, - - controller: function ($scope) { - $scope.getArrayRemoved = function(from, removed){ - var retArray = (from)? from:[]; - if(retArray && retArray.length >0 && removed){ - for(var i = 0, l = removed.length; i= 0; i--){ - if(!$scope.chosenIds) - $scope.chosenIds=[]; - $scope.chosenIds.push(dataFromTableData[i]); - $scope.canditateIds.splice(i,1); - - } - var dataFromChoosonTable = $scope.chosenIds; - for (var i = dataFromChoosonTable.length - 1; i >= 0; i--){ - if(dataFromChoosonTable[i].available){ - $scope.chosenIds[i].available=false; - } - } - }; - - $scope.removeAll = function() { - var dataFromTableData = $scope.chosenIds; - for (var i = dataFromTableData.length - 1; i >= 0; i--){ - $scope.canditateIds.push(dataFromTableData[i]); - $scope.chosenIds.splice(i,1); - - } - var dataFromChoosonTable = $scope.canditateIds; - for (var i = dataFromChoosonTable.length - 1; i >= 0; i--){ - if(dataFromChoosonTable[i].available){ - $scope.canditateIds[i].available=false; - } - } - }; - - $scope.chooseSelected = function() { - - var dataFromTableData = $scope.canditateIds; - - for (var i = dataFromTableData.length - 1; i >= 0; i--){ - - if(dataFromTableData[i].available){ - if(!$scope.chosenIds) - $scope.chosenIds=[]; - $scope.chosenIds.push(dataFromTableData[i]); - $scope.canditateIds.splice(i,1); - - } - } - var dataFromChoosonTable = $scope.chosenIds; - for (var i = dataFromChoosonTable.length - 1; i >= 0; i--){ - if(dataFromChoosonTable[i].available){ - $scope.chosenIds[i].available=false; - } - } - }; - $scope.removeSelected = function() { - - var dataFromTableData = $scope.chosenIds; - - for (var i = dataFromTableData.length - 1; i >= 0; i--){ - if(dataFromTableData[i].available){ - $scope.canditateIds.push(dataFromTableData[i]); - $scope.chosenIds.splice(i,1); - - } - } ; - var dataFromChoosonTable = $scope.canditateIds; - for (var i = dataFromChoosonTable.length - 1; i >= 0; i--){ - if(dataFromChoosonTable[i].available){ - $scope.canditateIds[i].available=false; - } - } - }; - $scope.checkCanditate = function(index) { - if($scope.oneMax){ - for (var i = $scope.canditateIds.length - 1; i >= 0; i--){ - if(i != index) - $scope.canditateIds[i].available=false; - } - } - }; - - - } - } - }); - app.directive("selectString", function() { - return { - // replace custom element with html5 markup - template: '
        ' - + '' - + '' - + ' ' - + ' ' - + ' ' - + ' ' - + '' - + '' - + '' - + '' - + ' ' - + '' - + ' ' - + ' ' - + '' - + '
        {{availableTitle}}{{assignedTitle}}
        ' - + '
        ' - + ' ' - + '
        ' - + '
        ' - + ' ' - + '

        ' - + ' ' - + '

        ' - + ' ' - + '

        ' - + ' ' - + '
        ' - + '
        ' - + ' ' - + '
        ' - + '
        ' - + '
        ', - replace: true, - // restrict usage to element only since we use attributes for APIs - restrict: 'EA', - // new isolate scope - scope: { - chosenIds : '=assignedOptions' - ,availableOptions : '=' - ,availableTitle : '@' - ,assignedTitle : '@' - }, - link: function(scope, iElement, attrs){ - scope.$watch("availableOptions", function(newval, oldval) { - scope.availableOptions = newval; - scope.canditateIds= scope.getArrayRemoved(scope.availableOptions, scope.chosenIds); - }); - - }, - - controller: function ($scope) { - $scope.getArrayRemoved = function(from, removed){ - var retArray = (from)? from:[]; - if(retArray && retArray.length >0 && removed){ - for(var i = 0, l = removed.length; i= 0; i--){ - if(!$scope.chosenIds) - $scope.chosenIds=[]; - $scope.chosenIds.push(dataFromTableData[i]); - $scope.canditateIds.splice(i,1); - - } - }; - - $scope.removeAll = function() { - var dataFromTableData = $scope.chosenIds; - for (var i = dataFromTableData.length - 1; i >= 0; i--){ - $scope.canditateIds.push(dataFromTableData[i]); - $scope.chosenIds.splice(i,1); - - } - }; - - $scope.chooseSelected = function() { - - var dataFromTableData = $scope.canditateIds; - - for (var i = dataFromTableData.length - 1; i >= 0; i--){ - - if(dataFromTableData[i].available){ - if(!$scope.chosenIds) - $scope.chosenIds=[]; - $scope.chosenIds.push(dataFromTableData[i]); - $scope.canditateIds.splice(i,1); - - } - } - }; - $scope.removeSelected = function() { - - var dataFromTableData = $scope.chosenIds; - - for (var i = dataFromTableData.length - 1; i >= 0; i--){ - if(dataFromTableData[i].available){ - $scope.canditateIds.push(dataFromTableData[i]); - $scope.chosenIds.splice(i,1); - - } - } ; - }; - - } - } - }); - function getParameterByName(name) { - name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); - var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), - results = regex.exec(location.search); - return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); - }; - - app.directive("time", function() { - return { - // replace custom element with html5 markup - template: '
        ' - + ' ' - + '
        ' - + '
        ', - replace: true, - // restrict usage to element only since we use attributes for APIs - restrict: 'EA', - // new isolate scope - scope: { - value : '=' - ,validTime : '=?' - }, - link: function(scope, iElement, attrs){ - }, - - controller: function ($scope) { - $scope.timeStr=''; - $scope.ampm=null; - var am ={index: 0, value: 'AM', title: 'AM', alias:'Name2'}; - var pm = {index: 1, value: 'PM', title: 'PM', alias:'Name'}; - $scope.ampmOptions=[ - am, - pm, - ] - $scope.parseTimeStr= function(str){ - if(str){ - try{ - var date; - if(/^(\d*):(\d*)$/.test(str)){ - var hh = Number(str.match(/^(\d+)/)[1]); - var mm = Number(str.match(/:(\d+)/)[1]); - date = new Date(1970, 0, 1, hh, mm, 0); - }else{ - date = new Date(str); - } - var hours = date.getHours(); - var minutes = date.getMinutes(); - var ampm = hours >= 12 ?pm : am; - hours = hours % 12; - hours = hours ? hours : 12; // the hour '0' should be '12' - minutes = minutes < 10 ? '0'+minutes : minutes; - hours = hours < 10 ? '0'+hours : hours; - var strTime = hours + ':' + minutes ; - - - $scope.timeStr =strTime; - $scope.ampm = ampm; - if (typeof $scope.validTime != 'undefined'){ - $scope.validTime=true; - } - }catch(err){ - if (typeof $scope.validTime != 'undefined'){ - $scope.validTime=false; - } - } - }else{ - $scope.timeStr = "12:00"; - $scope.ampm =am; - } - }; - $scope.parseTimeStr($scope.value); - $scope.parseValue = function(){ - try{ - var date; - var hh = Number($scope.timeStr.match(/^(\d+)/)[1]); - var mm = Number($scope.timeStr.match(/:(\d+)/)[1]); - - if(hh<=12 && hh>0 && mm>=0 && mm<=59){ - - if($scope.ampm.value=='PM'&& hh<12) hh = hh+12; - if($scope.ampm.value=='AM'&& hh==12) hh = hh-12; - mm = mm < 10 ? '0'+mm : mm; - hh = hh < 10 ? '0'+hh : hh; - $scope.value= hh+":"+mm; - if (typeof $scope.validTime != 'undefined'){ - $scope.validTime=true; - } - }else{ - if (typeof $scope.validTime != 'undefined'){ - $scope.validTime=false; - } - } - - }catch(err){ - if (typeof $scope.validTime != 'undefined'){ - $scope.validTime=false; - } - } - }; - } - } - }); \ No newline at end of file diff --git a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/SanityTest.java b/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/SanityTest.java deleted file mode 100644 index d455b843..00000000 --- a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/SanityTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.openecomp.portalapp; - -import org.junit.Assert; -import org.junit.Test; -import org.openecomp.portalsdk.core.MockApplicationContextTestSuite; -import org.springframework.test.web.servlet.ResultActions; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - -public class SanityTest extends MockApplicationContextTestSuite { - - @Test - public void testGetAvailableRoles() throws Exception { - - ResultActions ra =getMockMvc().perform(MockMvcRequestBuilders.get("/api/roles")); - //Assert.assertEquals(UrlAccessRestrictedException.class,ra.andReturn().getResolvedException().getClass()); - Assert.assertEquals("application/json",ra.andReturn().getResponse().getContentType()); - } - - -} diff --git a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/controller/CollaborationControllerTest.java b/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/controller/CollaborationControllerTest.java deleted file mode 100644 index 099cf518..00000000 --- a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/controller/CollaborationControllerTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.openecomp.portalapp.controller; - -import org.junit.Assert; -import org.junit.Test; -import org.openecomp.portalsdk.core.MockApplicationContextTestSuite; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.test.web.servlet.ResultActions; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - -public class CollaborationControllerTest extends MockApplicationContextTestSuite{ - - @Test - public void testGetAvailableRoles() throws Exception { - MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/collaborate_list"); - User user = new User(); - user.setId(1l); - user.setOrgUserId("abc"); - requestBuilder.sessionAttr(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME), user); - - ResultActions ra =getMockMvc().perform(requestBuilder); - Assert.assertEquals(2,ra.andReturn().getModelAndView().getModelMap().size()); - } - - -} diff --git a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/controller/NetMapTest.java b/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/controller/NetMapTest.java deleted file mode 100644 index 4622f66e..00000000 --- a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/controller/NetMapTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.openecomp.portalapp.controller; - -import org.junit.Assert; -import org.junit.Test; -import org.openecomp.portalsdk.core.MockApplicationContextTestSuite; -import org.springframework.test.web.servlet.ResultActions; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - -public class NetMapTest extends MockApplicationContextTestSuite { - - @Test - public void testGetNetMap() throws Exception { - ResultActions ra =getMockMvc().perform(MockMvcRequestBuilders.get("/net_map")); - //Assert.assertEquals(UrlAccessRestrictedException.class,ra.andReturn().getResolvedException().getClass()); - Assert.assertEquals("net_map_int",ra.andReturn().getModelAndView().getModel().get("frame_int")); - } - - -} diff --git a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/service/ProfileServiceTest.java b/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/service/ProfileServiceTest.java deleted file mode 100644 index f7f30fe5..00000000 --- a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalapp/service/ProfileServiceTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.openecomp.portalapp.service; - -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.openecomp.portalsdk.core.MockApplicationContextTestSuite; -import org.openecomp.portalsdk.core.domain.Profile; -import org.openecomp.portalsdk.core.domain.User; -import org.openecomp.portalsdk.core.service.ProfileService; -import org.openecomp.portalsdk.core.service.UserProfileService; -import org.springframework.beans.factory.annotation.Autowired; - - -public class ProfileServiceTest extends MockApplicationContextTestSuite { - - @Autowired - ProfileService service; - - @Autowired - UserProfileService userProfileService; - - @Test - public void testFindAll() { - - List profiles = service.findAll(); - Assert.assertTrue(profiles.size() > 0); - } - - @Test - public void testFindAllActive() { - - List users = userProfileService.findAllActive(); - List activeUsers = userProfileService.findAllActive(); - Assert.assertTrue(users.size() - activeUsers.size() >= 0); - } -} diff --git a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalsdk/core/MockApplicationContextTestSuite.java b/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalsdk/core/MockApplicationContextTestSuite.java deleted file mode 100644 index 1bafe203..00000000 --- a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalsdk/core/MockApplicationContextTestSuite.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.openecomp.portalsdk.core; - -import java.io.IOException; - -import org.junit.Before; -import org.junit.runner.RunWith; -import org.openecomp.portalsdk.core.conf.AppConfig; -import org.openecomp.portalsdk.core.objectcache.AbstractCacheManager; -import org.openecomp.portalsdk.core.util.CacheManager; -import org.openecomp.portalsdk.core.util.SystemProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.AnnotationConfigWebContextLoader; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; - -/** - * - * - * - * In order to write a unit test, - * 1. inherit this class - See SanityTest.java - * 2. place the "war" folder on your test class's classpath - * 3. run the test with the following VM argument; This is important because when starting the application from Container, the System Properties file (SystemProperties.java) can have the direct path - * but, when running from the Mock Junit container, the path should be prefixed with "classpath" to enable the mock container to search for the file in the classpath - * -Dcontainer.classpath="classpath:" - * - */ - -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -@ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, classes = {MockAppConfig.class}) -@ActiveProfiles(value="test") -public class MockApplicationContextTestSuite { - - @Autowired - public WebApplicationContext wac; - - private MockMvc mockMvc; - - @Before - public void setup() { - if(mockMvc == null) { - this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); - - } - } - - public Object getBean(String name) { - return this.wac.getBean(name); - } - - - public MockMvc getMockMvc() { - return mockMvc; - } - - public void setMockMvc(MockMvc mockMvc) { - this.mockMvc = mockMvc; - } - - public WebApplicationContext getWebApplicationContext() { - return wac; - } - - - - -} - - - @Configuration - @ComponentScan(basePackages = "org.openecomp", - excludeFilters = { - - } - ) - @Profile("test") - class MockAppConfig extends AppConfig { - - @Bean - public SystemProperties systemProperties(){ - return new MockSystemProperties(); - } - - @Bean - public AbstractCacheManager cacheManager() { - return new CacheManager() { - - public void configure() throws IOException { - - } - }; - } - - protected String[] tileDefinitions() { - return new String[] {"classpath:/WEB-INF/fusion/defs/definitions.xml", "classpath:/WEB-INF/defs/definitions.xml"}; - } - - @Override - public void addInterceptors(InterceptorRegistry registry) { - //registry.addInterceptor(new SessionTimeoutInterceptor()).excludePathPatterns(getExcludeUrlPathsForSessionTimeout()); - //registry.addInterceptor(resourceInterceptor()); - } - - public static class MockSystemProperties extends SystemProperties { - - public MockSystemProperties() { - } - - } - - } - - - - diff --git a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleServiceTest.java b/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleServiceTest.java deleted file mode 100644 index 584bad78..00000000 --- a/ecomp-sdk/sdk-app/src/test/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleServiceTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.openecomp.portalsdk.workflow.services; - -import java.util.Calendar; - -import org.junit.Assert; -import org.junit.Test; -import org.openecomp.portalsdk.core.MockApplicationContextTestSuite; -import org.openecomp.portalsdk.workflow.domain.WorkflowSchedule; -import org.springframework.beans.factory.annotation.Autowired; - -public class WorkflowScheduleServiceTest extends MockApplicationContextTestSuite { - - @Autowired - WorkflowScheduleService service; -// @Autowired -// SchedulerFactoryBean schedulerBean; - - @Test - public void testFire() { - - // List wfs = service.findAll(); - - final WorkflowSchedule ws = new WorkflowSchedule(); - ws.setId(999L); - ws.setWorkflowKey("test"); - ws.setCronDetails("0 38 13 3 5 ? 2016"); - final Calendar instance = Calendar.getInstance(); - instance.add(Calendar.YEAR, 3); - ws.setEndDateTime(instance.getTime()); - - ws.setStartDateTime(Calendar.getInstance().getTime()); - try{ - service.saveWorkflowSchedule(ws); - Assert.assertTrue(true); - } catch(Exception e) { - Assert.fail(e.getMessage()); - } - - } - -} diff --git a/ecomp-sdk/sdk-workflow/.gitignore b/ecomp-sdk/sdk-workflow/.gitignore deleted file mode 100644 index b83d2226..00000000 --- a/ecomp-sdk/sdk-workflow/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/ecomp-sdk/sdk-workflow/README.md b/ecomp-sdk/sdk-workflow/README.md deleted file mode 100644 index d144d21c..00000000 --- a/ecomp-sdk/sdk-workflow/README.md +++ /dev/null @@ -1,7 +0,0 @@ -ECOMP Portal SDK Workflow -========================= - -This is the Maven project for the ECOMP Portal SDK Workflow, -which is distributed as ecompSDK-workflow-nnn.jar. This library -requires Hibernate and Spring, and provides features including -schedulers, workflows and R Cloud integration. diff --git a/ecomp-sdk/sdk-workflow/pom.xml b/ecomp-sdk/sdk-workflow/pom.xml deleted file mode 100644 index 79f3067a..00000000 --- a/ecomp-sdk/sdk-workflow/pom.xml +++ /dev/null @@ -1,111 +0,0 @@ - - 4.0.0 - - - org.openecomp.ecompsdkos - ecompSDK-project - 1.1.0-SNAPSHOT - - - ecompSDK-workflow - Ecomp Portal SDK Workflow - Provides workflow features for SDK applications - jar - - - - - - - org.openecomp.ecompsdkos - ecompSDK-core - ${project.version} - - - - com.fasterxml.jackson.core - jackson-annotations - 2.6.3 - - - com.fasterxml.jackson.core - jackson-core - 2.6.3 - - - com.fasterxml.jackson.core - jackson-databind - 2.6.3 - - - javax.servlet - javax.servlet-api - 3.1.0 - - - org.hibernate - hibernate-core - ${hibernate.version} - - - org.hibernate - hibernate-validator - 5.1.3.Final - - - org.json - json - 20160212 - - - org.quartz-scheduler - quartz - 2.2.1 - - - - c3p0 - c3p0 - - - - - - org.slf4j - jcl-over-slf4j - 1.7.12 - - - org.springframework - spring-context-support - ${springframework.version} - - - org.springframework - spring-core - ${springframework.version} - - - commons-logging - commons-logging - - - - - org.springframework - spring-tx - ${springframework.version} - - - org.springframework - spring-web - ${springframework.version} - - - org.springframework - spring-webmvc - ${springframework.version} - - - - diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookController.java b/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookController.java deleted file mode 100644 index 037e80d5..00000000 --- a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookController.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.rnotebookintegration.controller; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.controller.CollaborateListController; -import org.openecomp.portalsdk.core.controller.RestrictedBaseController; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.UserProfileService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -@Controller -@RequestMapping("/") -public class NotebookController extends RestrictedBaseController{ - @Autowired - UserProfileService service; - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CollaborateListController.class); - - @RequestMapping(value = {"/notebook" }, method = RequestMethod.GET) - public ModelAndView noteBook(HttpServletRequest request) { - - try { - - } catch (Exception e) { - - - } - return new ModelAndView(getViewName()); - } - - -} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookTestController.java b/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookTestController.java deleted file mode 100644 index 74d1ae51..00000000 --- a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/NotebookTestController.java +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.rnotebookintegration.controller; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.controller.CollaborateListController; -import org.openecomp.portalsdk.core.controller.RestrictedBaseController; -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.service.UserProfileService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -@Controller -@RequestMapping("/") -public class NotebookTestController extends RestrictedBaseController{ - @Autowired - UserProfileService service; - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CollaborateListController.class); - - @RequestMapping(value = {"/nbooktest" }, method = RequestMethod.GET) - public ModelAndView noteBook(HttpServletRequest request) { - - try { - - } catch (Exception e) { - - - } - return new ModelAndView(getViewName()); - } - - -} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookController.java b/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookController.java deleted file mode 100644 index a53b0573..00000000 --- a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/controller/RNoteBookController.java +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.rnotebookintegration.controller; - -import org.openecomp.portalsdk.core.controller.RestrictedRESTfulBaseController; -import org.openecomp.portalsdk.core.web.support.JsonMessage; -import org.openecomp.portalsdk.rnotebookintegration.exception.RNotebookIntegrationException; -import org.openecomp.portalsdk.rnotebookintegration.service.RNoteBookIntegrationService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; - -@Controller -@RequestMapping("/rNotebook/") - -public class RNoteBookController extends RestrictedRESTfulBaseController { - - @Autowired - private RNoteBookIntegrationService rNoteBookIntegrationService; - - - - public RNoteBookIntegrationService getrNoteBookIntegrationService() { - return rNoteBookIntegrationService; - } - - - - public void setrNoteBookIntegrationService( - RNoteBookIntegrationService rNoteBookIntegrationService) { - this.rNoteBookIntegrationService = rNoteBookIntegrationService; - } - - - - @RequestMapping(value = { "authCr" }, method = RequestMethod.GET, produces = "application/json") - public @ResponseBody ResponseEntity getRNotebookCredentials (String token) throws Exception { - //ObjectMapper mapper = new ObjectMapper(); - //mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - //JsonNode root = mapper.readTree(request.getReader()); - //String token = root.get("authenticationToken").textValue(); - - String returnJSON = ""; - try{ - returnJSON = this.getrNoteBookIntegrationService().getRNotebookCredentials(token); - } catch(RNotebookIntegrationException re){ - if (re.getErrorCode().equals(RNotebookIntegrationException.ERROR_CODE_TOKEN_EXPIRED)){ - return new ResponseEntity(JsonMessage.buildJsonResponse(false, re.getMessage()), HttpStatus.BAD_REQUEST); - } - else { - return new ResponseEntity(JsonMessage.buildJsonResponse(false, re.getMessage()), HttpStatus.BAD_REQUEST); - } - } - catch (Exception e){ - return new ResponseEntity(JsonMessage.buildJsonResponse(false, e.getMessage()), HttpStatus.BAD_REQUEST); - } - - return new ResponseEntity(returnJSON, HttpStatus.OK); - - } - - -} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/domain/RNoteBookCredentials.java b/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/domain/RNoteBookCredentials.java deleted file mode 100644 index 9298c5a2..00000000 --- a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/domain/RNoteBookCredentials.java +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.rnotebookintegration.domain; - -import java.util.Date; -import java.util.Map; - -import org.openecomp.portalsdk.core.domain.support.DomainVo; -import org.openecomp.portalsdk.core.restful.domain.EcompUser; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -public class RNoteBookCredentials extends DomainVo { - private EcompUser userInfo; - private String token; - private Date createdDate; - private String notebookID; - private Map parameters; - private Date tokenReadDate; - @JsonIgnore - private String userString; - @JsonIgnore - private String parametersString; - - public String getToken() { - return token; - } - public void setToken(String token) { - this.token = token; - } - public Date getCreatedDate() { - return createdDate; - } - public void setCreatedDate(Date createdDate) { - this.createdDate = createdDate; - } - public String getNotebookID() { - return notebookID; - } - public EcompUser getUserInfo() { - return userInfo; - } - public void setUserInfo(EcompUser userInfo) { - this.userInfo = userInfo; - } - public void setNotebookID(String notebookID) { - this.notebookID = notebookID; - } - public String getUserString() { - return userString; - } - public void setUserString(String userString) { - this.userString = userString; - } - public Map getParameters() { - return parameters; - } - public void setParameters(Map parameters) { - this.parameters = parameters; - } - public String getParametersString() { - return parametersString; - } - public void setParametersString(String parametersString) { - this.parametersString = parametersString; - } - public Date getTokenReadDate() { - return tokenReadDate; - } - public void setTokenReadDate(Date tokenReadDate) { - this.tokenReadDate = tokenReadDate; - } - - - -} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationServiceImpl.java b/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationServiceImpl.java deleted file mode 100644 index 1d0972da..00000000 --- a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/rnotebookintegration/service/RNoteBookIntegrationServiceImpl.java +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.rnotebookintegration.service; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.openecomp.portalsdk.core.restful.domain.EcompUser; -import org.openecomp.portalsdk.core.service.DataAccessService; -import org.openecomp.portalsdk.rnotebookintegration.domain.RNoteBookCredentials; -import org.openecomp.portalsdk.rnotebookintegration.exception.RNotebookIntegrationException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Service("RNoteBookIntegrationService") -@Transactional -public class RNoteBookIntegrationServiceImpl implements RNoteBookIntegrationService { - - private final long tokenTTL = 50000L; - - EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RNoteBookIntegrationServiceImpl.class); - - - @Autowired - private DataAccessService dataAccessService; - - public DataAccessService getDataAccessService() { - return dataAccessService; - } - - public void setDataAccessService(DataAccessService dataAccessService) { - this.dataAccessService = dataAccessService; - } - - @Override - public String getRNotebookCredentials(String token) throws RNotebookIntegrationException, Exception { - String retString = ""; - - try{ - RNoteBookCredentials notebookCredentials = (RNoteBookCredentials) this.getDataAccessService().getDomainObject(RNoteBookCredentials.class, token, new HashMap()); - if (notebookCredentials.getToken() == null || notebookCredentials.getToken().equals("")){ - throw new RNotebookIntegrationException(RNotebookIntegrationException.ERROR_CODE_TOKEN_INVALID); - } - Date currDate = new Date(); - if ((currDate.getTime() - notebookCredentials.getCreatedDate().getTime() > tokenTTL) || (notebookCredentials.getTokenReadDate() != null)){ - throw new RNotebookIntegrationException(RNotebookIntegrationException.ERROR_CODE_TOKEN_EXPIRED); - } - ObjectMapper mapper = new ObjectMapper(); - - try{ - EcompUser userInfo = mapper.readValue(notebookCredentials.getUserString(), EcompUser.class); - notebookCredentials.setUserInfo(userInfo); - } catch(JsonMappingException me){ - logger.error("error converting string to user. from JSON" + me.getMessage()); - } catch(JsonParseException pe){ - logger.error("error converting string to user. from JSON" + pe.getMessage()); - } - - try{ - Map params = mapper.readValue(notebookCredentials.getParametersString(), HashMap.class); - notebookCredentials.setParameters(params); - } catch(JsonMappingException me){ - logger.error("error converting string to parameters. from JSON" + me.getMessage()); - } catch(JsonParseException pe){ - logger.error("error converting string to parameters. from JSON" + pe.getMessage()); - } - - //expiring the token - try{ - notebookCredentials.setTokenReadDate(new Date()); - this.getDataAccessService().saveDomainObject(notebookCredentials, null); - } catch(Exception e){ - logger.info("Error while expiring the token"); - logger.error(e.getMessage()); - throw new Exception(); - } - //notebookCredentials.setUserString(null); - retString = mapper.writeValueAsString(notebookCredentials); - } catch(RNotebookIntegrationException re){ - logger.error(re.getMessage()); - throw re; - } catch(Exception e){ - logger.info("Error while parsing the rcloud notebook credentials"); - logger.error(e.getMessage()); - throw new Exception(); - } - - return retString; - } - - @Override - public String saveRNotebookCredentials(String notebookId, EcompUser user, Map params) throws RNotebookIntegrationException, Exception { - - String token = ""; - try{ - token = UUID.randomUUID().toString(); - - ObjectMapper mapper = new ObjectMapper(); - ; - RNoteBookCredentials rc = new RNoteBookCredentials(); - rc.setToken(token); - rc.setCreatedDate(new Date()); - rc.setNotebookID(notebookId); - rc.setParametersString(mapper.writeValueAsString(params)); - rc.setUserString(mapper.writeValueAsString(user)); - - this.getDataAccessService().saveDomainObject(rc, null); - - } catch(Exception e){ - logger.info("Error while parsing the rcloud notebook credentials"); - logger.error(e.getMessage()); - throw new Exception(); - } - - return token; - } - - -} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/HibernateConfiguration.java b/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/HibernateConfiguration.java deleted file mode 100644 index e5ace071..00000000 --- a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/dao/HibernateConfiguration.java +++ /dev/null @@ -1,20 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.workflow.dao; diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/Workflow.java b/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/Workflow.java deleted file mode 100644 index 7f93c5ea..00000000 --- a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/models/Workflow.java +++ /dev/null @@ -1,202 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.workflow.models; - -import java.io.Serializable; -import java.util.Date; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToOne; -import javax.persistence.Table; - -import org.openecomp.portalsdk.core.domain.User; - -@Entity -@Table(name = "fn_workflow") -public class Workflow implements Serializable{ - - private static final long serialVersionUID = -3155065449938005856L; - - @Id - @Column(name = "id") - @GeneratedValue - private Long id; - - @Column - private String name; - - @Column (name = "workflow_key") - private String workflowKey; - - @Column - private String description; - - @Column(name = "created") - private Date created; - - @OneToOne(fetch = FetchType.EAGER)//, cascade = CascadeType.ALL) - @JoinColumn(name = "created_by") - private User createdBy; - - @Column(name = "modified") - private Date lastUpdated; - - @OneToOne(fetch = FetchType.EAGER)//, cascade = CascadeType.ALL) - @JoinColumn(name = "modified_by") - private User modifiedBy; - - @Column(name = "active_yn") - private Boolean active; - - @Column(name = "run_link") - private String runLink; - - @Column(name = "suspend_link") - private String suspendLink; - - @Column(name = "modified_link") - private String modifiedLink; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getRunLink() { - return runLink; - } - - public void setRunLink(String runLink) { - this.runLink = runLink; - } - - public String getSuspendLink() { - return suspendLink; - } - - public void setSuspendLink(String suspendLink) { - this.suspendLink = suspendLink; - } - - public String getModifiedLink() { - return modifiedLink; - } - - public void setModifiedLink(String modifiedLink) { - this.modifiedLink = modifiedLink; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Date getCreated() { - return created; - } - - public void setCreated(Date created) { - this.created = created; - } - - public User getCreatedBy() { - return createdBy; - } - - public void setCreatedBy(User createdBy) { - this.createdBy = createdBy; - } - - public Date getLastUpdated() { - return lastUpdated; - } - - public void setLastUpdated(Date lastUpdated) { - this.lastUpdated = lastUpdated; - } - - public User getModifiedBy() { - return modifiedBy; - } - - public void setModifiedBy(User modifiedBy) { - this.modifiedBy = modifiedBy; - } - - public String getWorkflowKey() { - return workflowKey; - } - - public void setWorkflowKey(String workflowKey) { - this.workflowKey = workflowKey; - } - - public Boolean getActive() { - return active; - } - - public void setActive(Boolean active) { - this.active = active; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Workflow other = (Workflow) obj; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - return true; - } -} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleExecutor.java b/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleExecutor.java deleted file mode 100644 index 8927e08b..00000000 --- a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowScheduleExecutor.java +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.workflow.services; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.nio.charset.Charset; - -public class WorkflowScheduleExecutor { - private String serverURL; - private String workflowKey; - private String myUrl; - private String payload; - - //constructor - public WorkflowScheduleExecutor(String serverURL,String workflowKey){ - this.serverURL = serverURL; - this.workflowKey = workflowKey; - this.myUrl = this.serverURL + "/engine-rest/process-definition/key/" + this.workflowKey + "/submit-form";; - this.payload="{\"variables\":{}}"; - } - - public static void main(String [] args) throws Exception { - - } - - public void execute() { - POST_fromURL(myUrl,payload); - } - - public static String get_fromURL(String myURL) { - System.out.println("Requeted URL:" + myURL); - StringBuilder sb = new StringBuilder(); - URLConnection urlConn = null; - InputStreamReader in = null; - try { - URL url = new URL(myURL); - urlConn = url.openConnection(); - if (urlConn != null) - urlConn.setReadTimeout(60 * 1000); - if (urlConn != null && urlConn.getInputStream() != null) { - in = new InputStreamReader(urlConn.getInputStream(), - Charset.defaultCharset()); - BufferedReader bufferedReader = new BufferedReader(in); - if (bufferedReader != null) { - int cp; - while ((cp = bufferedReader.read()) != -1) { - sb.append((char) cp); - } - bufferedReader.close(); - } - } - in.close(); - } catch (Exception e) { - throw new RuntimeException("Exception while calling URL:"+ myURL, e); - } - return sb.toString(); - } - - - public static String POST_fromURL(String myURL, String payload) { - String line; - StringBuffer jsonString = new StringBuffer(); - try { - URL url = new URL(myURL); - - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setDoInput(true); - connection.setDoOutput(true); - connection.setRequestMethod("POST"); - connection.setRequestProperty("Accept", "application/json"); - connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); - OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); - writer.write(payload); - writer.close(); - BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); - while ((line = br.readLine()) != null) { - jsonString.append(line); - } - br.close(); - connection.disconnect(); - } catch (Exception e) { - throw new RuntimeException(e.getMessage()); - } - return jsonString.toString(); - } -} diff --git a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowService.java b/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowService.java deleted file mode 100644 index 745b0b23..00000000 --- a/ecomp-sdk/sdk-workflow/src/main/java/org/openecomp/portalsdk/workflow/services/WorkflowService.java +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.workflow.services; - -import java.util.List; - -import org.openecomp.portalsdk.workflow.domain.WorkflowSchedule; -import org.openecomp.portalsdk.workflow.models.Workflow; -import org.openecomp.portalsdk.workflow.models.WorkflowLite; - - -public interface WorkflowService { - public void saveCronJob(WorkflowSchedule domainCronJobData); - public Workflow addWorkflow(Workflow workflow, String creatorId); - public Workflow editWorkflow(WorkflowLite worklow, String creatorId); - public void deleteWorkflow(Long worklow); - public List getAllWorkflows(); -} diff --git a/ecomp-sdk/thirdparty/.gitignore b/ecomp-sdk/thirdparty/.gitignore deleted file mode 100644 index b83d2226..00000000 --- a/ecomp-sdk/thirdparty/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/ecomp-sdk/thirdparty/README.md b/ecomp-sdk/thirdparty/README.md deleted file mode 100644 index f916e99f..00000000 --- a/ecomp-sdk/thirdparty/README.md +++ /dev/null @@ -1,23 +0,0 @@ -ECOMP Portal SDK Framework -========================== - -This is the Maven project for the ECOMP Portal SDK Framework, -which is distributed as ecompFW-nnn.jar. This library -(formerly called third-party onboarding) provides features to -partner applications that use a J2EE Servlet 3.0 container -as Apache Tomcat. These features include: -- REST endpoint for use by the ECOMP Portal aplication. This endpoint - answers queries about roles, users and user-role assignments. - The endpoint methods are defined by the Java interface class - IPortalRestAPIService. Application developers must provide a - class that implements this interface, and publish the name of - that class in the properties file as discussed below. -- A session listener that updates a collection with current user sessions - as sessions are created and destroyed. This information is used to maintain - and extend user session timeouts across applications that are on-boarded to - the ECOMP portal. -- Communication with the ECOMP Portal to fetch a user-specific functional menu, either - via REST or UEB. - -Unlike the other ECOMP SDK libraries, this library does NOT require Hibernate, -nor does it require Spring. \ No newline at end of file diff --git a/ecomp-sdk/thirdparty/pom.xml b/ecomp-sdk/thirdparty/pom.xml deleted file mode 100644 index 6729cd5f..00000000 --- a/ecomp-sdk/thirdparty/pom.xml +++ /dev/null @@ -1,93 +0,0 @@ - - 4.0.0 - - - org.openecomp.ecompsdkos - ecompSDK-project - 1.1.0-SNAPSHOT - - - - ecompFW - - jar - Ecomp Portal Framework (thirdparty) - - - - - - - - - - - - src/main/java - - **/portal*.properties - - - - - - - - - - org.apache.maven.plugins - maven-jar-plugin - 2.6 - - - **/com/att/fusion/core/onboarding/client/* - - - - ${project.version} - ${sdk-internal.version} - - - - - - - - - - - - - - - javax.servlet - javax.servlet-api - 3.0.1 - - - commons-logging - commons-logging - 1.2 - - - com.fasterxml.jackson.core - jackson-annotations - 2.6.3 - - - com.fasterxml.jackson.core - jackson-databind - 2.6.3 - - - - - com.att.nsa - cambriaClient - 0.0.1 - - - - - - diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/ECOMPSSOFilter.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/ECOMPSSOFilter.java deleted file mode 100644 index 0fc64999..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/ECOMPSSOFilter.java +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.client; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.annotation.WebFilter; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.openecomp.portalsdk.core.onboarding.crossapi.ECOMPSSO; - -/** - * This is an example filter that uses the ecompFW library to require the - */ -@WebFilter("/secure/*") -public class ECOMPSSOFilter implements Filter { - - /* - * (non-Javadoc) - * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) - */ - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws java.io.IOException, ServletException { - if (ECOMPSSO.valdiateECOMPSSO((HttpServletRequest) request) == null) { - String redirectURL = ECOMPSSO.getECOMPSSORedirectURL(((HttpServletRequest) request), - ((HttpServletResponse) response), - (((HttpServletRequest) request).getRequestURI() - .substring(((HttpServletRequest) request).getContextPath().length() + 1) - + (((HttpServletRequest) request).getQueryString() != null - ? ("?" + ((HttpServletRequest) request).getQueryString()) : ""))); - ((HttpServletResponse) response).sendRedirect(redirectURL); - } else { - // Pass request back down the filter chain - chain.doFilter(request, response); - } - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.Filter#destroy() - */ - public void destroy() { - // Called before the Filter instance is removed from service - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) - */ - public void init(FilterConfig arg0) throws ServletException { - // Called before the filter instance is installed into service. - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/SecureServlet.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/SecureServlet.java deleted file mode 100644 index 9a583d38..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/SecureServlet.java +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.client; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Servlet implementation class SecureServlet - */ -@WebServlet("/secure/SecureServlet") -public class SecureServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - /** - * @see HttpServlet#HttpServlet() - */ - public SecureServlet() { - super(); - // TODO Auto-generated constructor stub - } - - /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) - */ - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // TODO Auto-generated method stub - response.getWriter().append("Served at: ").append(request.getContextPath()); - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) - */ - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // TODO Auto-generated method stub - doGet(request, response); - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/UnSecureServlet.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/UnSecureServlet.java deleted file mode 100644 index d5cd2758..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/client/UnSecureServlet.java +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.client; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Servlet implementation class SecureServlet - */ -@WebServlet("/unsecure/SecureServlet") -public class UnSecureServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - /** - * @see HttpServlet#HttpServlet() - */ - public UnSecureServlet() { - super(); - // TODO Auto-generated constructor stub - } - - /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) - */ - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // TODO Auto-generated method stub - response.getWriter().append("Served at: ").append(request.getContextPath()); - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) - */ - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // TODO Auto-generated method stub - doGet(request, response); - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/CipherUtil.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/CipherUtil.java deleted file mode 100644 index d355e102..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/CipherUtil.java +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.binary.Base64; - -public class CipherUtil { - - private final static String key = "AGLDdG4D04BKm2IxIWEr8o==!"; - - /** - * @param plainText - * @param secretKey - * @return encrypted version of plain text. - * @throws Exception - */ - public static String encrypt(String plainText, String secretKey) throws Exception{ - byte[] rawKey; - String encryptedString; - SecretKeySpec sKeySpec; - byte[] encryptText = plainText.getBytes("UTF-8"); - Cipher cipher; - rawKey = Base64.decodeBase64(secretKey); - sKeySpec = new SecretKeySpec(rawKey, "AES"); - cipher = Cipher.getInstance("AES"); - cipher.init(Cipher.ENCRYPT_MODE, sKeySpec); - encryptedString = Base64.encodeBase64String(cipher.doFinal(encryptText)); - - return encryptedString; - } - - /** - * - * @param plainText - * @return Encrypted Text - * @throws Exception - */ - public static String encrypt(String plainText) throws Exception - { - return CipherUtil.encrypt(plainText,key); - } - - /** - * @param encryptedText - * @param secretKey - * @return plain text version of encrypted text - * @throws Exception - */ - public static String decrypt(String encryptedText, String secretKey) throws Exception { - Cipher cipher; - String encryptedString; - byte[] encryptText = null; - byte[] rawKey; - SecretKeySpec sKeySpec; - - rawKey = Base64.decodeBase64(secretKey); - sKeySpec = new SecretKeySpec(rawKey, "AES"); - encryptText = Base64.decodeBase64(encryptedText.getBytes("UTF-8")); - cipher = Cipher.getInstance("AES"); - cipher.init(Cipher.DECRYPT_MODE, sKeySpec); - encryptedString = new String(cipher.doFinal(encryptText)); - - return encryptedString; - } - - /** - * @param encryptedText - * @return Decrypted Text - * @throws Exception - */ - public static String decrypt(String encryptedText) throws Exception - { - return CipherUtil.decrypt(encryptedText,key); - } - - - public static void main(String[] args) throws Exception { - - String password = "Welcome123"; - String encrypted; - String decrypted; - - if (args.length != 2) { - System.out.println("Default password testing... "); - System.out.println("Plain password: " + password); - encrypted = encrypt(password); - System.out.println("Encrypted password: " + encrypted); - decrypted = decrypt(encrypted); - System.out.println("Decrypted password: " + decrypted); - } else { - String whatToDo = args[0]; - if (whatToDo.equalsIgnoreCase("d")) { - encrypted = args[1]; - System.out.println("Encrypted Text: " + encrypted); - decrypted = decrypt(encrypted); - System.out.println("Decrypted Text: " + decrypted); - } else { - decrypted = args[1]; - System.out.println("Plain Text: " + decrypted); - encrypted = encrypt(decrypted); - System.out.println("Encrypted Text" + encrypted); - } - } - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/ECOMPSSO.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/ECOMPSSO.java deleted file mode 100644 index 8fc2ec5b..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/ECOMPSSO.java +++ /dev/null @@ -1,238 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - - -/** - * Provides authentication service for onboarded ECOMP applications. - */ -public class ECOMPSSO { - - private static final String EP_SERVICE = "EPService"; - private static final String USER_ID = "UserId"; - - private static final Log logger = LogFactory.getLog(ECOMPSSO.class); - - - public static String valdiateECOMPSSO(HttpServletRequest request) { - // Check ECOMP Portal cookie - if (!isLoginCookieExist(request)) - return null; - - String userid = null; - try { - userid = getUserIdFromCookie(request); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return userid; - } - - public static String getUserIdFromCookie(HttpServletRequest request) throws Exception { - String userId = ""; - Cookie[] cookies = request.getCookies(); - Cookie userIdcookie = null; - if (cookies != null) - for (Cookie cookie : cookies) - if (cookie.getName().equals(USER_ID)) - userIdcookie = cookie; - if(userIdcookie!=null){ - userId = CipherUtil.decrypt(userIdcookie.getValue(), - PortalApiProperties.getProperty(PortalApiConstants.Decryption_Key)); - } - return userId; - - } - - /** - * Builds a redirect URL from properties file and the specified relative - * path in this app. The intent is to take the user to the portal, which - * will redirect the user to Global Log On, and finally the user will be - * returned to the app. - * - * @param request - * HttpServletRequest - * @param response - * HttpServletResponse - * @param forwardPath - * portion of the application path after the protocol, server and - * context path plus any query parameters; e.g., "welcome.html"; - * empty string is allowed. - * @return URL that redirects user to ECOMP Portal for login. - */ - public static String getECOMPSSORedirectURL(HttpServletRequest request, HttpServletResponse response, - String forwardPath) { - // Construct a path for this server, this app's context, etc. - String appURL = (request.isSecure() ? "https://" : "http://") + request.getServerName() + ":" - + request.getServerPort() + request.getContextPath() + "/" + forwardPath; - String encodedAppURL = null; - try { - encodedAppURL = URLEncoder.encode(appURL, "UTF-8"); - } catch (UnsupportedEncodingException ex) { - // should never happen - logger.error("getECOMPSSORedirectURL: Failed to encode app URL " + appURL); - } - String portalURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); - if (portalURL == null || portalURL.length() == 0) { - logger.error("getECOMPSSORedirectURL: Failed to get property " + PortalApiConstants.ECOMP_REDIRECT_URL); - return null; - } - String redirectURL = portalURL + "?redirectUrl=" + encodedAppURL; - return redirectURL; - } - - /** - * Answers whether the ECOMP Portal service cookie is present in the - * specified request. - * - * @param request - * @return true if the cookie is found, else false. - */ - private static boolean isLoginCookieExist(HttpServletRequest request) { - Cookie ep = getCookie(request, EP_SERVICE); - return (ep != null); - } - - /** - * Searches the request for a cookie with the specified name. - * - * @param request - * @param cookieName - * @return Cookie, or null if not found. - */ - public static Cookie getCookie(HttpServletRequest request, String cookieName) { - Cookie[] cookies = request.getCookies(); - if (cookies != null) - for (Cookie cookie : cookies) - if (cookie.getName().equals(cookieName)) - return cookie; - - return null; - } - - /** - * Splits a string into an array. - * - * @param str - * @param delimiter - * @return - */ - private static String[] delimitedListToStringArray(String str, String delimiter) { - return delimitedListToStringArray(str, delimiter, null); - } - - /** - * Splits a string into an array, optionally deleting characters. - * - * @param str - * String to be split - * @param delimiter - * Token to use as the delimiter - * @param charsToDelete - * Optional String of characters to be removed; ignored if null - * @return String array; empty if the input is null or delimiter are null. - */ - private static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) { - if (str == null) - return new String[0]; - if (delimiter == null) - return new String[] { str }; - - List result = new ArrayList(); - if ("".equals(delimiter)) { - for (int i = 0; i < str.length(); i++) { - result.add(deleteAny(str.substring(i, i + 1), charsToDelete)); - } - } else { - int pos = 0; - int delPos = 0; - while ((delPos = str.indexOf(delimiter, pos)) != -1) { - result.add(deleteAny(str.substring(pos, delPos), charsToDelete)); - pos = delPos + delimiter.length(); - } - if (str.length() > 0 && pos <= str.length()) { - // Add rest of String, but not in case of empty input. - result.add(deleteAny(str.substring(pos), charsToDelete)); - } - } - return toStringArray(result); - } - - /** - * Convenience method that creates a string array from the items in the - * collection. - * - * @param collection - * @return - */ - private static String[] toStringArray(Collection collection) { - if (collection == null) - return null; - return (String[]) collection.toArray(new String[collection.size()]); - } - - /** - * Builds a new string that has none of the characters in the charsToDelete - * argument. - * - * @param inString - * @param charsToDelete - * @return Input string after removing all characters in the second - * argument. - */ - private static String deleteAny(String inString, String charsToDelete) { - if (!hasLength(inString) || !hasLength(charsToDelete)) { - return inString; - } - StringBuffer out = new StringBuffer(); - for (int i = 0; i < inString.length(); i++) { - char c = inString.charAt(i); - if (charsToDelete.indexOf(c) == -1) { - out.append(c); - } - } - return out.toString(); - } - - /** - * - * @param str - * @return - */ - private static boolean hasLength(String str) { - return (str != null && str.length() > 0); - } - - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java deleted file mode 100644 index 25a8aeff..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalRestAPIService.java +++ /dev/null @@ -1,133 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -import org.openecomp.portalsdk.core.restful.domain.EcompRole; -import org.openecomp.portalsdk.core.restful.domain.EcompUser; - -/** - * Defines the REST API Interface that an onboarding non-SDK (i.e., third-party) - * application must implement to answer queries and accept updates from the - * ECOMP Portal about the application's users, roles and user-role assignments. - * - * @author Ikram Ikramullah - */ -public interface IPortalRestAPIService { - - // EcompUser Interface - - /** - * Creates a new user. - * - * @param user - * Model object with attributes of user to be created. - * @throws PortalAPIException - * If any error occurs while processing the request; for - * example, user exists already. - */ - public void pushUser(EcompUser user) throws PortalAPIException; - - /** - * Updates an existing user's attributes. - * - * @param loginId - * EcompUser ID to be updated. - * @param user - * Model object with attributes of user to be updated. - * @throws PortalAPIException - * If any error occurs while processing the request; for - * example, unknown user. - */ - public void editUser(String loginId, EcompUser user) throws PortalAPIException; - - /** - * Gets details about an existing user. - * - * @param loginId - * EcompUser ID to be fetched - * @return Model object with user attributes. - * @throws PortalAPIException - * If any error occurs while processing the request; for - * example, unknown user. - */ - public EcompUser getUser(String loginId) throws PortalAPIException; - - /** - * Gets all users. - * - * @return List of user attribute model objects; empty array if none are - * found. - * @throws PortalAPIException - * If any error occurs while processing the request. - */ - public List getUsers() throws PortalAPIException; - - // Roles Interface - - /** - * Gets all defined roles. - * - * @return List of role attribute objects; empty array if none are - * found. - * @throws PortalAPIException - * If an unexpected error occurs while processing the request. - */ - public List getAvailableRoles() throws PortalAPIException; - - /** - * Replaces existing user roles with new roles. - * - * @param loginId - * EcompUser ID to be updated. - * @param roles - * List of model objects with role attributes - * @throws PortalAPIException - * If any error occurs while processing the request. - */ - public void pushUserRole(String loginId, List roles) throws PortalAPIException; - - /** - * Gets the roles defined for the specified user. - * - * @param loginId - * @return List of model objects; empty if no roles are found. - * @throws PortalAPIException - * If any error occurs while processing the request; e.g., user - * not found. - */ - public List getUserRoles(String loginId) throws PortalAPIException; - - // Security Interface - - /** - * Answers whether the request is authenticated. - * - * @param request - * @return true if the request contains appropriate credentials, else false. - * @throws PortalAPIException - * If an unexpected error occurs while processing the request. - */ - public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException; - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java deleted file mode 100644 index 0b55a965..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/IPortalUebAPIService.java +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - - -/** - * - * @author Ikram Ikramullah - * - * UEB API Interface for all the onboarding third party applications. - * - */ - -public interface IPortalUebAPIService { - //User Interface - public String pushUser(String userJson) throws PortalAPIException; - public String editUser(String loginId, String userJson) throws PortalAPIException; - public String getUser(String loginId) throws PortalAPIException; - public String getUsers() throws PortalAPIException; - - //Roles Interface - public String getAvailableRoles() throws PortalAPIException; - public String getAvailableFullRoles() throws PortalAPIException; - public String pushUserRole(String loginId, String rolesJson) throws PortalAPIException; - public String getUserRoles(String loginId) throws PortalAPIException; - - //Security Interface - public boolean isAppAuthenticated(String appUserName, String appPassword) throws PortalAPIException; -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIException.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIException.java deleted file mode 100644 index 8a4c9e4e..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIException.java +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -/** - * @author Ikram Ikramullah - */ -public class PortalAPIException extends Exception{ - - private static final long serialVersionUID = 4854048794984375707L; - - public PortalAPIException() { - super(); - } - - public PortalAPIException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } - - public PortalAPIException(String message, Throwable cause) { - super(message, cause); - } - - public PortalAPIException(String message) { - super(message); - } - - public PortalAPIException(Throwable cause) { - super(cause); - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java deleted file mode 100644 index f8d73acc..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalAPIResponse.java +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -/** - * This bean holds a response that is returned by the role and user-management - * REST API. - */ -public class PortalAPIResponse { - - /** - * Either "ok" or "error" - */ - private String status; - /** - * Optional if status is ok - */ - private String message; - - public PortalAPIResponse(boolean isOk, String msg) { - status = (isOk? "ok" : "error"); - message = msg; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiConstants.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiConstants.java deleted file mode 100644 index 667ad289..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiConstants.java +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -public interface PortalApiConstants { - public static final String API_PREFIX = "/api"; - public static final String PORTAL_JSESSION_ID = "PORTAL_JSESSION_ID"; - public static final String PORTAL_JSESSION_BIND = "PORTAL_JSESSION_BIND"; - public static final String ACTIVE_USERS_NAME = "activeUsers"; - - /** Portal service cookie name */ - public static final String EP_SERVICE = "EPService"; - - public static final String GLOBAL_SESSION_MAX_IDLE_TIME = "global_session_max_idle_time"; - public static final String PORTAL_SESSION_SLOT_CHECK = "portal_session_slot_check"; - public static final String SESSION_PREVIOUS_ACCESS_TIME = "session_previous_access_time"; - public static final String MAX_IDLE_TIME = "max.idle.time"; - - // Names of keys in the portal.properties file - public static final String PORTAL_API_IMPL_CLASS = "portal.api.impl.class"; - public static final String ECOMP_REDIRECT_URL = "ecomp_redirect_url"; - public static final String ECOMP_REST_URL = "ecomp_rest_url"; - - // UEB related - public static final String UEB_URL_LIST = "ueb_url_list"; // In properties file - public static final String ECOMP_PORTAL_INBOX_NAME = "ecomp_portal_inbox_name"; - public static final String ECOMP_DEFAULT_MSG_ID = "0"; - public static final String ECOMP_GENERAL_UEB_PARTITION = "EPGeneralPartition"; - public static final String UEB_LISTENERS_ENABLE = "ueb_listeners_enable"; - public static final String UEB_APP_INBOUND_MAILBOX_NAME = "ueb_app_mailbox_name"; - public static final String UEB_APP_CONSUMER_GROUP_NAME = "ueb_app_consumer_group_name"; - // UebManager generates a consumer group name for special token {UUID} - public static final String UEB_APP_CONSUMER_GROUP_NAME_GENERATOR = "{UUID}"; - public static final String UEB_APP_KEY = "ueb_app_key"; - public static final String UEB_APP_SECRET = "ueb_app_secret"; - public static final String ECOMP_UEB_INVALID_MSG = "100: Invalid Message format."; - public static final String ECOMP_UEB_TIMEOUT_ERROR = "101: Timeout"; - public static final String ECOMP_UEB_UNKNOWN_PUBLISH_ERROR = "102: Unknown error during publish"; - public static final String ECOMP_UEB_UNKNOWN_CONSUME_ERROR = "103: Unknown error during consume"; - public static final String USE_REST_FOR_FUNCTIONAL_MENU = "use_rest_for_functional_menu"; - - //encrpt key - public static final String Decryption_Key = "decryption_key"; - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiProperties.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiProperties.java deleted file mode 100644 index b9853a9a..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalApiProperties.java +++ /dev/null @@ -1,98 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Singleton Class representing portal properties. Searches the classpath for - * the file "portal.properties". - * - * To put the file "portal.properties" on the classpath, it can be in the same - * directory where the first package folder is - 'myClasses' folder in the - * following case as an example: - * - */ -public class PortalApiProperties { - - private static final Log logger = LogFactory.getLog(PortalApiProperties.class); - - private static Properties properties; - private static String propertyFileName = "portal.properties"; - - /** - * Constructor is private. - */ - private PortalApiProperties() { - } - - /** - * Gets the property value for the specified key. - * - * @param property - * @return Value for the named property; null if the property file was not - * loaded or the key was not found. - */ - public static String getProperty(String property) { - if (properties == null) { - synchronized (propertyFileName) { - try { - if (!initialize()) { - logger.error("Failed to read property file " + propertyFileName); - return null; - } - } catch (IOException e) { - logger.error("Failed to read property file " + propertyFileName, e); - return null; - } - } - } - return properties.getProperty(property); - } - - /** - * Reads properties from a portal.properties file on the classpath. - * - * Clients DO NOT need to call this method. Clients MAY call this method to - * test whether the properties file can be loaded successfully. - * - * @return True if properties were successfully loaded, else false. - * @throws IOException - */ - public static boolean initialize() throws IOException { - if (properties != null) - return true; - InputStream in = PortalApiProperties.class.getClassLoader().getResourceAsStream(propertyFileName); - if (in == null) - return false; - properties = new Properties(); - try { - properties.load(in); - } finally { - in.close(); - } - return true; - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java deleted file mode 100644 index 3012d1c7..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalRestAPIProxy.java +++ /dev/null @@ -1,498 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.List; - -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openecomp.portalsdk.core.restful.domain.EcompRole; -import org.openecomp.portalsdk.core.restful.domain.EcompUser; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * This servlet responds to ECOMP Portal API calls to query and update user, - * role and user-role information. It registers itself at a path like "/api" - * (see {@link PortalApiConstants#API_PREFIX}) and proxies all requests on to a - * class that implements {@link IPortalRestAPIService}, as named in the required - * properties file ("portal.properties"). The servlet will not start if the - * properties file is not found. - * - * Implements the interface solely to ensure that changes to the interface are - * made here also, the compiler helps catch problems that way. - * - * @author Ikram Ikramullah - */ - -@WebServlet(urlPatterns = { PortalApiConstants.API_PREFIX + "/*" }) -public class PortalRestAPIProxy extends HttpServlet implements IPortalRestAPIService { - private static final long serialVersionUID = 1L; - - private final Log logger = LogFactory.getLog(getClass()); - - /** - * JSON to object etc. - */ - private final ObjectMapper mapper = new ObjectMapper(); - - /** - * Client-supplied class that implements our interface. - */ - private IPortalRestAPIService portalRestApiService; - - public PortalRestAPIProxy() { - // Ensure that any additional fields sent by the Portal - // will be ignored when creating objects. - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } - - @Override - public void init() throws ServletException { - String className = PortalApiProperties.getProperty(PortalApiConstants.PORTAL_API_IMPL_CLASS); - if (className == null) - throw new ServletException( - "init: Failed to find class name property " + PortalApiConstants.PORTAL_API_IMPL_CLASS); - try { - logger.debug("init: creating instance of class " + className); - Class implClass = Class.forName(className); - portalRestApiService = (IPortalRestAPIService) (implClass.getConstructor().newInstance()); - } catch (Exception ex) { - throw new ServletException("init: Failed to find or instantiate class " + className, ex); - } - } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException { - - if (portalRestApiService == null) { - // Should never happen due to checks in init() - logger.error("doPost: no service class instance"); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - response.getWriter().write(buildJsonResponse(false, "Misconfigured - no instance of service class")); - return; - } - boolean secure = false; - try { - secure = isAppAuthenticated(request); - } catch (PortalAPIException ex) { - logger.error("doPost: isAppAuthenticated threw exception", ex); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - response.getWriter().write(buildJsonResponse(false, "Failed to authenticate request")); - return; - } - if (!secure) { - if (logger.isDebugEnabled()) - logger.debug("doPost: isAppAuthenticated answered false"); - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - writeAndFlush(response, buildJsonResponse(false, "Not authorized")); - return; - } - - String requestUri = request.getRequestURI(); - try { - String requestBody = readRequestBody(request); - if (logger.isDebugEnabled()) - logger.debug("doPost: URI = " + requestUri + ", payload = " + requestBody); - - /* - * All APIs: - * - * 1. /user <-- save user - * - * 2. /user/{loginId} <-- edit user - * - * 3. /user/{loginId}/roles <-- save roles for user - */ - - // On success return the empty string. - String responseJson = ""; - if (requestUri.endsWith("/updateSessionTimeOuts")) { - if (updateSessionTimeOuts(requestBody)) { - if (logger.isDebugEnabled()) - logger.debug("doPost: updated session timeouts"); - response.setStatus(HttpServletResponse.SC_OK); - } else { - String msg = "Failed to update session time outs"; - logger.error("doPost: " + msg); - responseJson = buildJsonResponse(false, msg); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } else if (requestUri.endsWith("/timeoutSession")) { - String portalJSessionId = request.getParameter("portalJSessionId"); - if (portalJSessionId == null) { - portalJSessionId = ""; - } - if (timeoutSession(portalJSessionId)) { - if (logger.isDebugEnabled()) - logger.debug("doPost: timed out session"); - response.setStatus(HttpServletResponse.SC_OK); - } else { - String msg = "Failed to timeout session"; - logger.error("doPost: " + msg); - responseJson = buildJsonResponse(false, msg); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } else - // Example: /user <-- create user - if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/user")) { - try { - EcompUser user = mapper.readValue(requestBody, EcompUser.class); - pushUser(user); - if (logger.isDebugEnabled()) - logger.debug("doPost: pushUser: success"); - responseJson = buildJsonResponse(true, null); - response.setStatus(HttpServletResponse.SC_OK); - } catch (Exception ex) { - responseJson = buildJsonResponse(ex); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - logger.error("doPost: pushUser: caught exception", ex); - } - } else - // Example: /user/fi241c <-- edit user fi241c - if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !(requestUri.endsWith("/roles"))) { - String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1); - try { - EcompUser user = mapper.readValue(requestBody, EcompUser.class); - editUser(loginId, user); - if (logger.isDebugEnabled()) - logger.debug("doPost: editUser: success"); - responseJson = buildJsonResponse(true, null); - response.setStatus(HttpServletResponse.SC_OK); - } catch (Exception ex) { - responseJson = buildJsonResponse(ex); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - logger.error("doPost: editUser: caught exception", ex); - } - } else - // Example: /user/{loginId}/roles <-- save roles for user - if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) { - String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1, - requestUri.lastIndexOf('/')); - try { - TypeReference> typeRef = new TypeReference>() { - }; - List roles = mapper.readValue(requestBody, typeRef); - pushUserRole(loginId, roles); - if (logger.isDebugEnabled()) - logger.debug("doPost: pushUserRole: success"); - responseJson = buildJsonResponse(true, null); - response.setStatus(HttpServletResponse.SC_OK); - } catch (Exception ex) { - responseJson = buildJsonResponse(ex); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - logger.error("doPost: pushUserRole: caught exception", ex); - } - } else { - logger.warn("doPost: no match for request " + requestUri); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - } - writeAndFlush(response, responseJson); - } catch (Exception ex) { - logger.error("doPost: Failed to process request " + requestUri, ex); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - writeAndFlush(response, ex.toString()); - } - - } - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException { - - if (portalRestApiService == null) { - // Should never happen due to checks in init() - logger.error("doGet: no service class instance"); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - writeAndFlush(response, buildJsonResponse(false, "Misconfigured - no instance of service class")); - return; - } - boolean secure = false; - try { - secure = isAppAuthenticated(request); - } catch (PortalAPIException ex) { - logger.error("doGet: isAppAuthenticated threw exception", ex); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - writeAndFlush(response, buildJsonResponse(false, "Failed to authenticate request")); - return; - } - if (!secure) { - if (logger.isDebugEnabled()) - logger.debug("doGet: isAppAuthenticated answered false"); - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - writeAndFlush(response, buildJsonResponse(false, "Not authorized")); - return; - } - - String requestUri = request.getRequestURI(); - try { - // Ignore any request body in a GET. - // String requestBody = readRequestBody(request); - if (logger.isDebugEnabled()) - logger.debug("doGet: URI = " + requestUri); - - String responseJson = ""; - /* - * 1. /roles <-- get roles - * - * 2. /user/{loginId} <-- get user - * - * 3. /users <-- get all users - * - * 4. /user/{loginId}/roles <-- get roles for user - */ - - if (requestUri.endsWith("/sessionTimeOuts")) { - responseJson = getSessionTimeOuts(); - if (responseJson != null && responseJson.length() > 0) { - if (logger.isDebugEnabled()) - logger.debug("doGet: got session timeouts"); - response.setStatus(HttpServletResponse.SC_OK); - } else { - String msg = "Failed to get session time outs"; - logger.error("doGet: " + msg); - responseJson = buildJsonResponse(false, msg); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } else - // Example: /users <-- get all users - if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/users")) { - try { - List users = getUsers(); - responseJson = mapper.writeValueAsString(users); - if (logger.isDebugEnabled()) - logger.debug("doGet: getUsers: " + responseJson); - } catch (Exception ex) { - responseJson = buildJsonResponse(ex); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - logger.error("doGet: getUsers: caught exception", ex); - } - } else - // Example: /roles <-- get all roles - if (requestUri.endsWith(PortalApiConstants.API_PREFIX + "/roles")) { - try { - List roles = getAvailableRoles(); - responseJson = mapper.writeValueAsString(roles); - if (logger.isDebugEnabled()) - logger.debug("doGet: getAvailableRoles: " + responseJson); - } catch (Exception ex) { - responseJson = buildJsonResponse(ex); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - logger.error("doGet: getAvailableRoles: caught exception", ex); - } - } else - // Example: /user/fi241c <-- get user fi241c - if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && !requestUri.endsWith("/roles")) { - String loginId = requestUri.substring(requestUri.lastIndexOf('/') + 1); - try { - EcompUser user = getUser(loginId); - responseJson = mapper.writeValueAsString(user); - if (logger.isDebugEnabled()) - logger.debug("doGet: getUser: " + responseJson); - } catch (Exception ex) { - responseJson = buildJsonResponse(ex); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - logger.error("doGet: getUser: caught exception", ex); - } - } - // Example: /user/fi241c/roles <-- get roles for user fi241c - else if (requestUri.contains(PortalApiConstants.API_PREFIX + "/user/") && requestUri.endsWith("/roles")) { - String loginId = requestUri.substring(requestUri.indexOf("/user/") + ("/user").length() + 1, - requestUri.lastIndexOf('/')); - try { - List roles = getUserRoles(loginId); - responseJson = mapper.writeValueAsString(roles); - if (logger.isDebugEnabled()) - logger.debug("doGet: getUserRoles: " + responseJson); - } catch (Exception ex) { - responseJson = buildJsonResponse(ex); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - logger.error("doGet: getUserRoles: caught exception", ex); - } - } else { - logger.warn("doGet: no match found for request"); - responseJson = buildJsonResponse(false, "No match for request"); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - } - writeAndFlush(response, responseJson); - } catch (Exception ex) { - logger.error("doGet: Failed to process request", ex); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - writeAndFlush(response, buildJsonResponse(ex)); - } - } - - public String getSessionTimeOuts() throws Exception { - return PortalTimeoutHandler.gatherSessionExtensions(); - } - - public boolean timeoutSession(String portalJSessionId) throws Exception { - return PortalTimeoutHandler.invalidateSession(portalJSessionId); - } - - public boolean updateSessionTimeOuts(String sessionMap) throws Exception { - return PortalTimeoutHandler.updateSessionExtensions(sessionMap); - } - - @Override - public void pushUser(EcompUser user) throws PortalAPIException { - portalRestApiService.pushUser(user); - } - - @Override - public void editUser(String loginId, EcompUser user) throws PortalAPIException { - portalRestApiService.editUser(loginId, user); - } - - @Override - public EcompUser getUser(String loginId) throws PortalAPIException { - return portalRestApiService.getUser(loginId); - } - - @Override - public List getUsers() throws PortalAPIException { - return portalRestApiService.getUsers(); - } - - @Override - public List getAvailableRoles() throws PortalAPIException { - return portalRestApiService.getAvailableRoles(); - } - - @Override - public void pushUserRole(String loginId, List roles) throws PortalAPIException { - portalRestApiService.pushUserRole(loginId, roles); - } - - @Override - public List getUserRoles(String loginId) throws PortalAPIException { - return portalRestApiService.getUserRoles(loginId); - } - - @Override - public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException { - return portalRestApiService.isAppAuthenticated(request); - } - - private void writeAndFlush(HttpServletResponse response, String jsonResponse) throws IOException { - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.print(jsonResponse); - out.flush(); - } - - /** - * Reads the request body and closes the input stream. - * - * @param request - * @return String read from the request, the empty string if nothing is - * read. - * @throws IOException - */ - private static String readRequestBody(HttpServletRequest request) throws IOException { - - String body = null; - StringBuilder stringBuilder = new StringBuilder(); - BufferedReader bufferedReader = null; - try { - InputStream inputStream = request.getInputStream(); - if (inputStream != null) { - bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - char[] charBuffer = new char[1024]; - int bytesRead = -1; - while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { - stringBuilder.append(charBuffer, 0, bytesRead); - } - } else { - stringBuilder.append(""); - } - } finally { - if (bufferedReader != null) { - try { - bufferedReader.close(); - } catch (IOException ex) { - throw ex; - } - } - } - body = stringBuilder.toString(); - return body; - } - - /** - * Builds JSON object with status + message response body. - * - * @param success - * True to indicate success, false to signal failure. - * @param msg - * Message to include in the response object; ignored if null. - * @return - * - *
        -	 * { "status" : "ok" (or "error"), "message": "some explanation" }
        -	 *         
        - */ - private String buildJsonResponse(boolean success, String msg) { - PortalAPIResponse response = new PortalAPIResponse(success, msg); - String json = null; - try { - json = mapper.writeValueAsString(response); - } catch (JsonProcessingException ex) { - // Truly should never, ever happen - json = "{ \"status\": \"error\",\"message\":\"" + ex.toString() + "\" }"; - } - return json; - } - - /** - * Builds JSON object with status of error and message containing stack - * trace for the specified throwable. - * - * @param t - * Throwable with stack trace to use as message - * @return - * - *
        -	 * { "status" : "error", "message": "some-big-stacktrace" }
        -	 *         
        - */ - private String buildJsonResponse(Throwable t) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - t.printStackTrace(pw); - return buildJsonResponse(false, sw.toString()); - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutBindingListener.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutBindingListener.java deleted file mode 100644 index 906b7e88..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutBindingListener.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import java.io.Serializable; - -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class PortalTimeoutBindingListener implements HttpSessionBindingListener, Serializable { - - private final Log logger = LogFactory.getLog(getClass()); - - private static final long serialVersionUID = 1L; - - @Override - public void valueBound(HttpSessionBindingEvent event) { - final HttpSession session = event.getSession(); - PortalTimeoutHandler.sessionMap.put((String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID), - session); - } - - @Override - public void valueUnbound(HttpSessionBindingEvent event) { - final HttpSession session = event.getSession(); - String portalJSessionId = (String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); - logger.debug(portalJSessionId + " getting removed"); - PortalTimeoutHandler.sessionMap.remove(portalJSessionId); - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutHandler.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutHandler.java deleted file mode 100644 index 09166794..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutHandler.java +++ /dev/null @@ -1,419 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import java.util.Calendar; -import java.util.Hashtable; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * Invoked by listeners (UserContextListener and UserSessionListener) to track - * user sessions. - */ -public class PortalTimeoutHandler { - - protected static final SessionCommInf sessionComm = new SessionComm(); - - - - public interface SessionCommInf { - public Integer fetchSessionSlotCheckInterval(String... params) throws Exception; - - public void extendSessionTimeOuts(String... sessionMap) throws Exception; - } - - public static class SessionComm implements SessionCommInf { - public Integer fetchSessionSlotCheckInterval(String... params) throws Exception { - - String ecompRestURL = params[0]; - String userName = params[1]; - String pwd = params[2]; - String uebKey = params[3]; - - String sessionSlot = SessionCommunication.getSessionSlotCheckInterval(ecompRestURL, userName, pwd, uebKey); - if(sessionSlot == null) - return null; - return Integer.parseInt(sessionSlot); - } - - public void extendSessionTimeOuts(String... params) throws Exception { - - String ecompRestURL = params[0]; - String userName = params[1]; - String pwd = params[2]; - String uebKey = params[3]; - String sessionTimeoutMap = params[4]; - - SessionCommunication.requestPortalSessionTimeoutExtension(ecompRestURL, userName, pwd, uebKey, sessionTimeoutMap); - } - } - - - - public static final Map sessionMap = new Hashtable(); - public static final Integer repeatInterval = 15 * 60; // 15 minutes - protected static final Log logger = LogFactory.getLog(PortalTimeoutHandler.class); - static ObjectMapper mapper = new ObjectMapper(); - private static PortalTimeoutHandler timeoutHandler; - - public static PortalTimeoutHandler getInstance() { - if (timeoutHandler == null) - timeoutHandler = new PortalTimeoutHandler(); - - return timeoutHandler; - } - - /** - * TODO: remove static - * - * @param portalJSessionId - * @param jSessionId - * @param session - */ - public static void sessionCreated(String portalJSessionId, String jSessionId, HttpSession session) { - - storeMaxInactiveTime(session); - - // this key is a combination of portal jsession id and app session id - String jSessionKey = jSessionKey(jSessionId, portalJSessionId); - Object jSessionKeySessionVal = session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); - - // do not reset the attributes if the same values have already been set - // because that will cause PortalTimeoutBindingListener to unbound the value from map - if(jSessionKeySessionVal != null && jSessionKeySessionVal.equals(jSessionKey)) { - logger.debug(" Session Values already exist in te map for sessionKey " + jSessionKey); - return; - } - - session.setAttribute(PortalApiConstants.PORTAL_JSESSION_ID, jSessionKey); - - // session binding listener will add this value to the static map - // and with session replication the listener will fire in all tomcat - // instances - session.setAttribute(PortalApiConstants.PORTAL_JSESSION_BIND, new PortalTimeoutBindingListener()); - // sessionMap.put((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID), - // session); - - } - - /** - * TODO: remove static - * - * @param session - */ - protected static void storeMaxInactiveTime(HttpSession session) { - if (session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME) == null) - session.setAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME, session.getMaxInactiveInterval()); - } - - /** - * TODO: remove static - * - * @param session - */ - public static void sessionDestroyed(HttpSession session) { - try { - logger.info(" Session getting destroyed - id: " + session.getId()); - session.removeAttribute(PortalApiConstants.PORTAL_JSESSION_BIND); - // sessionMap.remove((String)session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID)); - } catch (Exception e) { - logger.error("Error while destroy user session" + e.getMessage()); - } - } - - /*** - * TODO: remove static - * - * @param portalJSessionId - * @return true on success, false if the session cannot be found, etc. - */ - public static boolean invalidateSession(String portalJSessionId) { - boolean result = false; - logger.debug("Session Management: request from Portal to invalidate the session: " + portalJSessionId); - for (String jSessionKey : sessionMap.keySet()) { - try { - HttpSession session = sessionMap.get(jSessionKey); - if (portalJSessionId(jSessionKey).equals(portalJSessionId)) { - session.invalidate(); - result = true; - } - } catch (Exception e) { - logger.error("Session Management: Error when invalidating session", e); - } - } - return result; - } - - /** - * TODO: remove static - * - * @return json version of the timeout map: session ID -> timeout object - */ - public static String gatherSessionExtensions() { - logger.debug("Session Management: gatherSessionExtensions"); - - Map sessionTimeoutMap = new Hashtable(); - String jsonMap = ""; - - for (String jSessionKey : sessionMap.keySet()) { - - try { - // get the expirytime in seconds - HttpSession session = sessionMap.get(jSessionKey); - - Long lastAccessedTimeMilliSec = session.getLastAccessedTime(); - Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L; - // Long currentTimeMilliSec = - // Calendar.getInstance().getTimeInMillis() ; - // (maxIntervalMilliSec - (currentTimeMilliSec - - // lastAccessedTimeMilliSec) + ; - Calendar instance = Calendar.getInstance(); - instance.setTimeInMillis(session.getLastAccessedTime()); - logger.debug("Session Management: Last Accessed time for " + jSessionKey + ": " + instance.getTime()); - - Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; - - sessionTimeoutMap.put(portalJSessionId(jSessionKey), - getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec)); - logger.debug("Session Management: putting session in map " + jSessionKey + " sessionTimoutSec" - + (int) (sessionTimOutMilliSec / 1000)); - - jsonMap = mapper.writeValueAsString(sessionTimeoutMap); - - } catch (Exception e) { - logger.error("Session Management: Error during JsonSessionTimout conversion", e); - } - - } - - return jsonMap; - - } - - /** - * TODO: remove static - * - * @param sessionTimeoutMapStr - * @return true on success, false otherwise - * @throws Exception - */ - public static boolean updateSessionExtensions(String sessionTimeoutMapStr) throws Exception { - logger.debug("Session Management: updateSessionExtensions"); - // Map sessionTimeoutMap = - // mapper.readValue(sessionTimeoutMapStr, Map.class); - Map sessionTimeoutMap = null; - - try { - TypeReference> typeRef = new TypeReference>() { - }; - sessionTimeoutMap = mapper.readValue(sessionTimeoutMapStr, typeRef); - } catch (Exception e) { - logger.error("Session Management:error when try to parse the sessionTimeoutMap from portal"); - return false; - } - - boolean result = true; - for (String jPortalSessionId : sessionTimeoutMap.keySet()) { - try { - PortalTimeoutVO extendedTimeoutVO = mapper.readValue( - mapper.writeValueAsString(sessionTimeoutMap.get(jPortalSessionId)), PortalTimeoutVO.class); - HttpSession session = sessionMap.get(jSessionKey(extendedTimeoutVO.getjSessionId(), jPortalSessionId)); - - if (session == null) { - continue; - } - - Long lastAccessedTimeMilliSec = session.getLastAccessedTime(); - Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L; - Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; - - Long maxTimeoutTimeMilliSec = extendedTimeoutVO.getSessionTimOutMilliSec(); - if (maxTimeoutTimeMilliSec > sessionTimOutMilliSec) { - session.setMaxInactiveInterval((int) (maxTimeoutTimeMilliSec - lastAccessedTimeMilliSec) / 1000); - logger.debug("Session Management: extended session for :" + session.getId() + " to :" - + (int) (maxTimeoutTimeMilliSec / 1000)); - // System.out.println("!!!!!!!!!extended session for :" + - // session.getId() + " to :" + - // (int)(maxTimeoutTimeMilliSec/1000)); - } - } catch (Exception e) { - logger.error("Session Management: error while updating the sessionTimeout" + e.getMessage()); - // Signal a problem if any one of them fails - result = false; - } - - } - return result; - } - - /** - * TODO: Remove static - * - * @param request - * @param userName - * @param pwd - * @param ecompRestURL - * @param _sessionComm - */ - public static void handleSessionUpdatesNative(HttpServletRequest request, String userName, String pwd, String uebKey, - String ecompRestURL, SessionCommInf _sessionComm) { - - if (_sessionComm == null) { - _sessionComm = sessionComm; - } - try { - synchronizeSessionForLastMinuteRequests(request, ecompRestURL, userName, pwd, uebKey, _sessionComm); - } catch (Exception e) { - logger.error(e); - } - resetSessionMaxIdleTimeOut(request); - } - - /** - * TODO: remove Static - * - * @param request - * @param ecompRestURL - * @param userName - * @param pwd - * @param _sessionComm - * @throws JsonProcessingException - * @throws Exception - */ - public static void synchronizeSessionForLastMinuteRequests(HttpServletRequest request, String ecompRestURL, - String userName, String pwd, String uebKey, SessionCommInf _sessionComm) throws JsonProcessingException, Exception { - - HttpSession session = request.getSession(false); - if (session == null) - return; - - Object portalSessionSlotCheckObj = session.getServletContext() - .getAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK); - Integer portalSessionSlotCheckinMilliSec = 5 * 60 * 1000; // (5 minutes) - if (portalSessionSlotCheckObj != null) { - portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString()); - } else { - portalSessionSlotCheckObj = _sessionComm - .fetchSessionSlotCheckInterval(new String[] { ecompRestURL, userName, pwd, uebKey }); - logger.debug("Fetching Portal Session Slot Object: " + portalSessionSlotCheckObj); - if (portalSessionSlotCheckObj != null) { - portalSessionSlotCheckinMilliSec = Integer.valueOf(portalSessionSlotCheckObj.toString()); - session.getServletContext().setAttribute(PortalApiConstants.PORTAL_SESSION_SLOT_CHECK, - portalSessionSlotCheckinMilliSec); - } - } - - Object previousToLastAccessTimeObj = session.getAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME); - final long lastAccessedTimeMilliSec = session.getLastAccessedTime(); - if (previousToLastAccessTimeObj == null) { - previousToLastAccessTimeObj = lastAccessedTimeMilliSec; - session.setAttribute(PortalApiConstants.SESSION_PREVIOUS_ACCESS_TIME, previousToLastAccessTimeObj); - } else { - Long previousToLastAccessTime = (Long) previousToLastAccessTimeObj; - final int maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000; - if (maxIntervalMilliSec - - (lastAccessedTimeMilliSec - previousToLastAccessTime) <= portalSessionSlotCheckinMilliSec) { - - String jSessionKey = (String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); - Map sessionTimeoutMap = new Hashtable(); - Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; - - sessionTimeoutMap.put(PortalTimeoutHandler.portalJSessionId(jSessionKey), - PortalTimeoutHandler.getSingleSessionTimeoutObj(jSessionKey, sessionTimOutMilliSec)); - String jsonMap = mapper.writeValueAsString(sessionTimeoutMap); - logger.debug("Extension requested for all the Apps and Portal; JessionKey: " + jSessionKey - + "; SessionMap: " + sessionTimeoutMap); - _sessionComm.extendSessionTimeOuts(new String[] { ecompRestURL, userName, pwd, uebKey, jsonMap }); - } - - } - } - - /** - * TODO: remove static - * - * @param request - */ - public static void resetSessionMaxIdleTimeOut(HttpServletRequest request) { - try { - HttpSession session = request.getSession(false); - if (session == null) - return; - - final Object maxIdleAttribute = session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME); - if (maxIdleAttribute != null) { - session.setMaxInactiveInterval(Integer.parseInt(maxIdleAttribute.toString())); - } - - } catch (Exception e) { - logger.error("Could not reset the session timeout", e); - } - - } - - /** - * - * @param jSessionKey - * @param sessionTimOutMilliSec - * @return - */ - private static PortalTimeoutVO getSingleSessionTimeoutObj(String jSessionKey, Long sessionTimOutMilliSec) { - return new PortalTimeoutVO(jSessionId(jSessionKey), sessionTimOutMilliSec); - } - - /** - * - * @param jSessionId - * @param portalJSessionId - * @return - */ - private static String jSessionKey(String jSessionId, String portalJSessionId) { - return portalJSessionId + "-" + jSessionId; - } - - /** - * - * @param jSessionKey - * @return - */ - private static String portalJSessionId(String jSessionKey) { - return jSessionKey.split("-")[0]; - } - - /** - * - * @param jSessionKey - * @return - */ - private static String jSessionId(String jSessionKey) { - return jSessionKey.split("-")[1]; - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutVO.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutVO.java deleted file mode 100644 index af6eab8a..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/PortalTimeoutVO.java +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -public class PortalTimeoutVO implements Comparable{ - - private String jSessionId; - private Long sessionTimOutMilliSec; - - public PortalTimeoutVO(){ - - } - - public PortalTimeoutVO(String _jSessionId, Long _sessionTimOutMilliSec) { - setjSessionId(_jSessionId); - setSessionTimOutMilliSec(_sessionTimOutMilliSec); - - } - - public String getjSessionId() { - return jSessionId; - } - - public void setjSessionId(String jSessionId) { - this.jSessionId = jSessionId; - } - - public Long getSessionTimOutMilliSec() { - return sessionTimOutMilliSec; - } - - public void setSessionTimOutMilliSec(Long sessionTimOutMilliSec) { - this.sessionTimOutMilliSec = sessionTimOutMilliSec; - } - - @Override - public int compareTo(PortalTimeoutVO o) { - return sessionTimOutMilliSec.compareTo(o.sessionTimOutMilliSec); - } - - - - - - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunication.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunication.java deleted file mode 100644 index 44178570..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/SessionCommunication.java +++ /dev/null @@ -1,161 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class SessionCommunication { - - protected static final Log logger = LogFactory.getLog(SessionCommunication.class); - - /** - * Calls the ECOMP Portal to retrieve the session slot check interval. - * - * @param ecompRestURL - * @param userName - * application user name used for authentication at Portal - * @param password - * application password used for authentication at Portal - * @param uebKey - * application UEB key (basically application ID) used for - * authentication at Portal - * @return Content read from the remote REST endpoint - */ - public static String getSessionSlotCheckInterval(String ecompRestURL, String userName, String password, - String uebKey) { - try { - String url = ecompRestURL + "/getSessionSlotCheckInterval"; - - URL obj = new URL(url); - - HttpURLConnection con = (HttpURLConnection) obj.openConnection(); - - // optional default is GET - con.setRequestMethod("GET"); - con.setConnectTimeout(3000); - con.setReadTimeout(8000); - // add request header - con.setRequestProperty("username", userName); - con.setRequestProperty("password", password); - con.setRequestProperty("uebkey", uebKey); - - int responseCode = con.getResponseCode(); - if (logger.isDebugEnabled()) { - logger.debug("getSessionSlotCheckInterval: Sending 'GET' request to URL : " + url); - logger.debug("getSessionSlotCheckInterval: Response Code : " + responseCode); - } - - StringBuffer response = new StringBuffer(); - - BufferedReader in = null; - try { - in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); - String inputLine; - while ((inputLine = in.readLine()) != null) - response.append(inputLine); - } finally { - in.close(); - } - return response.toString(); - } catch (Exception e) { - logger.error("getSessionSlotCheckInterval: failed to fetch the session slot check", e); - return null; - } - - } - - /** - * Calls the ECOMP Portal to request an extension of the current session. - * - * @param ecompRestURL - * @param userName - * application user name used for authentication at Portal - * @param password - * application password used for authentication at Portal - * @param uebKey - * application UEB key (basically application ID) used for - * authentication at Portal - * @param sessionTimeoutMap - * @return Content read from the remote REST endpoint - * @throws Exception - */ - public static String requestPortalSessionTimeoutExtension(String ecompRestURL, String userName, String password, - String uebKey, String sessionTimeoutMap) throws Exception { - - try { - - String url = ecompRestURL + "/extendSessionTimeOuts"; - // String decreptedPwd = - // app.appPassword;//CipherUtil.decrypt(encriptedPwdDB, - // SystemProperties.getProperty(SystemProperties.SECRET_KEY)); - - URL obj = new URL(url); - - HttpURLConnection con = (HttpURLConnection) obj.openConnection(); - - con.setRequestMethod("POST"); - con.setConnectTimeout(3000); - con.setReadTimeout(15000); - - // add request header - con.setRequestProperty("username", userName); - con.setRequestProperty("password", password); - con.setRequestProperty("uebkey", uebKey); - con.setRequestProperty("sessionMap", sessionTimeoutMap); - con.setDoInput(true); - con.setDoOutput(true); - con.getOutputStream().write(sessionTimeoutMap.getBytes()); - con.getOutputStream().flush(); - con.getOutputStream().close(); - - // con.set - - int responseCode = con.getResponseCode(); - if (logger.isDebugEnabled()) { - logger.debug("requestPortalSessionTimeoutExtension: Sending 'GET' request to URL : " + url); - logger.debug("requestPortalSessionTimeoutExtension: Response Code : " + responseCode); - } - - StringBuffer response = new StringBuffer(); - BufferedReader in = null; - try { - in = new BufferedReader(new InputStreamReader(con.getInputStream())); - String inputLine; - while ((inputLine = in.readLine()) != null) { - response.append(inputLine); - } - } finally { - in.close(); - } - return response.toString(); - } catch (Exception e) { - logger.error("requestPortalSessionTimeoutExtension: failed to request Portal to extend time out ", e); - return null; - } - - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserContextListener.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserContextListener.java deleted file mode 100644 index ea346f1e..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserContextListener.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import java.util.HashMap; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.annotation.WebListener; -import javax.servlet.http.HttpSession; - -@WebListener -public class UserContextListener implements ServletContextListener{ - - public void contextInitialized(ServletContextEvent event){ - ServletContext context = event.getServletContext(); - // - // instanciate a map to store references to all the active - // sessions and bind it to context scope. - // - HashMap activeUsers = new HashMap(); - context.setAttribute(PortalApiConstants.ACTIVE_USERS_NAME, activeUsers); - } - - /** - * Needed for the ServletContextListener interface. - */ - public void contextDestroyed(ServletContextEvent event){ - // To overcome the problem with losing the session references - // during server restarts, put code here to serialize the - // activeUsers HashMap. Then put code in the contextInitialized - // method that reads and reloads it if it exists... - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserSessionListener.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserSessionListener.java deleted file mode 100644 index b468851d..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/crossapi/UserSessionListener.java +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.crossapi; - -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.annotation.WebListener; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Listens to session-create and session-destroy events. - */ -@WebListener -public class UserSessionListener implements HttpSessionListener { - - private Log logger = LogFactory.getLog(getClass()); - - public static Map activeSessions = new Hashtable(); - - public void init(ServletConfig config) { - } - - /** - * Adds sessions to the context-scoped HashMap when they begin. - */ - public void sessionCreated(HttpSessionEvent event) { - HttpSession session = event.getSession(); - ServletContext context = session.getServletContext(); - @SuppressWarnings("unchecked") - HashMap activeUsers = (HashMap) context - .getAttribute(PortalApiConstants.ACTIVE_USERS_NAME); - if (activeUsers != null) - activeUsers.put(session.getId(), session); - context.setAttribute(PortalApiConstants.ACTIVE_USERS_NAME, activeUsers); - activeSessions.put(session.getId(), session); - session.getServletContext().setAttribute(PortalApiConstants.MAX_IDLE_TIME, session.getMaxInactiveInterval()); - } - - /** - * Removes sessions from the context-scoped HashMap when they expire or are - * invalidated. - */ - public void sessionDestroyed(HttpSessionEvent event) { - try { - HttpSession session = event.getSession(); - ServletContext context = session.getServletContext(); - @SuppressWarnings("unchecked") - HashMap activeUsers = (HashMap) context - .getAttribute(PortalApiConstants.ACTIVE_USERS_NAME); - if (activeUsers != null) - activeUsers.remove(session.getId()); - activeSessions.remove(session.getId()); - PortalTimeoutHandler.sessionDestroyed(session); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java deleted file mode 100644 index 9dce0221..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FavoritesClient.java +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.rest; - -/** - * Provides a convenience method for fetching the favorites for a user from the - * ECOMP Portal. - */ -public class FavoritesClient { - - /** - * Fetches the favorites data from portal - * - * @param userId - * userId value that it should be using to fetch the - * data - * @param appName - * Application name for logging etc. - * @param requestId - * 128-bit UUID value to uniquely identify the transaction; if null, a new one is generated. - * @param appUserName - * REST API user-name - * @param appPassword - * REST API decrypted password - * @return JSON with favorites - * @throws Exception - * on any failure - */ - public static String getFavorites(String userId, String appName, String requestId, String appUserName, - String appPassword) throws Exception { - return RestWebServiceClient.getInstance().getPortalContent("/getFavorites", userId, appName, requestId, appUserName, - appPassword); - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java deleted file mode 100644 index 8e12b33b..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/FunctionalMenuClient.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.rest; - -/** - * Provides a convenience method for fetching the functional menu for a user - * from the ECOMP Portal via UEB. - */ -public class FunctionalMenuClient { - - /** - * Fetches the functional menu data from the configured ECOMP Portal - * instance. - * - * @param userId - * userId for the user to whom the menu will be shown - * @param appName - * Application name for logging etc. - * @param requestId - * 128-bit UUID value to uniquely identify the transaction; if - * null, a new one is generated. - * @param appUserName - * REST API user name, used by Portal to authenticate the request - * @param appPassword - * REST API password (in the clear, not encrypted), used by - * Portal to authenticate the request - * @return JSON with functional menu - * @throws Exception - * on any failure - */ - public static String getFunctionalMenu(String userId, String appName, String requestId, String appUserName, - String appPassword) throws Exception { - return RestWebServiceClient.getInstance().getPortalContent("/functionalMenuItemsForUser", userId, appName, - requestId, appUserName, appPassword); - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java deleted file mode 100644 index fc5ce872..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/rest/RestWebServiceClient.java +++ /dev/null @@ -1,178 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.rest; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.UUID; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; - -public class RestWebServiceClient { - - private final Log logger = LogFactory.getLog(RestWebServiceClient.class); - - /** - * Singleton instance - */ - private static RestWebServiceClient instance = null; - - /** - * Constructor is private. Clients should obtain an instance via - * getInstance(). - */ - private RestWebServiceClient() { - } - - /** - * Gets the static instance of RestWebServiceClient; creates it if - * necessary. Synchronized to be thread safe. - * - * @return Static instance of RestWebServiceClient. - */ - public static synchronized RestWebServiceClient getInstance() { - if (instance == null) - instance = new RestWebServiceClient(); - return instance; - } - - /** - * Convenience method that fetches the URL for the Portal REST API endpoint - * and the application UEB key, then calls - * {@link #get(String, String, String, String, String, String, String)} to - * access the Portal's REST endpoint. - * - * @param restPath - * Partial path of the endpoint; e.g., "/specialRestService" - * @param userId - * userId for the user originating the request - * @param appName - * Application Name for logging. - * @param requestId - * 128-bit UUID value to uniquely identify the transaction. - * @param appUserName - * REST API user name for Portal to authenticate the request - * @param appPassword - * REST API password (in the clear, not encrypted) for Portal to - * authenticate the request - * @return Content from REST endpoint - * @throws Exception - * on any failure - */ - public String getPortalContent(String restPath, String userId, String appName, String requestId, String appUserName, - String appPassword) throws Exception { - String restURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL); - if (restURL == null) { - // should never happen - String msg = "getPortalContent: failed to get property " + PortalApiConstants.ECOMP_REST_URL; - logger.error(msg); - throw new Exception(msg); - } - String appUebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); - if (appUebKey == null) { - // should never happen - String msg = "getPortalContent: failed to get property " + PortalApiConstants.UEB_APP_KEY; - logger.error(msg); - throw new Exception(msg); - } - final String restEndpointUrl = restURL + restPath; - return get(restEndpointUrl, userId, appName, requestId, appUebKey, appUserName, appPassword); - } - - /** - * Makes a call to a Portal REST API using the specified URL and parameters. - * - * @param url - * Complete URL of the REST endpoint. - * @param loginId - * User that it should be fetching the data - * @param appName - * Application name for logging; if null or empty, defaulted to - * Unknown. - * @param requestId - * 128-bit UUID value to uniquely identify the transaction; if - * null or empty, one is generated. - * @param appUebKey - * Unique key for the application, used by Portal to authenticate - * the request - * @param appUserName - * REST API user name, used by Portal to authenticate the request - * @param appPassword - * REST API password, used by Portal to authenticate the request - * @return Content from REST endpoint - * @throws Exception - * On any failure; e.g., unknown host. - */ - public String get(String url, String loginId, String appName, String requestId, String appUebKey, - String appUserName, String appPassword) throws Exception { - - logger.debug("RestWebServiceClient.get (" + url + ") operation is started."); - if (appName == null || appName.trim().length() == 0) - appName = "Unknown"; - if (requestId == null || requestId.trim().length() == 0) - requestId = UUID.randomUUID().toString(); - - URL obj = new URL(url); - // Create the connection object - HttpURLConnection con = (HttpURLConnection) obj.openConnection(); - con.setRequestMethod("GET"); - con.setConnectTimeout(3000); - con.setReadTimeout(8000); - - // add request header - con.setRequestProperty("uebkey", appUebKey); - con.setRequestProperty("username", appUserName); - con.setRequestProperty("password", appPassword); - con.setRequestProperty("LoginId", loginId); - con.setRequestProperty("user-agent", appName); - con.setRequestProperty("X-ECOMP-RequestID", requestId); - - int responseCode = con.getResponseCode(); - logger.debug("get: received response code '" + responseCode + "' while getting the '" + url + "' for user: " - + loginId); - - StringBuffer sb = new StringBuffer(); - BufferedReader in = null; - try { - in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); - String inputLine = null; - while ((inputLine = in.readLine()) != null) - sb.append(inputLine); - } finally { - try { - if (in != null) - in.close(); - } catch (IOException ex) { - logger.error("get: failed to close reader", ex); - } - } - - final String response = sb.toString(); - if (logger.isDebugEnabled()) - logger.debug("get: url " + url + " yielded " + response); - return response; - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java deleted file mode 100644 index bb152294..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Consumer.java +++ /dev/null @@ -1,164 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.util.LinkedList; -import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedQueue; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; - -import com.att.nsa.cambria.client.CambriaClientBuilders; -import com.att.nsa.cambria.client.CambriaClientFactory; -import com.att.nsa.cambria.client.CambriaConsumer; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * Provides a consumer that reads messages from a UEB topic. Intended to be - * passed to a separate thread as its runnable object. - * - */ -public class Consumer implements Runnable { - - private final Log logger = LogFactory.getLog(getClass()); - - private final LinkedList urlList = Helper.uebUrlList(); - private final ConcurrentLinkedQueue queue; - private final WaitingRequestersQueueList waitingRequestersList; - private final String consumerKey, consumerSecret, topicName, consumerGroupName; - - /** - * Accepts coordinates needed to subscribe to a UEB topic, as well as the - * queues for passing along messages that arrive. - * - * @param consumerKey - * UEB key used to subscribe to the topic - * @param consumerSecret - * UEB secret used to subscribe to the topic - * @param topicName - * UEB topic name - * @param queue - * Queue to receive UEB messages. All inbound messages are - * enqueued here; ignored if null. - * @param waitingRequestersList - * Collection of queues to receive UEB messages that arrive in - * response to requests; i.e., emulating a synchronous request - * via pub/sub. - */ - public Consumer(String consumerKey, String consumerSecret, String topicName, String consumerGroupName, - ConcurrentLinkedQueue queue, WaitingRequestersQueueList waitingRequestersList) { - this.consumerKey = consumerKey; - this.consumerSecret = consumerSecret; - this.topicName = topicName; - this.consumerGroupName = consumerGroupName; - this.queue = queue; - this.waitingRequestersList = waitingRequestersList; - } - - /** - * Subscribes to a topic using credentials as supplied to the constructor. - * Distributes messages appropriately as they arrive: - *
          - *
        • If the queue is not null, adds the message to the queue. - *
        • If the message's getMsgId() method returns non-null and the ID is - * found in the collection of waiting requesters, adds the message in that - * requester's queue. - *
        - * - * This is intended to be called in a long running thread as a listener for - * any published messages on a topic. Typical async pub/sub model. We use a - * filter of "0" to prevent collisions with P2P messages with unique filter - * ids. - */ - protected void consume() throws IOException, UebException { - final String id = UUID.randomUUID().toString(); - - CambriaConsumer cc = null; - try { - cc = new CambriaClientBuilders.ConsumerBuilder() - .usingHosts(urlList) - .authenticatedBy(consumerKey, consumerSecret) - .onTopic (topicName) - .knownAs (consumerGroupName,id) - .waitAtServer (15*1000) - .receivingAtMost (1000) - .build(); - } catch (GeneralSecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - //CambriaClientFactory.createConsumer(urlList, topicName, consumerGroupName, id, - //15 * 1000, 1000, null, consumerKey, consumerSecret); - - while (true) { - for (String msg : cc.fetch()) { - logger.debug(" <== consume from topicName " + topicName + " msg: " + msg); - UebMsg uebMsg = new ObjectMapper().readValue(msg, UebMsg.class); - if (queue != null) { - // Add to general queue allowing listeners to act on any - // incoming messages. We don't know if a listener is - // also going to be a responder to a synchronous - // request. So put all received messages on the general - // listener queue. - queue.add(uebMsg); - if (logger.isDebugEnabled()) - logger.debug("Added msg to queue " + this.queue + " queue count = " + queue.size() + " msg :" - + uebMsg.getPayload()); - } - if (waitingRequestersList != null && uebMsg.getMsgId() != null) { - // If a msgId is present, this could be a synchronous - // reply. Here we add it to the waiting requester's - // queue if we find a requester waiting for this msgId. - if (!(uebMsg.getMsgId() - .equals(PortalApiProperties.getProperty(PortalApiConstants.ECOMP_DEFAULT_MSG_ID)))) { - waitingRequestersList.addMsg(uebMsg.getMsgId(), uebMsg); - } - } - } - if (Thread.interrupted()) { - logger.warn(Thread.currentThread() + " interrupted, exiting"); - break; - } - Helper.sleep(10); - } - - } - - /* - * (non-Javadoc) - * - * @see java.lang.Runnable#run() - */ - @Override - public void run() { - try { - consume(); - } catch (Exception ex) { - Thread t = Thread.currentThread(); - t.getUncaughtExceptionHandler().uncaughtException(t, ex); - } - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java deleted file mode 100644 index 94ca4ee8..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/FunctionalMenu.java +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Provides a convenience method for fetching the functional menu for a user - * from the ECOMP Portal via UEB. - */ -public class FunctionalMenu { - - private static final Log logger = LogFactory.getLog(FunctionalMenu.class); - - /** - * Makes a synchronous call to ECOMP Portal to get JSON with the functional - * menu, which arrives as the payload of the returned UEB message. - * - * @param userId - * User ID as known on the ECOMP Portal for customizing the - * functional menu appropriately - * @return JSON with functional menu - * @throws UebException - */ - public static String get(String userId) throws UebException { - String returnString = null; - logger.info("Making use of UEB communication and Requesting functional menu for user " + userId); - UebMsg funcMenuUebMsg = null; - UebMsg msg = new UebMsg(); - msg.putMsgType(UebMsgTypes.UEB_MSG_TYPE_GET_FUNC_MENU); - msg.putUserId(userId); - funcMenuUebMsg = UebManager.getInstance().requestReply(msg); - if (funcMenuUebMsg != null) { - if (funcMenuUebMsg.getPayload().startsWith("Error:")) { - logger.error("getFunctionalMenu received an error in UEB msg = " + funcMenuUebMsg.getPayload()); - } else { - returnString = funcMenuUebMsg.getPayload(); - } - } - return returnString; - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java deleted file mode 100644 index ce942341..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Helper.java +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -import java.util.LinkedList; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; - -/** - * Provides utility methods. - */ -public class Helper { - - private static final Log logger = LogFactory.getLog(Helper.class); - - /** - * Parses a comma-separated list of UEB servers from properties file into a - * list. - * - * @return List of UEB server names - */ - public static LinkedList uebUrlList() { - LinkedList urlList = null; - String url = PortalApiProperties.getProperty(PortalApiConstants.UEB_URL_LIST); - if (url == null) { - logger.error("uebUrlList: failed to get property " + PortalApiConstants.UEB_URL_LIST); - return null; - } - urlList = new LinkedList(); - for (String u : url.split(",")) { - urlList.add(u.trim()); - } - return urlList; - } - - public static void sleep(int milliseconds) { - try { - Thread.sleep(milliseconds); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java deleted file mode 100644 index a7e914c2..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/Publisher.java +++ /dev/null @@ -1,124 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.security.GeneralSecurityException; -import java.util.LinkedList; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; - -import com.att.nsa.cambria.client.CambriaBatchingPublisher; -import com.att.nsa.cambria.client.CambriaClientBuilders; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; - -/** - * Provides a publisher that sends messages to a UEB topic. - * - */ -public class Publisher { - - private final Log logger = LogFactory.getLog(getClass()); - - protected final LinkedList urlList = Helper.uebUrlList(); - - private final String topicName; - private final String publisherKey; - private final String publisherSecret; - - /** - * Accepts coordinates needed to publish to a UEB topic. - * - * @param publisherKey - * UEB key used to publish to the topic - * @param publisherSecret - * UEB secret used to publish to the topic - * @param topicName - * UEB topic name - */ - public Publisher(String publisherKey, String publisherSecret, String topicName) { - this.publisherKey = publisherKey; - this.publisherSecret = publisherSecret; - this.topicName = topicName; - logger.info("Publisher instantiated for topic " + topicName); - } - - /** - * Creates a publisher, subscribes to the topic, sends the specified message - * to the topic, then closes the publisher. This ensures that the single - * message goes immediately. UEB is designed for high throughput and tries - * to batch up multiple messages in each send, but this method wants the - * single message to go immediately. - * - * @param uebMsg - * Message object to send as the payload. - * @throws UebException - * If anything goes wrong, including JSON serialization of the - * specified message object. - */ - public void send(UebMsg uebMsg) throws UebException { - String msg = null; - - CambriaBatchingPublisher pub = null; - try { - pub = new CambriaClientBuilders.PublisherBuilder() - .authenticatedBy(publisherKey, publisherSecret).usingHosts(urlList).onTopic(topicName).build(); - } catch (MalformedURLException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } catch (GeneralSecurityException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - try { - ObjectWriter mapper = new ObjectMapper().writer().withDefaultPrettyPrinter(); - msg = mapper.writeValueAsString(uebMsg); - } catch (JsonProcessingException e) { - throw new UebException(PortalApiConstants.ECOMP_UEB_INVALID_MSG, topicName, null, null); - } - - try { - logger.debug("Publishing to " + topicName + " msg: " + msg); - int NumSent = pub.send(PortalApiConstants.ECOMP_GENERAL_UEB_PARTITION, msg); - if (NumSent == 0) { - throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, topicName, null, msg); - } - } catch (IOException ex) { - logger.error("Failed to publish", ex); - throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, ex, topicName, null, msg); - } - - try { - // close the publisher to make sure everything's sent before exiting - pub.close(5, TimeUnit.SECONDS); - } catch (Exception ex) { - logger.error("pub.close Exception ", ex); - throw new UebException(PortalApiConstants.ECOMP_UEB_UNKNOWN_PUBLISH_ERROR, ex, topicName, null, msg); - } - - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java deleted file mode 100644 index a3a00782..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/PublisherList.java +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * A thin wrapper around ConcurrentHashMap that stores a queue for each - * Requester that is waiting for a Reply. When a reply is received that has a - * matching msgId, that requesters queue is populated with the reply message. - * - * Primarily for Portal core to track the remote applications that have placed - * requests; never used by those applications. - */ -public class PublisherList { - - private final Log logger = LogFactory.getLog(getClass()); - - private final Map map; - - public PublisherList() { - map = new ConcurrentHashMap<>(); - } - - public void addPublisherToMap(String topicName, Publisher publisher) { - if (this.map.containsKey(topicName)) { - logger.error("Publisher already exists for " + topicName); - } else { - this.map.put(topicName, publisher); - } - } - - public Publisher getPublisher(String topicName) { - return this.map.get(topicName); - } - - public void removePublisherFromMap(String topicName) { - this.map.remove(topicName); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("Map contains " + this.map.size() + " Publishers."); - for (Map.Entry entry : this.map.entrySet()) { - String key = entry.getKey().toString(); - Publisher pub = entry.getValue(); - sb.append("Entry msgId, " + key + " publisher" + pub); - } - return sb.toString(); - } - - public int size() { - return this.map.size(); - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java deleted file mode 100644 index b9d730eb..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/TopicManager.java +++ /dev/null @@ -1,121 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.util.LinkedList; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.att.nsa.apiClient.http.HttpException; -import com.att.nsa.cambria.client.CambriaClient.CambriaApiException; -import com.att.nsa.cambria.client.CambriaClientBuilders; -import com.att.nsa.cambria.client.CambriaClientFactory; -import com.att.nsa.cambria.client.CambriaTopicManager; - -/** - * Provides methods to facilitate creating topics, and adding publishers and - * subscribers to existing topics. - * - */ -public class TopicManager { - - private final Log logger = LogFactory.getLog(getClass()); - - /** - * Creates a topic with the specified information. - * - * @param key - * Topic key - * @param secret - * Topic secret key - * @param topicName - * Topic name - * @param topicDescription - * Topic description - * @throws HttpException - * @throws CambriaApiException - * @throws IOException - */ - public void createTopic(String key, String secret, String topicName, String topicDescription) - throws HttpException, CambriaApiException, IOException { - final LinkedList urlList = Helper.uebUrlList(); - if (logger.isInfoEnabled()) { - logger.info("==> createTopic"); - logger.info("topicName: " + topicName); - logger.info("topicDescription: " + topicDescription); - } - final CambriaTopicManager tm = null; //to do for open source - //CambriaClientFactory.createTopicManager(urlList, key, secret); - tm.createTopic(topicName, topicDescription, 1, 1); - } - - /** - * Modifies the specified topic to accept a subscriber using the specified - * key. - * - * @param topicOwnerKey - * @param topicOwnerSecret - * @param subscriberKey - * @param topicName - * @throws HttpException - * @throws CambriaApiException - * @throws IOException - */ - public void addSubscriber(String topicOwnerKey, String topicOwnerSecret, String subscriberKey, String topicName) - throws HttpException, CambriaApiException, IOException { - logger.info("==> addSubscriber to topic " + topicName); - final LinkedList urlList = Helper.uebUrlList(); - CambriaTopicManager tm = null; - try { - tm = new CambriaClientBuilders.TopicManagerBuilder().usingHosts(urlList).authenticatedBy(topicOwnerKey, topicOwnerSecret).build(); - } catch (GeneralSecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - //old version num : CambriaClientFactory.createTopicManager(urlList, topicOwnerKey,topicOwnerSecret); - tm.allowConsumer(topicName, subscriberKey); - } - - /** - * Modifies the specified topic to accept a publisher using the specified - * key. - * - * @param topicOwnerKey - * @param topicOwnerSecret - * @param publisherKey - * @param topicName - * @throws HttpException - * @throws CambriaApiException - * @throws IOException - */ - - public void addPublisher(String topicOwnerKey, String topicOwnerSecret, String publisherKey, String topicName) - throws HttpException, CambriaApiException, IOException { - logger.info("==> addPublisher to topic " + topicName); - final LinkedList urlList = Helper.uebUrlList(); - final CambriaTopicManager tm = null; - //CambriaClientFactory.createTopicManager(urlList, topicOwnerKey, - //topicOwnerSecret); - tm.allowProducer(topicName, publisherKey); - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java deleted file mode 100644 index 62a80dd4..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebException.java +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -/** - * Stores UEB-specific information including topic, message ID and message body. - */ -public class UebException extends Exception { - - private static final long serialVersionUID = 1L; - private String topicName = null; - private String msgId = null; - private String msg = null; - - public UebException(String errorMsg, String topicName, String msgId, String msg) { - super(errorMsg); - this.topicName = topicName; - this.msgId = msgId; - this.msg = msg; - } - - public UebException(String errorMsg, Throwable ex, String topicName, String msgId, String msg) { - super(errorMsg, ex); - this.topicName = topicName; - this.msgId = msgId; - this.msg = msg; - } - - public UebException(String msg, Throwable ex) { - super(msg, ex); - } - - public UebException(Throwable ex) { - super(ex); - } - - public String getUebMsg() { - return this.msg; - } - - public String getTopicName() { - return this.topicName; - } - - public String getMsgId() { - return this.msgId; - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java deleted file mode 100644 index b38bcb79..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebManager.java +++ /dev/null @@ -1,358 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -import java.io.IOException; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.LinkedBlockingQueue; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; - -/** - * Manages UEB interactions and provides methods for publishing requests, - * replies and others. - */ -public class UebManager { - - private final Log logger = LogFactory.getLog(getClass()); - - private WaitingRequestersQueueList waitingRequestersQueueList; - private PublisherList publisherList = new PublisherList(); - private static UebManager uebManager = null; - - private final String inTopicName; - private final String consumerGroupName; - private final String outTopicName; - private final String appUebKey; - private final String appUebSecret; - - private Publisher appPublisher; - private Thread listenerThread; - private boolean bThisIsEcompPortalServer = false; - - /** - * Constructor initializes fields and validates values obtained from - * properties. - * - * The picture below is a simplified view of the relationships among ECOMP - * Portal and applications communicating via UEB: - * - *
        -	*                      ECOMP out to many.
        -	*                      App out to only ECOMP.
        -	*
        -	*  |----------------|<---------------------------------------------   
        -	*  |                |                                         | |  |
        -	*  |                |---------------------------> App 1 ------  |  |
        -	*  |  ECOMP Portal  |---------------------------> App 2 ---------  |
        -	*  |                |                            ...               |
        -	*  |                |---------------------------> App n -----------
        -	*  |----------------|
        -	 * 
        - * - * @throws IOException - */ - protected UebManager() throws UebException { - waitingRequestersQueueList = null; - listenerThread = null; - outTopicName = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_PORTAL_INBOX_NAME); - inTopicName = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME); - appUebKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY); - appUebSecret = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_SECRET); - String consGrp = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_CONSUMER_GROUP_NAME); - - if (outTopicName == null || outTopicName.length() == 0) - throw new UebException("Failed to get property " + PortalApiConstants.ECOMP_PORTAL_INBOX_NAME, null, null, - null); - if (inTopicName == null || inTopicName.length() == 0) - throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME, null, - null, null); - if (consGrp == null || consGrp.length() == 0) - throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_CONSUMER_GROUP_NAME, null, - null, null); - if (appUebKey == null || appUebKey.length() == 0) - throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_KEY, null, null, null); - if (appUebSecret == null || appUebSecret.length() == 0) - throw new UebException("Failed to get property " + PortalApiConstants.UEB_APP_SECRET, null, null, null); - List uebUrlList = Helper.uebUrlList(); - if (uebUrlList == null || uebUrlList.size() == 0) - throw new UebException("Failed to get property" + PortalApiConstants.UEB_URL_LIST, null, null, null); - // A bit of magic: if consumer group is a magic token, generate one. - consumerGroupName = (PortalApiConstants.UEB_APP_CONSUMER_GROUP_NAME_GENERATOR.equals(consGrp) - ? UUID.randomUUID().toString() : consGrp); - } - - /** - * Gets the static instance, creating it if necessary. - * - * @return Instance of UebManager - * @throws IOException - */ - public static synchronized UebManager getInstance() throws UebException { - if (uebManager == null) { - uebManager = new UebManager(); - } - return uebManager; - } - - /** - * Answers whether the getInstance() method has previously been called. - * - * @return True if a static instance is available, else false. - */ - public static boolean isInstanceAvailable() { - return uebManager != null; - } - - /** - * Creates a list of waiting requesters, creates and a consumer using cached - * information, and starts a new thread to run the consumer that listens for - * messages published to the inbound topic configured in the constructor. - * - * @param inboxQueue - * Queue supplied to the consumer. If not null, the consumer will - * enqueue every message it receives. - */ - public void initListener(ConcurrentLinkedQueue inboxQueue) throws UebException { - waitingRequestersQueueList = new WaitingRequestersQueueList(); - Consumer runnable = new Consumer(appUebKey, appUebSecret, inTopicName, consumerGroupName, inboxQueue, - waitingRequestersQueueList); - this.listenerThread = new Thread(runnable, "UEBConsumerThread"); - this.listenerThread.start(); - Helper.sleep(400); // UEB functions more reliably when we give this some - // time - - logger.info("UEBManager instance starting... " + inTopicName + " listener thread " - + this.listenerThread.getName() + " state = " + this.listenerThread.getState()); - - /* - * ECOMP Portal manages a dynamic list of outbound topics and so the - * outTopicName is initialized in this logic with the same value as the - * inbound topic. The real outbound topics name will be added to the - * publisher list for ECOMP Portal. For an SDK/App instance only one - * publisher is needed, appPublisher. - */ - if (inTopicName.equalsIgnoreCase(outTopicName)) { - this.bThisIsEcompPortalServer = true; - } else { - appPublisher = new Publisher(appUebKey, appUebSecret, outTopicName); - Helper.sleep(400); - } - } - - /** - * Creates and adds a publisher to the list for the specified topic. This - * should only be called by the ECOMP Portal App, other Apps have just one - * publisher and use appPublisher - * - * @param topicName - */ - public void addPublisher(String topicName) { - logger.info("UEBManager adding publisher for " + topicName); - Publisher outBoxToAppPublisher = new Publisher(appUebKey, appUebSecret, topicName); - publisherList.addPublisherToMap(topicName, outBoxToAppPublisher); - } - - /** - * Removes a publisher from the list for the specified topic. - * - * This should only be called by the ECOMP Portal App, other Apps have just - * one publisher and use appPublisher - * - * @param topicName - */ - public void removePublisher(String topicName) { - logger.info("UEBManager removing publisher for " + topicName); - publisherList.removePublisherFromMap(topicName); - } - - /** - * Adds the default ECOMP message ID to the message and sends the message to - * the topic. - * - * @param msg - * @throws UebException - */ - public void publish(UebMsg msg) throws UebException { - msg.putMsgId(PortalApiConstants.ECOMP_DEFAULT_MSG_ID); - appPublisher.send(msg); - } - - /** - * Sends the message using the default publisher. - * - * @param msg - * @throws UebException - */ - public void publishReply(UebMsg msg) throws UebException { - // Caller populates msgId with the echoed value from the request - appPublisher.send(msg); - } - - /** - * Sends the message using the appropriate publisher for the specified - * topic. - * - * @param msg - * @param topicName - * @throws UebException - */ - public void publishEP(UebMsg msg, String topicName) throws UebException { - Publisher publisher = publisherList.getPublisher(topicName); - if (publisher != null) { - msg.putMsgId(PortalApiConstants.ECOMP_DEFAULT_MSG_ID); - publisher.send(msg); - } - } - - /** - * Publishes a reply using the appropriate publisher for the specified - * topic. - * - * @param msg - * @param topicName - * @throws UebException - */ - public void publishReplyEP(UebMsg msg, String topicName) throws UebException { - // Caller populates msgId with the echoed value from the request - Publisher publisher = publisherList.getPublisher(topicName); - if (publisher != null) { - publisher.send(msg); - } - } - - /** - * Sends the specified message using the specified publisher, and waits for - * a reply. Retransmits if no reply is received in 5 seconds; gives up after - * 3 retries. - * - * @param msg - * @param publisher - * @return Message from a remote publisher, or null if timeout happens. - * @throws UebException - */ - public UebMsg requestReplyUsingPublisher(UebMsg msg, Publisher publisher) throws UebException { - UebMsg reply = null; - if (waitingRequestersQueueList == null) { - logger.error("requestReplyUsingPublisher called but listener thread not initialized"); - } else { - // Storing a non-default message ID identifies this as a synchronous - // request - msg.putMsgId(UUID.randomUUID().toString()); - - /* - * Create a queue for this request, the consumer thread will insert - * the reply on this queue - */ - LinkedBlockingQueue replyQueue = new LinkedBlockingQueue(); - waitingRequestersQueueList.addQueueToMap(msg.getMsgId(), replyQueue); - - /* - * Send the request - */ - publisher.send(msg); - - /* - * Wait for reply up to 3 * 5 = 15 seconds - */ - int reTransmits = 0; - int maxRetransmits = 3; - int retransmitTimeMs = 5000; - long sendTimeStamp = System.currentTimeMillis(); - while (reTransmits < maxRetransmits) { - if ((reply = replyQueue.poll()) != null) - break; - - long now = System.currentTimeMillis(); - if (now - sendTimeStamp > retransmitTimeMs) { - logger.debug("Retransmitting send... msg = " + msg.getPayload() + msg.getMsgId()); - publisher.send(msg); - sendTimeStamp = System.currentTimeMillis(); - reTransmits++; - } - } - waitingRequestersQueueList.removeQueueFromMap(msg.getMsgId()); - if (reTransmits == maxRetransmits) - throw new UebException(PortalApiConstants.ECOMP_UEB_TIMEOUT_ERROR, inTopicName, null, msg.toString()); - - } - return reply; - } - - /** - * Sends the specified message using the default publisher and waits for a - * reply. - * - * @param msg - * @return Message from a remote publisher, or null if timeout happens. - * @throws UebException - */ - public UebMsg requestReply(UebMsg msg) throws UebException { - return requestReplyUsingPublisher(msg, appPublisher); - } - - /** - * Sends the specified message using the publisher appropriate for the - * specified topic name, and waits for a reply. - * - * @param msg - * @param topicName - * @return Message from a remote publisher, or null if timeout happens. - * @throws UebException - */ - public UebMsg requestReplyEP(UebMsg msg, String topicName) throws UebException { - UebMsg returnMsg = null; - Publisher publisher = publisherList.getPublisher(topicName); - if (publisher != null) { - returnMsg = requestReplyUsingPublisher(msg, publisher); - } - return returnMsg; - } - - /** - * Publishes the payload as a UEB widget-notification message on the default - * publisher. Intended for use by Apps inter widget communication, not EP - * itself. - * - * @param payload - * @param userId - */ - public void postWidgetNotification(String payload, String userId) throws UebException { - UebMsg msg = new UebMsg(); - msg.putPayload(payload); - msg.putUserId(userId); - msg.putMsgType(UebMsgTypes.UEB_MSG_TYPE_WIDGET_NOTIFICATION); - this.publish(msg); - } - - /** - * Interrupts the long-running thread that runs the consumer. - */ - public void shutdown() { - if (this.listenerThread != null) { - this.listenerThread.interrupt(); - } - } -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java deleted file mode 100644 index ff30840c..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsg.java +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiConstants; -import org.openecomp.portalsdk.core.onboarding.crossapi.PortalApiProperties; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class UebMsg { - - private final Log logger = LogFactory.getLog(getClass()); - - private String version; - private String msgId; - private long timeStamp; - private String payload; - private String msgType; - private String userId; - private String sourceTopicName; - private String sourceIP; - private String sourceHostName; - - /** - * Creates a new object and populates the fields source IP, source topic, - * time stamp, version, and message id. - */ - public UebMsg() { - InetAddress ip; - try { - ip = InetAddress.getLocalHost(); - // Do not attempt to get name, why wait on DNS every time? - // sourceHostName = ip.getHostName(); - sourceIP = ip.getHostAddress(); - } catch (UnknownHostException e) { - sourceHostName = "unknown"; - sourceIP = "unknown"; - } - - this.timeStamp = System.currentTimeMillis(); - this.version = "1.0"; - this.msgId = PortalApiConstants.ECOMP_DEFAULT_MSG_ID; - this.payload = "empty payload content"; - this.sourceTopicName = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME); - if (this.sourceTopicName == null) - logger.error("Failed to get property " + PortalApiConstants.UEB_APP_INBOUND_MAILBOX_NAME); - } - - public void putMsgId(String msgId) { - this.msgId = msgId; - } - - public String getMsgId() { - return msgId; - } - - public void putPayload(String payload) { - this.payload = payload; - } - - public String getPayload() { - return payload; - } - - public void putMsgType(String msgType) { - this.msgType = msgType; - } - - public String getMsgType() { - return this.msgType; - } - - public void putUserId(String userId) { - this.userId = userId; - } - - public String getUserId() { - return this.userId; - } - - public void putSourceTopicName(String topic) { - this.sourceTopicName = topic; - } - - public String getSourceTopicName() { - return this.sourceTopicName; - } - - @Override - public String toString() { - return "UebMsg [version=" + version + ", msgId=" + msgId + ", timeStamp=" + timeStamp + ", msgType=" + msgType - + ", userId=" + userId + ", sourceTopicName=" + sourceTopicName + ", sourceIP=" + sourceIP - + ", sourceHostName=" + sourceHostName + "]" + System.lineSeparator() + "payload=" + payload; - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java deleted file mode 100644 index 9e51fe5c..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/UebMsgTypes.java +++ /dev/null @@ -1,28 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -/** - * Publishes constants used in the UEB package. - */ -public interface UebMsgTypes { - public static final String UEB_MSG_TYPE_GET_FUNC_MENU = "uebMsgTypeGetFuncMenu"; - public static final String UEB_MSG_TYPE_WIDGET_NOTIFICATION = "uebMsgTypeWidgetNotification"; -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java deleted file mode 100644 index d4063606..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/onboarding/ueb/WaitingRequestersQueueList.java +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.onboarding.ueb; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.LinkedBlockingQueue; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * A thin wrapper around ConcurrentHashMap that stores a queue for each - * Requester that is waiting for a Reply. When a reply is received that has a - * matching msgId, that requesters queue is populated with the reply message. - * - * Primarily for the UebManager to track requests while it waits for responses. - */ -public class WaitingRequestersQueueList { - private final Log logger = LogFactory.getLog(getClass()); - - private final Map> map; - - public WaitingRequestersQueueList() { - map = new ConcurrentHashMap<>(); - } - - public void addQueueToMap(String msgId, LinkedBlockingQueue queue) { - this.map.put(msgId, queue); - } - - public void addMsg(String msgId, UebMsg message) { - LinkedBlockingQueue queue = this.map.get(msgId); - if (queue != null) { - queue.add(message); - } else { - logger.warn("Did not find entry in WaitingRequestersQueueList for msgId " + msgId); - } - } - - public void removeQueueFromMap(String msgId) { - this.map.remove(msgId); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("Map contains " + this.map.size() + " Publishers."); - for (Map.Entry> entry : this.map.entrySet()) { - String key = entry.getKey().toString(); - LinkedBlockingQueue queue = entry.getValue(); - sb.append("Entry msgId, " + key + " queue " + queue); - } - return sb.toString(); - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java deleted file mode 100644 index a65d16f5..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompRole.java +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.restful.domain; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -/** - * This bean holds the information for a role in the role and user management - * REST API. - */ - -@JsonIgnoreProperties(ignoreUnknown = true) -public class EcompRole implements Comparable{ - - protected Long id; - private String name; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - EcompRole other = (EcompRole) obj; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - return true; - } - - @Override - public String toString() { - String s = "@EcompRole[id: " + id + "; name: " + name + "]"; - return s; - } - - @Override - public int compareTo(EcompRole o) { - return this.id.compareTo(o.id); - } - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java deleted file mode 100644 index 732878e1..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/EcompUser.java +++ /dev/null @@ -1,197 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.restful.domain; - -import java.util.Set; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -/** - * This bean holds the information for a user in the role and user management - * REST API. - */ - -@JsonIgnoreProperties(ignoreUnknown = true) -public class EcompUser implements Comparable{ - - private Long orgId; - private String managerId; - private String firstName; - private String middleInitial; - private String lastName; - private String phone; - private String email; - private String hrid; - private String orgUserId; - private String orgCode; - private String orgManagerUserId; - private String jobTitle; - private String loginId; - private boolean active; - - - private Set roles; - - public Long getOrgId() { - return orgId; - } - - public void setOrgId(Long orgId) { - this.orgId = orgId; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getMiddleInitial() { - return middleInitial; - } - - public void setMiddleInitial(String middleInitial) { - this.middleInitial = middleInitial; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getHrid() { - return hrid; - } - - public void setHrid(String hrid) { - this.hrid = hrid; - } - - public String getOrgUserId() { - return orgUserId; - } - - public void setOrgUserId(String orgUserId) { - this.orgUserId = orgUserId; - } - - public String getOrgCode() { - return orgCode; - } - - public void setOrgCode(String orgCode) { - this.orgCode = orgCode; - } - - public String getOrgManagerUserId() { - return orgManagerUserId; - } - - public void setOrgManagerUserId(String orgManagerUserId) { - this.orgManagerUserId = orgManagerUserId; - } - - public String getJobTitle() { - return jobTitle; - } - - public void setJobTitle(String jobTitle) { - this.jobTitle = jobTitle; - } - - public String getLoginId() { - return loginId; - } - - public void setLoginId(String loginId) { - this.loginId = loginId; - } - - public boolean isActive() { - return active; - } - - public void setActive(boolean active) { - this.active = active; - } - - public Set getRoles() { - return roles; - } - - public void setRoles(Set roles) { - this.roles = roles; - } - - public String getManagerId() { - return managerId; - } - - public void setManagerId(String managerId) { - this.managerId = managerId; - } - - @Override - public String toString() { - String s = "@EcompUser[orgId: " + orgId // - + ", firstName: " + firstName // - + ", mi: " + middleInitial // - + ", lastName: " + lastName // - + ", phone: " + phone // - + ", email: " + email // - + ", hrid: " + hrid // - + ", orgUserId: " + orgUserId // - + ", orgCode: " + orgCode // - + ", orgManagerUserId: " + orgManagerUserId // - + ", jobTitle: " + jobTitle // - + ", loginId: " + loginId // - + ", active:" + active // - + "]"; - return s; - } - - @Override - public int compareTo(EcompUser o) { - return this.loginId.compareTo(o.loginId); - } - - -} diff --git a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java b/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java deleted file mode 100644 index 4eeb12f4..00000000 --- a/ecomp-sdk/thirdparty/src/main/java/org/openecomp/portalsdk/core/restful/domain/SharedContext.java +++ /dev/null @@ -1,300 +0,0 @@ -/*- - * ================================================================================ - * eCOMP Portal SDK - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property - * ================================================================================ - * Licensed 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.openecomp.portalsdk.core.restful.domain; - -/** - * Bean that represents shared-context data transferred in JSON objects. This is - * a minimum example: - * - *
        - * {
        - *   "context_id": "abc123",
        - *   "ckey": "myKey",
        - *   "cvalue": "my context value to share"
        - * }
        - * 
        - */ -public class SharedContext { - - // Response field indicates nothing else is present - private String response; - // Required fields when data is present - private String context_id, ckey, cvalue; - private Long id, create_time; - // Additional database fields from the DomainVO object. - private String created, modified, createdId, modifiedId, auditUserId, auditTrail, rowNum; - - /** - * Gets the response field. - * - * @return response - */ - public String getResponse() { - return response; - } - - /** - * Sets the response field. - * - * @param response - * The response to set - */ - public void setResponse(final String response) { - this.response = response; - } - - /** - * Gets the database row ID. - * - * @return Database row ID - */ - public Long getId() { - return id; - } - - /** - * Sets the database row ID. - * - * @param id - */ - public void setId(final Long id) { - this.id = id; - } - - /** - * Gets the creation time - * - * @return Creation time as a Long - */ - public Long getCreate_time() { - return create_time; - } - - /** - * Sets the creation time - * - * @param create_time - */ - public void setCreate_time(final Long create_time) { - this.create_time = create_time; - } - - /** - * Gets the context ID - * - * @return Context ID - */ - public String getContext_id() { - return context_id; - } - - /** - * Sets the context ID - * - * @param context_id - */ - public void setContext_id(final String context_id) { - this.context_id = context_id; - } - - /** - * Gets the key of the key-value pair. Called ckey because "key" is a - * reserved word in Mysql. - * - * @return The key - */ - public String getCkey() { - return ckey; - } - - /** - * Sets the key of the key-value pair. - * - * @param ckey - */ - public void setCkey(final String ckey) { - this.ckey = ckey; - } - - /** - * Gets the value of the key-value pair. Called cvalue because "value" is a - * reserved word in Mysql. - * - * @return Value of the key-value pair. - */ - public String getCvalue() { - return cvalue; - } - - /** - * Sets the value of the key-value pair. - * - * @param cvalue - */ - public void setCvalue(final String cvalue) { - this.cvalue = cvalue; - } - - /** - * Gets the created value. - * - * @return Created info from database - */ - public String getCreated() { - return created; - } - - /** - * Sets the created value. - * - * @param created - */ - public void setCreated(String created) { - this.created = created; - } - - /** - * Gets the modified value. - * - * @return Modified info from database - */ - public String getModified() { - return modified; - } - - /** - * Sets the modified value. - * - * @param modified - */ - public void setModified(String modified) { - this.modified = modified; - } - - /** - * Gets the createdId value. - * - * @return CreatedId info from database - */ - public String getCreatedId() { - return createdId; - } - - /** - * Sets the createdId value. - * - * @param createdId - */ - public void setCreatedId(String createdId) { - this.createdId = createdId; - } - - /** - * Gets the modifiedId value. - * - * @return ModifiedId info from database - */ - public String getModifiedId() { - return modifiedId; - } - - /** - * Sets the modifiedId value. - * - * @param modifiedId - */ - public void setModifiedId(String modifiedId) { - this.modifiedId = modifiedId; - } - - /** - * Gets the audit user ID value. - * - * @return AuditUserId from database - */ - public String getAuditUserId() { - return auditUserId; - } - - /** - * Sets the audit user ID value. - * - * @param auditUserId - */ - public void setAuditUserId(String auditUserId) { - this.auditUserId = auditUserId; - } - - /** - * Gets the audit trail value. - * - * @return AuditTrail from database. - */ - public String getAuditTrail() { - return auditTrail; - } - - /** - * Sets the audit trail value. - * - * @param auditTrail - */ - public void setAuditTrail(String auditTrail) { - this.auditTrail = auditTrail; - } - - /** - * Gets the row num value. - * - * @return rowNum from database. - */ - public String getRowNum() { - return rowNum; - } - - /** - * Sets the row num value. - * - * @param rowNum - */ - public void setRowNum(String rowNum) { - this.rowNum = rowNum; - } - - @Override - public boolean equals(Object obj) { - SharedContext other = (SharedContext) obj; - return this.id == other.id && this.context_id.equals(other.context_id) && this.ckey.equals(other.ckey) - && this.cvalue.equals(other.cvalue); - } - - @Override - public int hashCode() { - return (int) (id + context_id.hashCode() + ckey.hashCode() + cvalue.hashCode()); - } - - @Override - public String toString() { - String s = "@SharedContext[id: " + id + "; context_id: " + context_id + "; ckey: " + ckey + "; cvalue: " - + cvalue + "]"; - return s; - } - -} -- 2.16.6